Question

I am trying to rotate the camera around to X-axis of the scene.
At this point my code is like this:

rotation += 0.05;
camera.position.y = Math.sin(rotation) * 500;
camera.position.z = Math.cos(rotation) * 500;

This makes the camera move around but during the rotation something weird happens and either the camera flips, or it skips some part of the imaginary circle it's following.

No correct solution

OTHER TIPS

You have only provided a snippet of code, so I have to make some assumptions about what you are doing.

This code:

rotation += 0.05;
camera.position.x = 0;
camera.position.y = Math.sin(rotation) * 500;
camera.position.z = Math.cos(rotation) * 500;
camera.lookAt( scene.position ); // the origin

will cause the "flipping" you refer to because the camera is trying to remain "right side up", and it will quickly change orientation as it passes over the "north pole."

If you offset the camera's x-coordinate like so,

camera.position.x = 200;

the camera behavior will appear more natural to you.

Three.js tries to keep the camera facing up. When you pass 0 along the z-axis, it'll "fix" the camera's rotation. You can just check and reset the camera's angle manually.

camera.lookAt( scene.position ); // the origin
if (camera.position.z < 0) {
    camera.rotation.z = 0;
}

I'm sure this is not the best solution, but if anyone else runs across this question while playing with three.js (like I just did), it'll give one step further.

This works for me, I hope it helps.

Rotating around X-Axis:

var x_axis = new THREE.Vector3( 1, 0, 0 );
var quaternion = new THREE.Quaternion;
camera.position.applyQuaternion(quaternion.setFromAxisAngle(x_axis, rotation_speed));
camera.up.applyQuaternion(quaternion.setFromAxisAngle(x_axis, rotation_speed));

Rotating around Y-Axis:

var y_axis = new THREE.Vector3( 0, 1, 0 );
camera.position.applyQuaternion(quaternion.setFromAxisAngle(y_axis, angle));

Rotating around Z-Axis:

var z_axis = new THREE.Vector3( 0, 0, 1 );
camera.up.applyQuaternion(quaternion.setFromAxisAngle(z_axis, angle));

I wanted to move my camera to a new location while having the camera look at a particular object, and this is what I came up with [make sure to load tween.js]:

/**
* Helper to move camera
* @param loc Vec3 - where to move the camera; has x, y, z attrs
* @param lookAt Vec3 - where the camera should look; has x, y, z attrs
* @param duration int - duration of transition in ms
**/

function flyTo(loc, lookAt, duration) {
  // Use initial camera quaternion as the slerp starting point
  var startQuaternion = camera.quaternion.clone();
  // Use dummy camera focused on target as the slerp ending point
  var dummyCamera = camera.clone();
  dummyCamera.position.set(loc.x, loc.y, loc.z);
  // set the dummy camera quaternion
  var rotObjectMatrix = new THREE.Matrix4();
  rotObjectMatrix.makeRotationFromQuaternion(startQuaternion);
  dummyCamera.quaternion.setFromRotationMatrix(rotObjectMatrix);
  dummyCamera.up.set(camera)
  console.log(camera.quaternion, dummyCamera.quaternion);
  // create dummy controls to avoid mutating main controls
  var dummyControls = new THREE.TrackballControls(dummyCamera);
  dummyControls.target.set(loc.x, loc.y, loc.z);
  dummyControls.update();
  // Animate between the start and end quaternions
  new TWEEN.Tween(camera.position)
    .to(loc, duration)
    .onUpdate(function(timestamp) {
      // Slerp the camera quaternion for smooth transition.
      // `timestamp` is the eased time value from the tween.
      THREE.Quaternion.slerp(startQuaternion, dummyCamera.quaternion, camera.quaternion, timestamp);
      camera.lookAt(lookAt);
    })
    .onComplete(function() {
      controls.target = new THREE.Vector3(scene.children[1].position-0.001);
      camera.lookAt(lookAt);
    }).start();
}

Example usage:

var pos = {
  x: -4.3,
  y: 1.7,
  z: 7.3,
};
var lookAt = scene.children[1].position;
flyTo(pos, lookAt, 60000);

Then in your update()/render() function, call TWEEN.update();

Full example

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top