Babylon.js: Make it easier to clone a mesh and start the associated animations/animationGroup

Created on 25 Oct 2018  路  7Comments  路  Source: BabylonJS/Babylon.js

http://www.html5gamedevs.com/topic/40837-trying-to-create-instance-babylon-assets-work-but-gltf-doesnt-why-see-pg/

Ideally, once a scene is loaded. We should have a way to clone a node and animationGroup such that they are instanced if possible and the animationGroup is also cloned such that the new clone can have its own animations.

It might also be helpful to add a beginHierarchyAnimation function to scene to start all the animations of a mesh hierarchy.

animations

Most helpful comment

Yes, your PG works fine. The issue in question here is with AnimationGroup which is not used in your PG.

All 7 comments

I introduced the new scene.beginHierarchyAnimation:
https://github.com/BabylonJS/Babylon.js/commit/561a6ab5e7938c83dc2f97052a35384f365b171c#diff-aaac583e72d3b9ddbcc6f5bcd46e849dR27653

Ideally, once a scene is loaded. We should have a way to clone a node and animationGroup such that they are instanced if possible and the animationGroup is also cloned such that the new clone can have its own animations.

We still want a helper function to do the former.

I will use this PG as use case: https://www.babylonjs-playground.com/#Y7XMAR#8

So I simplified the cloning of AnimationGroup but there is no easy way to go further.
Here is an example that I built to illustrate that:

    addNewDragon = function(mesh, x) {
        var newInstance = mesh.clone();
        newInstance.position = new BABYLON.Vector3(x, 0, 0);

        let children = newInstance.getChildMeshes();
        let sourceChildren = mesh.getChildMeshes();

        let bones = [];
        let sourceBones = [];

        for (var index = 0; index < children.length; index++) {
            var child = children[index];
            var sourceChild = sourceChildren[index];

            if (sourceChild.skeleton) {
                sourceBones.push(...sourceChild.skeleton.bones);
                child.skeleton = sourceChild.skeleton.clone();
                bones.push(...child.skeleton.bones);
            }
        }

        let sourceGroups = scene.animationGroups.slice(0);
        for (var index = 0; index < sourceGroups.length; index++) {
            let group = scene.animationGroups[index];
            let newGroup = group.clone("", (target) => {
                let index = sourceBones.indexOf(target);

                if (index > -1) {
                    return bones[index];
                }

                index = sourceChildren.indexOf(target);

                if (index > -1) {
                    return children[index];
                }

                return target;
            })

            newGroup.play(true);
        }
    }

As you can see here, I clone the group and provide a way to map to new bones / meshes. but the animation group is not targeting the bones or even the mesh itself. They are targeting meshes used as root for the bones to it is a far more complex topic.

In this case I would recommend reloading the file multiple times (would be fast thanks to the cache)

Closing for now as there is no simple API way

Hey, if you assign the skeleton to your cloned mesh it works somehow!
@bghgary

var rabbit2 = rabbit.clone("rabbit2");
rabbit2.skeleton = rabbit.skeleton.clone("clonedSkeleton");
scene.beginAnimation(rabbit2.skeleton, 73, 100, true, 0.8);

Reference: https://www.babylonjs-playground.com/#QY1WYT#0

Yes, your PG works fine. The issue in question here is with AnimationGroup which is not used in your PG.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

projectSHAI picture projectSHAI  路  38Comments

azchatlanin picture azchatlanin  路  17Comments

deltakosh picture deltakosh  路  39Comments

maxime1992 picture maxime1992  路  17Comments

deltakosh picture deltakosh  路  91Comments