MackeyK24 Posted February 24, 2018 Share Posted February 24, 2018 I have encountered a major issues when doing skeletal animation with dynamic state changing. Scenario: I have player input control coming from game pad to control the player movement... This causes Animation State Changes.. Going from walking to running for example... WITHOUT the enableBlending AND blendingSpeed properties being set on EACH BONE ANIMATION ... you get very SHARP and jerking transitions between animation state. The problem is coming into play when I need to UPDATE the enableBlending and blendingSpeed ON EVERY animation state change... that way can configure animation timing to interpolate from the last animation to the the one about to be played... So I have to check if the target is a skeleton and loop thru ALL the bones to update the enableBlending and blendingSpeed ... Now I get why we have those properties set on the 'Animation' itself BUT when animating a skeleton as the target we really are setting the SAME blending value on all the bones when transitioning from walk to run animations. This is cause a HUGE performance hit on my xbox ... especially when move TWO fully riggred 65 bone animated characters on the screen. Now my work around is to MOD the babylon.runtimeAnimatons class to CHECK if enableBlending and blendingSpeed (and loopMode) are specified on the target's metadata, if so use that info... that way I dont have to loop thru all the bones setting blending speed if the code in 'setValue' use the higher lever value IF EXISTS on target. setValue Code Mod: var enableBlending = (this._target._skeleton && this._target._skeleton.metadata && this._target._skeleton.metadata.enableBlending) ? this._target._skeleton.metadata.enableBlending : this._animation.enableBlending; var blendingSpeed = (this._target._skeleton && this._target._skeleton.metadata && this._target._skeleton.metadata.blendingSpeed) ? this._target._skeleton.metadata.blendingSpeed : this._animation.blendingSpeed; if (enableBlending && this._blendingFactor <= 1.0) { ... rest of code ... } Now @Deltakosh does not like Unity specific mods to the code but I think this would help ALL folks and not just my unity toolkit... Either way... I can keep this in my OWN BUILDS of the babylon.js engine and ships MY OWN builds with toolkit OR I can submit to BabylonJS master Yo @Deltakosh Please let me know if this Kool with you (checking for target level blending info) and I will submit... If not, just me know and I will keep in my OWN BUILDS of the engine... No worries wither way, just thought others could benefit from this little mod as well Quote Link to comment Share on other sites More sharing options...
Guest Posted February 26, 2018 Share Posted February 26, 2018 We cannot rely on metadata for sure But I like the idea of having enableBlending and blendingSpeed hosted on the skeleton instead of per bones. Also as your toolkit is the official unity exporter for babylon.js we cannot ship a custom version of bjs with it. So here is a plan: - We add enableBlendingOverride and blendingSpeedOverride (and actually to all nodes as well) - We change the setValue to look for this properties on target and if not present we keep the current behavior Thoughts? If you like it I'll implement it Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 26, 2018 Author Share Posted February 26, 2018 Thats perfect... same thing i was doing except not on the metadata ... and it keeps us from having to iterate down to each bone animation to set blending speed... can you also do loopMode ... that is another we to iterate all bone animations to set loopmode Quote Link to comment Share on other sites More sharing options...
Guest Posted February 26, 2018 Share Posted February 26, 2018 I will Quote Link to comment Share on other sites More sharing options...
Guest Posted February 26, 2018 Share Posted February 26, 2018 Here we are: http://doc.babylonjs.com/babylon101/animations#overriding-properties Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 26, 2018 Author Share Posted February 26, 2018 2 hours ago, Deltakosh said: Here we are: http://doc.babylonjs.com/babylon101/animations#overriding-properties Yo thanks @Deltakosh Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 26, 2018 Author Share Posted February 26, 2018 3 hours ago, Deltakosh said: Here we are: http://doc.babylonjs.com/babylon101/animations#overriding-properties Yo @Deltakosh I flipped over to using the new animation Properties override but the BLENDING is not happening... it still just snaps to other animation WITHOUT any blending... I am setting the animationPropertiesOverride... it shows it in console: But no blending is happening Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 27, 2018 Author Share Posted February 27, 2018 Yo @Deltakosh I found the problem: // Blending let enableBlending = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.enableBlending : this._animation.enableBlending; let blendingSpeed = this._target && this._target.animationPropertiesOverride ? this._target.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed; The 'this._target' is actually the BONE... So we gotta go 'this._target._skeleton' I fixed it here: // Blending let enableBlending = (this._target && this._target._skeleton && this._target._skeleton.animationPropertiesOverride) ? this._target._skeleton.animationPropertiesOverride.enableBlending : this._animation.enableBlending; let blendingSpeed = (this._target && this._target._skeleton && this._target._skeleton.animationPropertiesOverride) ? this._target._skeleton.animationPropertiesOverride.blendingSpeed : this._animation.blendingSpeed; And here: private _getCorrectLoopMode(): number | undefined { if (this._target && this._target._skeleton && this._target._skeleton.animationPropertiesOverride) { return this._target._skeleton.animationPropertiesOverride.loopMode; } return this._animation.loopMode; } I will submit the PR Thanks again bro Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 27, 2018 Author Share Posted February 27, 2018 10 hours ago, Deltakosh said: We cannot rely on metadata for sure But I like the idea of having enableBlending and blendingSpeed hosted on the skeleton instead of per bones. Also as your toolkit is the official unity exporter for babylon.js we cannot ship a custom version of bjs with it. So here is a plan: - We add enableBlendingOverride and blendingSpeedOverride (and actually to all nodes as well) - We change the setValue to look for this properties on target and if not present we keep the current behavior Thoughts? If you like it I'll implement it Yo @Deltakosh I pulled all my code out from custom version... EXCEPT the main reason I started all this skeletal animation stuff... BLENDING TWO OR MORE skeletal animations together to supper BLEND TREE / BLEND SPACE type behavior ... I needed that info of WHERE to get to the code to do the proper and most performant Bone Matrix Blending. My custom version was doing that in the RuntimeAnimations.animate function RIGHT AFTER the interpolate and RIGHT BEFORE the setValue... I called it blendValue... I still need to do this BUT you say I cant make a custom build of the engine... So I propose to add 'blendValueFunction' to the new animationPropertiesOverride: module BABYLON { /** * Class used to override all child animations of a given target */ export class AnimationPropertiesOverride { /** * Gets or sets a value indicating if animation blending must be used */ public enableBlending = false; /** * Gets or sets the blending speed to use when enableBlending is true */ public blendingSpeed = 0.01; /** * Gets or sets the default loop mode to use */ public loopMode = Animation.ANIMATIONLOOPMODE_CYCLE; /** * Gets or sets the blend value function to use */ public blendValueFunction:(runtimeAnimation:BABYLON.RuntimeAnimation, repeatCount:number, loopMode:number, currentValue:any)=>any; } } And use right here in the 'animate' function: // Compute value var repeatCount = (ratio / range) >> 0; var currentFrame = returnValue ? from + ratio % range : to; var currentValue = this._interpolate(currentFrame, repeatCount, loopMode, offsetValue, highLimitValue); // Blend value if (this._target && this._target._skeleton && this._target._skeleton.animationPropertiesOverride && this._target._skeleton.animationPropertiesOverride.blendValueFunction && typeof this._target._skeleton.animationPropertiesOverride.blendValueFunction === "function") { currentValue = this._target._skeleton.animationPropertiesOverride.blendValueFunction(this, repeatCount, loopMode, currentValue); } // Set value this.setValue(currentValue); I can then use mu custom blendValueFunction to get the other animations involved in the blending and blend them together based on the Blend Tree threshold and whatever propertees you setup on the Unity Animation Controller as the "Blend Factor" ... Like X and Y movement or speed property that would BLEND one or more animations together. Please let me know, if its Kool I will PR That works for me if it works for you Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted February 27, 2018 Author Share Posted February 27, 2018 Yo @Deltakosh I see you closed the animation properties fixes and told me to try again , but I dont see any of the runtimeAnimation 'this._target._skeleton' changes ??? Quote Link to comment Share on other sites More sharing options...
Guest Posted February 27, 2018 Share Posted February 27, 2018 Discussed offline. I fixed it by wrapping the animationPropertiesOverride on every bone Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.