mouse to Three.js world coordinates during TrackballControls

Posted by PanChan on Stack Overflow See other posts from Stack Overflow or by PanChan
Published on 2013-06-25T10:20:06Z Indexed on 2013/06/25 10:21 UTC
Read the original article Hit count: 1082

Filed under:

I know there are a lot of answers how to translate the mouse coordinates to the Three.js world coordinates (I prefere this one). But I have troubles on calculating when using TrackballControls.

First what I expect to do: I want to add a zoom function to my scene. Not by the mouse wheel, the user should be able to draw a rectangular and by lifting the mouse button, the camera is zooming on this rectangular.

I've implemented all and it works, but only when the user didn't rotate/zoom/pan with TrackballControls! If the camera was manipulated, I get wrong coordinates for my drawn rectangular. I really can't figure out why... I only know that it's an issue with TrackballControls, because without them, it works.

Does anyone see my mistake? I'm sitting here for two days now and can't find it.... :(

var onZoomPlaneMouseDown = function(event){
    event.preventDefault();
    var plane = document.getElementById("zoomPlane");
    var innerPlane = document.getElementById("innerZoomPlane");
    var mouseButton = event.keyCode || event.which;

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

    if(mouseButton === 1){ 
        var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
        projector.unprojectVector( vector, camera );
        var dir = vector.sub( camera.position ).normalize();
        var distance = - camera.position.z / dir.z;
        zoomPlaneUpperCorner = camera.position.clone().add( dir.multiplyScalar( distance ) );

        innerPlane.style.display = "block";
        innerPlane.style.top = event.clientY + "px";
        innerPlane.style.left = event.clientX + "px";

    }

    if(mouseButton === 3){ 
        plane.style.display = "none";
        innerPlane.style.display = "none";
    }
};

var onZoomPlaneMouseUp = function(event){
    event.preventDefault();
    var plane = document.getElementById("zoomPlane");
    var innerPlane = document.getElementById("innerZoomPlane");
    var mouseButton = event.keyCode || event.which;

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

    var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
    projector.unprojectVector( vector, camera );
    var dir = vector.sub( camera.position ).normalize();
    var distance = - camera.position.z / dir.z;
    zoomPlaneLowerCorner = camera.position.clone().add( dir.multiplyScalar( distance ) );

    if(mouseButton === 1){ 
        plane.style.display = "none";
        innerPlane.style.display = "none";

        var center = new THREE.Vector3();
        center.subVectors(zoomPlaneLowerCorner, zoomPlaneUpperCorner);
        center.multiplyScalar( 0.5 );
        center.add(zoomPlaneUpperCorner);   

        var rayDir = new THREE.Vector3();
            rayDir.subVectors(center, camera.position ).normalize();

        controls.target = center;               

        var height = zoomPlaneUpperCorner.y - zoomPlaneLowerCorner.y;
        var distanceToCenter = camera.position.distanceTo(center);
        var minDist = (height / 2) / (Math.tan((camera.fov/2)*Math.PI/180));

        camera.translateOnAxis(rayDir, (distanceToCenter - minDist));
    }
};

© Stack Overflow or respective owner

Related posts about three.js