How to LERP or smooth transitions between two looping animations?

Hi Team!

Is there a way to blend animations? I am currently switching between an idle, a walk-forward, and a walk-backward animation loop (and moving my Mixamo character) depending on bool variables that are set by the usual KeyboardEventTypes KEYDOWN/KEYUP events.

The animations look good while the appropriate key is pressed, but the transition is rough/jagged when I transition from one animation to another.

I have seen this before when trying out panda3d, and I was able to achieve smooth transitions by doing something like

LerpAnimInterval(actorName, transitionTime, currentAnimation, newAnimation)

Does anything like this exist for babylonjs?

As of now I just have a method that starts the new animation when a key is first pressed and stops all others (I have about 18 that are stored in the Mixamo model). The animation is not started repeatedly while holding down a key; it’s only started up once when it’s when the associated bool val first becomes true and stops looping when the bool first becomes false.

playAnimation(animationName) {
    for (let index = 0; index < this.actorAnimations.length; index++) {
        if (this.actorAnimations[index].name !== animationName) {
            this.actorAnimations[index].stop();
        } else {
            this.actorAnimations[index].start(true);
        }
    }
}

Thanks!

		// Enable animation blending for all animations
        scene.animationPropertiesOverride = new BABYLON.AnimationPropertiesOverride();
        scene.animationPropertiesOverride.enableBlending = true;
        scene.animationPropertiesOverride.blendingSpeed = 0.02;
        scene.animationPropertiesOverride.loopMode = 1;

Or one may use this solution at container level - Animation Blending

There is a lot of different examples of animation blending here at Forum and in the Docs as well - Advanced Animation Methods | Babylon.js Documentation

3 Likes

Thanks @labris !

1 Like

Yep that is awesome…works great. I wouldn’t have though you could do it so easily without having to look at the current animation and the desired animation and then pass them to some method each time a transition occurs.

Made my game scene class look like this:

import {
    AmmoJSPlugin, AnimationPropertiesOverride, Scene, Vector3,
} from '@babylonjs/core';
import '@babylonjs/core/Debug/debugLayer';
// eslint-disable-next-line import/no-extraneous-dependencies
import '@babylonjs/inspector';
import Ammo from 'ammo.js';

class GameScene {
    constructor(gameEngine) {
        this.scene = new Scene(gameEngine);
    }

    async createScene() {
        const ammo = await Ammo();
        this.scene.enablePhysics(new Vector3(0, -9.81, 0), new AmmoJSPlugin(true, ammo));

        // Enable babylonjs inspector
        await this.scene.debugLayer.show({
            embedMode: true,
        });

        this.scene.animationPropertiesOverride = new AnimationPropertiesOverride();
        this.scene.animationPropertiesOverride.enableBlending = true;
        this.scene.animationPropertiesOverride.blendingSpeed = 0.2;
        this.scene.animationPropertiesOverride.loopMode = 1;
        return this.scene;
    }
}

export { GameScene };


1 Like