I have a Three.js scene defined using Lume (3D HTML elements), loading the default animated character from Three’s animation blending example. When it has loaded the GLTF model (the <lume-gltf-model>
element uses GLTFLoader
under the hood) my plain Three.js code subsequently creates an AnimationMixer
and uses mixer.clipAction(model.animations[0])
/etc to initiate the animations.
When I run
// broken
walkAction.crossFadeTo(idleAction, 1)
it fades the walk animation to the rest T-pose for some reason.
If I instead use my own fade function, it works:
// use custom function instead (it works!)
crossFadeActions(walkAction, idleAction, 1000)
/** Cross fade between two actions linearly over the given duration in seconds. */
function crossFadeActions(fromAction, toAction, duration) {
Motor.addRenderTask((t, dt) => {
const portion = dt / duration
toAction.weight += portion
fromAction.weight -= portion
if (fromAction.weight <= 0) {
fromAction.weight = 0
toAction.weight = 1
return false
}
})
}
(Motor.addRenderTask
is a small wrapper around requestAnimationFrame
, providing dt
out of the box).
The question is, why would my custom crossFadeActions
function work fine, but Three’s crossFadeTo
not?
Here’s a live demo, where inside the player.on('MODEL_LOAD', ({model}) => {
event handler is plain Three.js code to wire up the model’s animations (model
is the object created by GLTFLoader
, containing model.scene
, model.animations
, etc).
If you comment out the call to crossFadeActions(walkAction, idleAction, 1000)
and uncomment the call to walkAction.crossFadeTo(idleAction, 1)
and rerun the demo, you’ll see the issue.
Here’s the example with the Three.js line uncommented, not working: