How to clone a model that's loaded with GLTFLoader()?

it seems i can’t use Object.assign() or jQuery’s .extend(), because the model contains functions?

is there any way at all to clone it?

Have you tried just this:

const model = gltf.scene.clone();
2 Likes

i’ll try it right now! :smiley:

it didn’t work… the model refused to show up entirely, even though i got no errors…

Please try to replicate the issue with a live example. You can also share a GitHub repository that demonstrates the problem.

This works well with a simple model.

See * discourse.threejs.hofk.de BeginnerExample BeginnerExample

// … step 03: load 3D models - gltf

2021-03-01 20.22.24

const modelBee = new THREE.Object3D( );
const modelBee1 = new THREE.Object3D( );
loader.load( 'Kelli Ray_Bee/toi uu.gltf', processBee );

 function processBee( gltf ) { // Kelli Ray  (CC-BY) Poly by Googl
 
			//https://threejs.org/docs/index.html#api/en/math/Box3
	const box = new THREE.Box3( ).setFromObject( gltf.scene );
	const c = box.getCenter( new THREE.Vector3( ) );
	const size = box.getSize( new THREE.Vector3( ) );
	gltf.scene.position.set( -c.x, size.y / 2 - c.y, -c.z ); // center the gltf scene
	modelBee.add( gltf.scene );
	modelBee1.add( gltf.scene.clone( ) );	
}

modelBee.scale.set( 0.002, 0.002, 0.002 ); // because gltf.scene is very big
modelBee.position.set( 2.4, 0.2, 0.5 );
modelBee.rotation.y = Math.PI;
scene.add( modelBee );

modelBee1.scale.set( 0.0025, 0.0025, 0.0025 ); // because gltf.scene is very big
modelBee1.position.set( -2.4, 0.9, 1.8 );
modelBee1.rotation.x = 0.8; // radiant
modelBee1.rotation.y = 1.2; // radiant
scene.add( modelBee1 );
1 Like

Here I show how to clone a glb file(its a bin version of a gltf file, which contains everything packaged in one file as .glb. it can contain textures too.) I hope someone finds this snippet below useful.

const ModelOriginal;
let ModelClone;
loader.load("./assets/3D models glb/3Dmodel.glb", function (glb) {
    //Adding original 3d model to scene
    ModelOriginal= glb.scene;
    ModelOriginal.position.set(0, 1.5, 1);
    ModelOriginal.scale.set(0.2, 0.2, 0.2);
    scene.add(ModelOriginal);

    //Now we create a clone of the ModelOriginal Object
    ModelClones = ModelOriginal.clone();//clone added
    // setting a different scale and position so that the clone doesnt overlap the original model
    ModelClones.position.set(0, 1, 0);
    ModelClones.scale.set(0.4, 0.4, 0.4); 
    scene.add(ModelClones); // clone added to scene
});```

Is it better to use glb files over gltf?
For a beginner yes, as they package the textures etc into a single file
and....i find it simpler.

Skinned meshes cloned with Object3D.clone() share the same geometry and bones so you have to use SkeletonUtils.clone(), which can be found here:
https://threejs.org/docs/?q=utils#examples/en/utils/SkeletonUtils

4 Likes

@Rene_Veerman
I had the same issue where const model = gltf.scene.clone(); didn’t show the cloned model even though there were no errors.

@WilliamBagel 's suggestion worked for me (SkeletonUtils.clone()), and here’s an example of the code I used:

import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js';

let tree = {};
const gltfLoader = new GLTFLoader();
gltfLoader.load(
  '/models/tree/scene.gltf',
  (gltf) => {
    tree = gltf.scene;
    tree.position.x = 20;
    scene.add(tree);

    const tree2 = clone(tree);
    tree2.position.x = -20;
    scene.add(tree2);
  }
);

I hope this helps the next person!

1 Like

I love you, you saved my life

to clone a gltf as a whole, you need to place all mesh under one node, if the meshes are separate, only the first mesh (gltf.scene[0]) will be cloned and the gltf.scene[1 … n] will be ignored.