Multiple Views Raycasting TransformControls

hi everyone!

I am trying to show multiple views on the same renderer like:

https://threejs.org/examples/webgl_multiple_views

In each view I am trying to perform object picking/raycasting once an object is picked in the specific view, I’d like to attach the THREE.TransformControls. It only works in the 2nd in the middle but not the others. Can you please help?

It’s a bit hard to help you without debugging your code. You might want to demonstrate the issue as a live example.

In any event, the mentioned example uses a perspective matrix per view. You have to ensure to THREE.TransformControls with the correct camera, otherwise the interaction won’t work correctly.


I have a teapot object and then…
raycaster = new THREE.Raycaster();

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

             control = new THREE.TransformControls( camera, renderer.domElement );

            control.addEventListener( 'change', render );

            scene.add( control );
            renderer.domElement.addEventListener( 'mousedown', clickEvent );

        function clickEvent( event ) {
            var elem = renderer.domElement,
                boundingRect = elem.getBoundingClientRect(),
                x = (event.clientX - boundingRect.left) * (elem.width / boundingRect.width),
                y = (event.clientY - boundingRect.top) * (elem.height / boundingRect.height);
			//1st view
            var view = tripleViews[1];
           camera = view.camera;
            var WIDTH = Math.floor(windowWidth * view.width);
            var HEIGHT = Math.floor(windowHeight * view.height);

            mouse.x = ( x / WIDTH ) * 2 - 1;
            mouse.y = - ( y / HEIGHT ) * 2 + 1;

            raycaster.setFromCamera( mouse, camera );
            var intersects = raycaster.intersectObjects( scene.children );
            if ( intersects.length > 0 ) {
                if ( INTERSECTED != intersects[ 0 ].object ) {
                    INTERSECTED = intersects[ 0 ].object;

                    if ( control.object === undefined || control.object !== INTERSECTED ) {
                        control.attach( INTERSECTED );
                    }
                }
            }

            render();
        }
the transform controls only work in the 2nd viewport. Here are the configurations for my viewport.


            var tripleViews = [
				{
					left: 0,
					bottom: 0,
					width: 0.33,
					height: 1.0,
					background: new THREE.Color( 0.8, 0.9, 1.0 ),
					eye: [ 0, 300, 1200 ],
					up: [ 0, 1, 0 ],
					fov: 70,
					updateCamera: function ( camera, scene, mouseX ) {

				//	 camera.position.x += mouseX * 0.05;
                        // 	camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), - 2000 );
					  camera.lookAt( scene.position );
                      		  //  background: new THREE.Color( 0.2, 0.9, 1.0 );
					}
				},
				{
					left: 0.33,
					bottom: 0,
					width: 0.34,
					height: 1,
					background: new THREE.Color( 1.0, 0.8, 0.9 ),
					eye: [ 0, 1800, 0 ],
					up: [1, 0, 0 ],
					fov: 45,
					updateCamera: function ( camera, scene, mouseX ) {
                        //camera.position.x -= mouseX * 0.05;
                        //camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), - 2000 );
					  camera.lookAt( camera.position.clone().setY( 0 ) );


					}
				},
				{
					left: 0.66,
					bottom: 0,
					width: 0.34,
					height: 1,
					background: new THREE.Color( 0.7, 0.897,  0.5),
					eye: [ 1400, 800, 0 ],
					up: [ 0, 1, 0 ],
					fov: 60,
					updateCamera: function ( camera, scene, mouseX ) {

				//	  camera.position.y -= mouseX * 0.05;
				///	  camera.position.y = Math.max( Math.min( camera.position.y, 1600 ), - 1600 );
					  camera.lookAt( scene.position );

					}
				}
			];

I  also just want to use the world coordinates. Please help!

How can transformcontrols be only applied to specific viewport within the same scene?

I’m not sure I understand this question. When you transform an object with the controls, you will see this effect in all of your views. Remember, that you don’t transform the camera but the object itself.

Thank you so much for taking the time to help! @Mugen87
Although the effect will be seen in all the views, if the controls in the 1st viewport is moved it should only move in the X direction. Likewise the controls in the 2nd viewport is moved, then only the object should move in the Y direction. We don’t have to worry about the 3rd viewport because it would just be a display. Can you please help me? I am able to find when the intersections happened with each viewport with the following code:

// 1st viewport
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 1;

// 2nd viewport
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;

// 3rd viewport
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 6 - 5;

mouse.y = - ( event.clientY / renderer.domElement.clientHeight) * 2 + 1;

Even though I can detect when my mouse intersects the object at that particular viewpoint, I still cannot used the transformcontrols in all of the viewports individually.

I was also considering using DragControls but I am not sure how to restrict the drag to a particular X or Y plane in each viewport. I really appreciate your suggestions.

I think the issue stems from the internal function getPointer for TransformControls.

It is hardcoded to use the dimensions of the HTML canvas. There doesn’t appear to be a way to do any override or supply options to factor for when you use renderer.setViewport and renderer.setScissor a new coordinate space is create.