void FAnimationRuntime::ConvertPoseToMeshSpace(const TArray<FTransform> & LocalTransforms, TArray<FTransform> & MeshSpaceTransforms, const FBoneContainer& RequiredBones) { const int32 NumBones = RequiredBones.GetNumBones(); // right now all this does is to convert to SpaceBases check( NumBones == LocalTransforms.Num() ); check( NumBones == MeshSpaceTransforms.Num() ); const FTransform* LocalTransformsData = LocalTransforms.GetData(); FTransform* SpaceBasesData = MeshSpaceTransforms.GetData(); const TArray<FBoneIndexType> & RequiredBoneIndexArray = RequiredBones.GetBoneIndicesArray(); // First bone is always root bone, and it doesn't have a parent. { check( RequiredBoneIndexArray[0] == 0 ); MeshSpaceTransforms[0] = LocalTransforms[0]; } const int32 NumRequiredBones = RequiredBoneIndexArray.Num(); for(int32 i=1; i<NumRequiredBones; i++) { const int32 BoneIndex = RequiredBoneIndexArray[i]; FPlatformMisc::Prefetch(SpaceBasesData + BoneIndex); // For all bones below the root, final component-space transform is relative transform * component-space transform of parent. const int32 ParentIndex = RequiredBones.GetParentBoneIndex(BoneIndex); FPlatformMisc::Prefetch(SpaceBasesData + ParentIndex); FTransform::Multiply(SpaceBasesData + BoneIndex, LocalTransformsData + BoneIndex, SpaceBasesData + ParentIndex); checkSlow( MeshSpaceTransforms[BoneIndex].IsRotationNormalized() ); checkSlow( !MeshSpaceTransforms[BoneIndex].ContainsNaN() ); } }
void FAnimationRuntime::InitializeTransform(const FBoneContainer& RequiredBones, /*inout*/ FTransformArrayA2 & Atoms) { check( Atoms.Num() == RequiredBones.GetNumBones() ); const TArray<FBoneIndexType> & RequiredBoneIndices = RequiredBones.GetBoneIndicesArray(); for (int32 j = 0; j < RequiredBoneIndices.Num(); ++j) { const int32 BoneIndex = RequiredBoneIndices[j]; Atoms[BoneIndex].SetIdentity(); } }