summaryrefslogtreecommitdiff
path: root/src/cgame/cg_view.c
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2001-08-22 03:15:18 +0000
committerTim Angus <tim@ngus.net>2001-08-22 03:15:18 +0000
commita384244670287eff2a448d3e3a4ba5673dfdd66c (patch)
tree455a0cb56ceac38271e116f477fa58981c155393 /src/cgame/cg_view.c
parentafe568e607fd020563fc4e2acba45f9521cf1869 (diff)
Fixed gimbal problems with view smoothing
Diffstat (limited to 'src/cgame/cg_view.c')
-rw-r--r--src/cgame/cg_view.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c
index e940698f..2c25e75b 100644
--- a/src/cgame/cg_view.c
+++ b/src/cgame/cg_view.c
@@ -758,7 +758,7 @@ static void CG_DrawSurfNormal( void )
CG_addSmoothOp
===============
*/
-static void CG_addSmoothOp( vec3_t deltaAngles )
+static void CG_addSmoothOp( vec3_t rotAxis, float rotAngle )
{
int i;
@@ -769,7 +769,8 @@ static void CG_addSmoothOp( vec3_t deltaAngles )
if( cg.sList[ i ].time + cg_smoothTime.integer < cg.time )
{
//copy to array and stop
- VectorCopy( deltaAngles, cg.sList[ i ].deltaAngles );
+ VectorCopy( rotAxis, cg.sList[ i ].rotAxis );
+ cg.sList[ i ].rotAngle = rotAngle;
cg.sList[ i ].time = cg.time;
return;
}
@@ -785,11 +786,13 @@ CG_smoothWWTransitions
*/
static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t out )
{
- vec3_t deltaAngles, surfNormal, inLocal;
+ vec3_t surfNormal, rotAxis, temp;
+ vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
vec3_t ceilingNormal = { 0.0f, 0.0f, -1.0f };
int i;
- float stLocal, sFraction;
+ float stLocal, sFraction, rotAngle;
qboolean performed = qfalse;
+ vec3_t inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ];
//set surfNormal
if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) )
@@ -797,25 +800,40 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o
else
VectorCopy( ceilingNormal, surfNormal );
- VectorCopy( in, inLocal );
-
+ AnglesToAxis( in, inAxis );
+
//if we are moving from one surface to another smooth the transition
if( !VectorCompare( surfNormal, cg.lastNormal ) )
{
- VectorSubtract( in, cg.lastVangles, deltaAngles );
-
- //normalise
- for( i = 0; i < 3; i++ )
+ //if we moving from the ceiling to the floor special case
+ //( x product of colinear vectors is undefined)
+ if( VectorCompare( ceilingNormal, cg.lastNormal ) &&
+ VectorCompare( refNormal, surfNormal ) )
{
- while( deltaAngles[ i ] < -180.0f )
- deltaAngles[ i ] += 360.0f;
-
- while( deltaAngles[ i ] > 180.0f )
- deltaAngles[ i ] -= 360.0f;
+ AngleVectors( in, NULL, rotAxis, NULL );
+ rotAngle = 180.0f;
}
+ else
+ {
+ AnglesToAxis( cg.lastVangles, lastAxis );
+ rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) +
+ DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) +
+ DotProduct( inAxis[ 2 ], lastAxis[ 2 ] );
+
+ rotAngle = RAD2DEG( acos( ( rotAngle - 1.0f ) / 2.0f ) );
+
+ CrossProduct( lastAxis[ 0 ], inAxis[ 0 ], temp );
+ VectorCopy( temp, rotAxis );
+ CrossProduct( lastAxis[ 1 ], inAxis[ 1 ], temp );
+ VectorAdd( rotAxis, temp, rotAxis );
+ CrossProduct( lastAxis[ 2 ], inAxis[ 2 ], temp );
+ VectorAdd( rotAxis, temp, rotAxis );
+ VectorNormalize( rotAxis );
+ }
+
//add the op
- CG_addSmoothOp( deltaAngles );
+ CG_addSmoothOp( rotAxis, rotAngle );
}
//iterate through ops
@@ -827,16 +845,20 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o
stLocal = 1.0 - ( ( ( cg.sList[ i ].time + cg_smoothTime.integer ) - cg.time ) / cg_smoothTime.integer );
sFraction = -( cos( stLocal * M_PI ) + 1 ) / 2;
- VectorMA( inLocal, sFraction, cg.sList[ i ].deltaAngles, out );
+ RotatePointAroundVector( outAxis[ 0 ], cg.sList[ i ].rotAxis, inAxis[ 0 ], sFraction * cg.sList[ i ].rotAngle );
+ RotatePointAroundVector( outAxis[ 1 ], cg.sList[ i ].rotAxis, inAxis[ 1 ], sFraction * cg.sList[ i ].rotAngle );
+ RotatePointAroundVector( outAxis[ 2 ], cg.sList[ i ].rotAxis, inAxis[ 2 ], sFraction * cg.sList[ i ].rotAngle );
- VectorCopy( out, inLocal );
+ AxisCopy( outAxis, inAxis );
performed = qtrue;
}
}
//if we performed any ops then return the smoothed angles
//otherwise simply return the in angles
- if( !performed )
+ if( performed )
+ AxisToAngles( outAxis, out );
+ else
VectorCopy( in, out );
//copy the current normal to the lastNormal