I am receiving an intermittent error when I run animations in my application.
The error description is “firstInactiveBinding is undefined” and it is being thrown by the AnimationMixer’s _lendBinding method. I have established that the error occurs because the “lastActiveIndex” exeeds the upper bound of the “bindings” array by 1.
In my application I allow the user to dynamically create and edit animations. The logic is as follows:
An AnimationMixer is instantiated for each object in the scene.
Each mixer can run mulitple AnimationActions, which may target the same properties of the root object.
Any changes to the animation properties results in the following update() method being called:
It appears that the errors occur only when there are multiple AnimationActions defined for clips that target the same object properties and they run concurrently.
I suspect it has something to do with the mixer cache keeping propertyBindings active. However, this is extremely difficult to debug due to the intermittent nature of the bug. I am considering now to simply recreate the mixer each time an animation is run. However, this would be extremely inefficient…
If anyone has encountered a similar issue or have some helpful advice, then I would really appreciate it!
Note that the code seems contrived, but this is because I have users dynamically creating and modifying animations, and in that scenario this logic is highly probable to happen (atleast in my application).
In the Fiddle you can click on the “play1” and “play2” buttons to turn the cube respectively red + transparent and blue + transparent. If you click “play Both” then both animations run concurrently resulting in a purple + transparent cube. This runs correctly.
To recreate the error do the following:
Click “Play Both” and let the animation run
Click “change clip 2”
Click “Play Both” and this time the error occurs as you can see in the console.
Note that I am currently calling mixer.uncacheRoot before creating a new clipAction2. This is merely because I find it easier to troubleshoot than calling uncacheClip, which is what I actually want to accomplish. This is because uncacheRoot completely empties the cache of the mixer.
Therefore, in this FiddIe could propably just recreate the mixer entirely and avoid the issue. However, if I could solve this problem and use uncacheClip instead it would be much more efficient for me, because in my application the mixer may contain a large number of actions.
Thank you. I am a big fan of your work, so i appreciate the feedback.
I did a detailed trace of this issue by hand to try and get to the root of the problem.
I believe the issue concerns the following block of code in the mixer’s _activateAction method:
// increment reference counts / sort out state
for ( let i = 0, n = bindings.length; i !== n; ++ i ) {
const binding = bindings[ i ];
if ( binding.useCount ++ === 0 ) {
this._lendBinding( binding );
binding.saveOriginalState();
}
}
When I trace the code, I my bindings cache and the _nActiveBindings index reaches a state that would cause the error if _lendBinding is executed next. However, in my trace binding.useCount is always 0 so that_lendBinding SHOULD NOT be executed!
Unfortunately I lack time at the moment to investigate further, but I believe somewhere useCount is incorrectly set to > 0.