Browse Source

Version 1 of morph animations

Michael Dahrea 8 years ago
parent
commit
45a008afb4
1 changed files with 59 additions and 19 deletions
  1. 59 19
      loaders/src/glTF/2.0/babylon.glTFLoader.ts

+ 59 - 19
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -4,8 +4,8 @@ module BABYLON.GLTF2 {
     /**
     * Values
     */
-    var glTFAnimationPaths = ["translation", "rotation", "scale"];
-    var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling"];
+    var glTFAnimationPaths = ["translation", "rotation", "scale", "weights"];
+    var babylonAnimationPaths = ["position", "rotationQuaternion", "scaling", "influence"];
 
     /**
     * Utils
@@ -80,8 +80,9 @@ module BABYLON.GLTF2 {
                 }
 
                 var isBone = targetNode instanceof Bone;
+                var numInfluencers = 0;
 
-                // Get target path (position, rotation or scaling)
+                // Get target path (position, rotation, scaling, or weights)
                 var targetPath = channel.target.path;
                 var targetPathIndex = glTFAnimationPaths.indexOf(targetPath);
 
@@ -97,6 +98,10 @@ module BABYLON.GLTF2 {
                         animationType = Animation.ANIMATIONTYPE_QUATERNION;
                         targetNode.rotationQuaternion = new Quaternion();
                     }
+                    else if (targetPath === "influence") {
+                        animationType = Animation.ANIMATIONTYPE_FLOAT;
+                        numInfluencers = (<Mesh>targetNode).morphTargetManager.numInfluencers;
+                    }
                     else {
                         animationType = Animation.ANIMATIONTYPE_VECTOR3;
                     }
@@ -113,19 +118,21 @@ module BABYLON.GLTF2 {
                     modifyKey = true;
                 }
 
-                if (!modifyKey) {
-                    var animationName = animation.name || "anim" + animationIndex;
-                    babylonAnimation = new Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, Animation.ANIMATIONLOOPMODE_CYCLE);
-                }
-
                 // For each frame
-                for (var j = 0; j < bufferInput.length; j++) {
+                for (var frameIndex = 0; frameIndex < bufferInput.length; frameIndex++) {
                     var value: any = null;
 
                     if (targetPath === "rotationQuaternion") { // VEC4
                         value = Quaternion.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2], bufferOutput[arrayOffset + 3]]);
                         arrayOffset += 4;
                     }
+                    else if (targetPath === "influence") { // FLOAT
+                        // There is 1 value for each morph target for each frame
+                        for (var influence = 0; influence < numInfluencers; influence++) {
+                            value.push(bufferOutput[arrayOffset + influence]);
+                        }
+                        arrayOffset += numInfluencers;
+                    }
                     else { // Position and scaling are VEC3
                         value = Vector3.FromArray([bufferOutput[arrayOffset], bufferOutput[arrayOffset + 1], bufferOutput[arrayOffset + 2]]);
                         arrayOffset += 3;
@@ -141,7 +148,7 @@ module BABYLON.GLTF2 {
                         var mat = bone.getBaseMatrix();
 
                         if (modifyKey) {
-                            mat = lastAnimation.getKeys()[j].value;
+                            mat = lastAnimation.getKeys()[frameIndex].value;
                         }
 
                         mat.decompose(scaling, rotationQuaternion, translation);
@@ -160,26 +167,59 @@ module BABYLON.GLTF2 {
                     }
 
                     if (!modifyKey) {
-                        keys.push({
-                            frame: bufferInput[j],
-                            value: value
-                        });
+                        if (targetPath === "influence") {
+                            for (var influence = 0; influence < numInfluencers; influence++) {
+                                keys[influence].push({
+                                    frame: bufferInput[frameIndex],
+                                    value: value[influence]
+                                });
+                            }
+                        }
+                        else {
+                            keys.push({
+                                frame: bufferInput[frameIndex],
+                                value: value
+                            });
+                        }
                     }
                     else {
-                        lastAnimation.getKeys()[j].value = value;
+                        lastAnimation.getKeys()[frameIndex].value = value;
                     }
                 }
 
                 // Finish
                 if (!modifyKey) {
-                    babylonAnimation.setKeys(keys);
-                    targetNode.animations.push(babylonAnimation);
+                    if (targetPath === "influence") {
+                        for (var influence = 0; influence < numInfluencers; influence++) {
+                            var animationName = (animation.name || "anim" + animationIndex) + "_" + influence;
+                            babylonAnimation = new Animation(animationName, targetPath, 1, animationType, Animation.ANIMATIONLOOPMODE_CYCLE);
+
+                            babylonAnimation.setKeys(keys[influence]);
+                            (<any>(<Mesh>targetNode).morphTargetManager.getActiveTarget(influence)).animations.push(babylonAnimation);
+                        }
+                    }
+                    else {
+                        var animationName = animation.name || "anim" + animationIndex;
+                        babylonAnimation = new Animation(animationName, isBone ? "_matrix" : targetPath, 1, animationType, Animation.ANIMATIONLOOPMODE_CYCLE);
+                
+                        babylonAnimation.setKeys(keys);
+                        targetNode.animations.push(babylonAnimation);
+                    }
                 }
 
                 lastAnimation = babylonAnimation;
 
-                runtime.babylonScene.stopAnimation(targetNode);
-                runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                if (targetPath === "influence") {
+                    for (var influence = 0; influence < numInfluencers; influence++) {
+                        var morph = (<Mesh>targetNode).morphTargetManager.getActiveTarget(influence);
+                        runtime.babylonScene.stopAnimation(morph);
+                        runtime.babylonScene.beginAnimation(morph, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                    }
+                }
+                else {
+                    runtime.babylonScene.stopAnimation(targetNode);
+                    runtime.babylonScene.beginAnimation(targetNode, 0, bufferInput[bufferInput.length - 1], true, 1.0);
+                }
             }
         }
     };