if anyone need this now:
Code:
/**
* Move actual view angles towards desired ones.
* This is the only place v_angle is altered.
* @todo Make stiffness and turn rate constants timestep invariant.
*/
void CCSBot::UpdateLookAngles( void )
{
VPROF_BUDGET( "CCSBot::UpdateLookAngles", VPROF_BUDGETGROUP_NPCS );
const float deltaT = g_BotUpkeepInterval;
float maxAccel;
float stiffness;
float damping;
// If mimicing the player, don't modify the view angles.
if ( bot_mimic.GetInt() )
return;
// springs are stiffer when attacking, so we can track and move between targets better
if (IsAttacking())
{
stiffness = 300.0f;
damping = 30.0f; // 20
maxAccel = 3000.0f; // 4000
}
else
{
stiffness = 200.0f;
damping = 25.0f;
maxAccel = 3000.0f;
}
// these may be overridden by ladder logic
float useYaw = m_lookYaw;
float usePitch = m_lookPitch;
//
// Ladders require precise movement, therefore we need to look at the
// ladder as we approach and ascend/descend it.
// If we are on a ladder, we need to look up or down to traverse it - override pitch in this case.
//
// If we're trying to break something, though, we actually need to look at it before we can
// look at the ladder
//
if ( IsUsingLadder() && !(IsLookingAtSpot( PRIORITY_HIGH ) && m_lookAtSpotAttack) )
{
ComputeLadderAngles( &useYaw, &usePitch );
}
// get current view angles
QAngle viewAngles = EyeAngles();
//
// Yaw
//
float angleDiff = AngleNormalize( useYaw - viewAngles.y );
/*
* m_forwardAngle is unreliable. Need to simulate mouse sliding & centering
if (!IsAttacking())
{
// do not allow rotation through our reverse facing angle - go the "long" way instead
float toCurrent = AngleNormalize( pev->v_angle.y - m_forwardAngle );
float toDesired = AngleNormalize( useYaw - m_forwardAngle );
// if angle differences are different signs, they cross the forward facing
if (toCurrent * toDesired < 0.0f)
{
// if the sum of the angles is greater than 180, turn the "long" way around
if (abs( toCurrent - toDesired ) >= 180.0f)
{
if (angleDiff > 0.0f)
angleDiff -= 360.0f;
else
angleDiff += 360.0f;
}
}
}
*/
// if almost at target angle, snap to it
const float onTargetTolerance = 1.0f; // 3
if (angleDiff < onTargetTolerance && angleDiff > -onTargetTolerance)
{
m_lookYawVel = 0.0f;
viewAngles.y = useYaw;
}
else
{
// simple angular spring/damper
float accel = stiffness * angleDiff - damping * m_lookYawVel;
// limit rate
if (accel > maxAccel)
accel = maxAccel;
else if (accel < -maxAccel)
accel = -maxAccel;
m_lookYawVel += deltaT * accel;
viewAngles.y += deltaT * m_lookYawVel;
// keep track of how long our view remains steady
const float steadyYaw = 1000.0f;
if (fabs( accel ) > steadyYaw)
{
m_viewSteadyTimer.Start();
}
}
//
// Pitch
// Actually, this is negative pitch.
//
angleDiff = usePitch - viewAngles.x;
angleDiff = AngleNormalize( angleDiff );
if (false && angleDiff < onTargetTolerance && angleDiff > -onTargetTolerance)
{
m_lookPitchVel = 0.0f;
viewAngles.x = usePitch;
}
else
{
// simple angular spring/damper
// double the stiffness since pitch is only +/- 90 and yaw is +/- 180
float accel = 2.0f * stiffness * angleDiff - damping * m_lookPitchVel;
// limit rate
if (accel > maxAccel)
accel = maxAccel;
else if (accel < -maxAccel)
accel = -maxAccel;
m_lookPitchVel += deltaT * accel;
viewAngles.x += deltaT * m_lookPitchVel;
// keep track of how long our view remains steady
const float steadyPitch = 1000.0f;
if (fabs( accel ) > steadyPitch)
{
m_viewSteadyTimer.Start();
}
}
//PrintIfWatched( "yawVel = %g, pitchVel = %g\n", m_lookYawVel, m_lookPitchVel );
// limit range - avoid gimbal lock
if (viewAngles.x < -89.0f)
viewAngles.x = -89.0f;
else if (viewAngles.x > 89.0f)
viewAngles.x = 89.0f;
// update view angles
SnapEyeAngles( viewAngles );
// if our weapon is zooming, our view is not steady
if (IsWaitingForZoom())
{
m_viewSteadyTimer.Start();
}
}