[SOLVED] .lookAt() flips cam rotation 180 degrees... how do i remove this?

1st off i’ve asked so far 2 other times in the last week (srry bout that) but im really happy with the community :smiley: hopefully i’ll get to help somebody soon :stuck_out_tongue:

ANYWAYS…
Im trying to re-create OrbitControls only with some slight changes… Plus for the coding experience!

I somehow manage to get the X-Z rotation working
but i cannot seem to Y rotation working…
as i get 50% of the way rotated when the camera flips 180 degrees as shown in the gif below…

i couldnt upload gif here so i uploaded it elsewhere

I made a jsfiddle as close as possible.
the problem is there in the jsfiddle but just without the colors to color code the sides
https://jsfiddle.net/FrustratedProgrammer/7fkbpfej/
I am still new to jsfiddle so i didnt know how to get the latest version of threejs and color code each side for easier viewing…

I “believe” my problem is in the .lookAt as it controls the camera’s rotation

I hear yeah, I ended up using a modified version of rodrigues rotation formula.

// camera.tilt is a preset value determined for best intended effect, ignore for the question.
// camera.tilt_value is a preset value determined for best result, ignore for the question.
if(  keyboard.pressed('d')){

	// Move right
    camera.camPosi = rotatePoint( angleToRadians( camera.rotationSpeed ), 1, camera.camPosi, camera.upAxis, true );
    camera.position.set(camera.camPosi.x * camera.Zoom, camera.camPosi.y * camera.Zoom , camera.camPosi.z * camera.Zoom);
    camera.up = camera.upAxis.clone();
    if ( camera.Zoom <=camera._tilt ) {
      camera.lookAtVector = newLookAt( camera.upAxis , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    } else {
      camera.lookAtVector = newLookAt( camera._base , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    }

}
if( keyboard.pressed('s') ){

  	// Move down
    camera.crossVector = rotatePoint( angleToRadians( 90 ), 1, camera.camPosi, camera.upAxis, true );
    camera.upAxis = rotatePoint( angleToRadians( camera.rotationSpeed ), 1, camera.upAxis, camera.crossVector, true );
    camera.camPosi = rotatePoint( angleToRadians( camera.rotationSpeed ), 1, camera.camPosi, camera.crossVector, true );
    camera.position.set(camera.camPosi.x * camera.Zoom, camera.camPosi.y * camera.Zoom , camera.camPosi.z * camera.Zoom);
    camera.up = camera.upAxis.clone();
    if ( camera.Zoom <=camera._tilt ) {
      camera.lookAtVector = newLookAt( camera.upAxis , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    } else {
      camera.lookAtVector = newLookAt( camera._base , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    }

}
if( keyboard.pressed('e')){

  	// Rotate left
    camera.upAxis = rotatePoint( angleToRadians( 5 * camera.rotationSpeed), 1, camera.upAxis, camera.camPosi, true);
    camera.position.set(camera.camPosi.x * camera.Zoom, camera.camPosi.y * camera.Zoom , camera.camPosi.z * camera.Zoom);
    camera.up = camera.upAxis.clone();

    if ( camera.Zoom <=camera._tilt ) {
      camera.lookAtVector = newLookAt( camera.upAxis , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    } else {
      camera.lookAtVector = newLookAt( camera._base , camera.Zoom , camera._tilt , camera._tilt_value );
      camera.lookAt( camera.lookAtVector.clone() );
    }

}

function rotatePoint( angle , inverseSpeed , v1 , v2 , toNormalize ){
	var c = Math.cos(angle);
	var s = Math.sin(angle);
	// inverseSpeed directly affects the speed of the camera.  so a higher inverseSpeed = slower speed.
	var v3 = new THREE.Vector3(
		inverseSpeed * ( c * v1.x ) + ( s * ( ( v2.y * v1.z ) - ( v2.z * v1.y ) ) ) ,
		inverseSpeed * ( c * v1.y ) + ( s * ( ( v2.z * v1.x ) - ( v2.x * v1.z ) ) ),
		inverseSpeed * ( c * v1.z ) + ( s * ( ( v2.x * v1.y ) - ( v2.y * v1.x ) ) )
	);
	if ( toNormalize ){ v3.normalize(); }
	return v3;
}; // used to rotate position of camera.

function newLookAt( axisVector , zoom , tilt , tiltIncrement ) {
	var a = new THREE.Vector3( axisVector.x * ( ( tilt - zoom ) * tilt * 0.5 ) , axisVector.y * ( ( tilt - zoom ) * tilt * 0.5 ) , axisVector.z * ( ( tilt - zoom ) * tiltIncrement * 0.5 ) );
	return a;
}; // used to update camera lookat position. 

As the camera gets closer to the world the true lookAt vector is no longer the center of the planet, but rather a point that gradually gets further from the center the closer to the planet the camera gets. That way the camera tilts upwards when zooming in closer to give a better field of view for the user.

This is the code I’m currently using for my camera. If it’s what you need copy and modify the 3 directions for their sister directions.

Rotating up and down needs to be restricted to 180°. You should also consider to work with THREE.Spherical. It’s used by THREE.OrbitControls.

sorry for really late reply i got sick…
I apologize for my lack of understanding… by restricting it to 180 degrees seems more like a first person type view… i would rather not have this…
also i looked it up and checked the docs… i cannot seem to get a grasp on how to use Three.Spherical

is there by any chance a example in the threejs examples that shows how todo either? i tried looking for it and cannot find one.

What exactly do you mean? An example that illustrates the usage of THREE.Spherical?

If possible.

No because THREE.Spherical is just class in order to work with spherical coordinates. If you understand the underlying concept, you are also able to work with THREE.Spherical. I suggest you start with the respective wikipedia article. The book 3D Math Primer for Graphics and Game Development also contains well-written chapter about this topic.

1 Like

Thank you…
No i do not understand Spherical coordinate system… :thinking:
The project i am working on is the first project I’ve ever worked on in 3D
thanks for the references. I’ll be sure to look more into it.

Anyways thank for your time :smiley:

You’re welcome! :blush: