I’ve been having the hardest time trying to clone an animated glb model since the deprecation of the LegacyJsonLoader.
Here is my fiddle:
https://jsfiddle.net/Screwhead28/6fvwuph3/1
I also added the skeletonutils script and havent had much success. Can someone point me in the right direction on how to clone an animated model? It used to be so much easier.
model = gltf.scene;
model.scale.set(1,1,1);
scene.add( model );
/* setTimeout(() => {
const clonedModel = SkeletonUtils.clone(model);
scene.add(clonedModel);
}, 1000);*/
for (let i = 0; i < 10; i++) {
let bird = model.clone();
bird.position.set(0,randnum(0,10),0);
bird.scale.set(1, 1, 1);
scene.add(bird);
}
You were using an old crusty version of THREE. I updated your fiddle a bit.
I made it use importmaps and “import”, and using latest threejs.
Seems to be working.
2 Likes
Thank you for that. I’m still wondering why the previous scripts weren’t working. I use the older script version because it also works in Firefox. I know that modules were introduces in version 128 and up but the SkeletonUtils script doesn’t seem to register unless you use the importmaps and import.
128 is pretty old at this point. Probably good to use something recent. 
You were missing THREE
in front of SkeletonUtils but I am not sure if that was the only wrong thing there.
If you still need to use old versions then here is something you can paste in the fiddle for a test (it has some bits of @manthrax code).
HTML Section
<script src="https://unpkg.com/three@0.147.0/build/three.min.js"></script>
<script src="https://unpkg.com/three@0.147.0/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://unpkg.com/three@0.147.0/examples/js/utils/SkeletonUtils.js"></script>
<script src="https://unpkg.com/three@0.147.0/examples/js/controls/OrbitControls.js"></script>
JavaScript Section
//===================================================== scene
const randnum = (min, max) => Math.round(Math.random() * (max - min) + min);
//===================================================== canvas
var renderer = new THREE.WebGLRenderer({ alpha: true, antialiase: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.outputEncoding = THREE.sRGBEncoding;//for colors to match blender material
document.body.appendChild(renderer.domElement);
//===================================================== scene
var scene = new THREE.Scene();
//===================================================== camera
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000);
camera.position.z = 5;
camera.position.y = 1.5;
//===================================================== lights
var light = new THREE.DirectionalLight(0xefefff, 3);
light.position.set(1, 1, 1).normalize();
scene.add(light);
var light = new THREE.DirectionalLight(0xffefef, 3);
light.position.set(-1, -1, -1).normalize();
scene.add(light);
//===================================================== resize
window.addEventListener("resize", function() {
let width = window.innerWidth;
let height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
//===================================================== model
var loader = new THREE.GLTFLoader();
var model;
var mixer;
loader.load(
"https://raw.githubusercontent.com/Data-Bee38/models/main/bird-fly.glb", function(gltf) {
gltf.scene.traverse( function( node ) {
if ( node instanceof THREE.Mesh ) {
node.castShadow = true;
node.material.side = THREE.DoubleSide;
}
});
model = gltf.scene;
model.scale.set(1,1,1);
mixer = new THREE.AnimationMixer();
for ( let i = 0; i < 10; i++ ) {
let bird = THREE.SkeletonUtils.clone( model );
bird.position.randomDirection().multiplyScalar( randnum( 0, 10 ) );
bird.scale.set( 1, 1, 1 );
bird.rotation.y = Math.PI * Math.random() * 2;
let action = mixer.clipAction( gltf.animations[0], bird ).play();
action.timeScale= ( Math.random() * .5 ) + 1;
action.time= ( Math.random() * .5 ) + 1;
scene.add( bird );
}
/* setTimeout(() => {
const clonedModel = SkeletonUtils.clone(model);
scene.add(clonedModel);
}, 1000);*/
//console.log(gltf.animations); //shows all animations imported into the dopesheet in blender
});
const controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.zoomSpeed = 0.5;
controls.rotateSpeed = 0.5;
//===================================================== animate
var clock = new THREE.Clock();
function render() {
requestAnimationFrame(render);
//https://discourse.threejs.org/t/how-to-update-more-than-60-times-second/10797/10
var delta = clock.getDelta();
var ticks = Math.round( delta / ( 1 / 120 ) );
for ( let i = 0 ; i < ticks ; i++ ) {
if (mixer) mixer.update(delta / ticks);
}
controls.update();
renderer.render(scene, camera);
}
render();
2 Likes
Nice! This is exactly what I needed. This also works in the Firefox browser. Big Thanks!

1 Like