Răsfoiți Sursa

Rename AnimationBlendingMode to AnimationBlendMode for brevity and similarity with Graphics class BlendMode. Rename ABM_OVERRIDE to ABM_LERP. Implement weight to additive blending. Serialize blend mode over network for AnimationController.

Lasse Öörni 9 ani în urmă
părinte
comite
33bea5392d

+ 7 - 7
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -1252,9 +1252,9 @@ static void RegisterAnimatedModel(asIScriptEngine* engine)
     RegisterRefCounted<AnimationState>(engine, "AnimationState");
     RegisterStaticModel<AnimatedModel>(engine, "AnimatedModel", false);
 
-    engine->RegisterEnum("AnimationBlendingMode");
-    engine->RegisterEnumValue("AnimationBlendingMode", "ABM_OVERRIDE", ABM_OVERRIDE);
-    engine->RegisterEnumValue("AnimationBlendingMode", "ABM_ADDITIVE", ABM_ADDITIVE);
+    engine->RegisterEnum("AnimationBlendMode");
+    engine->RegisterEnumValue("AnimationBlendMode", "ABM_LERP", ABM_LERP);
+    engine->RegisterEnumValue("AnimationBlendMode", "ABM_ADDITIVE", ABM_ADDITIVE);
 
     engine->RegisterObjectBehaviour("AnimationState", asBEHAVE_FACTORY, "AnimationState@+ f(Node@+, Animation@+)", asFUNCTION(ConstructAnimationState), asCALL_CDECL);
     engine->RegisterObjectMethod("AnimationState", "void AddWeight(float)", asMETHOD(AnimationState, AddWeight), asCALL_THISCALL);
@@ -1273,8 +1273,8 @@ static void RegisterAnimatedModel(asIScriptEngine* engine)
     engine->RegisterObjectMethod("AnimationState", "bool get_looped() const", asMETHOD(AnimationState, IsLooped), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationState", "void set_weight(float)", asMETHOD(AnimationState, SetWeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationState", "float get_weight() const", asMETHOD(AnimationState, GetWeight), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimationState", "void set_blendingMode(AnimationBlendingMode)", asMETHOD(AnimationState, SetBlendingMode), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimationState", "AnimationBlendingMode get_blendingMode() const", asMETHOD(AnimationState, GetBlendingMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationState", "void set_blendMode(AnimationBlendMode)", asMETHOD(AnimationState, SetBlendMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationState", "AnimationBlendMode get_blendMode() const", asMETHOD(AnimationState, GetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationState", "void set_time(float)", asMETHOD(AnimationState, SetTime), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationState", "float get_time() const", asMETHOD(AnimationState, GetTime), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationState", "void set_layer(uint8)", asMETHOD(AnimationState, SetLayer), asCALL_THISCALL);
@@ -1327,7 +1327,7 @@ static void RegisterAnimationController(asIScriptEngine* engine)
     engine->RegisterObjectMethod("AnimationController", "bool SetTime(const String&in, float)", asMETHOD(AnimationController, SetTime), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool SetWeight(const String&in, float)", asMETHOD(AnimationController, SetWeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool SetLooped(const String&in, bool)", asMETHOD(AnimationController, SetLooped), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimationController", "bool SetBlendingMode(const String&in, AnimationBlendingMode)", asMETHOD(AnimationController, SetBlendingMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationController", "bool SetBlendMode(const String&in, AnimationBlendMode)", asMETHOD(AnimationController, SetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool SetSpeed(const String&in, float)", asMETHOD(AnimationController, SetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool SetAutoFade(const String&in, float)", asMETHOD(AnimationController, SetAutoFade), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool SetRemoveOnCompletion(const String&in, bool)", asMETHOD(AnimationController, SetRemoveOnCompletion), asCALL_THISCALL);
@@ -1340,7 +1340,7 @@ static void RegisterAnimationController(asIScriptEngine* engine)
     engine->RegisterObjectMethod("AnimationController", "float GetTime(const String&in) const", asMETHOD(AnimationController, GetTime), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "float GetWeight(const String&in) const", asMETHOD(AnimationController, GetWeight), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "bool GetLooped(const String&in) const", asMETHOD(AnimationController, IsLooped), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AnimationController", "AnimationBlendingMode GetBlendingMode(const String&in) const", asMETHOD(AnimationController, GetBlendingMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AnimationController", "AnimationBlendMode GetBlendMode(const String&in) const", asMETHOD(AnimationController, GetBlendMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "float GetLength(const String&in) const", asMETHOD(AnimationController, GetLength), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "float GetSpeed(const String&in) const", asMETHOD(AnimationController, GetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimationController", "float GetFadeTarget(const String&in) const", asMETHOD(AnimationController, GetFadeTarget), asCALL_THISCALL);

+ 8 - 4
Source/Urho3D/Graphics/AnimationController.cpp

@@ -45,6 +45,7 @@ static const unsigned char CTRL_AUTOFADE = 0x4;
 static const unsigned char CTRL_SETTIME = 0x08;
 static const unsigned char CTRL_SETWEIGHT = 0x10;
 static const unsigned char CTRL_REMOVEONCOMPLETION = 0x20;
+static const unsigned char CTRL_ADDITIVE = 0x40;
 static const float EXTRA_ANIM_FADEOUT_TIME = 0.1f;
 static const float COMMAND_STAY_TIME = 0.25f;
 static const unsigned MAX_NODE_ANIMATION_STATES = 256;
@@ -393,13 +394,13 @@ bool AnimationController::SetLooped(const String& name, bool enable)
     return true;
 }
 
-bool AnimationController::SetBlendingMode(const String& name, AnimationBlendingMode mode)
+bool AnimationController::SetBlendMode(const String& name, AnimationBlendMode mode)
 {
     AnimationState* state = GetAnimationState(name);
     if (!state)
         return false;
 
-    state->SetBlendingMode(mode);
+    state->SetBlendMode(mode);
     MarkNetworkUpdate();
     return true;
 }
@@ -495,10 +496,10 @@ bool AnimationController::IsLooped(const String& name) const
     return state ? state->IsLooped() : false;
 }
 
-AnimationBlendingMode AnimationController::GetBlendingMode(const String& name) const
+AnimationBlendMode AnimationController::GetBlendMode(const String& name) const
 {
     AnimationState* state = GetAnimationState(name);
-    return state ? state->GetBlendingMode() : ABM_OVERRIDE;
+    return state ? state->GetBlendMode() : ABM_LERP;
 }
 
 float AnimationController::GetLength(const String& name) const
@@ -634,6 +635,7 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
         unsigned char ctrl = buf.ReadUByte();
         state->SetLayer(buf.ReadUByte());
         state->SetLooped((ctrl & CTRL_LOOPED) != 0);
+        state->SetBlendMode((ctrl & CTRL_ADDITIVE) != 0 ? ABM_ADDITIVE : ABM_LERP);
         animations_[index].speed_ = (float)buf.ReadShort() / 2048.0f; // 11 bits of decimal precision, max. 16x playback speed
         animations_[index].targetWeight_ = (float)buf.ReadUByte() / 255.0f; // 8 bits of decimal precision
         animations_[index].fadeTime_ = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade
@@ -760,6 +762,8 @@ const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() cons
         Bone* startBone = state->GetStartBone();
         if (state->IsLooped())
             ctrl |= CTRL_LOOPED;
+        if (state->GetBlendMode() == ABM_ADDITIVE)
+            ctrl |= CTRL_ADDITIVE;
         if (startBone && model && startBone != model->GetSkeleton().GetRootBone())
             ctrl |= CTRL_STARTBONE;
         if (i->autoFadeTime_ > 0.0f)

+ 2 - 2
Source/Urho3D/Graphics/AnimationController.h

@@ -130,7 +130,7 @@ public:
     /// Set whether an animation auto-removes on completion.
     bool SetRemoveOnCompletion(const String& name, bool removeOnCompletion);
     /// Set animation blending mode. Return true on success.
-    bool SetBlendingMode(const String& name, AnimationBlendingMode mode);
+    bool SetBlendMode(const String& name, AnimationBlendMode mode);
 
     /// Return whether an animation is active. Note that non-looping animations that are being clamped at the end also return true.
     bool IsPlaying(const String& name) const;
@@ -153,7 +153,7 @@ public:
     /// Return animation looping.
     bool IsLooped(const String& name) const;
     /// Return animation blending mode.
-    AnimationBlendingMode GetBlendingMode(const String& name) const;
+    AnimationBlendMode GetBlendMode(const String& name) const;
     /// Return animation length.
     float GetLength(const String& name) const;
     /// Return animation speed.

+ 21 - 17
Source/Urho3D/Graphics/AnimationState.cpp

@@ -53,7 +53,7 @@ AnimationState::AnimationState(AnimatedModel* model, Animation* animation) :
     weight_(0.0f),
     time_(0.0f),
     layer_(0),
-    blendingMode_(ABM_OVERRIDE)
+    blendingMode_(ABM_LERP)
 {
     // Set default start bone (use all tracks.)
     SetStartBone(0);
@@ -67,7 +67,7 @@ AnimationState::AnimationState(Node* node, Animation* animation) :
     weight_(1.0f),
     time_(0.0f),
     layer_(0),
-    blendingMode_(ABM_OVERRIDE)
+    blendingMode_(ABM_LERP)
 {
     if (animation_)
     {
@@ -180,7 +180,7 @@ void AnimationState::SetWeight(float weight)
     }
 }
 
-void AnimationState::SetBlendingMode(AnimationBlendingMode mode)
+void AnimationState::SetBlendMode(AnimationBlendMode mode)
 {
     if (model_)
     {
@@ -475,7 +475,7 @@ void AnimationState::ApplyToNodes()
 {
     // When applying to a node hierarchy, can only use full weight (nothing to blend to)
     for (Vector<AnimationStateTrack>::Iterator i = stateTracks_.Begin(); i != stateTracks_.End(); ++i)
-        ApplyTrack(*i, 1.0, false);
+        ApplyTrack(*i, 1.0f, false);
 }
 
 void AnimationState::ApplyTrack(AnimationStateTrack& stateTrack, float weight, bool silent)
@@ -535,32 +535,36 @@ void AnimationState::ApplyTrack(AnimationStateTrack& stateTrack, float weight, b
             newScale = keyFrame->scale_;
     }
     
-    if (!Equals(weight, 1.0f)) // not full weight
-    {
-        if (channelMask & CHANNEL_POSITION)
-            newPosition = node->GetPosition().Lerp(newPosition, weight);
-        if (channelMask & CHANNEL_ROTATION)
-            newRotation = node->GetRotation().Slerp(newRotation, weight);
-        if (channelMask & CHANNEL_SCALE)
-            newScale = node->GetScale().Lerp(newScale, weight);
-    }
-    
-    if (blendingMode_ == ABM_ADDITIVE) // not ABM_OVERRIDE
+    if (blendingMode_ == ABM_ADDITIVE) // not ABM_LERP
     {
         if (channelMask & CHANNEL_POSITION)
         {
             Vector3 delta = newPosition - stateTrack.bone_->initialPosition_;
-            newPosition = node->GetPosition() + delta;
+            newPosition = node->GetPosition() + delta * weight;
         }
         if (channelMask & CHANNEL_ROTATION)
         {
             Quaternion delta = newRotation * stateTrack.bone_->initialRotation_.Inverse();
             newRotation = (delta * node->GetRotation()).Normalized();
+            if (!Equals(weight, 1.0f))
+                newRotation = node->GetRotation().Slerp(newRotation, weight);
         }
         if (channelMask & CHANNEL_SCALE)
         {
             Vector3 delta = newScale - stateTrack.bone_->initialScale_;
-            newScale = node->GetScale() + delta;
+            newScale = node->GetScale() + delta * weight;
+        }
+    }
+    else
+    {
+        if (!Equals(weight, 1.0f)) // not full weight
+        {
+            if (channelMask & CHANNEL_POSITION)
+                newPosition = node->GetPosition().Lerp(newPosition, weight);
+            if (channelMask & CHANNEL_ROTATION)
+                newRotation = node->GetRotation().Slerp(newRotation, weight);
+            if (channelMask & CHANNEL_SCALE)
+                newScale = node->GetScale().Lerp(newScale, weight);
         }
     }
     

+ 7 - 5
Source/Urho3D/Graphics/AnimationState.h

@@ -37,9 +37,11 @@ struct AnimationTrack;
 struct Bone;
 
 /// %Animation blending mode.
-enum AnimationBlendingMode
+enum AnimationBlendMode
 {
-    ABM_OVERRIDE = 0,
+    // Lerp blending (default)
+    ABM_LERP = 0,
+    // Additive blending based on difference from bind pose
     ABM_ADDITIVE
 };
 
@@ -81,7 +83,7 @@ public:
     /// Set blending weight.
     void SetWeight(float weight);
     /// Set blending mode.
-    void SetBlendingMode(AnimationBlendingMode mode);
+    void SetBlendMode(AnimationBlendMode mode);
     /// Set time position. Does not fire animation triggers.
     void SetTime(float time);
     /// Set per-bone blending weight by track index. Default is 1.0 (full), is multiplied  with the state's blending weight when applying the animation. Optionally recurses to child bones.
@@ -129,7 +131,7 @@ public:
     float GetWeight() const { return weight_; }
 
     /// Return blending mode.
-    AnimationBlendingMode GetBlendingMode() const { return blendingMode_; }
+    AnimationBlendMode GetBlendMode() const { return blendingMode_; }
 
     /// Return time position.
     float GetTime() const { return time_; }
@@ -170,7 +172,7 @@ private:
     /// Blending layer.
     unsigned char layer_;
     /// Blending mode.
-    AnimationBlendingMode blendingMode_;
+    AnimationBlendMode blendingMode_;
 };
 
 }

+ 2 - 2
Source/Urho3D/LuaScript/pkgs/Graphics/AnimationController.pkg

@@ -32,7 +32,7 @@ class AnimationController : public Component
     bool SetTime(const String name, float time);
     bool SetWeight(const String name, float weight);
     bool SetLooped(const String name, bool enable);
-    bool SetBlendingMode(const String name, AnimationBlendingMode mode);
+    bool SetBlendMode(const String name, AnimationBlendMode mode);
     bool SetSpeed(const String name, float speed);
     bool SetAutoFade(const String name, float fadeOutTime);
     bool SetRemoveOnCompletion(const String name, bool removeOnCompletion);
@@ -47,7 +47,7 @@ class AnimationController : public Component
     float GetTime(const String name) const;
     float GetWeight(const String name) const;
     bool IsLooped(const String name) const;
-    AnimationBlendingMode GetBlendingMode(const String name) const;
+    AnimationBlendMode GetBlendMode(const String name) const;
     float GetLength(const String name) const;
     float GetSpeed(const String name) const;
     float GetFadeTarget(const String name) const;

+ 5 - 4
Source/Urho3D/LuaScript/pkgs/Graphics/AnimationState.pkg

@@ -1,8 +1,8 @@
 $#include "Graphics/AnimationState.h"
 
-enum AnimationBlendingMode
+enum AnimationBlendMode
 {
-    ABM_OVERRIDE = 0,
+    ABM_LERP = 0,
     ABM_ADDITIVE
 };
 
@@ -22,7 +22,7 @@ class AnimationState
     void AddWeight(float delta);
     void AddTime(float delta);
     void SetLayer(unsigned char layer);
-    void SetBlendingMode(AnimationBlendingMode mode);
+    void SetBlendMode(AnimationBlendMode mode);
 
     Animation* GetAnimation() const;
     Bone* GetStartBone() const;
@@ -37,7 +37,7 @@ class AnimationState
     float GetTime() const;
     float GetLength() const;
     unsigned char GetLayer() const;
-    AnimationBlendingMode GetBlendingMode() const;
+    AnimationBlendMode GetBlendMode() const;
 
     tolua_readonly tolua_property__get_set Animation* animation;
     tolua_property__get_set Bone* startBone;
@@ -47,4 +47,5 @@ class AnimationState
     tolua_property__get_set float time;
     tolua_readonly tolua_property__get_set float length;
     tolua_property__get_set unsigned char layer;
+    tolua_property__get_set AnimationBlendMode blendMode;
 };