//----------------------------------------------------------------------------- // Purpose: // Output : int //----------------------------------------------------------------------------- int CBaseAnimatingOverlay::AddGestureSequence( int sequence, bool autokill /*= true*/ ) { int i = AddLayeredSequence( sequence, 0 ); // No room? if ( IsValidLayer( i ) ) { SetLayerAutokill( i, autokill ); } return i; }
void CAI_BlendedMotor::MoveContinue() { m_nPrimarySequence = GetInteriorSequence( ACT_INVALID ); m_nGoalSequence = m_nPrimarySequence; Assert( m_nPrimarySequence != ACT_INVALID ); if (m_nPrimarySequence == ACT_INVALID) return; m_flStartCycle = 0.0; m_iPrimaryLayer = AddLayeredSequence( m_nPrimarySequence, 0 ); SetLayerWeight( m_iPrimaryLayer, 0.0 ); SetLayerPlaybackRate( m_iPrimaryLayer, 0.0 ); SetLayerNoRestore( m_iPrimaryLayer, true ); SetLayerCycle( m_iPrimaryLayer, m_flStartCycle, m_flStartCycle ); m_bDeceleratingToGoal = false; }
void CAI_BlendedMotor::MoveStart() { if (m_nPrimarySequence == -1) { m_nPrimarySequence = GetSequence(); m_flStartCycle = GetCycle(); m_flCurrRate = 0.4; // Assert( !GetOuter()->HasMovement( m_nStartSequence ) ); m_nSecondarySequence = -1; m_iPrimaryLayer = AddLayeredSequence( m_nPrimarySequence, 0 ); SetLayerWeight( m_iPrimaryLayer, 0.0 ); SetLayerPlaybackRate( m_iPrimaryLayer, 0.0 ); SetLayerNoRestore( m_iPrimaryLayer, true ); SetLayerCycle( m_iPrimaryLayer, m_flStartCycle, m_flStartCycle ); m_flSecondaryWeight = 0.0; } else { // suspect that MoveStop() wasn't called when the previous route finished // Assert( 0 ); } if (m_nGoalSequence == ACT_INVALID) { ResetGoalSequence(); } m_vecPrevOrigin2 = GetAbsOrigin(); m_vecPrevOrigin1 = GetAbsOrigin(); m_bDeceleratingToGoal = false; }
void CAI_BlendedMotor::SetMoveScriptAnim( float flNewSpeed ) { // don't bother if the npc is dead if (!GetOuter()->IsAlive()) return; // insert ideal layers // FIXME: needs full transitions, as well as starting vs stopping sequences, leaning, etc. CAI_Navigator *pNavigator = GetNavigator(); SetPlaybackRate( m_flCurrRate ); // calc weight of idle animation layer that suppresses the run animation float flWeight = 0.0; if (GetIdealSpeed() > 0.0) { flWeight = 1.0 - (flNewSpeed / (GetIdealSpeed() * GetPlaybackRate())); } if (flWeight < 0.0) { m_flCurrRate = flNewSpeed / GetIdealSpeed(); m_flCurrRate = clamp( m_flCurrRate, 0.0, 1.0 ); SetPlaybackRate( m_flCurrRate ); flWeight = 0.0; } // Msg("weight %.3f rate %.3f\n", flWeight, m_flCurrRate ); m_flCurrRate = min( m_flCurrRate + (1.0 - m_flCurrRate) * 0.8, 1.0 ); if (m_nSavedGoalActivity == ACT_INVALID) { ResetGoalSequence(); } // detect state change Activity activity = GetOuter()->NPC_TranslateActivity( m_nSavedGoalActivity ); if ( activity != m_nSavedTranslatedGoalActivity ) { m_nSavedTranslatedGoalActivity = activity; m_nInteriorSequence = ACT_INVALID; m_nGoalSequence = pNavigator->GetArrivalSequence( m_nPrimarySequence ); } if (m_bDeceleratingToGoal) { // find that sequence to play when at goal m_nGoalSequence = pNavigator->GetArrivalSequence( m_nPrimarySequence ); if (m_nGoalSequence == ACT_INVALID) { m_nGoalSequence = GetInteriorSequence( m_nPrimarySequence ); } Assert( m_nGoalSequence != ACT_INVALID ); } if (m_flSecondaryWeight == 1.0 || (m_iSecondaryLayer != -1 && m_nPrimarySequence == m_nSecondarySequence)) { // secondary layer at full strength last time, delete the primary and shift down RemoveLayer( m_iPrimaryLayer, 0.0, 0.0 ); m_iPrimaryLayer = m_iSecondaryLayer; m_nPrimarySequence = m_nSecondarySequence; m_iSecondaryLayer = -1; m_nSecondarySequence = ACT_INVALID; m_flSecondaryWeight = 0.0; } // look for transition sequence if needed if (m_nSecondarySequence == ACT_INVALID) { if (!m_bDeceleratingToGoal && m_nGoalSequence != GetInteriorSequence( m_nPrimarySequence )) { // strob interior sequence in case it changed m_nGoalSequence = GetInteriorSequence( m_nPrimarySequence ); } if (m_nGoalSequence != ACT_INVALID && m_nPrimarySequence != m_nGoalSequence) { // Msg("From %s to %s\n", GetOuter()->GetSequenceName( m_nPrimarySequence ), GetOuter()->GetSequenceName( m_nGoalSequence ) ); m_nSecondarySequence = GetOuter()->FindTransitionSequence(m_nPrimarySequence, m_nGoalSequence, NULL); if (m_nSecondarySequence == ACT_INVALID) m_nSecondarySequence = m_nGoalSequence; } } // set blending for if (m_nSecondarySequence != ACT_INVALID) { if (m_iSecondaryLayer == -1) { m_iSecondaryLayer = AddLayeredSequence( m_nSecondarySequence, 0 ); SetLayerWeight( m_iSecondaryLayer, 0.0 ); if (m_nSecondarySequence == m_nGoalSequence) { SetLayerPlaybackRate( m_iSecondaryLayer, 0.0 ); } else { SetLayerPlaybackRate( m_iSecondaryLayer, 1.0 ); } SetLayerNoRestore( m_iSecondaryLayer, true ); m_flSecondaryWeight = 0.0; } m_flSecondaryWeight = min( m_flSecondaryWeight + 0.3, 1.0 ); if (m_flSecondaryWeight < 1.0) { SetLayerWeight( m_iPrimaryLayer, (flWeight - m_flSecondaryWeight * flWeight) / (1.0f - m_flSecondaryWeight * flWeight) ); SetLayerWeight( m_iSecondaryLayer, flWeight * m_flSecondaryWeight ); } else { SetLayerWeight( m_iPrimaryLayer, 0.0f ); SetLayerWeight( m_iSecondaryLayer, flWeight ); } } else { // recreate layer if missing if (m_iPrimaryLayer == -1) { MoveContinue(); } // try to catch a stale layer if (m_iSecondaryLayer != -1) { // secondary layer at full strength last time, delete the primary and shift down RemoveLayer( m_iSecondaryLayer, 0.0, 0.0 ); m_iSecondaryLayer = -1; m_nSecondarySequence = ACT_INVALID; m_flSecondaryWeight = 0.0; } // debounce // flWeight = flWeight * 0.5 + 0.5 * GetOuter()->GetLayerWeight( m_iPrimaryLayer ); SetLayerWeight( m_iPrimaryLayer, flWeight ); } }
//----------------------------------------------------------------------------- // Purpose: Add string indexed scene/expression/duration to list of active expressions // Input : scenefile - // expression - // duration - //----------------------------------------------------------------------------- void CBaseFlex::AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event ) { if ( !scene || !event ) { Msg( "CBaseFlex::AddExpression: scene or event was NULL!!!\n" ); return; } CExpressionInfo info; info.m_pEvent = event; info.m_pScene = scene; info.m_bStarted = false; switch ( event->GetType() ) { case CChoreoEvent::SEQUENCE: { info.m_nSequence = LookupSequence( event->GetParameters() ); info.m_iLayer = -1; if (info.m_nSequence >= 0) { info.m_iLayer = AddLayeredSequence( info.m_nSequence, scene->GetChannelIndex( event->GetChannel()) ); SetLayerWeight( info.m_iLayer, 0.0 ); info.m_flStartAnim = m_flAnimTime; // ?? } } break; case CChoreoEvent::GESTURE: { info.m_nSequence = LookupSequence( event->GetParameters() ); info.m_iLayer = -1; if (info.m_nSequence >= 0) { // this happens before StudioFrameAdvance() info.m_iLayer = AddLayeredSequence( info.m_nSequence, scene->GetChannelIndex( event->GetChannel()) ); SetLayerDuration( info.m_iLayer, event->GetDuration() ); SetLayerWeight( info.m_iLayer, 0.0 ); bool looping = ((GetSequenceFlags( info.m_nSequence ) & STUDIO_LOOPING) != 0); if ( looping ) { DevMsg( 1, "vcd error, gesture %s of model %s is marked as STUDIO_LOOPING!\n", event->GetParameters(), GetModelName() ); } SetLayerLooping( info.m_iLayer, false ); // force to not loop // figure out the animtime when this was frame 0 float dt = scene->GetTime() - event->GetStartTime(); info.m_flStartAnim = m_flAnimTime - dt; // ?? float flCycle = 0; // assuming anim time is going to advance 0.1 seconds, what should our new cycle be? float duration = event->GetDuration( ); float orig_duration = SequenceDuration( info.m_nSequence ); SetLayerCycle( info.m_iLayer, 0.0 ); float flNextCycle = event->GetShiftedTimeFromReferenceTime( (m_flAnimTime - info.m_flStartAnim + 0.1) / duration ); float rate = (flNextCycle - flCycle) * orig_duration / 0.1; SetLayerPlaybackRate( info.m_iLayer, rate ); } } break; } m_Expressions.AddToTail( info ); }