Refactor RootMotionData into Transform to simplify code
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -39,8 +39,7 @@ struct InternalImpulse
|
||||
int32 NodesCount;
|
||||
int32 Unused;
|
||||
Transform* Nodes;
|
||||
Vector3 RootMotionTranslation;
|
||||
Quaternion RootMotionRotation;
|
||||
Transform RootMotion;
|
||||
float Position;
|
||||
float Length;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user