I have a quaternion that represents my camera direction. Using this, I can update the camera’s position and calculate the look-at coordinates and up vector. All this works great and I’ve got a nice demo of flying around in a 3D scene with control of heading, pitch and roll of the camera.
Now, I want to place an object directly in front of the camera and keep its position and orientation locked in sync with the camera’s. That is - it should just appear fixed in front of the camera.
Using the camera’s direction quaternion, I can correctly position the object, but I can’t figure out how to calculate the Euler angles that I need to pass to glRotate in order to orient the object.
I’ve tried numerous examples from euclidianspace.com, including the quaterion-to-euler conversion, but nothing is working. Depending on which direction I’m flying the object twists around in the wrong ways flips upside down or backwards. I really tried to do my homework before posting - I’ve read and tried dozens of different approaches, but I think I’m probably missing something fundamental.
Even if there is some other way to orient the object, I really would like to be able to determine the Euler angles from the camera direction for other uses in the program.
Here is the quaternion-to-euler code. I keep coming back to this because it seems like it should be what I’m looking for:
public static Number3d toEuler(Quaternion q)
{
float test = q.xq.y + q.zq.w;
// handle singularities
if (test > 0.4999f)
return new Number3d(
2f*(float)Math.atan2(q.x,q.w)r2d,
(float)Math.PI/2r2d,
0f);
if (test < -0.4999f)
return new Number3d(
-2f*(float)Math.atan2(q.x,q.w)r2d,
(float)-Math.PI/2r2d,
0f);
float sqw = q.wq.w;
float sqx = q.xq.x;
float sqy = q.yq.y;
float sqz = q.zq.z;
return new Number3d(
(float)Math.atan2(2q.yq.w-2q.xq.z , sqx - sqy - sqz + sqw)r2d,
(float)Math.asin(2test)r2d,
(float)Math.atan2(2q.xq.w-2q.y*q.z , -sqx + sqy - sqz + sqw)*r2d);
}