示例#1
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::ComputePlaybackRate()
{
    // Determine ideal playback rate
    Vector vel;
    GetOuterAbsVelocity( vel );
 
    float speed = vel.Length2D();
 
    bool isMoving = ( speed > 0.5f ) ? true : false;
 
    float maxspeed = GetBasePlayer()->GetSequenceGroundSpeed( GetBasePlayer()->GetSequence() );
 
    if ( isMoving && ( maxspeed > 0.0f ) )
    {
        float flFactor = 1.0f;
 
        // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
        GetBasePlayer()->SetPlaybackRate( ( speed * flFactor ) / maxspeed );
 
        // BUG BUG:
        // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed
    }
    else
    {
        GetBasePlayer()->SetPlaybackRate( 1.0f );
    }
}
示例#2
0
float CSDKPlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
{
	// Get the player's current velocity and speed.
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );
	float flSpeed = vecVelocity.Length2D();

	// Determine if the player is considered moving or not.
	bool bMoving = ( flSpeed > MOVING_MINIMUM_SPEED );

	// Initialize the return data.
	*bIsMoving = false;
	float flReturn = 1.0f;

	// If we are moving.
	if ( bMoving )
	{
		//		float flGroundSpeed = GetInterpolatedGroundSpeed();
		float flGroundSpeed = GetCurrentMaxGroundSpeed();
		if ( flGroundSpeed < 0.001f )
		{
			flReturn = 0.01;
		}
		else
		{
			// Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
			flReturn = flSpeed / flGroundSpeed;
			flReturn = clamp( flReturn, 0.01f, 10.0f );
		}

		*bIsMoving = true;
	}

	return flReturn;
}
示例#3
0
float CBasePlayerAnimState::CalcMovementPlaybackRate( bool *bIsMoving )
{
	// Determine ideal playback rate
	Vector vel;
	GetOuterAbsVelocity( vel );

	float speed = vel.Length2D();
	bool isMoving = ( speed > MOVING_MINIMUM_SPEED );

	*bIsMoving = false;
	float flReturnValue = 1;

	if ( isMoving && CanThePlayerMove() )
	{
		float flGroundSpeed = GetInterpolatedGroundSpeed();
		if ( flGroundSpeed < 0.001f )
		{
			flReturnValue = 0.01;
		}
		else
		{
			// Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
			flReturnValue = speed / flGroundSpeed;
			flReturnValue = clamp( flReturnValue, 0.01, 10 );	// don't go nuts here.
		}
		*bIsMoving = true;
	}
	
	return flReturnValue;
}
void CSDKPlayerAnimState::EstimateYaw( void )
{
	// Get the frame time.
	float flDeltaTime = gpGlobals->frametime * m_pSDKPlayer->GetSlowMoMultiplier();
	if ( flDeltaTime == 0.0f )
		return;

	// Get the player's velocity and angles.
	Vector vecEstVelocity;
	GetOuterAbsVelocity( vecEstVelocity );
	QAngle angles = GetBasePlayer()->GetLocalAngles();

	// If we are not moving, sync up the feet and eyes slowly.
	if (m_pSDKPlayer->m_Shared.IsProne())
	{
		// Don't touch it
	}
	else if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f )
	{
		float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
		flYawDelta = AngleNormalize( flYawDelta );

		if ( flDeltaTime < 0.25f )
		{
			flYawDelta *= ( flDeltaTime * 4.0f );
		}
		else
		{
			flYawDelta *= flDeltaTime;
		}

		m_PoseParameterData.m_flEstimateYaw += flYawDelta;
		m_PoseParameterData.m_flEstimateYaw = AngleNormalize( m_PoseParameterData.m_flEstimateYaw );
	}
	else if (m_pSDKPlayer->m_Shared.IsAimedIn() || m_pSDKPlayer->m_Shared.IsDiving() || m_pSDKPlayer->m_Shared.IsRolling() || m_pSDKPlayer->m_Shared.IsSliding())
	{
		m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI );
		m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f );
	}
	else
	{
		QAngle angDir;
		VectorAngles(vecEstVelocity, angDir);

		if (fabs(AngleNormalize(angDir[YAW] - m_flEyeYaw)) <= 90)
			m_bFacingForward = true;
		else if (fabs(AngleNormalize(angDir[YAW] - m_flEyeYaw)) >= 91)
			m_bFacingForward = false;

		float flYawDelta = AngleNormalize(m_flGoalFeetYaw - m_flCurrentFeetYaw);

		if (m_bFacingForward)
			m_PoseParameterData.m_flEstimateYaw = flYawDelta;
		else
			m_PoseParameterData.m_flEstimateYaw = 180-flYawDelta;
	}
}
//-----------------------------------------------------------------------------
// Purpose:
bool CPortalPlayerAnimState::HandleJumping( Activity &idealActivity )
{
    Vector vecVelocity;
    GetOuterAbsVelocity( vecVelocity );

    if ( ( vecVelocity.z > 300.0f || m_bInAirWalk ) )
    {
        // Check to see if we were in an airwalk and now we are basically on the ground.
        if ( GetBasePlayer()->GetFlags() & FL_ONGROUND )
        {
            m_bInAirWalk = false;
            RestartMainSequence();
            RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );
        }
        else
        {
            // In an air walk.
            idealActivity = ACT_MP_AIRWALK;
            m_bInAirWalk = true;
        }
    }
    // Jumping.
    else
    {
        if ( m_bJumping )
        {
            if ( m_bFirstJumpFrame )
            {
                m_bFirstJumpFrame = false;
                RestartMainSequence();	// Reset the animation.
            }

            // Don't check if he's on the ground for a sec.. sometimes the client still has the
            // on-ground flag set right when the message comes in.
            else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
            {
                if ( GetBasePlayer()->GetFlags() & FL_ONGROUND )
                {
                    m_bJumping = false;
                    RestartMainSequence();
                    RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );
                }
            }

            // if we're still jumping
            if ( m_bJumping )
            {
                idealActivity = ACT_MP_JUMP_START;
            }
        }
    }

    if ( m_bJumping || m_bInAirWalk )
        return true;

    return false;
}
//-----------------------------------------------------------------------------
// Purpose: 
bool CSDKPlayerAnimState::HandleJumping( Activity &idealActivity )
{
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );

	if ( m_bJumping )
	{
		if ( m_bFirstJumpFrame )
		{
			m_bFirstJumpFrame = false;
			RestartMainSequence();	// Reset the animation.
		}

		// Reset if we hit water and start swimming.
		if ( m_pSDKPlayer->GetWaterLevel() >= WL_Waist )
		{
			m_bJumping = false;
			RestartMainSequence();
		}
		// Don't check if he's on the ground for a sec.. sometimes the client still has the
		// on-ground flag set right when the message comes in.
		else if ( m_pSDKPlayer->GetCurrentTime() - m_flJumpStartTime > 0.2f )
		{
			if ( m_pSDKPlayer->GetFlags() & FL_ONGROUND )
			{
				m_bJumping = false;
				RestartMainSequence();

				RestartGesture( GESTURE_SLOT_JUMP, ACT_DA_JUMP_LAND );					
			}
		}

		// if we're still jumping
		if ( m_bJumping )
		{
			if ( m_pSDKPlayer->GetCurrentTime() - m_flJumpStartTime > 0.5 )
				idealActivity = ACT_DA_JUMP_FLOAT;
			else
				idealActivity = ACT_DA_JUMP_START;
		}
	}	

	if (!m_bJumping && 
		!(m_pSDKPlayer->GetFlags() & FL_ONGROUND) &&
		!m_pSDKPlayer->m_Shared.IsSliding () &&
		!m_pSDKPlayer->m_Shared.IsRolling () &&
		m_pSDKPlayer->GetAbsVelocity ().z < -270)
	{
		idealActivity = ACT_DA_JUMP_FLOAT;
		return true;
	}

	if ( m_bJumping )
		return true;

	return false;
}
示例#7
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : dt - 
//-----------------------------------------------------------------------------
void CBasePlayerAnimState::EstimateYaw()
{
	Vector est_velocity;
	GetOuterAbsVelocity( est_velocity );

	float flLength = est_velocity.Length2D();
	if ( flLength > MOVING_MINIMUM_SPEED )
	{
		m_flGaitYaw = atan2( est_velocity[1], est_velocity[0] );
		m_flGaitYaw = RAD2DEG( m_flGaitYaw );
		m_flGaitYaw = AngleNormalize( m_flGaitYaw );
	}
}
示例#8
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CPlayerAnimState::ComputePlaybackRate()
{
    // Determine ideal playback rate
    Vector vel;
    GetOuterAbsVelocity( vel );

    float speed = vel.Length2D();

    bool isMoving = ( speed > 0.5f ) ? true : false;

    Activity currentActivity = 	GetOuter()->GetSequenceActivity( GetOuter()->GetSequence() );

    switch ( currentActivity )
    {
    case ACT_WALK:
    case ACT_RUN:
    case ACT_IDLE:
    {
        float maxspeed = GetOuter()->MaxSpeed();
        if ( isMoving && ( maxspeed > 1.0f ) )
        {
            float flFactor = 1.0f;

            // Note this gets set back to 1.0 if sequence changes due to ResetSequenceInfo below
            float flWantedRate = ( speed * flFactor ) / maxspeed;
            flWantedRate = clamp( flWantedRate, 0.1, 10 );	// don't go nuts here.
            GetOuter()->SetPlaybackRate( flWantedRate );

            // BUG BUG:
            // This stuff really should be m_flPlaybackRate = speed / m_flGroundSpeed
        }
        else
        {
            GetOuter()->SetPlaybackRate( 1.0f );
        }
    }
    break;
    default:
    {
        GetOuter()->SetPlaybackRate( 1.0f );
    }
    break;
    }
}
示例#9
0
//-----------------------------------------------------------------------------
// Purpose:
// Input  : dt -
//-----------------------------------------------------------------------------
void CSinglePlayerAnimState::EstimateYaw( void )
{
    float dt = gpGlobals->frametime;
 
    if ( !dt )
    {
        return;
    }
 
    Vector est_velocity;
    QAngle    angles;
 
    GetOuterAbsVelocity( est_velocity );
 
    angles = GetBasePlayer()->GetLocalAngles();
 
    if ( est_velocity[1] == 0 && est_velocity[0] == 0 )
    {
        float flYawDiff = angles[YAW] - m_flGaitYaw;
        flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
        if (flYawDiff > 180)
            flYawDiff -= 360;
        if (flYawDiff < -180)
            flYawDiff += 360;
 
        if (dt < 0.25)
            flYawDiff *= dt * 4;
        else
            flYawDiff *= dt;
 
        m_flGaitYaw += flYawDiff;
        m_flGaitYaw = m_flGaitYaw - (int)(m_flGaitYaw / 360) * 360;
    }
    else
    {
        m_flGaitYaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
 
        if (m_flGaitYaw > 180)
            m_flGaitYaw = 180;
        else if (m_flGaitYaw < -180)
            m_flGaitYaw = -180;
    }
}
示例#10
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CSDKPlayerAnimState::EstimateYaw( void )
{
	// Get the frame time.
	float flDeltaTime = gpGlobals->frametime;
	if ( flDeltaTime == 0.0f )
		return;

	// Get the player's velocity and angles.
	Vector vecEstVelocity;
	GetOuterAbsVelocity( vecEstVelocity );
	QAngle angles = GetBasePlayer()->GetLocalAngles();

	// If we are not moving, sync up the feet and eyes slowly.
	if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f )
	{
		float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
		flYawDelta = AngleNormalize( flYawDelta );

		if ( flDeltaTime < 0.25f )
		{
			flYawDelta *= ( flDeltaTime * 4.0f );
		}
		else
		{
			flYawDelta *= flDeltaTime;
		}

		m_PoseParameterData.m_flEstimateYaw += flYawDelta;
		AngleNormalize( m_PoseParameterData.m_flEstimateYaw );
	}
	else
	{
		m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI );
		m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f );
	}
}
void CSDKPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
{
	if (m_pSDKPlayer->m_Shared.IsSliding() && !m_pSDKPlayer->m_Shared.IsDiveSliding())
	{
		Vector vecVelocity;
		GetOuterAbsVelocity( vecVelocity );

		QAngle angDir;
		VectorAngles(vecVelocity, angDir);

		//if (m_bFacingForward)
		m_flGoalFeetYaw = angDir[YAW];
		//else
		//	m_flGoalFeetYaw = AngleNormalize(angDir[YAW] + 180);

		m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
		if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
		{
			ConvergeYawAngles( m_flGoalFeetYaw, 720.0f, gpGlobals->frametime * m_pSDKPlayer->GetSlowMoMultiplier(), m_flCurrentFeetYaw );
			m_flLastAimTurnTime = m_pSDKPlayer->GetCurrentTime();
		}

		QAngle angSlide;
		VectorAngles(m_pSDKPlayer->m_Shared.GetSlideDirection(), angSlide);
		m_angRender[YAW] = angSlide.y;

		// Get the view yaw.
		float flAngle = AngleNormalize( m_flEyeYaw );

		// Calc side to side turning - the view vs. movement yaw.
		float flAimYaw = angSlide.y - flAngle;
		flAimYaw = AngleNormalize( flAimYaw );

		// Set the aim yaw and save.
		GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, flAimYaw );
		m_DebugAnimData.m_flAimYaw	= flAimYaw;

		// Turn off a force aim yaw - either we have already updated or we don't need to.
		m_bForceAimYaw = false;

#ifndef CLIENT_DLL
		QAngle angle = GetBasePlayer()->GetAbsAngles();
		angle[YAW] = m_flCurrentFeetYaw;

		GetBasePlayer()->SetAbsAngles( angle );
#endif

		return;
	}
	if (m_bFlipping)
	{
		m_angRender[YAW] = m_flEyeYaw;
#ifndef CLIENT_DLL
		QAngle angle = GetBasePlayer()->GetAbsAngles();
		angle[YAW] = m_flCurrentFeetYaw;

		GetBasePlayer()->SetAbsAngles( angle );
#endif
		return;
	}
	// Get the movement velocity.
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );

	// Check to see if we are moving.
	bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false;

	if ( m_pSDKPlayer->m_Shared.IsProne() )
	{
		m_flGoalFeetYaw = m_flCurrentFeetYaw = m_flEyeYaw;
	}
	else if ( bMoving || m_bForceAimYaw )
	{
		if (m_pSDKPlayer->m_Shared.IsAimedIn() || m_pSDKPlayer->m_Shared.IsDiving() || m_pSDKPlayer->m_Shared.IsRolling() || m_pSDKPlayer->m_Shared.IsSliding())
		{
			// The feet match the eye direction when moving - the move yaw takes care of the rest.
			m_flGoalFeetYaw = m_flEyeYaw;
		}
		else
		{
			QAngle angDir;
			VectorAngles(vecVelocity, angDir);

			if (m_bFacingForward)
			{
				m_flGoalFeetYaw = angDir[YAW];
			}
			else
			{
				m_flGoalFeetYaw = AngleNormalize(angDir[YAW] + 180);
			}
		}
	}
	// Else if we are not moving.
	else
	{
		// Initialize the feet.
		if ( m_PoseParameterData.m_flLastAimTurnTime <= 0.0f )
		{
			m_flGoalFeetYaw	= m_flEyeYaw;
			m_flCurrentFeetYaw = m_flEyeYaw;
			m_PoseParameterData.m_flLastAimTurnTime = m_pSDKPlayer->GetCurrentTime();
		}
		// Make sure the feet yaw isn't too far out of sync with the eye yaw.
		// TODO: Do something better here!
		else
		{
			float flYawDelta = AngleNormalize(  m_flGoalFeetYaw - m_flEyeYaw );

			if ( fabs( flYawDelta ) > 75.0f )
			{
				float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f;
				m_flGoalFeetYaw += ( 75.0f * flSide );
			}
		}
	}

	// Fix up the feet yaw.
	m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
	if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
	{
		if ( m_bForceAimYaw )
		{
			m_flCurrentFeetYaw = m_flGoalFeetYaw;
		}
		else
		{
			ConvergeYawAnglesThroughZero( m_flGoalFeetYaw, 720.0f, gpGlobals->frametime * m_pSDKPlayer->GetSlowMoMultiplier(), m_flCurrentFeetYaw );
			m_flLastAimTurnTime = m_pSDKPlayer->GetCurrentTime();
		}
	}

	if (m_pSDKPlayer->m_Shared.IsDiving())
		m_flCurrentFeetYaw = m_flGoalFeetYaw;

	// Rotate the body into position.
	m_angRender[YAW] = m_flCurrentFeetYaw;

	// Find the aim(torso) yaw base on the eye and feet yaws.
	float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw;

	if (m_pSDKPlayer->IsInThirdPerson())
		flAimYaw = m_flCharacterEyeYaw - m_flCurrentFeetYaw;

	flAimYaw = AngleNormalize( flAimYaw );

	// Set the aim yaw and save.
	GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, -flAimYaw );
	m_DebugAnimData.m_flAimYaw	= flAimYaw;

	// Turn off a force aim yaw - either we have already updated or we don't need to.
	m_bForceAimYaw = false;

#ifndef CLIENT_DLL
	QAngle angle = GetBasePlayer()->GetAbsAngles();
	angle[YAW] = m_flCurrentFeetYaw;

	GetBasePlayer()->SetAbsAngles( angle );
#endif
}
示例#12
0
//-----------------------------------------------------------------------------
// Purpose: 
bool CTFPlayerAnimState::HandleJumping( Activity &idealActivity )
{
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );

	// Don't allow a firing heavy to jump or air walk.
	if ( m_pTFPlayer->GetPlayerClass()->IsClass( TF_CLASS_HEAVYWEAPONS ) && m_pTFPlayer->m_Shared.InCond( TF_COND_AIMING ) )
		return false;
		
	// Handle air walking before handling jumping - air walking supersedes jump
	TFPlayerClassData_t *pData = m_pTFPlayer->GetPlayerClass()->GetData();
	bool bValidAirWalkClass = ( pData && pData->m_bDontDoAirwalk == false );

	if ( bValidAirWalkClass && ( vecVelocity.z > 300.0f || m_bInAirWalk ) )
	{
		// Check to see if we were in an airwalk and now we are basically on the ground.
		if ( ( GetBasePlayer()->GetFlags() & FL_ONGROUND ) && m_bInAirWalk )
		{				
			m_bInAirWalk = false;
			RestartMainSequence();
			RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );	
		}
		else if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
		{
			// Turn off air walking and reset the animation.
			m_bInAirWalk = false;
			RestartMainSequence();
		}
		else if ( ( GetBasePlayer()->GetFlags() & FL_ONGROUND ) == 0 )
		{
			// In an air walk.
			idealActivity = ACT_MP_AIRWALK;
			m_bInAirWalk = true;
		}
	}
	// Jumping.
	else
	{
		if ( m_bJumping )
		{
			// Remove me once all classes are doing the new jump
			TFPlayerClassData_t *pData = m_pTFPlayer->GetPlayerClass()->GetData();
			bool bNewJump = ( pData && pData->m_bDontDoNewJump == false );

			if ( m_bFirstJumpFrame )
			{
				m_bFirstJumpFrame = false;
				RestartMainSequence();	// Reset the animation.
			}

			// Reset if we hit water and start swimming.
			if ( GetBasePlayer()->GetWaterLevel() >= WL_Waist )
			{
				m_bJumping = false;
				RestartMainSequence();
			}
			// Don't check if he's on the ground for a sec.. sometimes the client still has the
			// on-ground flag set right when the message comes in.
			else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
			{
				if ( GetBasePlayer()->GetFlags() & FL_ONGROUND )
				{
					m_bJumping = false;
					RestartMainSequence();

					if ( bNewJump )
					{
						RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );					
					}
				}
			}

			// if we're still jumping
			if ( m_bJumping )
			{
				if ( bNewJump )
				{
					if ( gpGlobals->curtime - m_flJumpStartTime > 0.5 )
					{
						idealActivity = ACT_MP_JUMP_FLOAT;
					}
					else
					{
						idealActivity = ACT_MP_JUMP_START;
					}
				}
				else
				{
					idealActivity = ACT_MP_JUMP;
				}
			}
		}	
	}	

	if ( m_bJumping || m_bInAirWalk )
		return true;

	return false;
}
示例#13
0
void CPlayerAnimState::ComputePoseParam_BodyYaw()
{
    // See if we even have a blender for pitch
    int upper_body_yaw = GetOuter()->LookupPoseParameter( "body_yaw" );
    if ( upper_body_yaw < 0 )
    {
        return;
    }

    // Assume upper and lower bodies are aligned and that we're not turning
    float flGoalTorsoYaw = 0.0f;
    int turning = TURN_NONE;
    float turnrate = tf2_feetyawrate.GetFloat();

    Vector vel;
    GetOuterAbsVelocity( vel );

    bool isMoving = ( vel.Length() > 0.1f ) ? true : false;
    if ( isMoving )
    {
        m_flLastTurnTime = 0.0f;
        m_nTurningInPlace = TURN_NONE;
        m_flGoalFeetYaw = m_flEyeYaw;
        flGoalTorsoYaw = 0.0f;
        turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
        m_flCurrentTorsoYaw = m_flEyeYaw - m_flCurrentFeetYaw;
    }
    else
    {
        // Just stopped moving, try and clamp feet
        if ( m_flLastTurnTime <= 0.0f )
        {
            m_flLastTurnTime	= gpGlobals->curtime;
            m_flLastYaw			= m_flEyeYaw;
            // Snap feet to be perfectly aligned with torso/eyes
            m_flGoalFeetYaw		= m_flEyeYaw;
            m_flCurrentFeetYaw	= m_flGoalFeetYaw;
            m_nTurningInPlace	= TURN_NONE;
        }

        // If rotating in place, update stasis timer
        if ( m_flLastYaw != m_flEyeYaw )
        {
            m_flLastTurnTime	= gpGlobals->curtime;
            m_flLastYaw			= m_flEyeYaw;
        }

        if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
        {
            m_flLastTurnTime	= gpGlobals->curtime;
        }

        turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );

        // See how far off current feetyaw is from true yaw
        float yawdelta = m_flEyeYaw - m_flCurrentFeetYaw;
        yawdelta = AngleNormalize( yawdelta );

        bool rotated_too_far = false;

        float yawmagnitude = fabs( yawdelta );
        // If too far, then need to turn in place
        if ( yawmagnitude > MAX_TORSO_ANGLE )
        {
            rotated_too_far = true;
        }

        // Standing still for a while, rotate feet around to face forward
        // Or rotated too far
        // FIXME:  Play an in place turning animation
        if ( rotated_too_far ||
                ( gpGlobals->curtime > m_flLastTurnTime + tf2_facefronttime.GetFloat() ) )
        {
            m_flGoalFeetYaw		= m_flEyeYaw;
            m_flLastTurnTime	= gpGlobals->curtime;

            float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw;
            if ( yd > 0 )
            {
                m_nTurningInPlace = TURN_RIGHT;
            }
            else if ( yd < 0 )
            {
                m_nTurningInPlace = TURN_LEFT;
            }
            else
            {
                m_nTurningInPlace = TURN_NONE;
            }

            turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
            yawdelta = m_flEyeYaw - m_flCurrentFeetYaw;
        }

        // Snap upper body into position since the delta is already smoothed for the feet
        flGoalTorsoYaw = yawdelta;
        m_flCurrentTorsoYaw = flGoalTorsoYaw;
    }


    if ( turning == TURN_NONE )
    {
        m_nTurningInPlace = turning;
    }

    if ( m_nTurningInPlace != TURN_NONE )
    {
        // If we're close to finishing the turn, then turn off the turning animation
        if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION )
        {
            m_nTurningInPlace = TURN_NONE;
        }
    }

    // Counter rotate upper body as needed
    ConvergeAngles( flGoalTorsoYaw, turnrate, gpGlobals->frametime, m_flCurrentTorsoYaw );

    // Rotate entire body into position
    m_angRender[YAW] = m_flCurrentFeetYaw;
    m_angRender[PITCH] = m_angRender[ROLL] = 0;

    SetOuterPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -90.0f, 90.0f ) );
}
示例#14
0
void CBasePlayerAnimState::ComputePoseParam_BodyYaw()
{
	VPROF( "CBasePlayerAnimState::ComputePoseParam_BodyYaw" );

	// Find out which way he's running (m_flEyeYaw is the way he's looking).
	Vector vel;
	GetOuterAbsVelocity( vel );
	bool bIsMoving = vel.Length2D() > MOVING_MINIMUM_SPEED;

	// If we just initialized this guy (maybe he just came into the PVS), then immediately
	// set his feet in the right direction, otherwise they'll spin around from 0 to the 
	// right direction every time someone switches spectator targets.
	if ( !m_bCurrentFeetYawInitialized )
	{
		m_bCurrentFeetYawInitialized = true;
		m_flGoalFeetYaw = m_flCurrentFeetYaw = m_flEyeYaw;
		m_flLastTurnTime = 0.0f;
	}
	else if ( bIsMoving )
	{
		// player is moving, feet yaw = aiming yaw
		if ( m_AnimConfig.m_LegAnimType == LEGANIM_9WAY || m_AnimConfig.m_LegAnimType == LEGANIM_8WAY )
		{
			// His feet point in the direction his eyes are, but they can run in any direction.
			m_flGoalFeetYaw = m_flEyeYaw;
		}
		else
		{
			m_flGoalFeetYaw = RAD2DEG( atan2( vel.y, vel.x ) );

			// If he's running backwards, flip his feet backwards.
			Vector vEyeYaw( cos( DEG2RAD( m_flEyeYaw ) ), sin( DEG2RAD( m_flEyeYaw ) ), 0 );
			Vector vFeetYaw( cos( DEG2RAD( m_flGoalFeetYaw ) ), sin( DEG2RAD( m_flGoalFeetYaw ) ), 0 );
			if ( vEyeYaw.Dot( vFeetYaw ) < -0.01 )
			{
				m_flGoalFeetYaw += 180;
			}
		}

	}
	else if ( (gpGlobals->curtime - m_flLastTurnTime) > mp_facefronttime.GetFloat() )
	{
		// player didn't move & turn for quite some time
		m_flGoalFeetYaw = m_flEyeYaw;
	}
	else
	{
		// If he's rotated his view further than the model can turn, make him face forward.
		float flDiff = AngleNormalize(  m_flGoalFeetYaw - m_flEyeYaw );

		if ( fabs(flDiff) > m_AnimConfig.m_flMaxBodyYawDegrees )
		{
			if ( flDiff  > 0 )
				m_flGoalFeetYaw -= m_AnimConfig.m_flMaxBodyYawDegrees;
			else
				m_flGoalFeetYaw += m_AnimConfig.m_flMaxBodyYawDegrees;
		}
	}

	m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );

	if ( m_flCurrentFeetYaw != m_flGoalFeetYaw )
	{
		ConvergeAngles( m_flGoalFeetYaw, GetFeetYawRate(), m_AnimConfig.m_flMaxBodyYawDegrees,
			 gpGlobals->frametime, m_flCurrentFeetYaw );

		m_flLastTurnTime = gpGlobals->curtime;
	}

	float flCurrentTorsoYaw = AngleNormalize( m_flEyeYaw - m_flCurrentFeetYaw );

	// Rotate entire body into position
	m_angRender[YAW] = m_flCurrentFeetYaw;
	m_angRender[PITCH] = m_angRender[ROLL] = 0;
		
	SetOuterBodyYaw( flCurrentTorsoYaw );
	g_flLastBodyYaw = flCurrentTorsoYaw;
}
示例#15
0
float CBasePlayerAnimState::GetOuterXYSpeed() const
{
	Vector vel;
	GetOuterAbsVelocity( vel );
	return vel.Length2D();
}
示例#16
0
void CSinglePlayerAnimState::ComputePoseParam_BodyLookYaw( void )
{
    QAngle absangles = GetBasePlayer()->GetAbsAngles();
    absangles.y = AngleNormalize( absangles.y );
    m_angRender = absangles;
 
    // See if we even have a blender for pitch
    int upper_body_yaw = GetBasePlayer()->LookupPoseParameter( "aim_yaw" );
    if ( upper_body_yaw < 0 )
    {
        return;
    }
 
    // Assume upper and lower bodies are aligned and that we're not turning
    float flGoalTorsoYaw = 0.0f;
    int turning = TURN_NONE;
    float turnrate = 360.0f;
 
    Vector vel;
 
    GetOuterAbsVelocity( vel );
 
    bool isMoving = ( vel.Length() > 1.0f ) ? true : false;
 
    if ( !isMoving )
    {
        // Just stopped moving, try and clamp feet
        if ( m_flLastTurnTime <= 0.0f )
        {
            m_flLastTurnTime    = gpGlobals->curtime;
            m_flLastYaw            = GetBasePlayer()->EyeAngles().y;
            // Snap feet to be perfectly aligned with torso/eyes
            m_flGoalFeetYaw        = GetBasePlayer()->EyeAngles().y;
            m_flCurrentFeetYaw    = m_flGoalFeetYaw;
            m_nTurningInPlace    = TURN_NONE;
        }
 
        // If rotating in place, update stasis timer
 
        if ( m_flLastYaw != GetBasePlayer()->EyeAngles().y )
        {
            m_flLastTurnTime    = gpGlobals->curtime;
            m_flLastYaw            = GetBasePlayer()->EyeAngles().y;
        }
 
        if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
        {
            m_flLastTurnTime    = gpGlobals->curtime;
        }
 
        turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
 
        QAngle eyeAngles = GetBasePlayer()->EyeAngles();
        QAngle vAngle = GetBasePlayer()->GetLocalAngles();
 
        // See how far off current feetyaw is from true yaw
        float yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw;
        yawdelta = AngleNormalize( yawdelta );
 
        bool rotated_too_far = false;
 
        float yawmagnitude = fabs( yawdelta );
 
        // If too far, then need to turn in place
        if ( yawmagnitude > 45 )
        {
            rotated_too_far = true;
        }
 
        // Standing still for a while, rotate feet around to face forward
        // Or rotated too far
        // FIXME:  Play an in place turning animation
        if ( rotated_too_far ||
            ( gpGlobals->curtime > m_flLastTurnTime + mp_facefronttime.GetFloat() ) )
        {
            m_flGoalFeetYaw        = GetBasePlayer()->EyeAngles().y;
            m_flLastTurnTime    = gpGlobals->curtime;
 
        /*    float yd = m_flCurrentFeetYaw - m_flGoalFeetYaw;
            if ( yd > 0 )
            {
                m_nTurningInPlace = TURN_RIGHT;
            }
            else if ( yd < 0 )
            {
                m_nTurningInPlace = TURN_LEFT;
            }
            else
            {
                m_nTurningInPlace = TURN_NONE;
            }
 
            turning = ConvergeAngles( m_flGoalFeetYaw, turnrate, gpGlobals->frametime, m_flCurrentFeetYaw );
            yawdelta = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw;*/
 
        }
 
        // Snap upper body into position since the delta is already smoothed for the feet
        flGoalTorsoYaw = yawdelta;
        m_flCurrentTorsoYaw = flGoalTorsoYaw;
    }
    else
    {
        m_flLastTurnTime = 0.0f;
        m_nTurningInPlace = TURN_NONE;
        m_flCurrentFeetYaw = m_flGoalFeetYaw = GetBasePlayer()->EyeAngles().y;
        flGoalTorsoYaw = 0.0f;
        m_flCurrentTorsoYaw = GetBasePlayer()->EyeAngles().y - m_flCurrentFeetYaw;
    }
 
    if ( turning == TURN_NONE )
    {
        m_nTurningInPlace = turning;
    }
 
    if ( m_nTurningInPlace != TURN_NONE )
    {
        // If we're close to finishing the turn, then turn off the turning animation
        if ( fabs( m_flCurrentFeetYaw - m_flGoalFeetYaw ) < MIN_TURN_ANGLE_REQUIRING_TURN_ANIMATION )
        {
            m_nTurningInPlace = TURN_NONE;
        }
    }
 
    // Rotate entire body into position
    absangles = GetBasePlayer()->GetAbsAngles();
    absangles.y = m_flCurrentFeetYaw;
    m_angRender = absangles;
 
    GetBasePlayer()->SetPoseParameter( upper_body_yaw, clamp( m_flCurrentTorsoYaw, -60.0f, 60.0f ) );
 
    /*
    // FIXME: Adrian, what is this?
    int body_yaw = GetBasePlayer()->LookupPoseParameter( "body_yaw" );
 
    if ( body_yaw >= 0 )
    {
        GetBasePlayer()->SetPoseParameter( body_yaw, 30 );
    }
    */
 
}
示例#17
0
//-----------------------------------------------------------------------------
// Purpose: 
bool CHL2MPPlayerAnimState::HandleJumping( Activity &idealActivity )
{
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );

	if ( m_bJumping )
	{
		static bool bNewJump = false; //Tony; hl2mp players only have a 'hop'

		if ( m_bFirstJumpFrame )
		{
			m_bFirstJumpFrame = false;
			RestartMainSequence();	// Reset the animation.
		}

		// Reset if we hit water and start swimming.
		if ( m_pHL2MPPlayer->GetWaterLevel() >= WL_Waist )
		{
			m_bJumping = false;
			RestartMainSequence();
		}
		// Don't check if he's on the ground for a sec.. sometimes the client still has the
		// on-ground flag set right when the message comes in.
		else if ( gpGlobals->curtime - m_flJumpStartTime > 0.2f )
		{
			if ( m_pHL2MPPlayer->GetFlags() & FL_ONGROUND )
			{
				m_bJumping = false;
				RestartMainSequence();

				if ( bNewJump )
				{
					RestartGesture( GESTURE_SLOT_JUMP, ACT_MP_JUMP_LAND );					
				}
			}
		}

		// if we're still jumping
		if ( m_bJumping )
		{
			if ( bNewJump )
			{
				if ( gpGlobals->curtime - m_flJumpStartTime > 0.5 )
				{
					idealActivity = ACT_MP_JUMP_FLOAT;
				}
				else
				{
					idealActivity = ACT_MP_JUMP_START;
				}
			}
			else
			{
				idealActivity = ACT_MP_JUMP;
			}
		}
	}	

	if ( m_bJumping )
		return true;

	return false;
}
示例#18
0
// -----------------------------------------------------------------------------
void CBasePlayerAnimState::DebugShowAnimState( int iStartLine )
{
	Vector vOuterVel;
	GetOuterAbsVelocity( vOuterVel );

	int iLine = iStartLine;
	AnimStatePrintf( iLine++, "main: %s(%d), cycle: %.2f cyclerate: %.2f playbackrate: %.2f\n", 
		GetSequenceName( m_pOuter->GetModelPtr(), m_pOuter->GetSequence() ), 
		m_pOuter->GetSequence(),
		m_pOuter->GetCycle(), 
		m_pOuter->GetSequenceCycleRate(m_pOuter->GetModelPtr(), m_pOuter->GetSequence()),
		m_pOuter->GetPlaybackRate()
		);

	if ( m_AnimConfig.m_LegAnimType == LEGANIM_8WAY )
	{
		CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( MAIN_IDLE_SEQUENCE_LAYER );

		AnimStatePrintf( iLine++, "idle: %s, weight: %.2f\n",
			GetSequenceName( m_pOuter->GetModelPtr(), pLayer->GetSequence() ), 
			(float)pLayer->GetWeight() );
	}

	for ( int i=0; i < m_pOuter->GetNumAnimOverlays()-1; i++ )
	{
		CAnimationLayer *pLayer = m_pOuter->GetAnimOverlay( AIMSEQUENCE_LAYER + i );
#ifdef CLIENT_DLL
		AnimStatePrintf( iLine++, "%s(%d), weight: %.2f, cycle: %.2f, order (%d), aim (%d)", 
			!pLayer->IsActive() ? "-- ": (pLayer->GetSequence() == 0 ? "-- " : (showanimstate_activities.GetBool()) ? GetSequenceActivityName( m_pOuter->GetModelPtr(), pLayer->GetSequence() ) : GetSequenceName( m_pOuter->GetModelPtr(), pLayer->GetSequence() ) ), 
			!pLayer->IsActive() ? 0 : (int)pLayer->GetSequence(), 
			!pLayer->IsActive() ? 0 : (float)pLayer->GetWeight(), 
			!pLayer->IsActive() ? 0 : (float)pLayer->GetCycle(), 
			!pLayer->IsActive() ? 0 : (int)pLayer->GetOrder(),
			i
			);
#else
		AnimStatePrintf( iLine++, "%s(%d), flags (%d), weight: %.2f, cycle: %.2f, order (%d), aim (%d)", 
			!pLayer->IsActive() ? "-- " : ( pLayer->GetSequence() == 0 ? "-- " : (showanimstate_activities.GetBool()) ? GetSequenceActivityName( m_pOuter->GetModelPtr(), pLayer->GetSequence() ) : GetSequenceName( m_pOuter->GetModelPtr(), pLayer->GetSequence() ) ), 
			!pLayer->IsActive() ? 0 : (int)pLayer->GetSequence(), 
			!pLayer->IsActive() ? 0 : (int)pLayer->m_fFlags,// Doesn't exist on client
			!pLayer->IsActive() ? 0 : (float)pLayer->GetWeight(), 
			!pLayer->IsActive() ? 0 : (float)pLayer->GetCycle(), 
			!pLayer->IsActive() ? 0 : (int)pLayer->m_nOrder,
			i
			);
#endif
	}

	AnimStatePrintf( iLine++, "vel: %.2f, time: %.2f, MAX: %.2f, animspeed: %.2f", 
		vOuterVel.Length2D(), gpGlobals->curtime, GetInterpolatedGroundSpeed(), m_pOuter->GetSequenceGroundSpeed(m_pOuter->GetSequence()) );
	
	if ( m_AnimConfig.m_LegAnimType == LEGANIM_8WAY )
	{
		AnimStatePrintf( iLine++, "ent yaw: %.2f, body_yaw: %.2f, move_yaw: %.2f, gait_yaw: %.2f, body_pitch: %.2f", 
			m_angRender[YAW], g_flLastBodyYaw, m_flLastMoveYaw, m_flGaitYaw, g_flLastBodyPitch );
	}
	else
	{
		AnimStatePrintf( iLine++, "ent yaw: %.2f, body_yaw: %.2f, body_pitch: %.2f, move_x: %.2f, move_y: %.2f", 
			m_angRender[YAW], g_flLastBodyYaw, g_flLastBodyPitch, m_vLastMovePose.x, m_vLastMovePose.y );
	}

	// Draw a red triangle on the ground for the eye yaw.
	float flBaseSize = 10;
	float flHeight = 80;
	Vector vBasePos = GetOuter()->GetAbsOrigin() + Vector( 0, 0, 3 );
	QAngle angles( 0, 0, 0 );
	angles[YAW] = m_flEyeYaw;
	Vector vForward, vRight, vUp;
	AngleVectors( angles, &vForward, &vRight, &vUp );
	debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 255, 0, 0, 255, false, 0.01 );

	// Draw a blue triangle on the ground for the body yaw.
	angles[YAW] = m_angRender[YAW];
	AngleVectors( angles, &vForward, &vRight, &vUp );
	debugoverlay->AddTriangleOverlay( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 0, 0, 255, 255, false, 0.01 );

}
示例#19
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::EstimateYaw( void )
{
	// Get the frame time.
	float flDeltaTime = gpGlobals->frametime;
	if ( flDeltaTime == 0.0f )
		return;

#if 0 // 9way
	// Get the player's velocity and angles.
	Vector vecEstVelocity;
	GetOuterAbsVelocity( vecEstVelocity );
	QAngle angles = GetBasePlayer()->GetLocalAngles();

	// If we are not moving, sync up the feet and eyes slowly.
	if ( vecEstVelocity.x == 0.0f && vecEstVelocity.y == 0.0f )
	{
		float flYawDelta = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
		flYawDelta = AngleNormalize( flYawDelta );

		if ( flDeltaTime < 0.25f )
		{
			flYawDelta *= ( flDeltaTime * 4.0f );
		}
		else
		{
			flYawDelta *= flDeltaTime;
		}

		m_PoseParameterData.m_flEstimateYaw += flYawDelta;
		AngleNormalize( m_PoseParameterData.m_flEstimateYaw );
	}
	else
	{
		m_PoseParameterData.m_flEstimateYaw = ( atan2( vecEstVelocity.y, vecEstVelocity.x ) * 180.0f / M_PI );
		m_PoseParameterData.m_flEstimateYaw = clamp( m_PoseParameterData.m_flEstimateYaw, -180.0f, 180.0f );
	}
#else
	float dt = gpGlobals->frametime;

	// Get the player's velocity and angles.
	Vector vecEstVelocity;
	GetOuterAbsVelocity( vecEstVelocity );
	QAngle angles = GetBasePlayer()->GetLocalAngles();

	if ( vecEstVelocity.y == 0 && vecEstVelocity.x == 0 )
	{
		float flYawDiff = angles[YAW] - m_PoseParameterData.m_flEstimateYaw;
		flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
		if (flYawDiff > 180)
			flYawDiff -= 360;
		if (flYawDiff < -180)
			flYawDiff += 360;

		if (dt < 0.25)
			flYawDiff *= dt * 4;
		else
			flYawDiff *= dt;

		m_PoseParameterData.m_flEstimateYaw += flYawDiff;
		m_PoseParameterData.m_flEstimateYaw = m_PoseParameterData.m_flEstimateYaw - (int)(m_PoseParameterData.m_flEstimateYaw / 360) * 360;
	}
	else
	{
		m_PoseParameterData.m_flEstimateYaw = (atan2(vecEstVelocity.y, vecEstVelocity.x) * 180 / M_PI);

		if (m_PoseParameterData.m_flEstimateYaw > 180)
			m_PoseParameterData.m_flEstimateYaw = 180;
		else if (m_PoseParameterData.m_flEstimateYaw < -180)
			m_PoseParameterData.m_flEstimateYaw = -180;
	}
#endif
}
示例#20
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CHL2MPPlayerAnimState::ComputePoseParam_AimYaw( CStudioHdr *pStudioHdr )
{
	// Get the movement velocity.
	Vector vecVelocity;
	GetOuterAbsVelocity( vecVelocity );

	// Check to see if we are moving.
	bool bMoving = ( vecVelocity.Length() > 1.0f ) ? true : false;

	//DHL - Skillet
	#ifdef CLIENT_DLL
		if ( GetBasePlayer()->IsLocalPlayer() && input->CAM_IsThirdPerson() )
			m_bForceAimYaw = true;
	#endif

	// If we are moving or are prone and undeployed.
	if ( bMoving || m_bForceAimYaw )
	{
		// The feet match the eye direction when moving - the move yaw takes care of the rest.
		m_flGoalFeetYaw = m_flEyeYaw;
	}
	// Else if we are not moving.
	else
	{
		// Initialize the feet.
		if ( m_PoseParameterData.m_flLastAimTurnTime <= 0.0f )
		{
			m_flGoalFeetYaw	= m_flEyeYaw;
			m_flCurrentFeetYaw = m_flEyeYaw;
			m_PoseParameterData.m_flLastAimTurnTime = gpGlobals->curtime;
		}
		// Make sure the feet yaw isn't too far out of sync with the eye yaw.
		// TODO: Do something better here!
		else
		{
			float flYawDelta = AngleNormalize(  m_flGoalFeetYaw - m_flEyeYaw );

			if ( fabs( flYawDelta ) > 45.0f )
			{
				float flSide = ( flYawDelta > 0.0f ) ? -1.0f : 1.0f;
				m_flGoalFeetYaw += ( 45.0f * flSide );
			}
		}
	}

	// Fix up the feet yaw.
	m_flGoalFeetYaw = AngleNormalize( m_flGoalFeetYaw );
	if ( m_flGoalFeetYaw != m_flCurrentFeetYaw )
	{
		if ( m_bForceAimYaw )
		{
			m_flCurrentFeetYaw = m_flGoalFeetYaw;
		}
		else
		{
			ConvergeYawAngles( m_flGoalFeetYaw, 720.0f, gpGlobals->frametime, m_flCurrentFeetYaw );
			m_flLastAimTurnTime = gpGlobals->curtime;
		}
	}

	// Rotate the body into position.
	m_angRender[YAW] = m_flCurrentFeetYaw;

	// Find the aim(torso) yaw base on the eye and feet yaws.
	float flAimYaw = m_flEyeYaw - m_flCurrentFeetYaw;
	flAimYaw = AngleNormalize( flAimYaw );

	// Set the aim yaw and save.
	GetBasePlayer()->SetPoseParameter( pStudioHdr, m_PoseParameterData.m_iAimYaw, flAimYaw );
	m_DebugAnimData.m_flAimYaw	= flAimYaw;

	// Turn off a force aim yaw - either we have already updated or we don't need to.
	m_bForceAimYaw = false;

#ifndef CLIENT_DLL
	QAngle angle = GetBasePlayer()->GetAbsAngles();
	angle[YAW] = m_flCurrentFeetYaw;

	GetBasePlayer()->SetAbsAngles( angle );
#endif
}