mouse to Three.js world coordinates during TrackballControls
- by PanChan
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));
}
};