MCPcopy Create free account
hub / github.com/FlaxEngine/FlaxEngine / UpdateDeformationBuffer

Method UpdateDeformationBuffer

Source/Engine/Level/Actors/SplineModel.cpp:220–324  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

218}
219
220void SplineModel::UpdateDeformationBuffer()
221{
222 PROFILE_CPU();
223
224 // Deformation buffer contains precomputed matrices for each chunk of the spline segment (packed with transposed float3x4 matrix)
225 _deformationDirty = false;
226 if (!_deformationBuffer)
227 _deformationBuffer = GPUDevice::Instance->CreateBuffer(GetName());
228 const auto& keyframes = _spline->Curve.GetKeyframes();
229 const int32 segments = keyframes.Count() - 1;
230 const int32 chunksPerSegment = Math::Clamp(Math::CeilToInt(SPLINE_RESOLUTION * _quality), 2, 1024);
231 const int32 count = (chunksPerSegment * segments + 1) * 3;
232 const uint32 size = count * sizeof(Float4);
233 if (_deformationBuffer->GetSize() != size)
234 {
235 if (_deformationBufferData)
236 {
237 Allocator::Free(_deformationBufferData);
238 _deformationBufferData = nullptr;
239 }
240 if (_deformationBuffer->Init(GPUBufferDescription::Typed(count, PixelFormat::R32G32B32A32_Float, false, IsTransformStatic() ? GPUResourceUsage::Default : GPUResourceUsage::Dynamic)))
241 {
242 LOG(Error, "Failed to initialize the spline model {0} deformation buffer.", ToString());
243 return;
244 }
245 }
246 if (!_deformationBufferData)
247 _deformationBufferData = Allocator::Allocate(size);
248 _chunksPerSegment = (float)chunksPerSegment;
249
250 // Update pre-calculated matrices for spline chunks
251 auto ptr = (Matrix3x4*)_deformationBufferData;
252 const float chunksPerSegmentInv = 1.0f / (float)chunksPerSegment;
253 Matrix m;
254 Transform transform, leftTangent, rightTangent;
255 for (int32 segment = 0; segment < segments; segment++)
256 {
257 auto& instance = _instances[segment];
258 const auto& start = keyframes[segment];
259 const auto& end = keyframes[segment + 1];
260 const float tangentScale = (end.Time - start.Time) / 3.0f;
261 AnimationUtils::GetTangent(start.Value, start.TangentOut, tangentScale, leftTangent);
262 AnimationUtils::GetTangent(end.Value, end.TangentIn, tangentScale, rightTangent);
263 for (int32 chunk = 0; chunk < chunksPerSegment; chunk++)
264 {
265 const float alpha = (chunk == chunksPerSegment - 1) ? 1.0f : ((float)chunk * chunksPerSegmentInv);
266
267 // Evaluate transformation at the curve
268 AnimationUtils::Bezier(start.Value, leftTangent, rightTangent, end.Value, alpha, transform);
269
270 // Apply spline direction (from position 1st derivative)
271 Vector3 direction;
272 AnimationUtils::BezierFirstDerivative(start.Value.Translation, leftTangent.Translation, rightTangent.Translation, end.Value.Translation, alpha, direction);
273 direction.Normalize();
274 Quaternion orientation;
275 if (direction.IsZero())
276 orientation = Quaternion::Identity;
277 else if (Vector3::Dot(direction, Vector3::Up) >= 0.999f)

Callers

nothing calls this directly

Calls 15

ClampFunction · 0.85
IsTransformStaticFunction · 0.85
GetTangentFunction · 0.85
BezierFunction · 0.85
BezierFirstDerivativeFunction · 0.85
DotFunction · 0.85
RotationAxisFunction · 0.85
LookRotationFunction · 0.85
SetMatrixTransposeMethod · 0.80
RotDeterminantMethod · 0.80
CeilToIntFunction · 0.50
FreeFunction · 0.50

Tested by

no test coverage detected