javascriptcanvas3dwebglthree.js

three.js - how to make camera look at an object during a tween


so I'm experimenting with using tweens to tween a camera's fov based on an object that is clicked on in the scene, which is working great, but now what I want it to do is to have the camera switch its focus to the object that was clicked, which is not working. Here's my code for the click:

function onDocumentMouseDown( event ) {
    event.preventDefault();

    var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
    var intersects = ray.intersectObjects( objects );
    if ( intersects.length > 0 ) { //We've clicked a certain object

        camTarget = intersects[0].object.position; //HERE'S THE VECTOR3 I WANT TO LOOK AT
        camTween.start();
    }
}

and my code for the tween / camera movement:

var camUpdate = function(){
    camera.fov = currentFov.fov;  //WORKING
    camera.lookAt(camTarget); //NOT WORKING
    camera.updateProjectionMatrix();
}

var currentFov = { fov: camera.fov };

TWEEN.removeAll();
camTween = new TWEEN.Tween(currentFov).to({fov: +zoomInFov},tweenTime).easing(camEase).onUpdate(camUpdate);

The camera is tweening the field of view properly, but it appears to stay pointed in the same direction it always was pointed at, instead of switching to the "camTarget" vector specified in the lookAt command.


Solution

  • The renderer calls THREE.Camera.update(), which sets the rotation of the camera by default to look at THREE.Camera.target (which is an THREE.Object3D). Instead of doing...

    camera.lookAt( camTarget );
    

    ...try...

    camera.target.position.copy( camTarget );
    

    I'm not sure I follow how camTarget is tweened, or maybe it just should switch to the new object?

    Side note: it's advisable not to perform heavy computation in event handlers - in the best of worlds, you set a flag in the event handler and process in the render loop.