user1533481
user1533481

Reputation: 586

Three.js How to use quaternion to rotate camera

In Three.js, I would like to use THREE.quaternion to make the camera object rotate to the selected object.

I did search the web but found no example/demo or document about how to use this quaternion class.

I try my luck with following code:

    camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.y = 10;
    camera.position.z = 0;
    camera.position.x = radious;
    camera.useQuaternion = true;

   // I did use the TrackballTrackballControls. Maybe it causes the problem so I put it here
    controls = new THREE.TrackballControls( camera, document.getElementById(_canvasElement) );

    // function to make the camera rotate to the object
    function focusOn3DObject(obj){  
        obj.useQuaternion = true;
        obj.quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

        var newQuaternion = new THREE.Quaternion();
        THREE.Quaternion.slerp(camera.quaternion, obj.quaternion, newQuaternion, 0.07);
        camera.quaternion = newQuaternion;
    }

But it doesn't work. Did I miss something? Please help. Thanks in advance.

Upvotes: 14

Views: 32851

Answers (5)

Naej
Naej

Reputation: 15

This is how I've done it :

  1. Get the current quaternion of your camera (initialQuaternion)
  2. Create a clone of your camera
  3. Make the clone look at the target using the lookAt method
  4. The thing is, the lookAt method of the camera will actually make it look AWAY from the target, so you have two options :
  • Either use the lookAt method directly, then invert the rotation
  • Or compute the position the target should have so that when looking away from it, you actually look in the correct direction
  1. Get the new quaternion of the clone (targetQuaternion)
  2. By using an animation loop, do a slerp between the initialQuaternion and the targetQuaternion

Upvotes: 1

SAK
SAK

Reputation: 85

I have tried using it:

    var newQuaternion = new THREE.Quaternion();
        THREE.Quaternion.slerp(camera.quaternion, obj.quaternion, newQuaternion, 0.01);
        camera.quaternion = newQuaternion;
        camera.quaternion.normalize();
        camera.matrixAutoUpdate();

However, I have failed to get the desired outcome. I know it is a fairly old post but I would be happy if someone could respond. I didn't see any other relevant posts other than this so really hoping for someone to respond.

Here is my problem in detail: Rotate camera to look at Selected object in three.js

Upvotes: 0

sampopes
sampopes

Reputation: 2696

You can use the method applyQuaternion from ThreeJs

 const quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

 camera.applyQuaternion(quaternion); // Apply Quaternion

 camera.quaternion.normalize();  // Normalize Quaternion

Upvotes: 3

Sebastian Sachtleben
Sebastian Sachtleben

Reputation: 518

I think this line wont work:

obj.quaternion = new THREE.Quaternion(obj.position.x, obj.position.y, obj.position.z, 1);

You need to set

obj.useQuaternion = true

After adding object to scene, when you rotate it will be automatically applied to obj.quaternion.

The second point is you should apply the object to your controls and not the camera. Because you want to control the object and not the camera?

Upvotes: 2

Sebastian Sachtleben
Sebastian Sachtleben

Reputation: 518

Slerp is quite easy. It takes 4 parameters:

  • targetRotation the actual camera rotation
  • destinationRotation the object rotation
  • destinationRotation new quaternion which will be the new camera rotation
  • percentOfRotation this parameter is playground, I'm using 0.07 here right now, could be value between 0 (0%) and 1 (100%)

This is my rotation method:

var qm = new THREE.Quaternion();
THREE.Quaternion.slerp(camera.quaternion, destRotation, qm, 0.07);
camera.quaternion = qm;
camera.quaternion.normalize();

Hopefully this will help you. And don't bother I also worked some weeks on the perfect camera following.

Upvotes: 18

Related Questions