Пример #1
0
//-----------------------------------------------------------------------------
// 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 );
	}
}
Пример #5
0
//-----------------------------------------------------------------------------
// 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 );
}