Просмотр исходного кода

Merge pull request #120 from blackberry-gaming/next-kcunney

Fixes animation blending
Sean Paul Taylor 14 лет назад
Родитель
Сommit
8863a3c2b0

+ 0 - 1
gameplay/src/AnimationTarget.cpp

@@ -2,7 +2,6 @@
 #include "AnimationTarget.h"
 #include "Animation.h"
 #include "Game.h"
-#include "Transform.h"
 
 namespace gameplay
 {

+ 13 - 4
gameplay/src/Curve.cpp

@@ -703,6 +703,11 @@ void Curve::evaluate(float time, float* dst) const
     interpolateLinear(t, from, to, dst);
 }
 
+float Curve::lerp(float t, float from, float to)
+{
+    return lerpInl(t, from, to);
+}
+
 void Curve::setQuaternionOffset(unsigned int offset)
 {
     assert(offset <= (_componentCount - 4));
@@ -1078,7 +1083,7 @@ void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
             if (fromValue[i] == toValue[i])
                 dst[i] = fromValue[i];
             else
-                dst[i] = lerp(s, fromValue[i], toValue[i]);
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
         }
     }
     else
@@ -1091,7 +1096,7 @@ void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
             if (fromValue[i] == toValue[i])
                 dst[i] = fromValue[i];
             else
-                dst[i] = lerp(s, fromValue[i], toValue[i]);
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
         }
 
         // Handle quaternion component.
@@ -1103,18 +1108,22 @@ void Curve::interpolateLinear(float s, Point* from, Point* to, float* dst) const
             if (fromValue[i] == toValue[i])
                 dst[i] = fromValue[i];
             else
-                dst[i] = lerp(s, fromValue[i], toValue[i]);
+                dst[i] = lerpInl(s, fromValue[i], toValue[i]);
         }
     }
 }
 
 void Curve::interpolateQuaternion(float s, float* from, float* to, float* dst) const
-{        
+{
     // Evaluate.
     if (s >= 0)
+    {
         Quaternion::slerp(from[0], from[1], from[2], from[3], to[0], to[1], to[2], to[3], s, dst, dst + 1, dst + 2, dst + 3);
+    }
     else
         Quaternion::slerp(to[0], to[1], to[2], to[3], from[0], from[1], from[2], from[3], s, dst, dst + 1, dst + 2, dst + 3);
+
+    //((Quaternion*) dst)->normalize();
 }
 
 int Curve::determineIndex(float time) const

+ 11 - 6
gameplay/src/Curve.h

@@ -354,6 +354,11 @@ public:
      */
     void evaluate(float time, float* dst) const;
 
+    /**
+     * Linear interpolation function.
+     */
+    static float lerp(float t, float from, float to);
+
 private:
 
     /**
@@ -460,17 +465,17 @@ private:
     Point* _points;                     // The points on the curve.
 };
 
-inline float bezier(float eq0, float eq1, float eq2, float eq3, float from, float out, float to, float in);
+inline static float bezier(float eq0, float eq1, float eq2, float eq3, float from, float out, float to, float in);
 
-inline float bspline(float eq0, float eq1, float eq2, float eq3, float c0, float c1, float c2, float c3);
+inline static float bspline(float eq0, float eq1, float eq2, float eq3, float c0, float c1, float c2, float c3);
 
-inline float hermite(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
+inline static float hermite(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
 
-inline float hermiteFlat(float h00, float h01, float from, float to);
+inline static float hermiteFlat(float h00, float h01, float from, float to);
 
-inline float hermiteSmooth(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
+inline static float hermiteSmooth(float h00, float h01, float h10, float h11, float from, float out, float to, float in);
 
-inline float lerp(float s, float from, float to);
+inline static float lerpInl(float s, float from, float to);
 
 }
 

+ 1 - 1
gameplay/src/Curve.inl

@@ -28,7 +28,7 @@ inline float hermiteSmooth(float h00, float h01, float h10, float h11, float fro
     return h00 * from + h01 * to + h10 * out + h11 * in;
 }
 
-inline float lerp(float s, float from, float to)
+inline float lerpInl(float s, float from, float to)
 {
     return from + (to - from) * s;
 }

+ 17 - 64
gameplay/src/MaterialParameter.cpp

@@ -382,8 +382,6 @@ void MaterialParameter::getAnimationPropertyValue(int propertyId, AnimationValue
 void MaterialParameter::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
     assert(blendWeight >= 0.0f && blendWeight <= 1.0f);
-    if (blendWeight == 0.0f)
-        return;
 
     switch (propertyId)
     {
@@ -398,18 +396,11 @@ void MaterialParameter::setAnimationPropertyValue(int propertyId, AnimationValue
                         if ((_animationPropertyBitFlag & ANIMATION_UNIFORM_BIT) != ANIMATION_UNIFORM_BIT)
                         {
                             _animationPropertyBitFlag |= ANIMATION_UNIFORM_BIT;
-
-                            if (blendWeight != 1.0f)
-                                _value.floatValue = value->getFloat(0) * blendWeight;
-                            else
-                                _value.floatValue = value->getFloat(0);
+                            _value.floatValue = value->getFloat(0);
                         }
                         else
                         {
-                            if (blendWeight != 1.0f)
-                                _value.floatValue += value->getFloat(0) * blendWeight;
-                            else
-                                _value.floatValue += value->getFloat(0);
+                            _value.floatValue = Curve::lerp(blendWeight, _value.floatValue, value->getFloat(0));
                         }
                     }
                     else
@@ -420,52 +411,30 @@ void MaterialParameter::setAnimationPropertyValue(int propertyId, AnimationValue
                 }
                 case INT:
                 {
-                    if ((_animationPropertyBitFlag & ANIMATION_UNIFORM_BIT) != ANIMATION_UNIFORM_BIT)
+                    if (_count == 1)
                     {
-                        _animationPropertyBitFlag |= ANIMATION_UNIFORM_BIT;
-
-                        if (_count == 1)
+                        if ((_animationPropertyBitFlag & ANIMATION_UNIFORM_BIT) != ANIMATION_UNIFORM_BIT)
                         {
-                            if (blendWeight != 1.0f)
-                                _value.intValue = value->getFloat(0) * blendWeight;
-                            else
-                                _value.intValue = value->getFloat(0);
+                            _animationPropertyBitFlag |= ANIMATION_UNIFORM_BIT;
+                            _value.intValue = value->getFloat(0);
                         }
                         else
                         {
-                            if (blendWeight != 1.0f)
-                            {
-                                for (unsigned int i = 0; i < _count; i++)
-                                    _value.intPtrValue[i] = value->getFloat(i) * blendWeight;
-                            }
-                            else
-                            {
-                                for (unsigned int i = 0; i < _count; i++)
-                                    _value.intPtrValue[i] = value->getFloat(i);
-                            }
+                            _value.intValue = Curve::lerp(blendWeight, _value.intValue, value->getFloat(0));
                         }
                     }
                     else
                     {
-                        if (_count == 1)
+                        if ((_animationPropertyBitFlag & ANIMATION_UNIFORM_BIT) != ANIMATION_UNIFORM_BIT)
                         {
-                            if (blendWeight != 1.0f)
-                                _value.intValue += value->getFloat(0) * blendWeight;
-                            else
-                                _value.intValue += value->getFloat(0);
+                            _animationPropertyBitFlag |= ANIMATION_UNIFORM_BIT;
+                            for (unsigned int i = 0; i < _count; i++)
+                                _value.intPtrValue[i] = value->getFloat(i);
                         }
                         else
                         {
-                            if (blendWeight != 1.0f)
-                            {
-                                for (unsigned int i = 0; i < _count; i++)
-                                    _value.intPtrValue[i] += value->getFloat(i) * blendWeight;
-                            }
-                            else
-                            {
-                                for (unsigned int i = 0; i < _count; i++)
-                                    _value.intPtrValue[i] += value->getFloat(i);
-                            }
+                            for (unsigned int i = 0; i < _count; i++)
+                                _value.intPtrValue[i] = Curve::lerp(blendWeight, _value.intPtrValue[i], value->getFloat(i));
                         }
                     }
                     break;
@@ -499,29 +468,13 @@ void MaterialParameter::applyAnimationValue(AnimationValue* value, float blendWe
     {
         _animationPropertyBitFlag |= ANIMATION_UNIFORM_BIT;
 
-        if (blendWeight != 1.0f)
-        {
-            for (unsigned int i = 0; i < count; i++)
-                _value.floatPtrValue[i] = value->getFloat(i) * blendWeight;
-        }
-        else
-        {
-            for (unsigned int i = 0; i < count; i++)
-                _value.floatPtrValue[i] = value->getFloat(i);
-        }
+        for (unsigned int i = 0; i < count; i++)
+            _value.floatPtrValue[i] = value->getFloat(i);
     }
     else
     {
-        if (blendWeight != 1.0f)
-        {
-            for (unsigned int i = 0; i < count; i++)
-                _value.floatPtrValue[i] += (value->getFloat(i) * blendWeight);
-        }
-        else
-        {
-            for (unsigned int i = 0; i < count; i++)
-                _value.floatPtrValue[i] += value->getFloat(i);
-        }
+        for (unsigned int i = 0; i < count; i++)
+            _value.floatPtrValue[i] = Curve::lerp(blendWeight, _value.floatPtrValue[i], value->getFloat(i));
     }
 }
 

+ 56 - 183
gameplay/src/Transform.cpp

@@ -650,189 +650,85 @@ void Transform::getAnimationPropertyValue(int propertyId, AnimationValue* value)
 void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
 {
     assert(blendWeight >= 0.0f && blendWeight <= 1.0f);
-    if (blendWeight == 0.0f)
-        return;
 
     switch (propertyId)
     {
         case ANIMATE_SCALE_UNIT:
         {
-            float scale = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                scale *= blendWeight;
-
-            applyAnimationValueScaleX(scale);
-            applyAnimationValueScaleY(scale);
-            applyAnimationValueScaleZ(scale);
-            
+            applyAnimationValueScaleX(value->getFloat(0), blendWeight);
+            applyAnimationValueScaleY(value->getFloat(0), blendWeight);
+            applyAnimationValueScaleZ(value->getFloat(0), blendWeight);
             break;
         }   
         case ANIMATE_SCALE:
         {
-            float sx = value->getFloat(0);
-            float sy = value->getFloat(1);
-            float sz = value->getFloat(2);
-            if (blendWeight != 1.0f)
-            {
-                sx *= blendWeight;
-                sy *= blendWeight;
-                sz *= blendWeight;
-            }
-
-            applyAnimationValueScaleX(sx);
-            applyAnimationValueScaleY(sy);
-            applyAnimationValueScaleZ(sz);
-
+            applyAnimationValueScaleX(value->getFloat(0), blendWeight);
+            applyAnimationValueScaleY(value->getFloat(1), blendWeight);
+            applyAnimationValueScaleZ(value->getFloat(2), blendWeight);
             break;
         }
         case ANIMATE_SCALE_X:
         {
-            float sx = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                sx *= blendWeight;
-
-            applyAnimationValueScaleX(sx);
-
+            applyAnimationValueScaleX(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_SCALE_Y:
         {
-            float sy = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                sy *= blendWeight;
-
-            applyAnimationValueScaleY(sy);
-
+            applyAnimationValueScaleY(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_SCALE_Z:
         {
-            float sz = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                sz *= blendWeight;
-
-            applyAnimationValueScaleZ(sz);
-
+            applyAnimationValueScaleZ(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_ROTATE:
         {
             Quaternion q(value->getFloat(0), value->getFloat(1), value->getFloat(2), value->getFloat(3));
-
-            if (blendWeight != 1.0f)
-                Quaternion::slerp(Quaternion::identity(), q, blendWeight, &q);
-
-            applyAnimationValueRotation(&q);
-            
+            applyAnimationValueRotation(&q, blendWeight);
             break;
         }
         case ANIMATE_TRANSLATE:
         {
-            float tx = value->getFloat(0);
-            float ty = value->getFloat(1);
-            float tz = value->getFloat(2);
-
-            if (blendWeight != 1.0f)
-            {
-                tx *= blendWeight;
-                ty *= blendWeight;
-                tz *= blendWeight;
-            }
-
-            applyAnimationValueTranslationX(tx);
-            applyAnimationValueTranslationY(ty);
-            applyAnimationValueTranslationZ(tz);
-            
+            applyAnimationValueTranslationX(value->getFloat(0), blendWeight);
+            applyAnimationValueTranslationY(value->getFloat(1), blendWeight);
+            applyAnimationValueTranslationZ(value->getFloat(2), blendWeight);
             break;
         }
         case ANIMATE_TRANSLATE_X:
         {
-            float tx = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                tx *= blendWeight;
-
-            applyAnimationValueTranslationX(tx);
-
+            applyAnimationValueTranslationX(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_TRANSLATE_Y:
         {
-            float ty = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                ty *= blendWeight;
-            
-            applyAnimationValueTranslationY(ty);
-
+            applyAnimationValueTranslationY(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_TRANSLATE_Z:
         {
-            float tz = value->getFloat(0);
-
-            if (blendWeight != 1.0f)
-                tz *= blendWeight;
-
-            applyAnimationValueTranslationZ(tz);
-
+            applyAnimationValueTranslationZ(value->getFloat(0), blendWeight);
             break;
         }
         case ANIMATE_ROTATE_TRANSLATE:
         {
             Quaternion q(value->getFloat(0), value->getFloat(1), value->getFloat(2), value->getFloat(3));
-            float tx = value->getFloat(4);
-            float ty = value->getFloat(5);
-            float tz = value->getFloat(6);
-
-            if (blendWeight != 1.0f)
-            {
-                Quaternion::slerp(Quaternion::identity(), q, blendWeight, &q);
-                tx *= blendWeight;
-                ty *= blendWeight;
-                tz *= blendWeight;
-            }
-
-            applyAnimationValueRotation(&q);
-            applyAnimationValueTranslationX(tx);
-            applyAnimationValueTranslationY(ty);
-            applyAnimationValueTranslationZ(tz);
-            
+            applyAnimationValueRotation(&q, blendWeight);
+            applyAnimationValueTranslationX(value->getFloat(4), blendWeight);
+            applyAnimationValueTranslationY(value->getFloat(5), blendWeight);
+            applyAnimationValueTranslationZ(value->getFloat(6), blendWeight);
             break;
         }
         case ANIMATE_SCALE_ROTATE_TRANSLATE:
         {
-            float sx = value->getFloat(0);
-            float sy = value->getFloat(1);
-            float sz = value->getFloat(2);
+            applyAnimationValueScaleX(value->getFloat(0), blendWeight);
+            applyAnimationValueScaleY(value->getFloat(1), blendWeight);
+            applyAnimationValueScaleZ(value->getFloat(2), blendWeight);
             Quaternion q(value->getFloat(3), value->getFloat(4), value->getFloat(5), value->getFloat(6));
-            float tx = value->getFloat(7);
-            float ty = value->getFloat(8);
-            float tz = value->getFloat(9);
-
-            if (blendWeight != 1.0f)
-            {
-                sx *= blendWeight;
-                sy *= blendWeight;
-                sz *= blendWeight;
-                Quaternion::slerp(Quaternion::identity(), q, blendWeight, &q);
-                tx *= blendWeight;
-                ty *= blendWeight;
-                tz *= blendWeight;
-            }
-
-            applyAnimationValueScaleX(sx);
-            applyAnimationValueScaleY(sy);
-            applyAnimationValueScaleZ(sz);
-            applyAnimationValueRotation(&q);
-            applyAnimationValueTranslationX(tx);
-            applyAnimationValueTranslationY(ty);
-            applyAnimationValueTranslationZ(tz);
-            
+            applyAnimationValueRotation(&q, blendWeight);
+            applyAnimationValueTranslationX(value->getFloat(7), blendWeight);
+            applyAnimationValueTranslationY(value->getFloat(8), blendWeight);
+            applyAnimationValueTranslationZ(value->getFloat(9), blendWeight);
             break;
         }
         default:
@@ -884,97 +780,74 @@ void Transform::transformChanged()
     }
 }
 
-void Transform::applyAnimationValueScaleX(float sx)
+void Transform::applyAnimationValueScaleX(float sx, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_SCALE_X_BIT) != ANIMATION_SCALE_X_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_SCALE_X_BIT;
-        setScaleX(sx);
-    }
     else
-    {
-        _scale.x += sx;
-        dirty();
-    }
+        sx = Curve::lerp(blendWeight, _scale.x, sx);
+
+    setScaleX(sx);
 }
 
-void Transform::applyAnimationValueScaleY(float sy)
+void Transform::applyAnimationValueScaleY(float sy, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_SCALE_Y_BIT) != ANIMATION_SCALE_Y_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_SCALE_Y_BIT;
-        setScaleY(sy);
-    }
     else
-    {
-        _scale.y += sy;
-        dirty();
-    }
+        sy = Curve::lerp(blendWeight, _scale.y, sy);
+
+    setScaleY(sy);
 }
 
-void Transform::applyAnimationValueScaleZ(float sz)
+void Transform::applyAnimationValueScaleZ(float sz, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_SCALE_Z_BIT) != ANIMATION_SCALE_Z_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_SCALE_Z_BIT;
-        setScaleZ(sz);
-    }
     else
-    {
-        _scale.z += sz;
-        dirty();
-    }
+        sz = Curve::lerp(blendWeight, _scale.z, sz);
+
+    setScaleZ(sz);
 }
 
-void Transform::applyAnimationValueRotation(Quaternion* q)
+void Transform::applyAnimationValueRotation(Quaternion* q, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_ROTATION_BIT) != ANIMATION_ROTATION_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_ROTATION_BIT;
-        setRotation(*q);
-    }
     else
-    {
-        rotate(*q);
-    }
+        Quaternion::slerp(_rotation, *q, blendWeight, q);
+     
+    setRotation(*q);
 }
 
-void Transform::applyAnimationValueTranslationX(float tx)
+void Transform::applyAnimationValueTranslationX(float tx, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_TRANSLATION_X_BIT) != ANIMATION_TRANSLATION_X_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_TRANSLATION_X_BIT;
-        setTranslationX(tx);
-    }
     else
-    {
-        translateX(tx);
-    }
+        tx = Curve::lerp(blendWeight, _translation.x, tx);
+
+    setTranslationX(tx);
 }
 
-void Transform::applyAnimationValueTranslationY(float ty)
+void Transform::applyAnimationValueTranslationY(float ty, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_TRANSLATION_Y_BIT) != ANIMATION_TRANSLATION_Y_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_TRANSLATION_Y_BIT;
-        setTranslationY(ty);
-    }
     else
-    {
-        translateY(ty);
-    }
+        ty = Curve::lerp(blendWeight, _translation.y, ty);
+
+    setTranslationY(ty);
 }
 
-void Transform::applyAnimationValueTranslationZ(float tz)
+void Transform::applyAnimationValueTranslationZ(float tz, float blendWeight)
 {
     if ((_animationPropertyBitFlag & ANIMATION_TRANSLATION_Z_BIT) != ANIMATION_TRANSLATION_Z_BIT)
-    {
         _animationPropertyBitFlag |= ANIMATION_TRANSLATION_Z_BIT;
-        setTranslationZ(tz);
-    }
     else
-    {
-        translateZ(tz);
-    }
+        tz = Curve::lerp(blendWeight, _translation.z, tz);
+
+    setTranslationZ(tz);
 }
+
 }

+ 7 - 7
gameplay/src/Transform.h

@@ -754,13 +754,13 @@ private:
     static const char ANIMATION_TRANSLATION_Y_BIT = 0x20; 
     static const char ANIMATION_TRANSLATION_Z_BIT = 0x40; 
 
-    void applyAnimationValueScaleX(float sx);
-    void applyAnimationValueScaleY(float sy);
-    void applyAnimationValueScaleZ(float sz);
-    void applyAnimationValueRotation(Quaternion* q);
-    void applyAnimationValueTranslationX(float tx);
-    void applyAnimationValueTranslationY(float ty);
-    void applyAnimationValueTranslationZ(float tz);
+    void applyAnimationValueScaleX(float sx, float blendWeight);
+    void applyAnimationValueScaleY(float sy, float blendWeight);
+    void applyAnimationValueScaleZ(float sz, float blendWeight);
+    void applyAnimationValueRotation(Quaternion* q, float blendWeight);
+    void applyAnimationValueTranslationX(float tx, float blendWeight);
+    void applyAnimationValueTranslationY(float ty, float blendWeight);
+    void applyAnimationValueTranslationZ(float tz, float blendWeight);
 };
 
 }