Vousk-prod.

PlayAnimationAction / instances - Animation stopped when another started

Recommended Posts

Hello all,

 

I've just noticed something I don't know whether it's a bug or it should behave like this.

 

I have 2 objects with animations, and I register PlayAnimationAction on them.

I trigger one animation (by mouse click), and then immediatly the other : everything goes fine.

 

Now I instanciate object1. Since instance does not have animations, I reference instance1.animations = object1.animations. (I referenced it instead of duplicating the animations keys because I think for large number of instances and complex animations that would be a big ressource cruncher...). Then I register PlayAnimationAction on this instance.

 

I can now trigger animations independently on the 3 objects (the 2 real meshes and the instance).

But when I trigger the anim on object1 or instance1 and immediatly after I click the other, the first animation immediatly stops while the second animation starts.

 

You can test that on the repro-case (obj1 -blue- and obj2 -pink- are real objects, inst1 -also blue- is instance of obj1) :

http://www.babylonjs-playground.com/#1MYQJJ#6

 

Is this the expecting result ?

Share this post


Link to post
Share on other sites

Expected, yes.  Here is why.

 

The exeucte() of PlayAnimationAction is:

        public execute(): void {            var scene = this._actionManager.getScene();            scene.beginAnimation(this._target, this.from, this.to, this.loop);        }

Now the target is different for each, so it initiates on all three correctly.  scene.beginAnimation() calls scene.stopAnimation(), passing the correct target object.  Here is where sharing burns you though.

        public stopAnimation(target: any): void {            var animatable = this.getAnimatableByTarget(target);            if (animatable) {                animatable.stop();            }        }

It gets the animation for the target and stops it.  Being a reference stops it on the other object.  I am not good enough with the animation system combined with the action system to know an alternative, other than to clone the animation.  Hopefully this is not being done with bones.

Share this post


Link to post
Share on other sites

Arr, I'm using bones for most of my animations... and I really should avoid clones for the meshes, instances is the clean way to go for my needs. But I will try the clone approch for the animations if it's applicable. Thanks man.

Share this post


Link to post
Share on other sites

Vousk:  there is a demo on the Babylon.js site Link - scroll down to "Bones" (personally hate the way that is set up - as I can't mostly link directly to a specific example). The three rabbits are an original and two clones Then the animation for each rabbit is a different section of the total animation.

 

In my experience, instancing can be tricky. In my "Christmas Village" piece, rather than have all the trees an instance of one tree, I ended up splitting trees into 4 quadrants each with their own original tree as I was having issues with the lights(7)

 

Not sure if that helps :unsure:

 

cheers, gryff :)

Share this post


Link to post
Share on other sites

Cloning of meshes instead of instances is not what I was suggesting.  Rather cloning of BABYLON.Animation.  This class has a large internal array, _keys, which could be extracted into a new instance.  There would only be one copy, reference, of the keys.  This would separate it from the other tiny bit of state, the _stopped.  See:

    export class Animation {        private _keys: Array<any>;        private _offsetsCache = {};        private _highLimitsCache = {};        private _stopped = false;        public _target;        private _easingFunction: BABYLON.IEasingFunction;...}

There is a clone method in BABYLON.Animation that should fix your playground example:

        public clone(): Animation {            var clone = new Animation(this.name, this.targetPropertyPath.join("."), this.framePerSecond, this.dataType, this.loopMode);            clone.setKeys(this._keys);            return clone;        }

Big problem for skeletons though, as each bone has its own Animation object:

        var skeleton;        var bone;        var animation;        skeleton = new BABYLON.Skeleton("name", "0", scene);        bone = new BABYLON.Bone("hips", skeleton,null, BABYLON.Matrix.FromValues(0.9967,0.0513,-0.0632,0,-0.0495,0.9984,0.029,0,-0.0646,0.0258,-0.9976,0,0,0.9036,-0.0008,1));        animation = new BABYLON.Animation("anim", "_matrix", 30, 3, 1);        animation.setKeys([        {frame: 1, value: BABYLON.Matrix.FromValues(0.9967,0.0513,-0.0632,0,-0.0495,0.9984,0.029,0,-0.0646,0.0258,-0.9976,0,0,0.9036,-0.0008,1)},        {frame: 2, value: BABYLON.Matrix.FromValues(0.9972,0.0652,-0.0372,0,-0.0637,0.9972,0.0401,0,-0.0397,0.0376,-0.9985,0,0,0.8986,-0.0016,1)},        {frame: 3, value: BABYLON.Matrix.FromValues(0.9983,0.0569,-0.0135,0,-0.0564,0.9976,0.0395,0,-0.0157,0.0387,-0.9991,0,0,0.8937,-0.0025,1)},        ...         ]);        bone.animations.push(animation);        bone = new BABYLON.Bone("thigh.L", skeleton,skeleton.bones[0], BABYLON.Matrix.FromValues(0.9913,-0.1269,-0.0336,0,-0.1259,-0.9916,0.0306,0,-0.0372,-0.0261,-0.999,0,0.1085,-0.0034,-0.0113,1));        animation = new BABYLON.Animation("anim", "_matrix", 30, 3, 1);        animation.setKeys([...]);        ... continue for each bone

Share this post


Link to post
Share on other sites

 

Cloning of meshes instead of instances is not what I was suggesting.  Rather cloning of BABYLON.Animation.  This class has a large internal array, _keys, which could be extracted into a new instance.  There would only be one copy, reference, of the keys.  This would separate it from the other tiny bit of state, the _stopped.  See:

    export class Animation {        private _keys: Array<any>;        private _offsetsCache = {};        private _highLimitsCache = {};        private _stopped = false;        public _target;        private _easingFunction: BABYLON.IEasingFunction;...}

There is a clone method in BABYLON.Animation that should fix your playground example:

        public clone(): Animation {            var clone = new Animation(this.name, this.targetPropertyPath.join("."), this.framePerSecond, this.dataType, this.loopMode);            clone.setKeys(this._keys);            return clone;        }

Big problem for skeletons though, as each bone has its own Animation object:

        var skeleton;        var bone;        var animation;        skeleton = new BABYLON.Skeleton("name", "0", scene);        bone = new BABYLON.Bone("hips", skeleton,null, BABYLON.Matrix.FromValues(0.9967,0.0513,-0.0632,0,-0.0495,0.9984,0.029,0,-0.0646,0.0258,-0.9976,0,0,0.9036,-0.0008,1));        animation = new BABYLON.Animation("anim", "_matrix", 30, 3, 1);        animation.setKeys([        {frame: 1, value: BABYLON.Matrix.FromValues(0.9967,0.0513,-0.0632,0,-0.0495,0.9984,0.029,0,-0.0646,0.0258,-0.9976,0,0,0.9036,-0.0008,1)},        {frame: 2, value: BABYLON.Matrix.FromValues(0.9972,0.0652,-0.0372,0,-0.0637,0.9972,0.0401,0,-0.0397,0.0376,-0.9985,0,0,0.8986,-0.0016,1)},        {frame: 3, value: BABYLON.Matrix.FromValues(0.9983,0.0569,-0.0135,0,-0.0564,0.9976,0.0395,0,-0.0157,0.0387,-0.9991,0,0,0.8937,-0.0025,1)},        ...         ]);        bone.animations.push(animation);        bone = new BABYLON.Bone("thigh.L", skeleton,skeleton.bones[0], BABYLON.Matrix.FromValues(0.9913,-0.1269,-0.0336,0,-0.1259,-0.9916,0.0306,0,-0.0372,-0.0261,-0.999,0,0.1085,-0.0034,-0.0113,1));        animation = new BABYLON.Animation("anim", "_matrix", 30, 3, 1);        animation.setKeys([...]);        ... continue for each bone

How we know what every numbers in the matrix means ?  BABYLON.Matrix.FromValues(0.9913..........) in this example how we know what 0.9913 means etc....

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.