houbysoft
houbysoft

Reputation: 33392

ThreeJS camera.lookAt() has no effect, is there something I'm doing wrong?

In Three.js, I want a camera to be pointed at a point in 3D space.

For this purpose, I tried using the camera.lookAt function like so:

camera.lookAt(new THREE.Vector3(-100,-100,0));

However, I found out that the call has no effect whatsoever. It just does nothing at all. I tried changing the numbers in the vector, and I always get the same look on screen, when it should be changing.

I just found now that if I remove the THREE.TrackballControls I have in my code, the camera.lookAt() works as it should. Is there something wrong with how I use THREE.TrackballControls? This is how I initialize them:

    controls = new THREE.TrackballControls( camera, renderer.domElement );

    controls.rotateSpeed = 10.0;
    controls.zoomSpeed = 1.2;
    controls.panSpeed = 0.2;

    controls.noZoom = false;
    controls.noPan = false;

    controls.staticMoving = true;
    controls.dynamicDampingFactor = 1.0;

    var radius = 5;
    controls.minDistance = radius * 1.1;
    controls.maxDistance = radius * 100;

    controls.keys = [ 65, 83, 68 ]; // [ rotateKey, zoomKey, panKey ]*/

And then in my render function I do:

function render() {
  controls.update();
  renderer.render(scene, camera);
}

Documentation on Three.js is pretty scarce, so I thought I'd ask here. Am I doing something wrong?

Upvotes: 42

Views: 31960

Answers (6)

Huy Tran
Huy Tran

Reputation: 1

I ran into the same problem and was able to make it work by using OrbitControls.target. Below is what I did after declaring a controller.

    controller = new THREE.OrbitControls(camera, renderer.domElement);
    controller.addEventListener('change', renderer.domElement);
    controller.target = new THREE.Vector3(0, 1, 0);

Upvotes: 0

Khoubeib Bouthour
Khoubeib Bouthour

Reputation: 388

In my opinion, we are not supposed to mess with the original code. I found a way around to achieve the objective of looking at any particular point. After having declared your "control" variable, simply execute these two lines of code:

// Assuming you know how to set the camera and myCanvas variables
control = new THREE.OrbitControls(camera, myCanvas);

// Later in your code
control.object.position.set(camX, camY, camZ);
control.target = new THREE.Vector3(targetX, targetY, targetZ);

Keep in my mind that this will switch the center of the focus to your new target. In other words, your new target will be the center of all rotations of the camera. Some parts will be difficult to look at as you became familiar to manipulate the camera assuming the default center. Try zoom in as much as you can and you will have a sense of what I am saying Hope this help.

Upvotes: 9

sebjwallace
sebjwallace

Reputation: 795

Here's an alternative solution: create an object (i.e. cube) with 0 dimensions.

var cameraTarget = new THREE.Mesh( new THREE.CubeGeometry(0,0,0));

In the render function set the camera.lookAt to the position of the cameraTarget.

function render() {
    camera.lookAt( cameraTarget.position );
    renderer.render( scene, camera );
}

Then just move cameraTarget around as you wish.

Upvotes: 1

Andrea Aloi
Andrea Aloi

Reputation: 991

I figured it out. To prevent THREE.TrackballControls or THREE.OrbitControls from overriding camera.lookAt upon initialization, you need to change the line that sets the control's target property to equal the sum of the camera.position vector and the camera.getWorldDirection() vector, instead of how it's currently implemented using a new THREE.Vector3() (which defaults to (0, 0, 0)).

So, for THREE.TrackballControls, change line 39 to:

this.target = new THREE.Vector3().addVectors(/*new line for readability*/
    object.position, object.getWorldDirection());

Same goes for THREE.OrbitControls, on line 36. I actaully haven't tested it on TrackballControls.js but it does work on OrbitControls.js. Hope this helps.

Upvotes: 2

Leon
Leon

Reputation: 6069

Yes Please beware... It seems that having THREE.TrackballControls or THREE.OrbitControls seems to override the camera.lookAt function as your are passing in your camera when you instantiate an instance of the controls. You might want to get rid of the controls and then performing camera.lookAt() or tween your camera some other way to verify that the controls are having a overriding effect on your Camera. I googled for a while why camera.lookat() seemed to have no effect.

Upvotes: 14

houbysoft
houbysoft

Reputation: 33392

Looking at the source code of THREE.TrackballControls, I figured out that I can make the camera look where I want by setting trackballControls.target to the THREE.Vector3 I want it to look at, and then rerendering the scene.

Upvotes: 57

Related Questions