浏览代码

Add support for animating scalars with tangents
(to support animating morph target weights)

Gary Hsu 8 年之前
父节点
当前提交
b831dbd6bf
共有 3 个文件被更改,包括 44 次插入10 次删除
  1. 13 8
      src/Animations/babylon.animation.ts
  2. 29 2
      src/Math/babylon.math.ts
  3. 2 0
      src/Morph/babylon.morphTarget.ts

+ 13 - 8
src/Animations/babylon.animation.ts

@@ -278,7 +278,11 @@
         }
         }
 
 
         public floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number {
         public floatInterpolateFunction(startValue: number, endValue: number, gradient: number): number {
-            return startValue + (endValue - startValue) * gradient;
+            return Scalar.Lerp(startValue, endValue, gradient);
+        }
+
+        public floatInterpolateFunctionWithTangents(startValue: number, outTangent: number, endValue: number, inTangent: number, gradient: number): number {
+            return Scalar.Hermite(startValue, outTangent, endValue, inTangent, gradient);
         }
         }
 
 
         public quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion {
         public quaternionInterpolateFunction(startValue: Quaternion, endValue: Quaternion, gradient: number): Quaternion {
@@ -376,7 +380,7 @@
                     var startValue = this._getKeyValue(startKey.value);
                     var startValue = this._getKeyValue(startKey.value);
                     var endValue = this._getKeyValue(endKey.value);
                     var endValue = this._getKeyValue(endKey.value);
 
 
-                    var useTangent = startKey.outTangent && endKey.inTangent;
+                    var useTangent = startKey.outTangent !== undefined && endKey.inTangent !== undefined;
                     var frameDelta = endKey.frame - startKey.frame;
                     var frameDelta = endKey.frame - startKey.frame;
 
 
                     // gradient : percent of currentFrame between the frame inf and the frame sup
                     // gradient : percent of currentFrame between the frame inf and the frame sup
@@ -390,26 +394,27 @@
                     switch (this.dataType) {
                     switch (this.dataType) {
                         // Float
                         // Float
                         case Animation.ANIMATIONTYPE_FLOAT:
                         case Animation.ANIMATIONTYPE_FLOAT:
+                            var floatValue = useTangent ? this.floatInterpolateFunctionWithTangents(startValue, startKey.outTangent * frameDelta, endValue, endKey.inTangent * frameDelta, gradient) : this.floatInterpolateFunction(startValue, endValue, gradient);
                             switch (loopMode) {
                             switch (loopMode) {
                                 case Animation.ANIMATIONLOOPMODE_CYCLE:
                                 case Animation.ANIMATIONLOOPMODE_CYCLE:
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return this.floatInterpolateFunction(startValue, endValue, gradient);
+                                    return floatValue;
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return offsetValue * repeatCount + this.floatInterpolateFunction(startValue, endValue, gradient);
+                                    return offsetValue * repeatCount + floatValue;
                             }
                             }
                             break;
                             break;
                         // Quaternion
                         // Quaternion
                         case Animation.ANIMATIONTYPE_QUATERNION:
                         case Animation.ANIMATIONTYPE_QUATERNION:
-                            var quaternion = useTangent ? this.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.quaternionInterpolateFunction(startValue, endValue, gradient);
+                            var quatValue = useTangent ? this.quaternionInterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.quaternionInterpolateFunction(startValue, endValue, gradient);
                             switch (loopMode) {
                             switch (loopMode) {
                                 case Animation.ANIMATIONLOOPMODE_CYCLE:
                                 case Animation.ANIMATIONLOOPMODE_CYCLE:
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
-                                    return quaternion;
+                                    return quatValue;
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return quaternion.add(offsetValue.scale(repeatCount));
+                                    return quatValue.add(offsetValue.scale(repeatCount));
                             }
                             }
 
 
-                            return quaternion;
+                            return quatValue;
                         // Vector3
                         // Vector3
                         case Animation.ANIMATIONTYPE_VECTOR3:
                         case Animation.ANIMATIONTYPE_VECTOR3:
                             var vec3Value = useTangent ? this.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector3InterpolateFunction(startValue, endValue, gradient);
                             var vec3Value = useTangent ? this.vector3InterpolateFunctionWithTangents(startValue, startKey.outTangent.scale(frameDelta), endValue, endKey.inTangent.scale(frameDelta), gradient) : this.vector3InterpolateFunction(startValue, endValue, gradient);

+ 29 - 2
src/Math/babylon.math.ts

@@ -53,6 +53,30 @@
     }
     }
 
 
 
 
+    export class Scalar {
+        /**
+         * Creates a new scalar with values linearly interpolated of "amount" between the start scalar and the end scalar.
+         */
+        public static Lerp(start: number, end: number, amount: number): number {
+            return start + ((end - start) * amount);
+        }
+
+        /**
+         * Returns a new scalar located for "amount" (float) on the Hermite spline defined by the scalars "value1", "value3", "tangent1", "tangent2".
+         */
+        public static Hermite(value1: number, tangent1: number, value2: number, tangent2: number, amount: number): number {
+            var squared = amount * amount;
+            var cubed = amount * squared;
+            var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0;
+            var part2 = (-2.0 * cubed) + (3.0 * squared);
+            var part3 = (cubed - (2.0 * squared)) + amount;
+            var part4 = cubed - squared;
+
+            return (((value1 * part1) + (value2 * part2)) + (tangent1 * part3)) + (tangent2 * part4);
+        }
+    }
+
+
     export class Color3 {
     export class Color3 {
         /**
         /**
          * Creates a new Color3 object from red, green, blue values, all between 0 and 1.  
          * Creates a new Color3 object from red, green, blue values, all between 0 and 1.  
@@ -899,7 +923,7 @@
         }
         }
 
 
         /**
         /**
-         * Returns a new Vecto2 located for "amount" (float) on the Hermite spline defined by the vectors "value1", "value3", "tangent1", "tangent2".  
+         * Returns a new Vector2 located for "amount" (float) on the Hermite spline defined by the vectors "value1", "value3", "tangent1", "tangent2".
          */
          */
         public static Hermite(value1: Vector2, tangent1: Vector2, value2: Vector2, tangent2: Vector2, amount: number): Vector2 {
         public static Hermite(value1: Vector2, tangent1: Vector2, value2: Vector2, tangent2: Vector2, amount: number): Vector2 {
             var squared = amount * amount;
             var squared = amount * amount;
@@ -1586,7 +1610,7 @@
         }
         }
 
 
         /**
         /**
-         * Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2".  
+         * Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2".
          */
          */
         public static Hermite(value1: Vector3, tangent1: Vector3, value2: Vector3, tangent2: Vector3, amount: number): Vector3 {
         public static Hermite(value1: Vector3, tangent1: Vector3, value2: Vector3, tangent2: Vector3, amount: number): Vector3 {
             var squared = amount * amount;
             var squared = amount * amount;
@@ -2849,6 +2873,9 @@
             result.w = (num3 * left.w) + (num2 * right.w);
             result.w = (num3 * left.w) + (num2 * right.w);
         }
         }
 
 
+        /**
+         * Returns a new Quaternion located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2".
+         */
         public static Hermite(value1: Quaternion, tangent1: Quaternion, value2: Quaternion, tangent2: Quaternion, amount: number): Quaternion {
         public static Hermite(value1: Quaternion, tangent1: Quaternion, value2: Quaternion, tangent2: Quaternion, amount: number): Quaternion {
             var squared = amount * amount;
             var squared = amount * amount;
             var cubed = amount * squared;
             var cubed = amount * squared;

+ 2 - 0
src/Morph/babylon.morphTarget.ts

@@ -1,5 +1,7 @@
 module BABYLON {
 module BABYLON {
     export class MorphTarget {
     export class MorphTarget {
+        public animations = new Array<Animation>();
+
         private _positions: Float32Array;
         private _positions: Float32Array;
         private _normals: Float32Array;
         private _normals: Float32Array;
         private _tangents: Float32Array;
         private _tangents: Float32Array;