void QUATERNION::AddRotation(VERTEX *vAxis, float fAngle)
{
QUATERNION qTemp;
float fS;
// Convert Axis/Angle to Quaternion
fS = (float)sin((double)(fAngle / 2.0f));
qTemp.w = (float)cos((double)(fAngle / 2.0f));
qTemp.x = fS * vAxis->x;
qTemp.y = fS * vAxis->y;
qTemp.z = fS * vAxis->z;
// Multiply two Quats.
Multiply(&qTemp);
} // End of QUATERNION::AddRotation()
void QUATERNION::Multiply(QUATERNION *qOther)
{
VERTEX v1;
VERTEX v2;
VERTEX vCross;
float fW;
float fX;
float fY;
float fZ;
v1.x = x;
v1.y = y;
v1.z = z;
v2.x = qOther->x;
v2.y = qOther->y;
v2.z = qOther->z;
vCross = v1.CrossProduct(&v2);
fW = (w * qOther->w) - v1.DotProduct(&v2);
fX = (w * qOther->x) + (qOther->w * x) + vCross.x;
fY = (w * qOther->y) + (qOther->w * y) + vCross.y;
fZ = (w * qOther->z) + (qOther->w * z) + vCross.z;
w = fW;
x = fX;
y = fY;
z = fZ;
} // End of QUATERNION::GetRotation()
/***
* Use this to get the values for use in glRotatef() when drawing your primitive.
***/
void QUATERNION::GetRotation(VERTEX *vAxis, float *fAngle)
{
float fS;
Normalise();
fS = (x * x) + (y * y) + (z * z);
if (fS < FLOAT_TOLERANCE)
{
vAxis->x = vAxis->z = 0.0f;
vAxis->y = 1.0f;
*fAngle = 0.0f;
}
else
{
vAxis->x = x / fS;
vAxis->y = y / fS;
vAxis->z = z / fS;
*fAngle = 2.0f * (float)acos(w);
}
} // End of QUATERNION::GetRotation()