Skip to content

Instantly share code, notes, and snippets.

@rokups
Created August 13, 2018 15:49
Show Gist options
  • Save rokups/1aa808922681d8ba4d9ffdef66668504 to your computer and use it in GitHub Desktop.
Save rokups/1aa808922681d8ba4d9ffdef66668504 to your computer and use it in GitHub Desktop.
diff --git a/Source/Urho3D/Graphics/AnimationState.cpp b/Source/Urho3D/Graphics/AnimationState.cpp
index a6a22d16b..3d54836e9 100644
--- a/Source/Urho3D/Graphics/AnimationState.cpp
+++ b/Source/Urho3D/Graphics/AnimationState.cpp
@@ -138,7 +138,10 @@ void AnimationState::SetStartBone(Bone* startBone)
const StringHash& nameHash = i->second_.nameHash_;
if (nameHash == startBone->nameHash_)
+ {
trackBone = startBone;
+ previousRootPosition_ = i->second_.keyFrames_.Front().position_;
+ }
else
{
Node* trackBoneNode = startBone->node_->GetChild(nameHash, true);
@@ -564,6 +567,29 @@ void AnimationState::ApplyTrack(AnimationStateTrack& stateTrack, float weight, b
}
}
+ if (rootMotion_ != ARM_NONE && track->nameHash_ == startBone_->nameHash_)
+ {
+ if (lastFrame_ > frame)
+ {
+ // Handle animation wraps around.
+ previousRootPosition_ -= track->keyFrames_.Back().position_;
+ }
+
+ auto delta = newPosition - previousRootPosition_;
+ previousRootPosition_ = newPosition;
+ lastFrame_ = frame;
+
+ if (rootMotion_ == ARM_XZ)
+ {
+ const auto& nodePosition = node->GetPosition();
+ newPosition.x_ = nodePosition.x_;
+ newPosition.z_ = nodePosition.z_;
+ delta.y_ = 0;
+ }
+
+ node->GetParent()->Translate(delta * node->GetParent()->GetScale());
+ }
+
if (silent)
{
if (channelMask & CHANNEL_POSITION)
diff --git a/Source/Urho3D/Graphics/AnimationState.h b/Source/Urho3D/Graphics/AnimationState.h
index 337708612..67f94e350 100644
--- a/Source/Urho3D/Graphics/AnimationState.h
+++ b/Source/Urho3D/Graphics/AnimationState.h
@@ -25,6 +25,7 @@
#include "../Container/HashMap.h"
#include "../Container/Ptr.h"
#include "../Math/StringHash.h"
+#include "../Math/Vector3.h"
namespace Urho3D
{
@@ -47,6 +48,17 @@ enum AnimationBlendMode
ABM_ADDITIVE
};
+/// %Animation root motion mode.
+enum AnimationRootMotion
+{
+ /// Motion of the root bone is applied directly to that bone.
+ ARM_NONE,
+ /// XZ motion of the root bone is applied to the parent of the bone.
+ ARM_XZ,
+ /// Motion of the root bone is applied to its parent.
+ ARM_FULL,
+};
+
/// %Animation instance per-track data.
struct AnimationStateTrack
{
@@ -175,6 +187,12 @@ private:
unsigned char layer_;
/// Blending mode.
AnimationBlendMode blendingMode_;
+ /// Root motion state.
+ AnimationRootMotion rootMotion_{ARM_XZ};
+ /// Previous position of root bone.
+ Vector3 previousRootPosition_;
+ ///
+ unsigned lastFrame_ = 0;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment