// LordHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
{
- float d;
-
- right[0] = forward[2];
- right[1] = -forward[0];
- right[2] = forward[1];
- // BUG!
- // assume forward = {sqrt(1/3), sqrt(1/3), -sqrt(1/3)}
- // then right will be {-sqrt(1/3), -sqrt(1/3), sqrt(1/3)}
- // PROBLEM?
-
- d = DotProduct(forward, right);
- VectorMA(right, -d, forward, right);
- VectorNormalize(right);
- CrossProduct(right, forward, up);
- VectorNormalize(up); // CrossProduct in this case returns 'up thats length is not 1
+ // NOTE: this is consistent to AngleVectors applied to AnglesFromVectors
+ if (forward[0] == 0 && forward[1] == 0)
+ {
+ if(forward[2] > 0)
+ {
+ VectorSet(right, 0, -1, 0);
+ VectorSet(up, -1, 0, 0);
+ }
+ else
+ {
+ VectorSet(right, 0, -1, 0);
+ VectorSet(up, 1, 0, 0);
+ }
+ }
+ else
+ {
+ right[0] = forward[1];
+ right[1] = -forward[0];
+ right[2] = 0;
+ VectorNormalize(right);
+
+ up[0] = (-forward[2]*forward[0]);
+ up[1] = (-forward[2]*forward[1]);
+ up[2] = (forward[0]*forward[0] + forward[1]*forward[1]);
+ VectorNormalize(up);
+ }
}
void VectorVectorsDouble(const double *forward, double *right, double *up)
{
- double d;
-
- right[0] = forward[2];
- right[1] = -forward[0];
- right[2] = forward[1];
-
- d = DotProduct(forward, right);
- VectorMA(right, -d, forward, right);
- VectorNormalize(right);
- CrossProduct(right, forward, up);
+ if (forward[0] == 0 && forward[1] == 0)
+ {
+ if(forward[2] > 0)
+ {
+ VectorSet(right, 0, -1, 0);
+ VectorSet(up, -1, 0, 0);
+ }
+ else
+ {
+ VectorSet(right, 0, -1, 0);
+ VectorSet(up, 1, 0, 0);
+ }
+ }
+ else
+ {
+ right[0] = forward[1];
+ right[1] = -forward[0];
+ right[2] = 0;
+ VectorNormalize(right);
+
+ up[0] = (-forward[2]*forward[0]);
+ up[1] = (-forward[2]*forward[1]);
+ up[2] = (forward[0]*forward[0] + forward[1]*forward[1]);
+ VectorNormalize(up);
+ }
}
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
{
angles[YAW] = atan2(forward[1], forward[0]);
angles[PITCH] = -atan2(forward[2], sqrt(forward[0]*forward[0] + forward[1]*forward[1]));
+ // note: we know that angles[PITCH] is in ]-pi/2..pi/2[ due to atan2(anything, positive)
if (up)
{
vec_t cp = cos(angles[PITCH]), sp = sin(angles[PITCH]);
+ // note: we know cp > 0, due to the range angles[pitch] is in
vec_t cy = cos(angles[YAW]), sy = sin(angles[YAW]);
vec3_t tleft, tup;
tleft[0] = -sy;
tup[1] = sp*sy;
tup[2] = cp;
angles[ROLL] = -atan2(DotProduct(up, tleft), DotProduct(up, tup));
+ // for up == '0 0 1', this is
+ // angles[ROLL] = -atan2(0, cp);
+ // which is 0
}
else
angles[ROLL] = 0;
+
+ // so no up vector is equivalent to '1 0 0'!
}
// now convert radians to degrees, and make all values positive