No way of cloning a mesh so it works with a skinning material

Skinned material need their own geometry to work. This is because the material deforms the geometry, so if you share the same geometry between two meshes with deformation, things are going to get weird (at least that’s how I understand it).

Now the problem is, if you load a mesh from a FBX or something else and it contains at some point a skinned mesh, and you need multiple instances of it, here’s what happens:

  • You call clone(); on the mesh to generate your new instances
  • The clone function doesn’t generate a new geometry, so both models share geometry, and things gets bad (the mesh doesn’t appear at all).

Here’s a code sample: I was able to replicate this problem in the webgl_loader_fbx.html demo with a simple modification: Just clone the mesh once loaded before using it, and you’ll see that the cloned version of it doesn’t work:

loader.load( 'models/fbx/xsi_man_skinning.fbx', function( originalObject ) {

	// Using a clone of the mesh, it won't work
	var object = originalObject.clone();
	object.mixer = new THREE.AnimationMixer( object );
	mixers.push( object.mixer );

	var action = object.mixer.clipAction( object.animations[ 0 ] );
	action.play();

	scene.add( object );


}, onProgress, onError );

Is there a way to fix this behaviour? Like a deep clone function that also recreates geometries?

If not, should I just write a function that recursively recreates all the meshes in my object, regenerating their geometry? Or is it a bad idea?

Author: Fantashit

2 thoughts on “No way of cloning a mesh so it works with a skinning material

  1. I’ve been dealing with this while working on #11603 – the problem I’ve seen is that after cloning, all your bones have new UUIDs, but the skeleton still references the UUIDs from the original model. I’ve experimented with adding a function to SkinnedMesh which remaps bone UUIDs by name, but it has problems with some models which load with nameless bones.

    Will update this issue with any updates if we find a good solution while working on the other issue.

  2. Following up here, #14494 includes a utility function to help with cloning skinned meshes:

    var copy = SkeletonUtils.clone( original );

    The object given as a parameter may be a SkinnedMesh or an Object3D or Scene containing one or more SkinnedMesh instances. Any bones referenced by the SkinnedMesh(es) must also be children of the given object.

Comments are closed.