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; }
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 ) ); }
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 ); } */ }