From 6392dac8450695340fe6c7b3614aa7d07b2cd7c4 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 9 May 2025 13:24:42 -0500 Subject: [PATCH 1/4] Comment dangers of MakeNormalVectors() --- src/engine/qcommon/q_math.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/engine/qcommon/q_math.cpp b/src/engine/qcommon/q_math.cpp index 19114fe9fc..a45a78f469 100644 --- a/src/engine/qcommon/q_math.cpp +++ b/src/engine/qcommon/q_math.cpp @@ -530,14 +530,17 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t point, const vec3_t normal ) * * Given a normalized forward vector, create two * other perpendicular vectors + * This function seems to aim to be continuous (unlike the similar vectoangles + * or PerpendicularVector), but that is impossible to fully realize per the + * Hairy Ball Theorem. At least it can work for stuff that doesn't use the + * roll angle. * ================ */ void MakeNormalVectors( const vec3_t forward, vec3_t right, vec3_t up ) { float d; - // this rotate and negate guarantees a vector - // not colinear with the original + // this fails at {-1/sqrt(3), -1/sqrt(3), 1/sqrt(3)} right[ 1 ] = -forward[ 0 ]; right[ 2 ] = forward[ 1 ]; right[ 0 ] = forward[ 2 ]; From 662f10ec580f5e1652c49783d3d2ab34270a684c Mon Sep 17 00:00:00 2001 From: slipher Date: Tue, 20 May 2025 01:41:04 -0500 Subject: [PATCH 2/4] Remove 'static to help MS compiler fp bugs' --- src/engine/qcommon/q_math.cpp | 49 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/engine/qcommon/q_math.cpp b/src/engine/qcommon/q_math.cpp index a45a78f469..96ee91276d 100644 --- a/src/engine/qcommon/q_math.cpp +++ b/src/engine/qcommon/q_math.cpp @@ -1009,22 +1009,17 @@ void AxisMultiply( const float in1[ 3 ][ 3 ], const float in2[ 3 ][ 3 ], float o void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up ) { - float angle; - static float sr, sp, sy, cr, cp, cy; - - // static to help MS compiler fp bugs - - angle = DEG2RAD( angles[ YAW ] ); - sy = sinf( angle ); - cy = cosf( angle ); + float angle = DEG2RAD( angles[ YAW ] ); + float sy = sinf( angle ); + float cy = cosf( angle ); angle = DEG2RAD( angles[ PITCH ] ); - sp = sinf( angle ); - cp = cosf( angle ); + float sp = sinf( angle ); + float cp = cosf( angle ); angle = DEG2RAD( angles[ ROLL ] ); - sr = sinf( angle ); - cr = cosf( angle ); + float sr = sinf( angle ); + float cr = cosf( angle ); if ( forward ) { @@ -1900,17 +1895,14 @@ void MatrixToAngles( const matrix_t m, vec3_t angles ) // Tait-Bryan angles z-y-x void MatrixFromAngles( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll ) { - static float sr, sp, sy, cr, cp, cy; + float sp = sinf( DEG2RAD( pitch ) ); + float cp = cosf( DEG2RAD( pitch ) ); - // static to help MS compiler fp bugs - sp = sinf( DEG2RAD( pitch ) ); - cp = cosf( DEG2RAD( pitch ) ); + float sy = sinf( DEG2RAD( yaw ) ); + float cy = cosf( DEG2RAD( yaw ) ); - sy = sinf( DEG2RAD( yaw ) ); - cy = cosf( DEG2RAD( yaw ) ); - - sr = sinf( DEG2RAD( roll ) ); - cr = cosf( DEG2RAD( roll ) ); + float sr = sinf( DEG2RAD( roll ) ); + float cr = cosf( DEG2RAD( roll ) ); m[ 0 ] = cp * cy; m[ 4 ] = ( sr * sp * cy + cr * -sy ); @@ -2839,17 +2831,14 @@ void QuatFromAngles( quat_t q, vec_t pitch, vec_t yaw, vec_t roll ) MatrixFromAngles( tmp, pitch, yaw, roll ); QuatFromMatrix( q, tmp ); #else - static float sr, sp, sy, cr, cp, cy; - - // static to help MS compiler fp bugs - sp = sinf(DEG2RAD(pitch) * 0.5); - cp = cosf(DEG2RAD(pitch) * 0.5); + float sp = sinf(DEG2RAD(pitch) * 0.5); + float cp = cosf(DEG2RAD(pitch) * 0.5); - sy = sinf(DEG2RAD(yaw) * 0.5); - cy = cosf(DEG2RAD(yaw) * 0.5); + float sy = sinf(DEG2RAD(yaw) * 0.5); + float cy = cosf(DEG2RAD(yaw) * 0.5); - sr = sinf(DEG2RAD(roll) * 0.5); - cr = cosf(DEG2RAD(roll) * 0.5); + float sr = sinf(DEG2RAD(roll) * 0.5); + float cr = cosf(DEG2RAD(roll) * 0.5); q[0] = sr * cp * cy - cr * sp * sy; // x q[1] = cr * sp * cy + sr * cp * sy; // y From 814d6e36d78c700d302804c73d900c0fdd6f713e Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 6 Jun 2025 03:12:00 -0500 Subject: [PATCH 3/4] NUKE MatrixToAngles function Caused issues #1527 and #1663, and using it was a sign of stupidly architected code anyway. --- src/engine/qcommon/q_math.cpp | 62 ----------------------------------- src/engine/qcommon/q_shared.h | 1 - 2 files changed, 63 deletions(-) diff --git a/src/engine/qcommon/q_math.cpp b/src/engine/qcommon/q_math.cpp index 96ee91276d..64a2a0b6c0 100644 --- a/src/engine/qcommon/q_math.cpp +++ b/src/engine/qcommon/q_math.cpp @@ -1830,68 +1830,6 @@ void MatrixMultiplyShear( matrix_t m, vec_t x, vec_t y ) m[ 7 ] += tmp[ 3 ] * x; } -void MatrixToAngles( const matrix_t m, vec3_t angles ) -{ -#if 1 - float theta; - float cp; - float sp; - - sp = m[ 2 ]; - - // cap off our sin value so that we don't get any NANs - if ( sp > 1.0f ) - { - sp = 1.0f; - } - - else if ( sp < -1.0f ) - { - sp = -1.0f; - } - - theta = -asinf( sp ); - cp = cosf( theta ); - - if ( cp > 8192 * FLT_EPSILON ) - { - angles[ PITCH ] = RAD2DEG( theta ); - angles[ YAW ] = RAD2DEG( atan2f( m[ 1 ], m[ 0 ] ) ); - angles[ ROLL ] = RAD2DEG( atan2f( m[ 6 ], m[ 10 ] ) ); - } - - else - { - angles[ PITCH ] = RAD2DEG( theta ); - angles[ YAW ] = RAD2DEG( -atan2f( m[ 4 ], m[ 5 ] ) ); - angles[ ROLL ] = 0; - } - -#else - float a; - float ca; - - a = asinf( -m[ 2 ] ); - ca = cosf( a ); - - if ( fabsf( ca ) > 0.005f ) // Gimbal lock? - { - angles[ PITCH ] = RAD2DEG( atan2f( m[ 6 ] / ca, m[ 10 ] / ca ) ); - angles[ YAW ] = RAD2DEG( a ); - angles[ ROLL ] = RAD2DEG( atan2f( m[ 1 ] / ca, m[ 0 ] / ca ) ); - } - - else - { - // Gimbal lock has occurred - angles[ PITCH ] = RAD2DEG( atan2f( -m[ 9 ], m[ 5 ] ) ); - angles[ YAW ] = RAD2DEG( a ); - angles[ ROLL ] = 0; - } - -#endif -} - // Tait-Bryan angles z-y-x void MatrixFromAngles( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll ) { diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index 7f78512324..98671517b7 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -838,7 +838,6 @@ inline vec_t VectorNormalize2( const vec3_t v, vec3_t out ) void MatrixMultiplyTranslation( matrix_t m, vec_t x, vec_t y, vec_t z ); void MatrixMultiplyScale( matrix_t m, vec_t x, vec_t y, vec_t z ); void MatrixMultiplyShear( matrix_t m, vec_t x, vec_t y ); - void MatrixToAngles( const matrix_t m, vec3_t angles ); void MatrixFromAngles( matrix_t m, vec_t pitch, vec_t yaw, vec_t roll ); void MatrixFromVectorsFLU( matrix_t m, const vec3_t forward, const vec3_t left, const vec3_t up ); void MatrixFromVectorsFRU( matrix_t m, const vec3_t forward, const vec3_t right, const vec3_t up ); From b24fb54f6711c5780d7f8f8f0b0fe6aa84f38328 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 6 Jun 2025 03:28:26 -0500 Subject: [PATCH 4/4] Remove some unused calculations in renderer --- src/engine/renderer/tr_backend.cpp | 3 --- src/engine/renderer/tr_model_md5.cpp | 2 -- 2 files changed, 5 deletions(-) diff --git a/src/engine/renderer/tr_backend.cpp b/src/engine/renderer/tr_backend.cpp index b56f29f416..6b3b4014fe 100644 --- a/src/engine/renderer/tr_backend.cpp +++ b/src/engine/renderer/tr_backend.cpp @@ -1950,15 +1950,12 @@ static void RB_RenderDebugUtils() } VectorCopy( skel->bones[ j ].t.trans, offset ); - vec3_t forward, right, up; - QuatToVectorsFRU( skel->bones[ j ].t.rot, forward, right, up ); VectorSubtract( offset, origin, diff ); if ( ( length = VectorNormalize( diff ) ) ) { PerpendicularVector( tmp, diff ); - //VectorCopy(up, tmp); VectorScale( tmp, length * 0.1, tmp2 ); VectorMA( tmp2, length * 0.2, diff, tmp2 ); diff --git a/src/engine/renderer/tr_model_md5.cpp b/src/engine/renderer/tr_model_md5.cpp index 3f351f50dd..317e28a254 100644 --- a/src/engine/renderer/tr_model_md5.cpp +++ b/src/engine/renderer/tr_model_md5.cpp @@ -100,7 +100,6 @@ bool R_LoadMD5( model_t *mod, const char *buffer, const char *modName ) const char *token; vec3_t boneOrigin; quat_t boneQuat; - matrix_t boneMat; int numBoneReferences; @@ -238,7 +237,6 @@ bool R_LoadMD5( model_t *mod, const char *buffer, const char *modName ) } QuatCalcW( boneQuat ); - MatrixFromQuat( boneMat, boneQuat ); VectorCopy( boneOrigin, bone->origin ); QuatCopy( boneQuat, bone->rotation );