Can't I use DragControl and OrbitControl at the same time?

Hello :slight_smile:
I’m working on https://threejs.org/examples/?q=fra#webgl_framebuffer_texture 's code

I have main box object which I want to apply orbit control to overlay div.

and I added cone object relative to box object which I want to apply dragObject.

but when I tried to do so, dragStart callback function is not called.
it’s because I’m touching overlay.

is there a any way that I can use both of them?

full code snippet is as belows. (generating function is called when I press button and generating cone to box object and I want to drag that cone)

<script>

        var camera, scene, renderer,camera_left;
        var objects = [];
		var box, sprite, texture;
		var cameraOrtho, sceneOrtho;
		var dpr = window.devicePixelRatio;
		var textureSize = 128 * dpr;
        var vector = new THREE.Vector2();
		init();
        animate();
        function generating(){
            const RADIUS = 40
            const geometrys = new THREE.OctahedronGeometry(RADIUS, 0);
            const coneGeometry = new THREE.ConeBufferGeometry( 0.1, 0.2 );
            const materials = new THREE.MeshNormalMaterial();
            var object = new THREE.Mesh( coneGeometry, materials );
            object.position.set( 0, 0.2, 0 );
            box.add(object);
            objects.push( object );
        }
		function init() {
            //
            document.getElementById("ss").addEventListener("click", generating);
			var width = window.innerWidth;
			var height = window.innerHeight;
			camera = new THREE.PerspectiveCamera( 70, width / height, 1, 1000 );
            camera.position.set( 0, 1, 1 );
			cameraOrtho = new THREE.OrthographicCamera( - width / 2, width / 2, height / 2, - height / 2, 1, 15 );
			cameraOrtho.position.z = 15;
			scene = new THREE.Scene();
			scene.background = new THREE.Color( 0x20252f );
			sceneOrtho = new THREE.Scene();
			// mini screen shown upper -left side of main screen. 
            const boxGeometry = new THREE.BoxBufferGeometry( 0.2, 0.2, 0.2 );
            const material = new THREE.MeshNormalMaterial();
            box = new THREE.Mesh( boxGeometry, material );
            scene.add( box );
			var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
			scene.add( ambientLight );
			var pointLight = new THREE.PointLight( 0xffffff, 0.8 );
			camera.add( pointLight );
			scene.add( camera );
			//
			var data = new Uint8Array( textureSize * textureSize * 3 );
			texture = new THREE.DataTexture( data, textureSize, textureSize, THREE.RGBFormat );
			texture.minFilter = THREE.NearestFilter;
			texture.magFilter = THREE.NearestFilter;
			texture.needsUpdate = true;
			//
			var spriteMaterial = new THREE.SpriteMaterial( { map: texture } );
			sprite = new THREE.Sprite( spriteMaterial );
			sprite.scale.set( textureSize, textureSize, 1 );
			sceneOrtho.add( sprite );
			updateSpritePosition();
			//
			renderer = new THREE.WebGLRenderer( { antialias: true } );
			renderer.setPixelRatio( window.devicePixelRatio );
			renderer.setSize( window.innerWidth, window.innerHeight );
			renderer.autoClear = false;
            $(".main").append( renderer.domElement );
            var dragControls = new THREE.DragControls( objects, camera, renderer.domElement );
			dragControls.addEventListener( 'dragstart', function ( event ) {
                console.log("drag start");
                 controls.enabled = false; 
                } );
			dragControls.addEventListener( 'dragend', function ( event ) { controls.enabled = true; } );
			//
			var overlay = document.getElementById( 'overlay' );
			var controls = new THREE.OrbitControls( camera, overlay );
			controls.enablePan = true;
			//
			window.addEventListener( 'resize', onWindowResize, false );
		}
		function onWindowResize() {
			var width = window.innerWidth;
			var height = window.innerHeight;
			camera.aspect = width / height;
			camera.updateProjectionMatrix();
			cameraOrtho.left = - width / 2;
			cameraOrtho.right = width / 2;
			cameraOrtho.top = height / 2;
			cameraOrtho.bottom = - height / 2;
			cameraOrtho.updateProjectionMatrix();
			renderer.setSize( window.innerWidth, window.innerHeight );
			updateSpritePosition();
		}
		function updateSpritePosition() {
			var halfWidth = window.innerWidth / 2;
			var halfHeight = window.innerHeight / 2;
			var halfImageWidth = textureSize / 2;
			var halfImageHeight = textureSize / 2;
			sprite.position.set( - halfWidth + halfImageWidth, halfHeight - halfImageHeight, 1 );
		}
		function animate() {
			requestAnimationFrame( animate );
			// mesh.rotation.x += 0.005;
			// mesh.rotation.y += 0.005;
			renderer.clear();
			renderer.render( scene, camera );
			// calculate start position for copying data
			vector.x = ( window.innerWidth * dpr / 2 ) - ( textureSize / 2 );
			vector.y = ( window.innerHeight * dpr / 2 ) - ( textureSize / 2 );
			renderer.copyFramebufferToTexture( vector, texture );
			renderer.clearDepth();
			renderer.render( sceneOrtho, cameraOrtho );
		}
	</script>
1 Like

I’ve create a little fiddle that shows that you can use DragControls and OrbitControls at the same time. In order to avoid a conflict between both controls, you have to disable OrbitControls when you hover with the mouse over an object. Not super elegant but it works. Maybe this helps a bit to illustrate the problematic situation when using multiple controls in parallel.

https://jsfiddle.net/L379hjfs/

7 Likes

This uses OrbitControls, DragControls and TransformControls at the same time.
https://sbcode.net/threejs/multi-controls-example/
The code shown is in typescript though so you should ignore the type annotations and modify your imports appropriately.
See the addEventListener sections for each control example in the code, for examples of how to stop conflicts.

3 Likes

@Mugen87
Thanks for your idea, but it behaves strange at dragging object outside of canvas. Just release mouse outside of canvas and move it back to it again. Model flies away

The fiddle above doesn’t work with at least versions 120 to latest (122). Looks like the OrbitControls is hijacking the mousedown and not letting it get to the DragControls any more. This fiddle shows the problem, or just change the versions.

I don’t have a solution to the problem as of yet; but will post when/if I get a decent solution.

You can deactivate drag controls via .deactivate()
This enables orbit controls and then in case of need to drag objects you can activate it again with .activate()
I was not able to find a solution to use both simultaneously.
Here is an example with enabling and disabling controls via pressing left Ctrl.
https://jsfiddle.net/DaniilKhokho/g4xnz5db/3/

You can probably make this better with checking for object to move via raycast and then enabling drag controls. Please share if you find a better solution.

1 Like

After moving to r126, the problem went away.

1 Like

FYI: It should work again since r123:

2 Likes