Transform node animations ignored (#2160)
* Fixing user asset issue having a transform node as root rather than a bone making the whole character not animate. * Enabled the ability to export animations for transform nodes. Signed-off-by: Benjamin Jillich <jillich@amazon.com>
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/DataTypeUtilities.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IAnimationData.h>
|
||||
#include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
|
||||
|
||||
@@ -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<const SceneDataTypes::IBoneData*>(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<const SceneDataTypes::IBoneData> nodeBone = azrtti_cast<const SceneDataTypes::IBoneData*>(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<const SceneDataTypes::IBoneData*>(it->second.get());
|
||||
const SceneDataTypes::ITransform* nodeTransform = azrtti_cast<const SceneDataTypes::ITransform*>(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<const SceneDataTypes::IBoneData> parentNodeBone = azrtti_cast<const SceneDataTypes::IBoneData*>(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<double>(timeStep, lowestTimeStep);
|
||||
|
||||
SceneAPIMatrixType sampleFrameTransformInverse;
|
||||
AZ::SceneAPI::DataTypes::MatrixType sampleFrameTransformInverse;
|
||||
if (additiveRule)
|
||||
{
|
||||
size_t sampleFrameIndex = additiveRule->GetSampleFrameIndex();
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include <SceneAPI/SceneCore/Components/ExportingComponent.h>
|
||||
#include <SceneAPI/SceneCore/Containers/Scene.h>
|
||||
#include <SceneAPI/SceneCore/Containers/SceneGraph.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
|
||||
#include <SceneAPI/SceneCore/DataTypes/GraphData/ITransform.h>
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user