Three.js - Cannot drag GLTF mesh with DragControls

Hi. Anybody know three.js?

In the following code, I add a cube and a GLTF mesh - which is a simple cone.

And Drag Controls.

The cube drags as expected but the mesh does not.

Can anyone see what I’m doing wrong?

Thanks! (see it at: http://therawaudio.com/radioc/LIL3D.html)

CODE:

	<script type="module">
		import * as THREE from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/build/three.module.js';
		import {GLTFLoader} from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/loaders/GLTFLoader.js';
		import { DragControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/DragControls.js';
		
		const scene = new THREE.Scene();
		const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

		const renderer = new THREE.WebGLRenderer();
		renderer.setSize( window.innerWidth, window.innerHeight );
		document.body.appendChild( renderer.domElement );

		const objects = [];
		
		const geometry = new THREE.BoxGeometry();
		const material = new THREE.MeshBasicMaterial( { color: 0x444400 } );
		const cube = new THREE.Mesh( geometry, material );
		scene.add( cube );
		objects.push( cube );

		const loader = new GLTFLoader();
		let model, mixer;

		loader.load( 'cone.glb', function ( gltf ) {
			model = gltf.scene;

			scene.add( model );
			
			gltf.scene.traverse( function( object ) {

			   if ( object.isMesh) {
					objects.push( object );
			   }
			} );
		} );

		const directionalLight = new THREE.DirectionalLight( 0xFAEBD7, 20 );
		scene.add( directionalLight );
		
		camera.position.z = 5;

		let controlsDrag, group;

		controlsDrag = new DragControls( [ ... objects ], camera, renderer.domElement );

		const animate = function () {
			requestAnimationFrame( animate );

			cube.rotation.x += 0.01;
			cube.rotation.y += 0.01;

			renderer.render( scene, camera );
		};

		animate();
	</script>

The callback function given to loader.load runs asynchronously, only after the model has finished downloading and processing. So code later in the file, including the line below, actually happen before the objects are added to the array:

controlsDrag = new DragControls( [ ... objects ], ... );

A common way to work around this would be to have an init() function that finishes setting up the controls (or other things that depend on the model) that is only called once all models have been loaded.

Just FYI there is also a three.js discourse forum, which can be helpful for this type of question :slight_smile:

UPDATE: Code change worked! Much rejoicing!

Thank you.

I’ll try the code change.

I did ask this question on the three.js forum but got no reply.

Thanks again.

1 Like