Hello there!
The problem
I'm working on a retro space action game in Unity3D. I say retro because we do not use 3D models to visualize other ships in space but sprites, rendered from a total of 544 angles. I need to find the right sprite (ie. the right angle) for each ship in space, relative to my own camera orientation. Both the camera and other ships have six degrees of freedom.
While I made some progress using Matrix math and some help I've gotten in the past here on the forums a while back, we have since switched to Unity3D, which works with quaternions. I'm well aware of the fact that I can simply stick to my old attempts and convert unit quaternions to rotation matrices and back, but I would optimally like to hear if there may be a smart solution that works with quaternions throughout.
My attempt so far
Vector3 getEulerAnglesFromQuaternion(Quaternion q1)
{
float sqw = q1.w*q1.w;
float sqx = q1.x*q1.x;
float sqy = q1.y*q1.y;
float sqz = q1.z*q1.z;
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
float test = q1.x*q1.y + q1.z*q1.w;
float pitch, yaw, roll;
if (test > 0.499*unit)
// singularity at north pole
{
yaw = 2 * Mathf.Atan2(q1.x,q1.w);
roll = Mathf.PI/2;
pitch = 0;
}
else if (test < -0.499*unit)
// singularity at south pole
{
yaw = -2 * Mathf.Atan2(q1.x,q1.w);
roll = -Mathf.PI/2;
pitch = 0;
}
else
{
yaw = Mathf.Atan2(2*q1.y*q1.w-2*q1.x*q1.z , sqx - sqy - sqz + sqw);
roll = Mathf.Asin(2*test/unit);
pitch = Mathf.Atan2(2*q1.x*q1.w-2*q1.y*q1.z , -sqx + sqy - sqz + sqw);
}
return new Vector3(pitch, yaw, roll);
}
// in Ship::Update():
Quaternion q1 = Quaternion.LookRotation(Camera.main.transform.position - transform.position);
Quaternion q2 = transform.rotation;
Quaternion q = q1 * q2;
Vector3 eulerAngles = getEulerAnglesFromQuaternion(q) * Mathf.Rad2Deg;
// use eulerAngles to pick the right sprite
My idea was to combine the ship with the camera rotation by multiplication and then use a standard formula to retrieve euler angles from the resulting quaternion. This, however, simply does not yield the expected angle values. I'm not sure if my problem can even be solved in this fashion.
In short
I would like to know if anybody has an idea how to solve my problem of finding the angle at which a camera is looking at something, combining that with the orientation of the entity itself and using the result to find the right sprite to pick for it. I have access to what seems to be very good and complete math functionality in Unity3D and would like, if possible, to find a solution following the engine's quaternion-based approach. Are quaternions even usable in this case? Or am I forced to use matrix math here?