I have a camera defined through three vectors for view, right and up.
The camera itself appears to be working fine. However when I try to determine the roll of the camera, compared to the horizon, I am running into some issues.
(The reason I am doing trying to do this is to be able to draw a horizon reference line on the display.)
I think I have myself pretty confused at the moment, I have a feeling the answer is relatively simple, I just can't see it.
My camera vectors are: viewDir, rightVector and upVector; and since I am implementing in OpenGL they initially are set to:
viewDir = new Vector3( 0, 0, -1);
rightVector = new Vector3( 1, 0, 0);
upVector = new Vector3( 0, 1, 0);
I'm calculating heading and pitch with the following:
public double GetHeading()
{
return Math.Atan2(viewDir.X, -viewDir.Z);
}
public double GetPitch()
{
return Math.Asin(viewDir.Y);
}
Everything I have tried to calculate the roll relative to the horizon has failed in one way or another.
In my current approach (which is probably overcomplicated) I do the following:
public double GetRoll()
{
// initialize temporary vectors
Vector3 tmpView = new Vector3(0,0,-1);
Vector3 tmpRight = new Vector3(1,0,0);
Vector3 tmpUp = new Vector3(0,1,0);
// get Heading and Pitch
double H = GetHeading();
double P = GetPitch();
// rotate around up vector (heading)
tmpView = Vector3.Normalize(
(tmpView * Math.Cos(H)) - (tmpRight * Math.Sin(H));
tmpRight = Vector3.CrossProduct( tmpView, tmpUp);
// rotate around right vector (pitch)
tmpView = Vector3.Normalize(
(tmpView * Math.Cos(P)) + (tmpUp * Math.Sin(P));
tmpUp = -1 * Vector3.CrossProduct( tmpView, tmpRight)
// calculate cross/dot products
Vector3 cross = tmpUp.CrossProduct(upVector);
double dot = tmpUp.DotProduct(upVector);
double angle = Math.Atan2( cross.Magnitude, dot);
return angle;
}
The problems I have with the above include:
1) Angle is only 'correct' for clockwise rotation (I thought the cross product was supposed to provide me with a direction.)
2) The Pitch and Heading are effecting the Roll angle. For instance when turning 90 degrees right or left from the initial heading, for every 1 degree of pitch up or down, the roll angle is being increased by two degrees.
I am sure I have a fundamental problem with my approach, but after 3 days of banging my head against this, and searching google and these forums, i'm no closer to figuring out my mistake. Seems like the only answers I can find are limited to 2D, not 3D.
Thanks for any suggestions.