I have a little game where a ball can roll around a square level. I want the camera position to follow the ball, but always look at 0, 0, 0
. Moving the camera x
and z
to the ball position gets me close, however, as you can see in the below animation (sorry for any motion sickness):
When using camera.lookAt( new THREE.Vector3( 0, 0, 0 ) )
, the camera rolls around its y
axis (I think?) causing the illusion that the level is rotating.
What I want to achieve is moving the camera and looking at 0,0,0
without the camera roll. As in, when the camera moves, the bottom edge of the level should stay relatively parallel with the bottom edge of the screen. Is this possible / does it make sense? I'm having trouble visualizing it.
I created a CodePen demo that illustrates the problem. I've extracted the lookAt function into a standalone function so that I can modify the quaternion once its returned:
function lookAtVector( sourcePoint, destPoint ) {
And I basically rotate and position the camera by hand:
var cameraPosition = new THREE.Vector3(
radius * Math.sin( Date.now() * speed ),
radius * Math.cos( Date.now() * speed ),
5
);
var lookAtQuaternion = lookAtVector(
cameraPosition,
new THREE.Vector3( 0, 0 ,0 )
);
camera.position.copy( cameraPosition );
camera.quaternion.copy( lookAtQuaternion );
How can I modify the camera quaternion to not roll this way, while still looking at 0,0,0?. I've tried:
I've tried setting the
x
,y
,z
, andw
fields of the quaternion to0
,Math.PI / 2
etc to try to force no rotation, but the results are unexpected and I haven't found a combination of manual field setting that works.I've tried manually setting the camera up vector (
camera.up = new THREE.Vector3(0,0,1);
) as in this question but the results are the same.
Edit: Basically I want to remove the camera roll like any traditional 3d software camera, and like Three's OrbitControls. The perspective from bottom left and bottom right edges should look like:
Notice how the camera isn't rolled in these pictures.
0, 0, 0
" – Amit