Selaa lähdekoodia

Merge pull request #4644 from fmmoret/fm-animation-masking

masking for scene beginAnimation functions
David Catuhe 7 vuotta sitten
vanhempi
commit
33850ac7dc
3 muutettua tiedostoa jossa 23 lisäystä ja 13 poistoa
  1. 1 0
      dist/preview release/what's new.md
  2. 9 4
      src/Animations/babylon.animatable.ts
  3. 13 9
      src/babylon.scene.ts

+ 1 - 0
dist/preview release/what's new.md

@@ -64,6 +64,7 @@
 - Added canvas toBlob polyfill in tools ([sebavan](http://www.github.com/sebavan))
 - Added `RawCubeTexture` class with RGBD and mipmap support ([bghgary](http://www.github.com/bghgary))
 - Added effect layer per rendering group addressing [Issue 4463](https://github.com/BabylonJS/Babylon.js/issues/4463) ([sebavan](http://www.github.com/sebavan))
+- Added predicate function `targetMask` argument to `scene.beginWeightedAnimation`, `scene.beginAnimation`, `scene.stopAnimation`, and `animatable.stop` to allow for selective application of animations.  ([fmmoret](http://github.com/fmmoret))
 
 ### glTF Loader
 

+ 9 - 4
src/Animations/babylon.animatable.ts

@@ -282,9 +282,10 @@
         /**
          * Stop and delete the current animation
          * @param animationName defines a string used to only stop some of the runtime animations instead of all
+         * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)
          */
-        public stop(animationName?: string): void {
-            if (animationName) {
+        public stop(animationName?: string, targetMask?: (target: any) => boolean): void {
+            if (animationName || targetMask) {
                 var idx = this._scene._activeAnimatables.indexOf(this);
 
                 if (idx > -1) {
@@ -292,11 +293,15 @@
                     var runtimeAnimations = this._runtimeAnimations;
 
                     for (var index = runtimeAnimations.length - 1; index >= 0; index--) {
-                        if (typeof animationName === "string" && runtimeAnimations[index].animation.name != animationName) {
+                        const runtimeAnimation = runtimeAnimations[index];
+                        if (animationName && runtimeAnimation.animation.name != animationName) {
+                            continue;
+                        }
+                        if (targetMask && !targetMask(runtimeAnimation.target)) {
                             continue;
                         }
 
-                        runtimeAnimations[index].dispose();
+                        runtimeAnimation.dispose();
                         runtimeAnimations.splice(index, 1);
                     }
 

+ 13 - 9
src/babylon.scene.ts

@@ -2523,10 +2523,11 @@
          * @param speedRatio defines the speed in which to run the animation (1.0 by default)
          * @param onAnimationEnd defines the function to be executed when the animation ends
          * @param animatable defines an animatable object. If not provided a new one will be created from the given params
+         * @param targetMask defines if the target should be animated if animations are present (this is called recursively on descendant animatables regardless of return value)
          * @returns the animatable object created for this animation
          */
-        public beginWeightedAnimation(target: any, from: number, to: number, weight = 1.0, loop?: boolean, speedRatio: number = 1.0, onAnimationEnd?: () => void, animatable?: Animatable): Animatable {
-            let returnedAnimatable = this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, false);
+        public beginWeightedAnimation(target: any, from: number, to: number, weight = 1.0, loop?: boolean, speedRatio: number = 1.0, onAnimationEnd?: () => void, animatable?: Animatable, targetMask?: (target: any) => boolean): Animatable { 
+            let returnedAnimatable = this.beginAnimation(target, from, to, loop, speedRatio, onAnimationEnd, animatable, false, targetMask);
             returnedAnimatable.weight = weight;
 
             return returnedAnimatable;
@@ -2542,24 +2543,26 @@
          * @param onAnimationEnd defines the function to be executed when the animation ends
          * @param animatable defines an animatable object. If not provided a new one will be created from the given params
          * @param stopCurrent defines if the current animations must be stopped first (true by default)
+         * @param targetMask defines if the target should be animated if animations are present (this is called recursively on descendant animatables regardless of return value)
          * @returns the animatable object created for this animation
          */
-        public beginAnimation(target: any, from: number, to: number, loop?: boolean, speedRatio: number = 1.0, onAnimationEnd?: () => void, animatable?: Animatable, stopCurrent = true): Animatable {
+        public beginAnimation(target: any, from: number, to: number, loop?: boolean, speedRatio: number = 1.0, onAnimationEnd?: () => void, animatable?: Animatable, stopCurrent = true, targetMask?: (target: any) => boolean): Animatable {
 
             if (from > to && speedRatio > 0) {
                 speedRatio *= -1;
             }
 
             if (stopCurrent) {
-                this.stopAnimation(target);
+                this.stopAnimation(target, undefined, targetMask);
             }
 
             if (!animatable) {
                 animatable = new Animatable(this, target, from, to, loop, speedRatio, onAnimationEnd);
             }
 
+            const shouldRunTargetAnimations = targetMask ? targetMask(target) : true;
             // Local animations
-            if (target.animations) {
+            if (target.animations && shouldRunTargetAnimations) {
                 animatable.appendAnimations(target, target.animations);
             }
 
@@ -2567,7 +2570,7 @@
             if (target.getAnimatables) {
                 var animatables = target.getAnimatables();
                 for (var index = 0; index < animatables.length; index++) {
-                    this.beginAnimation(animatables[index], from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent);
+                    this.beginAnimation(animatables[index], from, to, loop, speedRatio, onAnimationEnd, animatable, stopCurrent, targetMask);
                 }
             }
 
@@ -2662,13 +2665,14 @@
         /**
          * Will stop the animation of the given target
          * @param target - the target
-         * @param animationName - the name of the animation to stop (all animations will be stopped if empty)
+         * @param animationName - the name of the animation to stop (all animations will be stopped if both this and targetMask are empty)
+         * @param targetMask - a function that determines if the animation should be stopped based on its target (all animations will be stopped if both this and animationName are empty)
          */
-        public stopAnimation(target: any, animationName?: string): void {
+        public stopAnimation(target: any, animationName?: string, targetMask?: (target: any) => boolean): void {
             var animatables = this.getAllAnimatablesByTarget(target);
 
             for (var animatable of animatables) {
-                animatable.stop(animationName);
+                animatable.stop(animationName, targetMask);
             }
         }