瀏覽代碼

Fix bugs in animationGroup code and use animationGroups in glTF loader

Gary Hsu 7 年之前
父節點
當前提交
dddee4d8db

+ 11 - 13
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -253,6 +253,10 @@ module BABYLON.GLTF2 {
                 return;
             }
 
+            for (const animation of animations) {
+                animation.babylonAnimationGroup.normalize();
+            }
+
             switch (this.animationStartMode) {
                 case GLTFLoaderAnimationStartMode.NONE: {
                     // do nothing
@@ -260,16 +264,12 @@ module BABYLON.GLTF2 {
                 }
                 case GLTFLoaderAnimationStartMode.FIRST: {
                     const animation = animations[0];
-                    for (const target of animation.targets) {
-                        this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                    }
+                    animation.babylonAnimationGroup.start(true);
                     break;
                 }
                 case GLTFLoaderAnimationStartMode.ALL: {
                     for (const animation of animations) {
-                        for (const target of animation.targets) {
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                     }
                     break;
                 }
@@ -941,7 +941,7 @@ module BABYLON.GLTF2 {
         }
 
         private _loadAnimation(context: string, animation: IGLTFAnimation): void {
-            animation.targets = [];
+            animation.babylonAnimationGroup = new AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
 
             for (let index = 0; index < animation.channels.length; index++) {
                 const channel = GLTFLoader._GetProperty(animation.channels, index);
@@ -1096,7 +1096,7 @@ module BABYLON.GLTF2 {
 
                     for (let targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                         const morphTarget = morphTargetManager.getTarget(targetIndex);
-                        const animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                        const animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys.map(key => ({
                             frame: key.frame,
@@ -1105,19 +1105,17 @@ module BABYLON.GLTF2 {
                             outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                         })));
 
-                        morphTarget.animations.push(babylonAnimation);
-                        animation.targets.push(morphTarget);
+                        animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                     }
                 }
                 else {
-                    const animationName = animation.name || "anim" + animation.index;
+                    const animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                     const babylonAnimation = new Animation(animationName, targetPath, 1, animationType);
                     babylonAnimation.setKeys(keys);
 
                     if (targetNode.babylonAnimationTargets) {
                         for (const target of targetNode.babylonAnimationTargets) {
-                            target.animations.push(babylonAnimation.clone());
-                            animation.targets.push(target);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                         }
                     }
                 }

+ 1 - 1
loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts

@@ -109,7 +109,7 @@ module BABYLON.GLTF2 {
 
         // Runtime values
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
 
     export interface IGLTFAsset extends IGLTFChildRootProperty {

+ 19 - 10
src/Animations/babylon.animationGroup.ts

@@ -16,7 +16,7 @@ module BABYLON {
         private _targetedAnimations = new Array<TargetedAnimation>();
         private _animatables = new Array<Animatable>();
         private _from = Number.MAX_VALUE;
-        private _to = Number.MIN_VALUE;
+        private _to = -Number.MAX_VALUE;
         private _isStarted: boolean;
         private _speedRatio = 1;
 
@@ -52,6 +52,13 @@ module BABYLON {
             }
         }
 
+        /**
+         * Gets the targeted animations for this animation group
+         */
+        public get targetedAnimations(): Array<TargetedAnimation> {
+            return this._targetedAnimations;
+        }
+
         public constructor(public name: string, scene: Nullable<Scene> = null) {
             this._scene = scene || Engine.LastCreatedScene!;
 
@@ -87,11 +94,11 @@ module BABYLON {
         /**
          * This function will normalize every animation in the group to make sure they all go from beginFrame to endFrame
          * It can add constant keys at begin or end
-         * @param beginFrame defines the new begin frame for all animations. It can't be bigger than the smaller begin frame of all animations
-         * @param endFrame defines the new end frame for all animations. It can't be smaller than the larger end frame of all animations
+         * @param beginFrame defines the new begin frame for all animations. It can't be bigger than the smallest begin frame of all animations
+         * @param endFrame defines the new end frame for all animations. It can't be smaller than the largest end frame of all animations
          */
-        public normalize(beginFrame: number, endFrame: number): AnimationGroup {
-            beginFrame = Math.min(beginFrame, this._from);
+        public normalize(beginFrame = -Number.MAX_VALUE, endFrame = Number.MAX_VALUE): AnimationGroup {
+            beginFrame = Math.max(beginFrame, this._from);
             endFrame = Math.min(endFrame, this._to);
 
             for (var index = 0; index < this._targetedAnimations.length; index++) {
@@ -101,21 +108,23 @@ module BABYLON {
                 let endKey = keys[keys.length - 1];
 
                 if (startKey.frame > beginFrame) {
-                    let newKey = {
+                    let newKey: IAnimationKey = {
                         frame: beginFrame,
                         value: startKey.value,
                         inTangent: startKey.inTangent,
-                        outTangent: startKey.outTangent
+                        outTangent: startKey.outTangent,
+                        interpolation: startKey.interpolation
                     }
                     keys.splice(0, 0, newKey);
                 }
 
                 if (endKey.frame < endFrame) {
-                    let newKey = {
+                    let newKey: IAnimationKey = {
                         frame: endFrame,
                         value: endKey.value,
-                        inTangent: startKey.outTangent,
-                        outTangent: startKey.outTangent
+                        inTangent: endKey.outTangent,
+                        outTangent: endKey.outTangent,
+                        interpolation: endKey.interpolation
                     }
                     keys.push(newKey);
                 }