diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp index d0963a33ee..00eff6c047 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include @@ -166,6 +165,34 @@ namespace EMotionFX return finalMotionData; } + AZ::SceneAPI::DataTypes::MatrixType MotionDataBuilder::GetLocalSpaceBindPose(const SceneContainers::SceneGraph& sceneGraph, + const SceneContainers::SceneGraph::NodeIndex rootBoneNodeIndex, + const SceneContainers::SceneGraph::NodeIndex nodeIndex, + const SceneDataTypes::ITransform* transform, + const SceneDataTypes::IBoneData* bone) const + { + if (nodeIndex != rootBoneNodeIndex) + { + const SceneContainers::SceneGraph::NodeIndex parentNodeIndex = sceneGraph.GetNodeParent(nodeIndex); + const SceneDataTypes::IGraphObject* parentNode = sceneGraph.GetNodeContent(parentNodeIndex).get(); + if (const SceneDataTypes::IBoneData* parentBone = azrtti_cast(parentNode)) + { + return parentBone->GetWorldTransform().GetInverseFull() * bone->GetWorldTransform(); + } + } + + if (bone) + { + return bone->GetWorldTransform(); + } + else if (transform) + { + return transform->GetMatrix(); + } + + return AZ::SceneAPI::DataTypes::MatrixType::CreateIdentity(); + } + AZ::SceneAPI::Events::ProcessingResult MotionDataBuilder::BuildMotionData(MotionDataBuilderContext& context) { if (context.m_phase != AZ::RC::Phase::Filling) @@ -220,8 +247,10 @@ namespace EMotionFX continue; } - AZStd::shared_ptr nodeBone = azrtti_cast(it->second); - if (!nodeBone) + // Check if we are dealing with a transform node or a bone and only recurse down the node hierarchy in this case. + const SceneDataTypes::IBoneData* nodeBone = azrtti_cast(it->second.get()); + const SceneDataTypes::ITransform* nodeTransform = azrtti_cast(it->second.get()); + if (!nodeBone && !nodeTransform) { it.IgnoreNodeDescendants(); continue; @@ -289,24 +318,13 @@ namespace EMotionFX // Get the bind pose transform in local space. using SceneAPIMatrixType = AZ::SceneAPI::DataTypes::MatrixType; - SceneAPIMatrixType bindSpaceLocalTransform; - const SceneContainers::SceneGraph::NodeIndex parentIndex = graph.GetNodeParent(boneNodeIndex); - if (boneNodeIndex != rootBoneNodeIndex) - { - auto parentNode = graph.GetNodeContent(parentIndex); - AZStd::shared_ptr parentNodeBone = azrtti_cast(parentNode); - bindSpaceLocalTransform = parentNodeBone->GetWorldTransform().GetInverseFull() * nodeBone->GetWorldTransform(); - } - else - { - bindSpaceLocalTransform = nodeBone->GetWorldTransform(); - } + const SceneAPIMatrixType bindSpaceLocalTransform = GetLocalSpaceBindPose(graph, rootBoneNodeIndex, boneNodeIndex, nodeTransform, nodeBone); // Get the time step and make sure it didn't change compared to other joint animations. const double timeStep = animation->GetTimeStepBetweenFrames(); lowestTimeStep = AZ::GetMin(timeStep, lowestTimeStep); - SceneAPIMatrixType sampleFrameTransformInverse; + AZ::SceneAPI::DataTypes::MatrixType sampleFrameTransformInverse; if (additiveRule) { size_t sampleFrameIndex = additiveRule->GetSampleFrameIndex(); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h index 5cf865324b..ca7402f83b 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionDataBuilder.h @@ -9,6 +9,9 @@ #include #include +#include +#include +#include namespace EMotionFX { @@ -28,6 +31,14 @@ namespace EMotionFX static void Reflect(AZ::ReflectContext* context); AZ::SceneAPI::Events::ProcessingResult BuildMotionData(MotionDataBuilderContext& context); + + private: + //! Get the bind pose transform in local space. + AZ::SceneAPI::DataTypes::MatrixType GetLocalSpaceBindPose(const AZ::SceneAPI::Containers::SceneGraph& sceneGraph, + const AZ::SceneAPI::Containers::SceneGraph::NodeIndex rootBoneNodeIndex, + const AZ::SceneAPI::Containers::SceneGraph::NodeIndex nodeIndex, + const AZ::SceneAPI::DataTypes::ITransform* transform, + const AZ::SceneAPI::DataTypes::IBoneData* bone) const; }; } // namespace Pipeline } // namespace EMotionFX