in QuatSlerp you don't need to get the sinHalfTheta testing if cosHalfTheta>0.95 is enough to fallback to nlerp. Also you may want to add nlerp as an explicit option.
in QuaternionToMatrix you should divide xx, xy, xz, ... with the length squared. Or replace the 1.0f with the length squared so the calculation works with non-normalized quaternions.
I'm also not a fan of only having axis angle as a way to create quaternions. A way to create a quaternion based on the rotation from one vector to another will allow the user to avoid the acos -> cos roundtrip:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
{
Quaternion q = { 0 };
float cos2Theta = VectorDotProduct(from, to);
Vector3 cross = VectorCrossProduct(from, to);
q.x = cross.x;
q.y = cross.y;
q.z = cross.y;
q.w = 1 + cos2Theta;
QuaternionNormalize(&q);
//inlined nlerp(q, QuaternionIdentity(), 0.5f);
return q;
}
|