void FAnimationRuntime::ConvertPoseToMeshRotation(FCompactPose& LocalPose) { // Convert all rotations to mesh space // only the root bone doesn't have a parent. So skip it to save a branch in the iteration. for (FCompactPoseBoneIndex BoneIndex(1); BoneIndex < LocalPose.GetNumBones(); ++BoneIndex) { const FCompactPoseBoneIndex ParentIndex = LocalPose.GetParentBoneIndex(BoneIndex); const FQuat MeshSpaceRotation = LocalPose[ParentIndex].GetRotation() * LocalPose[BoneIndex].GetRotation(); LocalPose[BoneIndex].SetRotation(MeshSpaceRotation); } }
void FAnimationRuntime::ConvertMeshRotationPoseToLocalSpace(FCompactPose& Pose) { // Convert all rotations to mesh space // only the root bone doesn't have a parent. So skip it to save a branch in the iteration. for (FCompactPoseBoneIndex BoneIndex(Pose.GetNumBones()-1); BoneIndex > 0; --BoneIndex) { const FCompactPoseBoneIndex ParentIndex = Pose.GetParentBoneIndex(BoneIndex); FQuat LocalSpaceRotation = Pose[ParentIndex].GetRotation().Inverse() * Pose[BoneIndex].GetRotation(); Pose[BoneIndex].SetRotation(LocalSpaceRotation); } }
void FAnimationRuntime::BlendPosesTogetherPerBoneInMeshSpace(TArray<FCompactPose>& SourcePoses, const TArray<FBlendedCurve>& SourceCurves, const UBlendSpaceBase* BlendSpace, const TArray<FBlendSampleData>& BlendSampleDataCache, FCompactPose& ResultPose, FBlendedCurve& ResultCurve) { FQuat NewRotation; USkeleton* Skeleton = BlendSpace->GetSkeleton(); // all this is going to do is to convert SourcePoses.Rotation to be mesh space, and then once it goes through BlendPosesTogetherPerBone, convert back to local for (FCompactPose& Pose : SourcePoses) { for (const FCompactPoseBoneIndex BoneIndex : Pose.ForEachBoneIndex()) { const FCompactPoseBoneIndex ParentIndex = Pose.GetParentBoneIndex(BoneIndex); if (ParentIndex != INDEX_NONE) { NewRotation = Pose[ParentIndex].GetRotation()*Pose[BoneIndex].GetRotation(); NewRotation.Normalize(); } else { NewRotation = Pose[BoneIndex].GetRotation(); } // now copy back to SourcePoses Pose[BoneIndex].SetRotation(NewRotation); } } // now we have mesh space rotation, call BlendPosesTogetherPerBone BlendPosesTogetherPerBone(SourcePoses, SourceCurves, BlendSpace, BlendSampleDataCache, ResultPose, ResultCurve); // now result atoms has the output with mesh space rotation. Convert back to local space, start from back for (const FCompactPoseBoneIndex BoneIndex : ResultPose.ForEachBoneIndex()) { const FCompactPoseBoneIndex ParentIndex = ResultPose.GetParentBoneIndex(BoneIndex); if (ParentIndex != INDEX_NONE) { FQuat LocalBlendQuat = ResultPose[ParentIndex].GetRotation().Inverse()*ResultPose[BoneIndex].GetRotation(); ResultPose[BoneIndex].SetRotation(LocalBlendQuat); ResultPose[BoneIndex].NormalizeRotation(); } } }