firstInactiveBinding is undefined

Good day, community!

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:

update() {
        this.resetMixer();
        this.setAction();
    }

resetMixer() {
        this.mixer.stopAllAction();
        if (this.action) {
            const clip = this.action.getClip();
            this.mixer.uncacheAction(clip);
            this.mixer.uncacheClip(clip);
            this.action = null
        }
        this.mixer.uncacheRoot(this.mixer.getRoot())
    }

setAction() {
        if (!this.action) {
            const clip = this.getClip();
            if (clip) {
                this.action = this.mixer.clipAction(clip);
                this.resetAction()
            } else {
                this.action = null;
            }
        }
        return this.action;
    }

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!

Good day, community!

After deep diving into the AnimationMixer I have still not been able to determine the cause of this error.

Therefore, I have created a JSFiddle project that recreates the issue.
https://jsfiddle.net/mornejac/eqf0d59a/78/

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:

  1. Click “Play Both” and let the animation run
  2. Click “change clip 2”
  3. 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.

Any advice would be much appreciated!

It seems you are running into this issue:

Like mentioned at GitHub I was not able to find out the problem for the runtime error so far. Please avoid the usage of uncacheRoot() for now.

Also feel free to continue the discussion at GitHub.

Thank you, I would not have gotten to this GitHub issue by myself.

You already did a great investigation job in Material.opacity set to NaN after animation stops. I would appreciate a second pair of eyes helping to understand the issue in uncacheRoot() :innocent: .

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.

1 Like