Refactor RootMotionData into Transform to simplify code

This commit is contained in:
Wojtek Figat
2023-05-04 14:18:12 +02:00
parent 2b2b4f6b6f
commit a889d888ff
7 changed files with 31 additions and 137 deletions

View File

@@ -175,12 +175,7 @@ namespace FlaxEngine
/// <summary>
/// The root motion data.
/// </summary>
public Vector3 RootMotionTranslation;
/// <summary>
/// The root motion data.
/// </summary>
public Quaternion RootMotionRotation;
public Transform RootMotion;
/// <summary>
/// The animation time position (in seconds).
@@ -251,8 +246,7 @@ namespace FlaxEngine
destination->NodesCount = source->NodesCount;
destination->Unused = source->Unused;
Utils.MemoryCopy(new IntPtr(destination->Nodes), new IntPtr(source->Nodes), (ulong)(source->NodesCount * sizeof(Transform)));
destination->RootMotionTranslation = source->RootMotionTranslation;
destination->RootMotionRotation = source->RootMotionRotation;
destination->RootMotion = source->RootMotion;
destination->Position = source->Position;
destination->Length = source->Length;
}

View File

@@ -39,8 +39,7 @@ struct InternalImpulse
int32 NodesCount;
int32 Unused;
Transform* Nodes;
Vector3 RootMotionTranslation;
Quaternion RootMotionRotation;
Transform RootMotion;
float Position;
float Length;
};

View File

@@ -11,53 +11,6 @@ extern void RetargetSkeletonNode(const SkeletonData& sourceSkeleton, const Skele
ThreadLocal<AnimGraphContext> AnimGraphExecutor::Context;
RootMotionData RootMotionData::Identity = { Vector3(0.0f), Quaternion(0.0f, 0.0f, 0.0f, 1.0f) };
RootMotionData& RootMotionData::operator+=(const RootMotionData& b)
{
Translation += b.Translation;
Rotation *= b.Rotation;
return *this;
}
RootMotionData& RootMotionData::operator+=(const Transform& b)
{
Translation += b.Translation;
Rotation *= b.Orientation;
return *this;
}
RootMotionData& RootMotionData::operator-=(const Transform& b)
{
Translation -= b.Translation;
Quaternion invRotation = Rotation;
invRotation.Invert();
Quaternion::Multiply(invRotation, b.Orientation, Rotation);
return *this;
}
RootMotionData RootMotionData::operator+(const RootMotionData& b) const
{
RootMotionData result;
result.Translation = Translation + b.Translation;
result.Rotation = Rotation * b.Rotation;
return result;
}
RootMotionData RootMotionData::operator-(const RootMotionData& b) const
{
RootMotionData result;
result.Rotation = Rotation;
result.Rotation.Invert();
Vector3::Transform(b.Translation - Translation, result.Rotation, result.Translation);
Quaternion::Multiply(result.Rotation, b.Rotation, result.Rotation);
return result;
}
Transform AnimGraphImpulse::GetNodeModelTransformation(SkeletonData& skeleton, int32 nodeIndex) const
{
const int32 parentIndex = skeleton.Nodes[nodeIndex].ParentIndex;
@@ -89,7 +42,7 @@ void AnimGraphInstanceData::Clear()
LastUpdateTime = -1;
CurrentFrame = 0;
RootTransform = Transform::Identity;
RootMotion = RootMotionData::Identity;
RootMotion = Transform::Identity;
Parameters.Resize(0);
State.Resize(0);
NodesPose.Resize(0);
@@ -105,7 +58,7 @@ void AnimGraphInstanceData::ClearState()
LastUpdateTime = -1;
CurrentFrame = 0;
RootTransform = Transform::Identity;
RootMotion = RootMotionData::Identity;
RootMotion = Transform::Identity;
State.Resize(0);
NodesPose.Resize(0);
Slots.Clear();
@@ -259,7 +212,7 @@ void AnimGraphExecutor::Update(AnimGraphInstanceData& data, float dt)
e.Hit = false;
// Init empty nodes data
context.EmptyNodes.RootMotion = RootMotionData::Identity;
context.EmptyNodes.RootMotion = Transform::Identity;
context.EmptyNodes.Position = 0.0f;
context.EmptyNodes.Length = 0.0f;
context.EmptyNodes.Nodes.Resize(_skeletonNodesCount, false);

View File

@@ -26,58 +26,6 @@ class AnimGraphExecutor;
class SkinnedModel;
class SkeletonData;
/// <summary>
/// The root motion data container. Supports displacement and rotation (no scale component).
/// </summary>
struct RootMotionData
{
static RootMotionData Identity;
Vector3 Translation;
Quaternion Rotation;
RootMotionData()
{
}
RootMotionData(const Vector3& translation, const Quaternion& rotation)
{
Translation = translation;
Rotation = rotation;
}
RootMotionData(const RootMotionData& other)
{
Translation = other.Translation;
Rotation = other.Rotation;
}
explicit RootMotionData(const Transform& other)
{
Translation = other.Translation;
Rotation = other.Orientation;
}
RootMotionData& operator=(const Transform& other)
{
Translation = other.Translation;
Rotation = other.Orientation;
return *this;
}
RootMotionData& operator+=(const RootMotionData& b);
RootMotionData& operator+=(const Transform& b);
RootMotionData& operator-=(const Transform& b);
RootMotionData operator+(const RootMotionData& b) const;
RootMotionData operator-(const RootMotionData& b) const;
static void Lerp(const RootMotionData& t1, const RootMotionData& t2, float amount, RootMotionData& result)
{
Vector3::Lerp(t1.Translation, t2.Translation, amount, result.Translation);
Quaternion::Slerp(t1.Rotation, t2.Rotation, amount, result.Rotation);
}
};
/// <summary>
/// The animation graph 'impulse' connections data container (the actual transfer is done via pointer as it gives better performance).
/// Container for skeleton nodes transformation hierarchy and any other required data.
@@ -93,7 +41,7 @@ struct FLAXENGINE_API AnimGraphImpulse
/// <summary>
/// The root motion extracted from the animation to apply on animated object.
/// </summary>
RootMotionData RootMotion = RootMotionData::Identity;
Transform RootMotion = Transform::Identity;
/// <summary>
/// The animation time position (in seconds).
@@ -348,7 +296,7 @@ public:
/// <summary>
/// The current root motion delta to apply on a target object.
/// </summary>
RootMotionData RootMotion = RootMotionData::Identity;
Transform RootMotion = Transform::Identity;
/// <summary>
/// The animation graph parameters collection (instanced, override the default values).
@@ -883,7 +831,7 @@ private:
};
int32 GetRootNodeIndex(Animation* anim);
void ExtractRootMotion(Span<int32> mapping, int32 rootNodeIndex, Animation* anim, float pos, float prevPos, Transform& rootNode, RootMotionData& rootMotion);
void ExtractRootMotion(Span<int32> mapping, int32 rootNodeIndex, Animation* anim, float pos, float prevPos, Transform& rootNode, Transform& rootMotion);
void ProcessAnimEvents(AnimGraphNode* node, bool loop, float length, float animPos, float animPrevPos, Animation* anim, float speed);
void ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode* node, bool loop, float length, float pos, float prevPos, Animation* anim, float speed, float weight = 1.0f, ProcessAnimationMode mode = ProcessAnimationMode::Override);
Variant SampleAnimation(AnimGraphNode* node, bool loop, float length, float startTimePos, float prevTimePos, float& newTimePos, Animation* anim, float speed);

View File

@@ -58,7 +58,7 @@ int32 AnimGraphExecutor::GetRootNodeIndex(Animation* anim)
return rootNodeIndex;
}
void AnimGraphExecutor::ExtractRootMotion(const Span<int32> mapping, int32 rootNodeIndex, Animation* anim, float pos, float prevPos, Transform& rootNode, RootMotionData& rootMotion)
void AnimGraphExecutor::ExtractRootMotion(const Span<int32> mapping, int32 rootNodeIndex, Animation* anim, float pos, float prevPos, Transform& rootNode, Transform& rootMotion)
{
const Transform& refPose = GetEmptyNodes()->Nodes[rootNodeIndex];
const int32 nodeToChannel = mapping[rootNodeIndex];
@@ -88,15 +88,15 @@ void AnimGraphExecutor::ExtractRootMotion(const Span<int32> mapping, int32 rootN
// (end - before + now - begin)
// It sums the motion since the last update to anim end and since the start to now
rootMotion.Translation = rootEnd.Translation - rootBefore.Translation + rootNode.Translation - rootBegin.Translation;
rootMotion.Rotation = rootEnd.Orientation * rootBefore.Orientation.Conjugated() * (rootNode.Orientation * rootBegin.Orientation.Conjugated());
//rootMotion.Rotation = Quaternion::Identity;
rootMotion.Orientation = rootEnd.Orientation * rootBefore.Orientation.Conjugated() * (rootNode.Orientation * rootBegin.Orientation.Conjugated());
//rootMotion.Orientation = Quaternion::Identity;
}
else
{
// Simple motion delta
// (now - before)
rootMotion.Translation = rootNode.Translation - rootBefore.Translation;
rootMotion.Rotation = rootBefore.Orientation.Conjugated() * rootNode.Orientation;
rootMotion.Orientation = rootBefore.Orientation.Conjugated() * rootNode.Orientation;
}
}
@@ -335,25 +335,25 @@ void AnimGraphExecutor::ProcessAnimation(AnimGraphImpulse* nodes, AnimGraphNode*
// Calculate the root motion node transformation
const int32 rootNodeIndex = GetRootNodeIndex(anim);
Transform rootNode = emptyNodes->Nodes[rootNodeIndex];
RootMotionData& dstNode = nodes->RootMotion;
RootMotionData srcNode(rootNode);
Transform& dstNode = nodes->RootMotion;
Transform srcNode(rootNode);
ExtractRootMotion(mapping.NodesMapping, rootNodeIndex, anim, animPos, animPrevPos, rootNode, srcNode);
// Blend root motion
if (mode == ProcessAnimationMode::BlendAdditive)
{
dstNode.Translation += srcNode.Translation * weight;
BlendAdditiveWeightedRotation(dstNode.Rotation, srcNode.Rotation, weight);
BlendAdditiveWeightedRotation(dstNode.Orientation, srcNode.Orientation, weight);
}
else if (mode == ProcessAnimationMode::Add)
{
dstNode.Translation += srcNode.Translation * weight;
dstNode.Rotation += srcNode.Rotation * weight;
dstNode.Orientation += srcNode.Orientation * weight;
}
else if (weighted)
{
dstNode.Translation = srcNode.Translation * weight;
dstNode.Rotation = srcNode.Rotation * weight;
dstNode.Orientation = srcNode.Orientation * weight;
}
else
{
@@ -410,7 +410,7 @@ Variant AnimGraphExecutor::SampleAnimationsWithBlend(AnimGraphNode* node, bool l
}
if (_rootMotionMode != RootMotionMode::NoExtraction)
{
nodes->RootMotion.Rotation.Normalize();
nodes->RootMotion.Orientation.Normalize();
}
return nodes;
@@ -444,7 +444,7 @@ Variant AnimGraphExecutor::SampleAnimationsWithBlend(AnimGraphNode* node, bool l
}
if (_rootMotionMode != RootMotionMode::NoExtraction)
{
nodes->RootMotion.Rotation.Normalize();
nodes->RootMotion.Orientation.Normalize();
}
return nodes;
@@ -469,7 +469,7 @@ Variant AnimGraphExecutor::Blend(AnimGraphNode* node, const Value& poseA, const
{
Transform::Lerp(nodesA->Nodes[i], nodesB->Nodes[i], alpha, nodes->Nodes[i]);
}
RootMotionData::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
Transform::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
nodes->Position = Math::Lerp(nodesA->Position, nodesB->Position, alpha);
nodes->Length = Math::Lerp(nodesA->Length, nodesB->Length, alpha);
@@ -1017,7 +1017,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
{
Transform::Lerp(nodesA->Nodes[i], nodesB->Nodes[i], alpha, nodes->Nodes[i]);
}
RootMotionData::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
Transform::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
value = nodes;
}
@@ -1063,7 +1063,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
t.Orientation.Normalize();
Transform::Lerp(tA, t, alpha, nodes->Nodes[i]);
}
RootMotionData::Lerp(nodesA->RootMotion, nodesA->RootMotion + nodesB->RootMotion, alpha, nodes->RootMotion);
Transform::Lerp(nodesA->RootMotion, nodesA->RootMotion + nodesB->RootMotion, alpha, nodes->RootMotion);
value = nodes;
}
}
@@ -1111,7 +1111,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
nodes->Nodes[nodeIndex] = tA;
}
}
RootMotionData::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
Transform::Lerp(nodesA->RootMotion, nodesB->RootMotion, alpha, nodes->RootMotion);
value = nodes;
}
@@ -1496,7 +1496,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
value = poseData->RootMotion.Translation;
break;
case 1:
value = poseData->RootMotion.Rotation;
value = poseData->RootMotion.Orientation;
break;
}
}
@@ -1528,7 +1528,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
auto nodes = node->GetNodes(this);
nodes->Nodes = poseData->Nodes;
nodes->RootMotion.Translation = (Vector3)tryGetValue(node->GetBox(2), Value::Zero);
nodes->RootMotion.Rotation = (Quaternion)tryGetValue(node->GetBox(3), Value::Zero);
nodes->RootMotion.Orientation = (Quaternion)tryGetValue(node->GetBox(3), Value::Zero);
value = nodes;
break;
}
@@ -1546,7 +1546,7 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
auto nodes = node->GetNodes(this);
nodes->Nodes = poseData->Nodes;
nodes->RootMotion.Translation = poseData->RootMotion.Translation + (Vector3)tryGetValue(node->GetBox(2), Value::Zero);
nodes->RootMotion.Rotation = poseData->RootMotion.Rotation * (Quaternion)tryGetValue(node->GetBox(3), Value::Zero);
nodes->RootMotion.Orientation = poseData->RootMotion.Orientation * (Quaternion)tryGetValue(node->GetBox(3), Value::Zero);
value = nodes;
break;
}