Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Three.js 3D Zoom to mouse position

I have a next problem. I have a project made with Three.js + orbitControls.js for camera handling. There is a scene, with a simple cube on it, and the camera. I have a camera from orbitControls.js, when I do mouse wheel, it zoom in/out towards the center of the screen(default behaviour). I need to modify that, so that will be zooming in/out to mouse position on 3D object, like it is in 3D editors, like 3D Max, blender.

I do understand that logic should be something like that: take the position of mouse from where you are starting zooming, and actually where to you want to zoom in, store that value, zoom in and get the new mouse position, find offset between the first mouse position and current, and move camera to that offset during zooming in. But, it is not working ok. Mostly I think it is a probably the problem of coordinates of my camera, and the position where to I want to zoom in.

Here is my code:

 window.onload = function() {

        var renderer = new THREE.WebGLRenderer();
        var width = 640;
        var height = 480;
        renderer.setSize( width, height );
        var div = document.getElementById('canvas')
        div.appendChild( renderer.domElement );

        var scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera(
            70,
            width / height,
            0.1,
            10000
        );
        camera.position.set( 0, 10, 10 );
        camera.lookAt( scene.position );

        control = new THREE.OrbitControls( camera );

        var geometry = new THREE.CubeGeometry( 5, 5, 5 );
        var material = new THREE.MeshLambertMaterial( { color: 0xFF0000 } );
         mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );

        var light = new THREE.PointLight( 0xFFFF00 );
        light.position.set( 10, 0, 10 );
        scene.add( light );

        var dt = 30;
        var renderFunc = function() {
          update(dt);
          renderer.render(scene,camera);
        };

        setInterval(renderFunc,dt);

        //MY ZOOMING CODE.
        var mouseVector = new THREE.Vector3();
        var projector = new THREE.Projector();  
        var startMousePos = new THREE.Vector3();
        var intersectedPoint = new THREE.Vector3();
        var intersectedOffset = new THREE.Vector3();

//FIND INTERSECTED POSITION ON THE CUBE         
        canvas.onmousemove = function (event)
        {
            mouseVector.x = ( event.clientX / 640 ) * 2 - 1;
            mouseVector.y = - ( event.clientY / 480 ) * 2 + 1;
            startMousePos.x = mouseVector.x;
            startMousePos.y = mouseVector.y;

            var vector = new THREE.Vector3( mouseVector.x, mouseVector.y, 1 );
            projector.unprojectVector( vector, camera );
            var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

            var intersects = ray.intersectObjects( scene.children );

            if ( intersects.length > 0 )
            {
                 intersectedPoint = intersects[0].point;
            }
        }
//HERE I THINK I MUST TRANSLATE MY CAMERA.
        canvas.onmousewheel = function(event)
        {
            if(event.wheelDelta > 0)
            {
                camera.position.x -= intersectedPoint.x;
                camera.position.y -= intersectedPoint.y;
                camera.position.z -= intersectedPoint.z;
            }
            else
            {
                camera.position.x += intersectedPoint.x;
                camera.position.y += intersectedPoint.y;
                camera.position.z += intersectedPoint.z;

            }
        }
    };

Have somebody done that before? Could you please show me how did you solved that, or give me an advice how to handle that?

Thanks!

like image 219
PolosatiyVjih Avatar asked Sep 28 '22 17:09

PolosatiyVjih


1 Answers

After you get the intersect point, you can apply it as the orbitControl's target like this:

  if ( intersects.length > 0 )
        {
             intersectedPoint = intersects[0].point;
        }

 control.target = intersectedPoint ;

then, when you will zoom in it will be towards the point you chose.

like image 54
Normal Avatar answered Oct 03 '22 01:10

Normal