From a181d753fe91f86da79cf465b3137738d2cff8b4 Mon Sep 17 00:00:00 2001 From: divverent Date: Fri, 9 Mar 2012 19:08:04 +0000 Subject: [PATCH] try to really fix vectorvectors to be 100% equivalent to makevectors(flippitch(vectoangles(v))) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11751 d7cf8633-e32d-0410-b094-e92efae38249 --- mathlib.c | 83 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/mathlib.c b/mathlib.c index ed0a43c6..b4a1b6a0 100644 --- a/mathlib.c +++ b/mathlib.c @@ -198,35 +198,61 @@ void PerpendicularVector( vec3_t dst, const vec3_t src ) // 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 ) @@ -544,9 +570,11 @@ void AnglesFromVectors (vec3_t angles, const vec3_t forward, const vec3_t up, qb { 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; @@ -556,9 +584,14 @@ void AnglesFromVectors (vec3_t angles, const vec3_t forward, const vec3_t up, qb 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 -- 2.39.2