/* ============= R_CullIQM ============= */ static int R_CullIQM( trRefEntity_t *ent ) { vec3_t localBounds[ 2 ]; if ( ent->e.skeleton.type == SK_INVALID || VectorCompareEpsilon( ent->e.skeleton.bounds[0], vec3_origin, 0.001f) ) { // no properly set skeleton so use the bounding box by the model instead by the animations IQModel_t *model = tr.currentModel->iqm; IQAnim_t *anim = model->anims; VectorScale( anim->bounds, ent->e.skeleton.scale, localBounds[ 0 ] ); VectorScale( anim->bounds + 3, ent->e.skeleton.scale, localBounds[ 1 ] ); } else { // copy a bounding box in the current coordinate system provided by skeleton VectorCopy( ent->e.skeleton.bounds[ 0 ], localBounds[ 0 ] ); VectorCopy( ent->e.skeleton.bounds[ 1 ], localBounds[ 1 ] ); } switch ( R_CullLocalBox( localBounds ) ) { case CULL_IN: tr.pc.c_box_cull_md5_in++; return CULL_IN; case CULL_CLIP: tr.pc.c_box_cull_md5_clip++; return CULL_CLIP; case CULL_OUT: default: tr.pc.c_box_cull_md5_out++; return CULL_OUT; } }
/* =============== CG_smoothWWTransitions =============== */ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t out ) { vec3_t surfNormal, rotAxis, temp; int i; float stLocal, sFraction, rotAngle; float smoothTime, timeMod; qboolean performed = qfalse; vec3_t inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ]; if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) { VectorCopy( in, out ); return; } //set surfNormal BG_GetClientNormal( ps, surfNormal ); AnglesToAxis( in, inAxis ); //if we are moving from one surface to another smooth the transition if( !VectorCompareEpsilon( surfNormal, cg.lastNormal, 0.01f ) ) { AnglesToAxis( cg.lastVangles, lastAxis ); rotAngle = DotProduct( inAxis[ 0 ], lastAxis[ 0 ] ) + DotProduct( inAxis[ 1 ], lastAxis[ 1 ] ) + DotProduct( inAxis[ 2 ], lastAxis[ 2 ] ); // if inAxis and lastAxis collinear, prevent NaN on acos( -1 ) if ( rotAngle < -0.9999f ) { rotAngle = 180.0f; } else { 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 ); timeMod = 1.0f; //add the op CG_addSmoothOp( rotAxis, rotAngle, timeMod ); } //iterate through ops for ( i = MAXSMOOTHS - 1; i >= 0; i-- ) { smoothTime = ( int )( cg_wwSmoothTime.integer * cg.sList[ i ].timeMod ); //if this op has time remaining, perform it if ( cg.time < cg.sList[ i ].time + smoothTime ) { stLocal = 1.0f - ( ( ( cg.sList[ i ].time + smoothTime ) - cg.time ) / smoothTime ); sFraction = - ( cos( stLocal * M_PI ) + 1.0f ) / 2.0f; 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 ); AxisCopy( outAxis, inAxis ); performed = qtrue; } } //if we performed any ops then return the smoothed angles //otherwise simply return the in angles if ( performed ) { AxisToAngles( outAxis, out ); } else { VectorCopy( in, out ); } //copy the current normal to the lastNormal VectorCopy( in, cg.lastVangles ); VectorCopy( surfNormal, cg.lastNormal ); }