aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/choreoevent.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/choreoevent.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/shared/choreoevent.cpp')
-rw-r--r--mp/src/game/shared/choreoevent.cpp9028
1 files changed, 4514 insertions, 4514 deletions
diff --git a/mp/src/game/shared/choreoevent.cpp b/mp/src/game/shared/choreoevent.cpp
index ef9058c8..50755f04 100644
--- a/mp/src/game/shared/choreoevent.cpp
+++ b/mp/src/game/shared/choreoevent.cpp
@@ -1,4514 +1,4514 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//=============================================================================//
-
-#include "tier0/dbg.h"
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "choreoevent.h"
-#include "choreoactor.h"
-#include "choreochannel.h"
-#include "minmax.h"
-#include "mathlib/mathlib.h"
-#include "tier1/strtools.h"
-#include "choreoscene.h"
-#include "ichoreoeventcallback.h"
-#include "tier1/utlbuffer.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-int CChoreoEvent::s_nGlobalID = 1;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *owner -
-// *name -
-// percentage -
-//-----------------------------------------------------------------------------
-CEventRelativeTag::CEventRelativeTag( CChoreoEvent *owner, const char *name, float percentage )
-{
- Assert( owner );
- Assert( name );
- Assert( percentage >= 0.0f );
- Assert( percentage <= 1.0f );
-
- m_Name = name;
- m_flPercentage = percentage;
- m_pOwner = owner;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : src -
-//-----------------------------------------------------------------------------
-CEventRelativeTag::CEventRelativeTag( const CEventRelativeTag& src )
-{
- m_Name = src.m_Name;
- m_flPercentage = src.m_flPercentage;
- m_pOwner = src.m_pOwner;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CEventRelativeTag::GetName( void )
-{
- return m_Name.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CEventRelativeTag::GetPercentage( void )
-{
- return m_flPercentage;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void CEventRelativeTag::SetPercentage( float percentage )
-{
- m_flPercentage = percentage;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-CChoreoEvent *CEventRelativeTag::GetOwner( void )
-{
- return m_pOwner;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventRelativeTag::SetOwner( CChoreoEvent *event )
-{
- m_pOwner = event;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns the corrected time based on the owner's length and start time
-// Output : float
-//-----------------------------------------------------------------------------
-float CEventRelativeTag::GetStartTime( void )
-{
- Assert( m_pOwner );
- if ( !m_pOwner )
- {
- return 0.0f;
- }
-
- float ownerstart = m_pOwner->GetStartTime();
- float ownerduration = m_pOwner->GetDuration();
-
- return ( ownerstart + ownerduration * m_flPercentage );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *owner -
-// *name -
-// percentage -
-//-----------------------------------------------------------------------------
-CFlexTimingTag::CFlexTimingTag( CChoreoEvent *owner, const char *name, float percentage, bool locked )
-: BaseClass( owner, name, percentage )
-{
- m_bLocked = locked;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : src -
-//-----------------------------------------------------------------------------
-CFlexTimingTag::CFlexTimingTag( const CFlexTimingTag& src )
-: BaseClass( src )
-{
- m_bLocked = src.m_bLocked;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CFlexTimingTag::GetLocked( void )
-{
- return m_bLocked;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : locked -
-//-----------------------------------------------------------------------------
-void CFlexTimingTag::SetLocked( bool locked )
-{
- m_bLocked = locked;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *owner -
-// *name -
-// percentage -
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag::CEventAbsoluteTag( CChoreoEvent *owner, const char *name, float t )
-{
- Assert( owner );
- Assert( name );
- Assert( t >= 0.0f );
-
- m_Name = name;
- m_flPercentage = t;
- m_pOwner = owner;
- m_bLocked = false;
- m_bLinear = false;
- m_bEntry = false;
- m_bExit = false;
-
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : src -
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag::CEventAbsoluteTag( const CEventAbsoluteTag& src )
-{
- m_Name = src.m_Name;
- m_flPercentage = src.m_flPercentage;
- m_pOwner = src.m_pOwner;
- m_bLocked = src.m_bLocked;
- m_bLinear = src.m_bLinear;
- m_bEntry = src.m_bEntry;
- m_bExit = src.m_bExit;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CEventAbsoluteTag::GetName( void )
-{
- return m_Name.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CEventAbsoluteTag::GetPercentage( void )
-{
- return m_flPercentage;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetPercentage( float percentage )
-{
- m_flPercentage = percentage;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CEventAbsoluteTag::GetEventTime( void )
-{
- Assert( m_pOwner );
- if ( !m_pOwner )
- {
- return 0.0f;
- }
-
- float ownerduration = m_pOwner->GetDuration();
-
- return (m_flPercentage * ownerduration);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetEventTime( float t )
-{
- Assert( m_pOwner );
- if ( !m_pOwner )
- {
- return;
- }
-
- float ownerduration = m_pOwner->GetDuration();
-
- m_flPercentage = (t / ownerduration);
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CEventAbsoluteTag::GetAbsoluteTime( void )
-{
- Assert( m_pOwner );
- if ( !m_pOwner )
- {
- return 0.0f;
- }
-
- float ownerstart = m_pOwner->GetStartTime();
- float ownerduration = m_pOwner->GetDuration();
-
- return (ownerstart + m_flPercentage * ownerduration);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : percentage -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetAbsoluteTime( float t )
-{
- Assert( m_pOwner );
- if ( !m_pOwner )
- {
- return;
- }
-
- float ownerstart = m_pOwner->GetStartTime();
- float ownerduration = m_pOwner->GetDuration();
-
- m_flPercentage = (t - ownerstart) / ownerduration;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-CChoreoEvent *CEventAbsoluteTag::GetOwner( void )
-{
- return m_pOwner;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetOwner( CChoreoEvent *event )
-{
- m_pOwner = event;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetLocked( bool bLocked )
-{
- m_bLocked = bLocked;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-bool CEventAbsoluteTag::GetLocked( void )
-{
- return m_bLocked;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetLinear( bool bLinear )
-{
- m_bLinear = bLinear;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-bool CEventAbsoluteTag::GetLinear( void )
-{
- return m_bLinear;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetEntry( bool bEntry )
-{
- m_bEntry = bEntry;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-bool CEventAbsoluteTag::GetEntry( void )
-{
- return m_bEntry;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CEventAbsoluteTag::SetExit( bool bExit )
-{
- m_bExit = bExit;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-bool CEventAbsoluteTag::GetExit( void )
-{
- return m_bExit;
-}
-
-
-
-
-// FLEX ANIMATIONS
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-// Input : *event -
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack::CFlexAnimationTrack( CChoreoEvent *event )
-{
- m_pEvent = event;
- m_pControllerName = NULL;
- m_bActive = false;
- m_bCombo = false;
- m_bServerSide = false;
- m_nFlexControllerIndex[ 0 ] = m_nFlexControllerIndex[ 1 ] = -1;
- m_nFlexControllerIndexRaw[ 0 ] = m_nFlexControllerIndexRaw[ 1 ] = LocalFlexController_t(-1);
-
- // base track has range, combo is always 0..1
- m_flMin = 0.0f;
- m_flMax = 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : src -
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack::CFlexAnimationTrack( const CFlexAnimationTrack* src )
-{
- m_pControllerName = NULL;
- SetFlexControllerName( src->m_pControllerName ? src->m_pControllerName : "" );
-
- m_bActive = src->m_bActive;
- m_bCombo = src->m_bCombo;
- m_bServerSide = src->m_bServerSide;
-
- for ( int t = 0; t < 2; t++ )
- {
- m_Samples[ t ].Purge();
- for ( int i = 0 ;i < src->m_Samples[ t ].Size(); i++ )
- {
- CExpressionSample s = src->m_Samples[ t ][ i ];
- m_Samples[ t ].AddToTail( s );
- }
- }
-
- for ( int side = 0; side < 2; side++ )
- {
- m_nFlexControllerIndex[ side ] = src->m_nFlexControllerIndex[ side ];
- m_nFlexControllerIndexRaw[ side ] = src->m_nFlexControllerIndexRaw[ side ];
- }
-
- m_flMin = src->m_flMin;
- m_flMax = src->m_flMax;
-
- m_EdgeInfo[ 0 ] = src->m_EdgeInfo[ 0 ];
- m_EdgeInfo[ 1 ] = src->m_EdgeInfo[ 1 ];
-
- m_pEvent = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack::~CFlexAnimationTrack( void )
-{
- delete[] m_pControllerName;
-
- for ( int t = 0; t < 2; t++ )
- {
- m_Samples[ t ].Purge();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *event -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetEvent( CChoreoEvent *event )
-{
- m_pEvent = event;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::Clear( void )
-{
- for ( int t = 0; t < 2; t++ )
- {
- m_Samples[ t ].RemoveAll();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::RemoveSample( int index, int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- m_Samples[ type ].Remove( index );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *name -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetFlexControllerName( const char *name )
-{
- delete[] m_pControllerName;
- int len = Q_strlen( name ) + 1;
- m_pControllerName = new char[ len ];
- Q_strncpy( m_pControllerName, name, len );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : char const
-//-----------------------------------------------------------------------------
-const char *CFlexAnimationTrack::GetFlexControllerName( void )
-{
- return m_pControllerName ? m_pControllerName : "";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CFlexAnimationTrack::GetNumSamples( int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- return m_Samples[ type ].Size();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-// Output : CExpressionSample
-//-----------------------------------------------------------------------------
-CExpressionSample *CFlexAnimationTrack::GetSample( int index, int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- if ( index < 0 || index >= GetNumSamples( type ) )
- return NULL;
- return &m_Samples[ type ][ index ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CFlexAnimationTrack::IsTrackActive( void )
-{
- return m_bActive;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : active -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetTrackActive( bool active )
-{
- m_bActive = active;
-}
-
-void CFlexAnimationTrack::SetEdgeInfo( bool leftEdge, int curveType, float zero )
-{
- int idx = leftEdge ? 0 : 1;
- m_EdgeInfo[ idx ].m_CurveType = curveType;
- m_EdgeInfo[ idx ].m_flZeroPos = zero;
-}
-
-void CFlexAnimationTrack::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
-{
- int idx = leftEdge ? 0 : 1;
- curveType = m_EdgeInfo[ idx ].m_CurveType;
- zero = m_EdgeInfo[ idx ].m_flZeroPos;
-}
-
-void CFlexAnimationTrack::SetEdgeActive( bool leftEdge, bool state )
-{
- int idx = leftEdge ? 0 : 1;
- m_EdgeInfo[ idx ].m_bActive = state;
-}
-
-bool CFlexAnimationTrack::IsEdgeActive( bool leftEdge ) const
-{
- int idx = leftEdge ? 0 : 1;
- return m_EdgeInfo[ idx ].m_bActive;
-}
-
-int CFlexAnimationTrack::GetEdgeCurveType( bool leftEdge ) const
-{
- if ( !IsEdgeActive( leftEdge ) )
- {
- return CURVE_DEFAULT;
- }
-
- int idx = leftEdge ? 0 : 1;
- return m_EdgeInfo[ idx ].m_CurveType;
-}
-
-float CFlexAnimationTrack::GetEdgeZeroValue( bool leftEdge ) const
-{
- if ( !IsEdgeActive( leftEdge ) )
- {
- return 0.0f;
- }
-
- int idx = leftEdge ? 0 : 1;
- return m_EdgeInfo[ idx ].m_flZeroPos;
-}
-
-float CFlexAnimationTrack::GetDefaultEdgeZeroPos() const
-{
- float zero = 0.0f;
- if ( m_flMin != m_flMax )
- {
- zero = ( 0.0f - m_flMin ) / ( m_flMax - m_flMin );
- }
- return zero;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetZeroValue( int type, bool leftSide )
-{
- // Stereo track is always clamped to 0.5 and doesn't care about l/r settings
- if ( type == 1 )
- {
- return 0.5f;
- }
-
- if ( IsEdgeActive( leftSide ) )
- {
- return GetEdgeZeroValue( leftSide );
- }
-
- return GetDefaultEdgeZeroPos();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : number -
-// Output : CExpressionSample
-//-----------------------------------------------------------------------------
-CExpressionSample *CFlexAnimationTrack::GetBoundedSample( int number, bool& bClamped, int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- if ( number < 0 )
- {
- // Search for two samples which span time f
- static CExpressionSample nullstart;
- nullstart.time = 0.0f;
- nullstart.value = GetZeroValue( type, true );
- if ( type == 0 )
- {
- nullstart.SetCurveType( GetEdgeCurveType( true ) );
- }
- else
- {
- nullstart.SetCurveType( CURVE_DEFAULT );
- }
- bClamped = true;
- return &nullstart;
- }
- else if ( number >= GetNumSamples( type ) )
- {
- static CExpressionSample nullend;
- nullend.time = m_pEvent->GetDuration();
- nullend.value = GetZeroValue( type, false );
- if ( type == 0 )
- {
- nullend.SetCurveType( GetEdgeCurveType( false ) );
- }
- else
- {
- nullend.SetCurveType( CURVE_DEFAULT );
- }
- bClamped = true;
- return &nullend;
- }
-
- bClamped = false;
- return GetSample( number, type );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// type -
-// Output : float
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetIntensityInternal( float time, int type )
-{
- Assert( type == 0 || type == 1 );
-
- float retval = 0.0f;
-
- // find samples that span the time
- if ( !m_pEvent || !m_pEvent->HasEndTime() || time < m_pEvent->GetStartTime() )
- {
- retval = GetZeroValue( type, true );;
- }
- else if ( time > m_pEvent->GetEndTime() )
- {
- retval = GetZeroValue( type, false );;
- }
- else
- {
- float elapsed = time - m_pEvent->GetStartTime();
- retval = GetFracIntensity( elapsed, type );
- }
-
- // scale
- if (type == 0 && m_flMin != m_flMax)
- {
- retval = retval * (m_flMax - m_flMin) + m_flMin;
- }
- return retval;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// type -
-// Output : float
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetFracIntensity( float time, int type )
-{
- float zeroValueLeft = GetZeroValue( type, true );
-
- Assert( type == 0 || type == 1 );
-
- // find samples that span the time
- if ( !m_pEvent || !m_pEvent->HasEndTime() )
- return zeroValueLeft;
-
- int rampCount = GetNumSamples( type );
- if ( rampCount < 1 )
- {
- return zeroValueLeft;
- }
-
- CExpressionSample *esStart = NULL;
- CExpressionSample *esEnd = NULL;
-
- // do binary search for sample in time period
- int j = MAX( rampCount / 2, 1 );
- int i = j;
- while ( i > -2 && i < rampCount + 1 )
- {
- bool dummy;
- esStart = GetBoundedSample( i, dummy, type );
- esEnd = GetBoundedSample( i + 1, dummy, type );
-
- j = MAX( j / 2, 1 );
- if ( time < esStart->time)
- {
- i -= j;
- }
- else if ( time > esEnd->time)
- {
- i += j;
- }
- else
- {
- if ( time == esEnd->time )
- {
- ++i;
- esStart = GetBoundedSample( i, dummy, type );
- esEnd = GetBoundedSample( i + 1, dummy, type );
- }
- break;
- }
- }
-
- if (!esStart)
- {
- return zeroValueLeft;
- }
-
- int prev = i - 1;
- int next = i + 2;
-
- prev = MAX( -1, prev );
- next = MIN( next, rampCount );
-
- bool bclamp[ 2 ];
- CExpressionSample *esPre = GetBoundedSample( prev, bclamp[ 0 ], type );
- CExpressionSample *esNext = GetBoundedSample( next, bclamp[ 1 ], type );
-
- float dt = esEnd->time - esStart->time;
-
- Vector vPre( esPre->time, esPre->value, 0 );
- Vector vStart( esStart->time, esStart->value, 0 );
- Vector vEnd( esEnd->time, esEnd->value, 0 );
- Vector vNext( esNext->time, esNext->value, 0 );
-
- float f2 = 0.0f;
- if ( dt > 0.0f )
- {
- f2 = ( time - esStart->time ) / ( dt );
- }
- f2 = clamp( f2, 0.0f, 1.0f );
-
- Vector vOut;
- int dummy;
- int earlypart, laterpart;
-
- // Not holding out value of previous curve...
- Interpolator_CurveInterpolatorsForType( esStart->GetCurveType(), dummy, earlypart );
- Interpolator_CurveInterpolatorsForType( esEnd->GetCurveType(), laterpart, dummy );
-
- if ( earlypart == INTERPOLATE_HOLD )
- {
- // Hold "out" of previous sample (can cause a discontinuity)
- VectorLerp( vStart, vEnd, f2, vOut );
- vOut.y = vStart.y;
- }
- else if ( laterpart == INTERPOLATE_HOLD )
- {
- // Hold "out" of previous sample (can cause a discontinuity)
- VectorLerp( vStart, vEnd, f2, vOut );
- vOut.y = vEnd.y;
- }
- else
- {
- bool sameCurveType = earlypart == laterpart ? true : false;
- if ( sameCurveType )
- {
- Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
- }
- else // curves differ, sigh
- {
- Vector vOut1, vOut2;
-
- Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
- Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
-
- VectorLerp( vOut1, vOut2, f2, vOut );
- }
- }
-
- float retval = clamp( vOut.y, 0.0f, 1.0f );
- return retval;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// Output : float
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetSampleIntensity( float time )
-{
- return GetIntensityInternal( time, 0 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// Output : float
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetBalanceIntensity( float time )
-{
- if ( IsComboType() )
- {
- return GetIntensityInternal( time, 1 );
- }
-
- return 1.0f;
-}
-
-// For a given time, computes 0->1 intensity value for the slider
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// Output : float
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetIntensity( float time, int side )
-{
- float mag = GetSampleIntensity( time );
-
- float scale = 1.0f;
-
- if ( IsComboType() )
- {
- float balance = GetBalanceIntensity( time );
-
- // Asking for left but balance is to right, then fall off as we go
- // further right
- if ( side == 0 && balance > 0.5f )
- {
- scale = (1.0f - balance ) / 0.5f;
- }
- // Asking for right, but balance is left, fall off as we go left.
- else if ( side == 1 && balance < 0.5f )
- {
- scale = ( balance / 0.5f );
- }
- }
-
- return mag * scale;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : time -
-// value -
-//-----------------------------------------------------------------------------
-CExpressionSample *CFlexAnimationTrack::AddSample( float time, float value, int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- CExpressionSample sample;
- sample.time = time;
- sample.value = value;
- sample.selected = false;
-
- int idx = m_Samples[ type ].AddToTail( sample );
-
- // Resort( type );
- return &m_Samples[ type ][ idx ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::Resort( int type /*=0*/ )
-{
- Assert( type == 0 || type == 1 );
-
- for ( int i = 0; i < m_Samples[ type ].Size(); i++ )
- {
- for ( int j = i + 1; j < m_Samples[ type ].Size(); j++ )
- {
- CExpressionSample src = m_Samples[ type ][ i ];
- CExpressionSample dest = m_Samples[ type ][ j ];
-
- if ( src.time > dest.time )
- {
- m_Samples[ type ][ i ] = dest;
- m_Samples[ type ][ j ] = src;
- }
- }
- }
-
- // Make sure nothing is out of range
- RemoveOutOfRangeSamples( 0 );
- RemoveOutOfRangeSamples( 1 );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoEvent
-//-----------------------------------------------------------------------------
-CChoreoEvent *CFlexAnimationTrack::GetEvent( void )
-{
- return m_pEvent;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : side -
-// Output : int
-//-----------------------------------------------------------------------------
-int CFlexAnimationTrack::GetFlexControllerIndex( int side /*= 0*/ )
-{
- Assert( side == 0 || side == 1 );
-
- if ( IsComboType() )
- {
- return m_nFlexControllerIndex[ side ];
- }
-
- return m_nFlexControllerIndex[ 0 ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : side -
-// Output : int
-//-----------------------------------------------------------------------------
-LocalFlexController_t CFlexAnimationTrack::GetRawFlexControllerIndex( int side /*= 0*/ )
-{
- Assert( side == 0 || side == 1 );
-
- if ( IsComboType() )
- {
- return m_nFlexControllerIndexRaw[ side ];
- }
-
- return m_nFlexControllerIndexRaw[ 0 ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-// side -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetFlexControllerIndex( LocalFlexController_t raw, int index, int side /*= 0*/ )
-{
- Assert( side == 0 || side == 1 );
-
- m_nFlexControllerIndex[ side ] = index;
- // Model specific
- m_nFlexControllerIndexRaw[ side ] = raw;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : combo -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetComboType( bool combo )
-{
- m_bCombo = combo;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CFlexAnimationTrack::IsComboType( void )
-{
- return m_bCombo;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: True if this should be simulated on the server side always
-// Input : state -
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetServerSide( bool state )
-{
- m_bServerSide = state;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CFlexAnimationTrack::IsServerSide() const
-{
- return m_bServerSide;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetMin( float value )
-{
- m_flMin = value;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetMax( float value )
-{
- m_flMax = value;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetMin( int type )
-{
- if (type == 0)
- return m_flMin;
- else
- return 0.0f;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-float CFlexAnimationTrack::GetMax( int type )
-{
- if (type == 0)
- return m_flMax;
- else
- return 1.0f;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-bool CFlexAnimationTrack::IsInverted( void )
-{
- if (m_bInverted)
- return true;
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::SetInverted( bool isInverted )
-{
- m_bInverted = isInverted;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-void CFlexAnimationTrack::RemoveOutOfRangeSamples( int type )
-{
- Assert( m_pEvent );
- if ( !m_pEvent )
- return;
-
- Assert( m_pEvent->HasEndTime() );
- float duration = m_pEvent->GetDuration();
-
- int c = m_Samples[ type ].Size();
- for ( int i = c-1; i >= 0; i-- )
- {
- CExpressionSample src = m_Samples[ type ][ i ];
- if ( src.time < 0 ||
- src.time > duration )
- {
- m_Samples[ type ].Remove( i );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CChoreoEvent::CChoreoEvent( CChoreoScene *scene )
-{
- Init( scene );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *name -
-//-----------------------------------------------------------------------------
-CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name )
-{
- Init( scene );
- SetType( type );
- SetName( name );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *name -
-// *param -
-//-----------------------------------------------------------------------------
-CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name, const char *param )
-{
- Init( scene );
- SetType( type );
- SetName( name );
- SetParameters( param );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-CChoreoEvent::~CChoreoEvent( void )
-{
- RemoveAllTracks();
- ClearEventDependencies();
- delete m_pSubScene;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Assignment
-// Input : src -
-// Output : CChoreoEvent&
-//-----------------------------------------------------------------------------
-CChoreoEvent& CChoreoEvent::operator=( const CChoreoEvent& src )
-{
- MEM_ALLOC_CREDIT();
-
- // Copy global id when copying entity
- m_nGlobalID = src.m_nGlobalID;
-
- m_pActor = NULL;
- m_pChannel = NULL;
-
- m_nDefaultCurveType = src.m_nDefaultCurveType;
- m_fType = src.m_fType;
- m_Name = src.m_Name;
- m_Parameters = src.m_Parameters;
- m_Parameters2= src.m_Parameters2;
- m_Parameters3= src.m_Parameters3;
- m_flStartTime = src.m_flStartTime;
- m_flEndTime = src.m_flEndTime;
-
- m_bFixedLength = src.m_bFixedLength;
- m_flGestureSequenceDuration = src.m_flGestureSequenceDuration;
- m_bResumeCondition = src.m_bResumeCondition;
- m_bLockBodyFacing = src.m_bLockBodyFacing;
- m_flDistanceToTarget = src.m_flDistanceToTarget;
- m_bForceShortMovement = src.m_bForceShortMovement;
- m_bSyncToFollowingGesture = src.m_bSyncToFollowingGesture;
- m_bPlayOverScript = src.m_bPlayOverScript;
- m_bUsesTag = src.m_bUsesTag;
- m_TagName = src.m_TagName;
- m_TagWavName = src.m_TagWavName;
-
- ClearAllRelativeTags();
- ClearAllTimingTags();
- int t;
- for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
- {
- ClearAllAbsoluteTags( (AbsTagType)t );
- }
-
- int i;
- for ( i = 0; i < src.m_RelativeTags.Size(); i++ )
- {
- CEventRelativeTag newtag( src.m_RelativeTags[ i ] );
- newtag.SetOwner( this );
- m_RelativeTags.AddToTail( newtag );
- }
-
- for ( i = 0; i < src.m_TimingTags.Size(); i++ )
- {
- CFlexTimingTag newtag( src.m_TimingTags[ i ] );
- newtag.SetOwner( this );
- m_TimingTags.AddToTail( newtag );
- }
- for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
- {
- for ( i = 0; i < src.m_AbsoluteTags[ t ].Size(); i++ )
- {
- CEventAbsoluteTag newtag( src.m_AbsoluteTags[ t ][ i ] );
- newtag.SetOwner( this );
- m_AbsoluteTags[ t ].AddToTail( newtag );
- }
- }
-
- RemoveAllTracks();
-
- for ( i = 0 ; i < src.m_FlexAnimationTracks.Size(); i++ )
- {
- CFlexAnimationTrack *newtrack = new CFlexAnimationTrack( src.m_FlexAnimationTracks[ i ] );
- newtrack->SetEvent( this );
- m_FlexAnimationTracks.AddToTail( newtrack );
- }
-
- m_bTrackLookupSet = src.m_bTrackLookupSet;
-
- // FIXME: Use a safe handle?
- //m_pSubScene = src.m_pSubScene;
-
- m_bProcessing = src.m_bProcessing;
- m_pMixer = src.m_pMixer;
-
- m_pScene = src.m_pScene;
-
- m_nPitch = src.m_nPitch;
- m_nYaw = src.m_nYaw;
-
- m_nNumLoops = src.m_nNumLoops;
- m_nLoopsRemaining = src.m_nLoopsRemaining;
-
- // Copy ramp over
- m_Ramp = src.m_Ramp;
-
- m_ccType = src.m_ccType;
- m_CCToken = src.m_CCToken;
- m_bUsingCombinedSoundFile = src.m_bUsingCombinedSoundFile;
- m_uRequiredCombinedChecksum = src.m_uRequiredCombinedChecksum;
- m_nNumSlaves = src.m_nNumSlaves;
- m_flLastSlaveEndTime = src.m_flLastSlaveEndTime;
- m_bCCTokenValid = src.m_bCCTokenValid;
- m_bCombinedUsingGenderToken = src.m_bCombinedUsingGenderToken;
-
- m_bSuppressCaptionAttenuation = src.m_bSuppressCaptionAttenuation;
-
- m_bActive = src.m_bActive;
-
- return *this;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::Init( CChoreoScene *scene )
-{
- m_nGlobalID = s_nGlobalID++;
- m_nDefaultCurveType = CURVE_CATMULL_ROM_TO_CATMULL_ROM;
- m_fType = UNSPECIFIED;
- m_Name.Set("");
- m_Parameters.Set("");
- m_Parameters2.Set("");
- m_Parameters3.Set("");
-
- m_flStartTime = 0.0f;
- m_flEndTime = -1.0f;
-
- m_pActor = NULL;
- m_pChannel = NULL;
- m_pScene = scene;
-
- m_bFixedLength = false;
- m_bResumeCondition = false;
- SetUsingRelativeTag( false, 0, 0 );
-
- m_bTrackLookupSet = false;
-
- m_bLockBodyFacing = false;
- m_flDistanceToTarget = 0.0f;
- m_bForceShortMovement = false;
- m_bSyncToFollowingGesture = false;
- m_bPlayOverScript = false;
-
- m_pSubScene = NULL;
- m_bProcessing = false;
- m_pMixer = NULL;
- m_flGestureSequenceDuration = 0.0f;
-
- m_nPitch = m_nYaw = 0;
-
- m_nNumLoops = -1;
- m_nLoopsRemaining = 0;
-
- // Close captioning/localization support
- m_CCToken.Set("");
- m_ccType = CC_MASTER;
- m_bUsingCombinedSoundFile = false;
- m_uRequiredCombinedChecksum = 0;
- m_nNumSlaves = 0;
- m_flLastSlaveEndTime = 0.0f;
- m_bCCTokenValid = false;
- m_bCombinedUsingGenderToken = false;
- m_bSuppressCaptionAttenuation = false;
- m_bActive = true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-CChoreoEvent::EVENTTYPE CChoreoEvent::GetType( void )
-{
- return (EVENTTYPE)m_fType;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetType( EVENTTYPE type )
-{
- m_fType = type;
-
- if ( m_fType == SPEAK ||
- m_fType == SUBSCENE )
- {
- m_bFixedLength = true;
- }
- else
- {
- m_bFixedLength = false;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *name -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetName( const char *name )
-{
- m_Name = name;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetName( void )
-{
- return m_Name.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *param -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetParameters( const char *param )
-{
- m_Parameters = param;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetParameters( void )
-{
- return m_Parameters.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *param -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetParameters2( const char *param )
-{
- int iLength = Q_strlen( param );
- m_Parameters2 = param;
-
- // HACK: Remove trailing " " until faceposer is fixed
- if ( iLength > 0 )
- {
- if ( param[iLength-1] == ' ' )
- {
- char tmp[1024];
- Q_strncpy( tmp, param, sizeof(tmp) );
- tmp[iLength-1] = 0;
- m_Parameters2.Set(tmp);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetParameters2( void )
-{
- return m_Parameters2.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *param -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetParameters3( const char *param )
-{
- int iLength = Q_strlen( param );
- m_Parameters3 = param;
-
- // HACK: Remove trailing " " until faceposer is fixed
- if ( iLength > 0 )
- {
- if ( param[iLength-1] == ' ' )
- {
- char tmp[1024];
- Q_strncpy( tmp, param, sizeof(tmp) );
- tmp[iLength-1] = 0;
- m_Parameters3.Set(tmp);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetParameters3( void )
-{
- return m_Parameters3.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: debugging description
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetDescription( void )
-{
- static char description[ 256 ];
-
- description[ 0 ] = 0;
-
- if ( !GetActor() )
- {
- Q_snprintf( description,sizeof(description), "global %s", m_Name.Get() );
- }
- else
- {
- Assert( m_pChannel );
- Q_snprintf( description,sizeof(description), "%s : %s : %s -- %s \"%s\"", m_pActor->GetName(), m_pChannel->GetName(), GetName(), NameForType( GetType() ), GetParameters() );
- if ( GetType() == EXPRESSION )
- {
- char sz[ 256 ];
-
- Q_snprintf( sz,sizeof(sz), " \"%s\"", GetParameters2() );
- Q_strncat( description, sz, sizeof(description), COPY_ALL_CHARACTERS );
- }
- }
-
- return description;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : starttime -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetStartTime( float starttime )
-{
- m_flStartTime = starttime;
- if ( m_flEndTime != -1.0f )
- {
- if ( m_flEndTime < m_flStartTime )
- {
- m_flEndTime = m_flStartTime;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetStartTime( )
-{
- return m_flStartTime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : endtime -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetEndTime( float endtime )
-{
- bool changed = m_flEndTime != endtime;
-
- m_flEndTime = endtime;
-
- if ( endtime != -1.0f )
- {
- if ( m_flEndTime < m_flStartTime )
- {
- m_flEndTime = m_flStartTime;
- }
-
- if ( changed )
- {
- OnEndTimeChanged();
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetEndTime( )
-{
- return m_flEndTime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::HasEndTime( void )
-{
- return m_flEndTime != -1.0f ? true : false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetCompletion( float time )
-{
- float t = (time - GetStartTime()) / (GetEndTime() - GetStartTime());
-
- if (t < 0.0f)
- return 0.0f;
- else if (t > 1.0f)
- return 1.0f;
-
- return t;
-}
-
-// ICurveDataAccessor method
-bool CChoreoEvent::CurveHasEndTime()
-{
- return HasEndTime();
-}
-
-//-----------------------------------------------------------------------------
-// Default curve type
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetDefaultCurveType( int nCurveType )
-{
- m_nDefaultCurveType = nCurveType;
-}
-
-int CChoreoEvent::GetDefaultCurveType()
-{
- return m_nDefaultCurveType;
-}
-
-float CCurveData::GetIntensity( ICurveDataAccessor *data, float time )
-{
- float zeroValue = 0.0f;
-
- // find samples that span the time
- if ( !data->CurveHasEndTime() )
- {
- return zeroValue;
- }
-
- int rampCount = GetCount();
- if ( rampCount < 1 )
- {
- // Full intensity
- return 1.0f;
- }
-
- CExpressionSample *esStart = NULL;
- CExpressionSample *esEnd = NULL;
-
- // do binary search for sample in time period
- int j = MAX( rampCount / 2, 1 );
- int i = j;
- while ( i > -2 && i < rampCount + 1 )
- {
- bool dummy;
- esStart = GetBoundedSample( data, i, dummy );
- esEnd = GetBoundedSample( data, i + 1, dummy );
-
- j = MAX( j / 2, 1 );
- if ( time < esStart->time)
- {
- i -= j;
- }
- else if ( time > esEnd->time)
- {
- i += j;
- }
- else
- {
- break;
- }
- }
-
- if (!esStart)
- {
- return 1.0f;
- }
-
- int prev = i - 1;
- int next = i + 2;
-
- prev = MAX( -1, prev );
- next = MIN( next, rampCount );
-
- bool bclamp[ 2 ];
- CExpressionSample *esPre = GetBoundedSample( data, prev, bclamp[ 0 ] );
- CExpressionSample *esNext = GetBoundedSample( data, next, bclamp[ 1 ] );
-
- float dt = esEnd->time - esStart->time;
-
- Vector vPre( esPre->time, esPre->value, 0 );
- Vector vStart( esStart->time, esStart->value, 0 );
- Vector vEnd( esEnd->time, esEnd->value, 0 );
- Vector vNext( esNext->time, esNext->value, 0 );
-
- if ( bclamp[ 0 ] )
- {
- vPre.x = vStart.x;
- }
-
- if ( bclamp[ 1 ] )
- {
- vNext.x = vEnd.x;
- }
-
- float f2 = 0.0f;
- if ( dt > 0.0f )
- {
- f2 = ( time - esStart->time ) / ( dt );
- }
- f2 = clamp( f2, 0.0f, 1.0f );
-
- Vector vOut;
- int dummy;
- int earlypart, laterpart;
-
- int startCurve = esStart->GetCurveType();
- int endCurve = esEnd->GetCurveType();
-
- if ( startCurve == CURVE_DEFAULT )
- {
- startCurve = data->GetDefaultCurveType();
- }
- if ( endCurve == CURVE_DEFAULT )
- {
- endCurve = data->GetDefaultCurveType();
- }
-
- // Not holding out value of previous curve...
- Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
- Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
-
- if ( earlypart == INTERPOLATE_HOLD )
- {
- // Hold "out" of previous sample (can cause a discontinuity)
- VectorLerp( vStart, vEnd, f2, vOut );
- vOut.y = vStart.y;
- }
- else if ( laterpart == INTERPOLATE_HOLD )
- {
- // Hold "out" of previous sample (can cause a discontinuity)
- VectorLerp( vStart, vEnd, f2, vOut );
- vOut.y = vEnd.y;
- }
- else
- {
- bool sameCurveType = earlypart == laterpart ? true : false;
- if ( sameCurveType )
- {
- Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
- }
- else // curves differ, sigh
- {
- Vector vOut1, vOut2;
-
- Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
- Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
-
- VectorLerp( vOut1, vOut2, f2, vOut );
- }
- }
-
- float retval = clamp( vOut.y, 0.0f, 1.0f );
- return retval;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Get intensity for event, bounded by scene global intensity
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetIntensity( float scenetime )
-{
- float global_intensity = 1.0f;
- if ( m_pScene )
- {
- global_intensity = m_pScene->GetSceneRampIntensity( scenetime );
- }
- else
- {
- Assert( 0 );
- }
-
- float event_intensity = _GetIntensity( scenetime );
-
- return global_intensity * event_intensity;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::_GetIntensity( float scenetime )
-{
- // Convert to event local time
- float time = scenetime - GetStartTime();
- return m_Ramp.GetIntensity( this, time );
-}
-
-
-float CChoreoEvent::GetIntensityArea( float scenetime )
-{
- // Convert to event local time
- float time = scenetime - GetStartTime();
- return m_Ramp.GetIntensityArea( this, time );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CCurveData::GetIntensityArea( ICurveDataAccessor *data, float time )
-{
- float zeroValue = 0.0f;
-
- // find samples that span the time
- if ( !data->CurveHasEndTime() )
- {
- return zeroValue;
- }
-
- int rampCount = GetCount();
- if ( rampCount < 1 )
- {
- // Full intensity
- return 1.0f;
- }
-
- CExpressionSample *esStart = NULL;
- CExpressionSample *esEnd = NULL;
-
- // do binary search for sample in time period
- int j = MAX( rampCount / 2, 1 );
- int i = j;
- while ( i > -2 && i < rampCount + 1 )
- {
- bool dummy;
- esStart = GetBoundedSample( data, i, dummy );
- esEnd = GetBoundedSample( data, i + 1, dummy );
-
- j = MAX( j / 2, 1 );
- if ( time < esStart->time)
- {
- i -= j;
- }
- else if ( time > esEnd->time)
- {
- i += j;
- }
- else
- {
- break;
- }
- }
-
- UpdateIntensityArea( data );
-
- float flTotal = 0.0f;
- flTotal = m_RampAccumulator[i+1];
-
- int prev = i - 1;
- int next = i + 2;
-
- prev = MAX( -1, prev );
- next = MIN( next, rampCount );
-
- bool bclamp[ 2 ];
- CExpressionSample *esPre = GetBoundedSample( data, prev, bclamp[ 0 ] );
- CExpressionSample *esNext = GetBoundedSample( data, next, bclamp[ 1 ] );
-
- float dt = esEnd->time - esStart->time;
-
- Vector vPre( esPre->time, esPre->value, 0 );
- Vector vStart( esStart->time, esStart->value, 0 );
- Vector vEnd( esEnd->time, esEnd->value, 0 );
- Vector vNext( esNext->time, esNext->value, 0 );
-
- if ( bclamp[ 0 ] )
- {
- vPre.x = vStart.x;
- }
-
- if ( bclamp[ 1 ] )
- {
- vNext.x = vEnd.x;
- }
-
- float f2 = 0.0f;
- if ( dt > 0.0f )
- {
- f2 = ( time - esStart->time ) / ( dt );
- }
- f2 = clamp( f2, 0.0f, 1.0f );
-
- Vector vOut;
- int dummy;
- int earlypart, laterpart;
-
- int startCurve = esStart->GetCurveType();
- int endCurve = esEnd->GetCurveType();
-
- if ( startCurve == CURVE_DEFAULT )
- {
- startCurve = data->GetDefaultCurveType();
- }
- if ( endCurve == CURVE_DEFAULT )
- {
- endCurve = data->GetDefaultCurveType();
- }
-
- // Not holding out value of previous curve...
- Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
- Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
-
- // FIXME: needs other curve types
- Catmull_Rom_Spline_Integral_Normalize(
- vPre,
- vStart,
- vEnd,
- vNext,
- f2,
- vOut );
-
- // Con_Printf( "Accum %f : Partial %f\n", flTotal, vOut.y * (vEnd.x - vStart.x) * f2 );
- flTotal = flTotal + clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
- return flTotal;
-}
-
-
-void CCurveData::UpdateIntensityArea( ICurveDataAccessor *data )
-{
- int rampCount = GetCount();;
- if ( rampCount < 1 )
- {
- return;
- }
-
- if (m_RampAccumulator.Count() == rampCount + 2)
- {
- return;
- }
-
- m_RampAccumulator.SetCount( rampCount + 2 );
-
- int i = -1;
-
- bool dummy;
- CExpressionSample *esPre = GetBoundedSample( data, i - 1, dummy );
- CExpressionSample *esStart = GetBoundedSample( data, i, dummy );
- CExpressionSample *esEnd = GetBoundedSample( data, MIN( i + 1, rampCount ), dummy );
-
- Vector vPre( esPre->time, esPre->value, 0 );
- Vector vStart( esStart->time, esStart->value, 0 );
- Vector vEnd( esEnd->time, esEnd->value, 0 );
-
- Vector vOut;
- for (i = -1; i < rampCount; i++)
- {
- CExpressionSample *esNext = GetBoundedSample( data, MIN( i + 2, rampCount ), dummy );
- Vector vNext( esNext->time, esNext->value, 0 );
-
- Catmull_Rom_Spline_Integral_Normalize(
- vPre,
- vStart,
- vEnd,
- vNext,
- 1.0f,
- vOut );
-
- m_RampAccumulator[i+1] = clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
-
- vPre = vStart;
- vStart = vEnd;
- vEnd = vNext;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : dt -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::OffsetStartTime( float dt )
-{
- SetStartTime( GetStartTime() + dt );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : dt -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::OffsetEndTime( float dt )
-{
- if ( HasEndTime() )
- {
- SetEndTime( GetEndTime() + dt );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : dt -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::OffsetTime( float dt )
-{
- if ( HasEndTime() )
- {
- m_flEndTime += dt;
- }
- m_flStartTime += dt;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *actor -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetActor( CChoreoActor *actor )
-{
- m_pActor = actor;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoActor
-//-----------------------------------------------------------------------------
-CChoreoActor *CChoreoEvent::GetActor( void )
-{
- return m_pActor;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *channel -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetChannel( CChoreoChannel *channel )
-{
- m_pChannel = channel;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoChannel
-//-----------------------------------------------------------------------------
-CChoreoChannel *CChoreoEvent::GetChannel( void )
-{
- return m_pChannel;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *scene -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetSubScene( CChoreoScene *scene )
-{
- m_pSubScene = scene;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoScene
-//-----------------------------------------------------------------------------
-CChoreoScene *CChoreoEvent::GetSubScene( void )
-{
- return m_pSubScene;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-struct EventNameMap_t
-{
- CChoreoEvent::EVENTTYPE type;
- char const *name;
-};
-
-static EventNameMap_t g_NameMap[] =
-{
- { CChoreoEvent::UNSPECIFIED, "unspecified" }, // error condition!!!
- { CChoreoEvent::SECTION, "section" },
- { CChoreoEvent::EXPRESSION, "expression" },
- { CChoreoEvent::LOOKAT, "lookat" },
- { CChoreoEvent::MOVETO, "moveto" },
- { CChoreoEvent::SPEAK, "speak" },
- { CChoreoEvent::GESTURE, "gesture" },
- { CChoreoEvent::SEQUENCE, "sequence" },
- { CChoreoEvent::FACE, "face" },
- { CChoreoEvent::FIRETRIGGER, "firetrigger" },
- { CChoreoEvent::FLEXANIMATION, "flexanimation" },
- { CChoreoEvent::SUBSCENE, "subscene" },
- { CChoreoEvent::LOOP, "loop" },
- { CChoreoEvent::INTERRUPT, "interrupt" },
- { CChoreoEvent::STOPPOINT, "stoppoint" },
- { CChoreoEvent::PERMIT_RESPONSES, "permitresponses" },
- { CChoreoEvent::GENERIC, "generic" },
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: A simple class to verify the names data above at runtime
-//-----------------------------------------------------------------------------
-class CCheckEventNames
-{
-public:
- CCheckEventNames()
- {
- if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES )
- {
- Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!",
- ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES );
- }
- for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i )
- {
- if ( !g_NameMap[ i ].name )
- {
- Error( "g_NameMap: Event type at %i has NULL name string!", i );
- }
-
- if ( (CChoreoEvent::EVENTTYPE)(i) == g_NameMap[ i ].type )
- continue;
-
- Error( "g_NameMap: Event type at %i has wrong value (%i)!",
- i, (int)g_NameMap[ i ].type );
- }
- }
-};
-static CCheckEventNames g_CheckNamesSingleton;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *name -
-// Output : int
-//-----------------------------------------------------------------------------
-CChoreoEvent::EVENTTYPE CChoreoEvent::TypeForName( const char *name )
-{
- for ( int i = 0; i < NUM_TYPES; ++i )
- {
- EventNameMap_t *slot = &g_NameMap[ i ];
- if ( !Q_stricmp( name, slot->name ) )
- return slot->type;
- }
-
- Assert( !"CChoreoEvent::TypeForName failed!!!" );
- return UNSPECIFIED;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::NameForType( EVENTTYPE type )
-{
- int i = (int)type;
- if ( i < 0 || i >= NUM_TYPES )
- {
- Assert( "!CChoreoEvent::NameForType: bogus type!" );
- // returns "unspecified!!!";
- return g_NameMap[ 0 ].name;
- }
-
- return g_NameMap[ i ].name;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-struct CCNameMap_t
-{
- CChoreoEvent::CLOSECAPTION type;
- char const *name;
-};
-
-static CCNameMap_t g_CCNameMap[] =
-{
- { CChoreoEvent::CC_MASTER, "cc_master" }, // error condition!!!
- { CChoreoEvent::CC_SLAVE, "cc_slave" },
- { CChoreoEvent::CC_DISABLED, "cc_disabled" },
-};
-
-//-----------------------------------------------------------------------------
-// Purpose: A simple class to verify the names data above at runtime
-//-----------------------------------------------------------------------------
-class CCheckCCNames
-{
-public:
- CCheckCCNames()
- {
- if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES )
- {
- Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!",
- ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES );
- }
- for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i )
- {
- if ( !g_CCNameMap[ i ].name )
- {
- Error( "g_NameMap: CC type at %i has NULL name string!", i );
- }
-
- if ( (CChoreoEvent::CLOSECAPTION)(i) == g_CCNameMap[ i ].type )
- continue;
-
- Error( "g_CCNameMap: Event type at %i has wrong value (%i)!",
- i, (int)g_CCNameMap[ i ].type );
- }
- }
-};
-static CCheckCCNames g_CheckCCNamesSingleton;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *name -
-// Output : CLOSECAPTION
-//-----------------------------------------------------------------------------
-CChoreoEvent::CLOSECAPTION CChoreoEvent::CCTypeForName( const char *name )
-{
- for ( int i = 0; i < NUM_CC_TYPES; ++i )
- {
- CCNameMap_t *slot = &g_CCNameMap[ i ];
- if ( !Q_stricmp( name, slot->name ) )
- return slot->type;
- }
-
- Assert( !"CChoreoEvent::TypeForName failed!!!" );
- return CC_MASTER;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::NameForCCType( CLOSECAPTION type )
-{
- int i = (int)type;
- if ( i < 0 || i >= NUM_CC_TYPES )
- {
- Assert( "!CChoreoEvent::NameForType: bogus type!" );
- // returns "unspecified!!!";
- return g_CCNameMap[ 0 ].name;
- }
-
- return g_CCNameMap[ i ].name;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Is the event something that can be sized ( a wave file, e.g. )
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::IsFixedLength( void )
-{
- return m_bFixedLength;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : isfixedlength -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetFixedLength( bool isfixedlength )
-{
- m_bFixedLength = isfixedlength;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : resumecondition -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetResumeCondition( bool resumecondition )
-{
- m_bResumeCondition = resumecondition;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::IsResumeCondition( void )
-{
- return m_bResumeCondition;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : lockbodyfacing -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetLockBodyFacing( bool lockbodyfacing )
-{
- m_bLockBodyFacing = lockbodyfacing;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::IsLockBodyFacing( void )
-{
- return m_bLockBodyFacing;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : distancetotarget -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetDistanceToTarget( float distancetotarget )
-{
- m_flDistanceToTarget = distancetotarget;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns ideal distance to target
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetDistanceToTarget( void )
-{
- return m_flDistanceToTarget;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : set if small (sub-1/2 bbox) movements are forced
-//-----------------------------------------------------------------------------
-
-void CChoreoEvent::SetForceShortMovement( bool bForceShortMovement )
-{
- m_bForceShortMovement = bForceShortMovement;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : get if small (sub-1/2 bbox) movements are forced
-//-----------------------------------------------------------------------------
-
-bool CChoreoEvent::GetForceShortMovement( void )
-{
- return m_bForceShortMovement;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : set if the gesture should sync its exit tag with the following gestures entry tag
-//-----------------------------------------------------------------------------
-
-void CChoreoEvent::SetSyncToFollowingGesture( bool bSyncToFollowingGesture )
-{
- m_bSyncToFollowingGesture = bSyncToFollowingGesture;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : get if the gesture should sync its exit tag with the following gestures entry tag
-//-----------------------------------------------------------------------------
-
-bool CChoreoEvent::GetSyncToFollowingGesture( void )
-{
- return m_bSyncToFollowingGesture;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : set if the sequence should player overtop of an underlying SS
-//-----------------------------------------------------------------------------
-
-void CChoreoEvent::SetPlayOverScript( bool bPlayOverScript )
-{
- m_bPlayOverScript = bPlayOverScript;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : get if the sequence should player overtop of an underlying SS
-//-----------------------------------------------------------------------------
-
-bool CChoreoEvent::GetPlayOverScript( void )
-{
- return m_bPlayOverScript;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetDuration( void )
-{
- if ( HasEndTime() )
- {
- return GetEndTime() - GetStartTime();
- }
-
- return 0.0f;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ClearAllRelativeTags( void )
-{
- m_RelativeTags.Purge();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetNumRelativeTags( void )
-{
- return m_RelativeTags.Size();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : tagnum -
-// Output : CEventRelativeTag
-//-----------------------------------------------------------------------------
-CEventRelativeTag *CChoreoEvent::GetRelativeTag( int tagnum )
-{
- Assert( tagnum >= 0 && tagnum < m_RelativeTags.Size() );
- return &m_RelativeTags[ tagnum ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-// percentage -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::AddRelativeTag( const char *tagname, float percentage )
-{
- CEventRelativeTag rt( this, tagname, percentage );
- m_RelativeTags.AddToTail( rt );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RemoveRelativeTag( const char *tagname )
-{
- for ( int i = 0; i < m_RelativeTags.Size(); i++ )
- {
- CEventRelativeTag *prt = &m_RelativeTags[ i ];
- if ( !prt )
- continue;
-
- if ( !stricmp( prt->GetName(), tagname ) )
- {
- m_RelativeTags.Remove( i );
- return;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-// Output : CEventRelativeTag *
-//-----------------------------------------------------------------------------
-CEventRelativeTag * CChoreoEvent::FindRelativeTag( const char *tagname )
-{
- for ( int i = 0; i < m_RelativeTags.Size(); i++ )
- {
- CEventRelativeTag *prt = &m_RelativeTags[ i ];
- if ( !prt )
- continue;
-
- if ( !stricmp( prt->GetName(), tagname ) )
- {
- return prt;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::IsUsingRelativeTag( void )
-{
- return m_bUsesTag;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : usetag -
-// 0 -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetUsingRelativeTag( bool usetag, const char *tagname /*= 0*/,
- const char *wavname /* = 0 */ )
-{
- m_bUsesTag = usetag;
- if ( tagname )
- {
- m_TagName = tagname;
- }
- else
- {
- m_TagName.Set("");
- }
- if ( wavname )
- {
- m_TagWavName = wavname;
- }
- else
- {
- m_TagWavName.Set("");
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetRelativeTagName( void )
-{
- return m_TagName.Get();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : const char
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::GetRelativeWavName( void )
-{
- return m_TagWavName.Get();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ClearAllTimingTags( void )
-{
- m_TimingTags.Purge();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetNumTimingTags( void )
-{
- return m_TimingTags.Size();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : tagnum -
-// Output : CEventRelativeTag
-//-----------------------------------------------------------------------------
-CFlexTimingTag *CChoreoEvent::GetTimingTag( int tagnum )
-{
- Assert( tagnum >= 0 && tagnum < m_TimingTags.Size() );
- return &m_TimingTags[ tagnum ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-// percentage -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::AddTimingTag( const char *tagname, float percentage, bool locked )
-{
- CFlexTimingTag tt( this, tagname, percentage, locked );
- m_TimingTags.AddToTail( tt );
-
- // Sort tags
- CFlexTimingTag temp( (CChoreoEvent *)0x1, "", 0.0f, false );
-
- // ugly bubble sort
- for ( int i = 0; i < m_TimingTags.Size(); i++ )
- {
- for ( int j = i + 1; j < m_TimingTags.Size(); j++ )
- {
- CFlexTimingTag *t1 = &m_TimingTags[ i ];
- CFlexTimingTag *t2 = &m_TimingTags[ j ];
-
- if ( t1->GetPercentage() > t2->GetPercentage() )
- {
- temp = *t1;
- *t1 = *t2;
- *t2 = temp;
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RemoveTimingTag( const char *tagname )
-{
- for ( int i = 0; i < m_TimingTags.Size(); i++ )
- {
- CFlexTimingTag *ptt = &m_TimingTags[ i ];
- if ( !ptt )
- continue;
-
- if ( !stricmp( ptt->GetName(), tagname ) )
- {
- m_TimingTags.Remove( i );
- return;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *tagname -
-// Output : CEventRelativeTag *
-//-----------------------------------------------------------------------------
-CFlexTimingTag * CChoreoEvent::FindTimingTag( const char *tagname )
-{
- for ( int i = 0; i < m_TimingTags.Size(); i++ )
- {
- CFlexTimingTag *ptt = &m_TimingTags[ i ];
- if ( !ptt )
- continue;
-
- if ( !stricmp( ptt->GetName(), tagname ) )
- {
- return ptt;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::OnEndTimeChanged( void )
-{
- int c = GetNumFlexAnimationTracks();
- for ( int i = 0; i < c; i++ )
- {
- CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
- Assert( track );
- if ( !track )
- continue;
-
- track->Resort( 0 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetNumFlexAnimationTracks( void )
-{
- return m_FlexAnimationTracks.Size();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-// Output : CFlexAnimationTrack
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack *CChoreoEvent::GetFlexAnimationTrack( int index )
-{
- if ( index < 0 || index >= GetNumFlexAnimationTracks() )
- return NULL;
- return m_FlexAnimationTracks[ index ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *controllername -
-// Output : CFlexAnimationTrack
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack *CChoreoEvent::AddTrack( const char *controllername )
-{
- CFlexAnimationTrack *newTrack = new CFlexAnimationTrack( this );
- newTrack->SetFlexControllerName( controllername );
-
- m_FlexAnimationTracks.AddToTail( newTrack );
-
- return newTrack;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : index -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RemoveTrack( int index )
-{
- CFlexAnimationTrack *track = GetFlexAnimationTrack( index );
- if ( !track )
- return;
-
- m_FlexAnimationTracks.Remove( index );
- delete track;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RemoveAllTracks( void )
-{
- while ( GetNumFlexAnimationTracks() > 0 )
- {
- RemoveTrack( 0 );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *controllername -
-// Output : CFlexAnimationTrack
-//-----------------------------------------------------------------------------
-CFlexAnimationTrack *CChoreoEvent::FindTrack( const char *controllername )
-{
- for ( int i = 0; i < GetNumFlexAnimationTracks(); i++ )
- {
- CFlexAnimationTrack *t = GetFlexAnimationTrack( i );
- if ( t && !stricmp( t->GetFlexControllerName(), controllername ) )
- {
- return t;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::GetTrackLookupSet( void )
-{
- return m_bTrackLookupSet;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : set -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetTrackLookupSet( bool set )
-{
- m_bTrackLookupSet = set;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::IsProcessing( void ) const
-{
- return m_bProcessing;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *cb -
-// t -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::StartProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
-{
- Assert( !m_bProcessing );
- m_bProcessing = true;
- if ( cb )
- {
- cb->StartEvent( t, scene, this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *cb -
-// t -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ContinueProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
-{
- Assert( m_bProcessing );
- if ( cb )
- {
- cb->ProcessEvent( t, scene, this );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *cb -
-// t -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::StopProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
-{
- Assert( m_bProcessing );
- if ( cb )
- {
- cb->EndEvent( t, scene, this );
- }
- m_bProcessing = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *cb -
-// t -
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::CheckProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
-{
- //Assert( !m_bProcessing );
- if ( cb )
- {
- return cb->CheckEvent( t, scene, this );
- }
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ResetProcessing( void )
-{
- if ( GetType() == LOOP )
- {
- m_nLoopsRemaining = m_nNumLoops;
- }
-
- m_bProcessing = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *mixer -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetMixer( CAudioMixer *mixer )
-{
- m_pMixer = mixer;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CAudioMixer
-//-----------------------------------------------------------------------------
-CAudioMixer *CChoreoEvent::GetMixer( void ) const
-{
- return m_pMixer;
-}
-
-// Snap to scene framerate
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SnapTimes()
-{
- if ( HasEndTime() && !IsFixedLength() )
- {
- m_flEndTime = SnapTime( m_flEndTime );
- }
- float oldstart = m_flStartTime;
- m_flStartTime = SnapTime( m_flStartTime );
-
- // Don't snap end time for fixed length events, just set based on new start time
- if ( IsFixedLength() )
- {
- float dt = m_flStartTime - oldstart;
- m_flEndTime += dt;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : t -
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::SnapTime( float t )
-{
- CChoreoScene *scene = GetScene();
- if ( !scene)
- {
- Assert( 0 );
- return t;
- }
-
- return scene->SnapTime( t );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : CChoreoScene
-//-----------------------------------------------------------------------------
-CChoreoScene *CChoreoEvent::GetScene( void )
-{
- return m_pScene;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *scene -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetScene( CChoreoScene *scene )
-{
- m_pScene = scene;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : t -
-// Output : char const
-//-----------------------------------------------------------------------------
-const char *CChoreoEvent::NameForAbsoluteTagType( AbsTagType t )
-{
- switch ( t )
- {
- case PLAYBACK:
- return "playback_time";
- case ORIGINAL:
- return "shifted_time";
- default:
- break;
- }
-
- return "AbsTagType(unknown)";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *name -
-// Output : AbsTagType
-//-----------------------------------------------------------------------------
-CChoreoEvent::AbsTagType CChoreoEvent::TypeForAbsoluteTagName( const char *name )
-{
- if ( !Q_strcasecmp( name, "playback_time" ) )
- {
- return PLAYBACK;
- }
- else if ( !Q_strcasecmp( name, "shifted_time" ) )
- {
- return ORIGINAL;
- }
-
- return (AbsTagType)-1;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ClearAllAbsoluteTags( AbsTagType type )
-{
- m_AbsoluteTags[ type ].Purge();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetNumAbsoluteTags( AbsTagType type )
-{
- return m_AbsoluteTags[ type ].Size();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// tagnum -
-// Output : CEventAbsoluteTag
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag *CChoreoEvent::GetAbsoluteTag( AbsTagType type, int tagnum )
-{
- Assert( tagnum >= 0 && tagnum < m_AbsoluteTags[ type ].Size() );
- return &m_AbsoluteTags[ type ][ tagnum ];
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *tagname -
-// Output : CEventAbsoluteTag
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag *CChoreoEvent::FindAbsoluteTag( AbsTagType type, const char *tagname )
-{
- for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
- {
- CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
- if ( !ptag )
- continue;
-
- if ( !stricmp( ptag->GetName(), tagname ) )
- {
- return ptag;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *tagname -
-// t -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::AddAbsoluteTag( AbsTagType type, const char *tagname, float t )
-{
- CEventAbsoluteTag at( this, tagname, t );
- m_AbsoluteTags[ type ].AddToTail( at );
-
- // Sort tags
- CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
-
- // ugly bubble sort
- for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
- {
- for ( int j = i + 1; j < m_AbsoluteTags[ type ].Size(); j++ )
- {
- CEventAbsoluteTag *t1 = &m_AbsoluteTags[ type ][ i ];
- CEventAbsoluteTag *t2 = &m_AbsoluteTags[ type ][ j ];
-
- if ( t1->GetPercentage() > t2->GetPercentage() )
- {
- temp = *t1;
- *t1 = *t2;
- *t2 = temp;
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *tagname -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RemoveAbsoluteTag( AbsTagType type, const char *tagname )
-{
- for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
- {
- CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
- if ( !ptag )
- continue;
-
- if ( !stricmp( ptag->GetName(), tagname ) )
- {
- m_AbsoluteTags[ type ].Remove( i );
- return;
- }
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose: makes sure tags in PLAYBACK are in the same order as ORIGINAL
-// Input :
-// Output : true if they were in order, false if it has to reorder them
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::VerifyTagOrder( )
-{
- bool bInOrder = true;
-
- // Sort tags
- CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
-
- for ( int i = 0; i < m_AbsoluteTags[ CChoreoEvent::ORIGINAL ].Size(); i++ )
- {
- CEventAbsoluteTag *ptag = &m_AbsoluteTags[ CChoreoEvent::ORIGINAL ][ i ];
- if ( !ptag )
- continue;
-
- CEventAbsoluteTag *t1 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ i ];
-
- if ( stricmp( ptag->GetName(), t1->GetName() ) == 0)
- continue;
-
- bInOrder = false;
- for ( int j = i + 1; j < m_AbsoluteTags[ CChoreoEvent::PLAYBACK ].Size(); j++ )
- {
- CEventAbsoluteTag *t2 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ j ];
-
- if ( stricmp( ptag->GetName(), t2->GetName() ) == 0 )
- {
- temp = *t1;
- *t1 = *t2;
- *t2 = temp;
- break;
- }
- }
- }
- return bInOrder;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// *tagname -
-//-----------------------------------------------------------------------------
-
-float CChoreoEvent::GetBoundedAbsoluteTagPercentage( AbsTagType type, int tagnum )
-{
- if ( tagnum <= -2 )
- {
- /*
- if (GetNumAbsoluteTags( type ) >= 1)
- {
- CEventAbsoluteTag *tag = GetAbsoluteTag( type, 0 );
- Assert( tag );
- return -tag->GetTime();
- }
- */
- return 0.0f; // -0.5f;
- }
- else if ( tagnum == -1 )
- {
- return 0.0f;
- }
- else if ( tagnum == GetNumAbsoluteTags( type ) )
- {
- return 1.0;
- }
- else if ( tagnum > GetNumAbsoluteTags( type ) )
- {
- /*
- if (GetNumAbsoluteTags( type ) >= 1)
- {
- CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum - 2 );
- Assert( tag );
- return 2.0 - tag->GetTime();
- }
- */
- return 1.0; // 1.5;
- }
-
- /*
- {
- float duration = GetDuration();
-
- if ( type == SHIFTED )
- {
- float seqduration;
- GetGestureSequenceDuration( seqduration );
- return seqduration;
- }
- return duration;
- }
- */
-
- CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum );
- Assert( tag );
- return tag->GetPercentage();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : t -
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetOriginalPercentageFromPlaybackPercentage( float t )
-{
- Assert( GetType() == GESTURE );
- if ( GetType() != GESTURE )
- return t;
-
- int count = GetNumAbsoluteTags( PLAYBACK );
-
- if ( count != GetNumAbsoluteTags( ORIGINAL ) )
- {
- return t;
- }
-
- if ( count <= 0 )
- {
- return t;
- }
-
- if ( t <= 0.0f )
- return 0.0f;
-
- float s = 0.0f, n = 0.0f;
-
- // find what tags this is between
- int i;
- for ( i = -1 ; i < count; i++ )
- {
- s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
- n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
-
- if ( t >= s && t <= n )
- {
- break;
- }
- }
-
- int prev = i - 1;
- int start = i;
- int end = i + 1;
- int next = i + 2;
-
- prev = MAX( -2, prev );
- start = MAX( -1, start );
- end = MIN( end, count );
- next = MIN( next, count + 1 );
-
- CEventAbsoluteTag *pStartTag = NULL;
- CEventAbsoluteTag *pEndTag = NULL;
-
- // check for linear portion of lookup
- if (start >= 0 && start < count)
- {
- pStartTag = GetAbsoluteTag( PLAYBACK, start );
- }
- if (end >= 0 && end < count)
- {
- pEndTag = GetAbsoluteTag( PLAYBACK, end );
- }
-
- if (pStartTag && pEndTag)
- {
- if (pStartTag->GetLinear() && pEndTag->GetLinear())
- {
- CEventAbsoluteTag *pOrigStartTag = GetAbsoluteTag( ORIGINAL, start );
- CEventAbsoluteTag *pOrigEndTag = GetAbsoluteTag( ORIGINAL, end );
-
- if (pOrigStartTag && pOrigEndTag)
- {
- s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
- return (1 - s) * pOrigStartTag->GetPercentage() + s * pOrigEndTag->GetPercentage();
- }
- }
- }
-
- float dt = n - s;
-
- Vector vPre( GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), 0 );
- Vector vStart( GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), 0 );
- Vector vEnd( GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), 0 );
- Vector vNext( GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), 0 );
-
- // simulate sections of either side of "linear" portion of ramp as linear slope
- if (pStartTag && pStartTag->GetLinear())
- {
- vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
- }
-
- if (pEndTag && pEndTag->GetLinear())
- {
- vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
- }
-
-
- float f2 = 0.0f;
- if ( dt > 0.0f )
- {
- f2 = ( t - s ) / ( dt );
- }
- f2 = clamp( f2, 0.0f, 1.0f );
-
- Vector vOut;
- Catmull_Rom_Spline_NormalizeX(
- vPre,
- vStart,
- vEnd,
- vNext,
- f2,
- vOut );
-
- return vOut.y;
-
- /*
- float duration;
- GetGestureSequenceDuration( duration );
-
- float retval = clamp( vOut.y, 0.0f, duration );
- return retval;
- */
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : t -
-// Output : float
-//-----------------------------------------------------------------------------
-float CChoreoEvent::GetPlaybackPercentageFromOriginalPercentage( float t )
-{
- Assert( GetType() == GESTURE );
- if ( GetType() != GESTURE )
- return t;
-
- int count = GetNumAbsoluteTags( PLAYBACK );
-
- if ( count != GetNumAbsoluteTags( ORIGINAL ) )
- {
- return t;
- }
-
- if ( count <= 0 )
- {
- return t;
- }
-
- if ( t <= 0.0f )
- return 0.0f;
-
- float s = 0.0f, n = 0.0f;
-
- // find what tags this is between
- int i;
- for ( i = -1 ; i < count; i++ )
- {
- s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
- n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
-
- if ( t >= s && t <= n )
- {
- break;
- }
- }
-
- int prev = i - 1;
- int start = i;
- int end = i + 1;
- int next = i + 2;
-
- prev = MAX( -2, prev );
- start = MAX( -1, start );
- end = MIN( end, count );
- next = MIN( next, count + 1 );
-
- CEventAbsoluteTag *pStartTag = NULL;
- CEventAbsoluteTag *pEndTag = NULL;
-
- // check for linear portion of lookup
- if (start >= 0 && start < count)
- {
- pStartTag = GetAbsoluteTag( ORIGINAL, start );
- }
- if (end >= 0 && end < count)
- {
- pEndTag = GetAbsoluteTag( ORIGINAL, end );
- }
-
- // check for linear portion of lookup
- if (pStartTag && pEndTag)
- {
- if (pStartTag->GetLinear() && pEndTag->GetLinear())
- {
- CEventAbsoluteTag *pPlaybackStartTag = GetAbsoluteTag( PLAYBACK, start );
- CEventAbsoluteTag *pPlaybackEndTag = GetAbsoluteTag( PLAYBACK, end );
-
- if (pPlaybackStartTag && pPlaybackEndTag)
- {
- s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
- return (1 - s) * pPlaybackStartTag->GetPercentage() + s * pPlaybackEndTag->GetPercentage();
- }
- }
- }
-
- float dt = n - s;
-
- Vector vPre( GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), 0 );
- Vector vStart( GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), 0 );
- Vector vEnd( GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), 0 );
- Vector vNext( GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), 0 );
-
- // simulate sections of either side of "linear" portion of ramp as linear slope
- if (pStartTag && pStartTag->GetLinear())
- {
- vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
- }
-
- if (pEndTag && pEndTag->GetLinear())
- {
- vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
- }
-
- float f2 = 0.0f;
- if ( dt > 0.0f )
- {
- f2 = ( t - s ) / ( dt );
- }
- f2 = clamp( f2, 0.0f, 1.0f );
-
- Vector vOut;
- Catmull_Rom_Spline_NormalizeX(
- vPre,
- vStart,
- vEnd,
- vNext,
- f2,
- vOut );
-
- return vOut.y;
-
- /*
- float duration;
- GetGestureSequenceDuration( duration );
-
- float retval = clamp( vOut.y, 0.0f, duration );
- return retval;
- */
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : duration -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetGestureSequenceDuration( float duration )
-{
- m_flGestureSequenceDuration = duration;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : duration -
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::GetGestureSequenceDuration( float& duration )
-{
- bool valid = m_flGestureSequenceDuration != 0.0f;
-
- if ( !valid )
- {
- duration = GetDuration();
- }
- else
- {
- duration = m_flGestureSequenceDuration;
- }
-
- return valid;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pitch -
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetPitch( void ) const
-{
- return m_nPitch;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pitch -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetPitch( int pitch )
-{
- m_nPitch = pitch;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : yaw -
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetYaw( void ) const
-{
- return m_nYaw;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : yaw -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetYaw( int yaw )
-{
- m_nYaw = yaw;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : t -
-// -1 -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetLoopCount( int numloops )
-{
- Assert( GetType() == LOOP );
- // Never below -1
- m_nNumLoops = MAX( numloops, -1 );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetNumLoopsRemaining( void )
-{
- Assert( GetType() == LOOP );
-
- return m_nLoopsRemaining;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : loops -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetNumLoopsRemaining( int loops )
-{
- Assert( GetType() == LOOP );
-
- m_nLoopsRemaining = loops;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CChoreoEvent::GetLoopCount( void )
-{
- Assert( GetType() == LOOP );
- return m_nNumLoops;
-}
-
-EdgeInfo_t *CCurveData::GetEdgeInfo( int idx )
-{
- return &m_RampEdgeInfo[ idx ];
-}
-
-int CCurveData::GetCount( void )
-{
- return m_Ramp.Count();
-}
-
-CExpressionSample *CCurveData::Get( int index )
-{
- if ( index < 0 || index >= GetCount() )
- return NULL;
-
- return &m_Ramp[ index ];
-}
-
-CExpressionSample *CCurveData::Add( float time, float value, bool selected )
-{
- CExpressionSample sample;
-
- sample.time = time;
- sample.value = value;
- sample.selected = selected;
-
- int idx = m_Ramp.AddToTail( sample );
- return &m_Ramp[ idx ];
-}
-
-void CCurveData::Delete( int index )
-{
- if ( index < 0 || index >= GetCount() )
- return;
-
- m_Ramp.Remove( index );
-}
-
-void CCurveData::Clear( void )
-{
- m_Ramp.RemoveAll();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCurveData::Resort( ICurveDataAccessor *data )
-{
- for ( int i = 0; i < m_Ramp.Size(); i++ )
- {
- for ( int j = i + 1; j < m_Ramp.Size(); j++ )
- {
- CExpressionSample src = m_Ramp[ i ];
- CExpressionSample dest = m_Ramp[ j ];
-
- if ( src.time > dest.time )
- {
- m_Ramp[ i ] = dest;
- m_Ramp[ j ] = src;
- }
- }
- }
-
- RemoveOutOfRangeSamples( data );
-
- // m_RampAccumulator.RemoveAll();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : number -
-// Output : CExpressionSample
-//-----------------------------------------------------------------------------
-CExpressionSample *CCurveData::GetBoundedSample( ICurveDataAccessor *data, int number, bool& bClamped )
-{
- // Search for two samples which span time f
- if ( number < 0 )
- {
- static CExpressionSample nullstart;
- nullstart.time = 0.0f;
- nullstart.value = GetEdgeZeroValue( true );
- nullstart.SetCurveType( GetEdgeCurveType( true ) );
- bClamped = true;
- return &nullstart;
- }
- else if ( number >= GetCount() )
- {
- static CExpressionSample nullend;
- nullend.time = data->GetDuration();
- nullend.value = GetEdgeZeroValue( false );
- nullend.SetCurveType( GetEdgeCurveType( false ) );
- bClamped = true;
- return &nullend;
- }
-
- bClamped = false;
- return Get( number );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCurveData::RemoveOutOfRangeSamples( ICurveDataAccessor *data )
-{
- float duration = data->GetDuration();
-
- int c = GetCount();
- for ( int i = c-1; i >= 0; i-- )
- {
- CExpressionSample src = m_Ramp[ i ];
- if ( src.time < 0 ||
- src.time > duration + 0.01 )
- {
- m_Ramp.Remove( i );
- }
- }
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::RescaleGestureTimes( float newstart, float newend, bool bMaintainAbsoluteTagPositions )
-{
- if ( GetType() != CChoreoEvent::GESTURE )
- return;
-
- // Did it actually change
- if ( newstart == GetStartTime() &&
- newend == GetEndTime() )
- {
- return;
- }
-
- float newduration = newend - newstart;
-
- float dt = 0.0f;
- //If the end is moving, leave tags stay where they are (dt == 0.0f)
- if ( newstart != GetStartTime() )
- {
- // Otherwise, if the new start is later, then tags need to be shifted backwards
- dt -= ( newstart - GetStartTime() );
- }
-
- if ( bMaintainAbsoluteTagPositions )
- {
- int i;
- int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
- for ( i = 0; i < count; i++ )
- {
- CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
- float tagtime = tag->GetPercentage() * GetDuration();
-
- tagtime += dt;
-
- tagtime = clamp( tagtime / newduration, 0.0f, 1.0f );
-
- tag->SetPercentage( tagtime );
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Make sure tags aren't co-located or out of order
-//-----------------------------------------------------------------------------
-bool CChoreoEvent::PreventTagOverlap( void )
-{
- bool bHadOverlap = false;
-
- // FIXME: limit to single frame?
- float minDp = 0.01;
-
- float minP = 1.00;
-
- int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
- for ( int i = count - 1; i >= 0; i-- )
- {
- CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
-
- if (tag->GetPercentage() > minP)
- {
- tag->SetPercentage( minP );
-
- minDp = MIN( 0.01, minP / (i + 1) );
- bHadOverlap = true;
- }
- else
- {
- minP = tag->GetPercentage();
- }
- minP = MAX( minP - minDp, 0 );
- }
-
- return bHadOverlap;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// Output : CEventAbsoluteTag
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag *CChoreoEvent::FindEntryTag( AbsTagType type )
-{
- for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
- {
- CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
- if ( !ptag )
- continue;
-
- if ( ptag->GetEntry() )
- {
- return ptag;
- }
- }
- return NULL;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : type -
-// Output : CEventAbsoluteTag
-//-----------------------------------------------------------------------------
-CEventAbsoluteTag *CChoreoEvent::FindExitTag( AbsTagType type )
-{
- for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
- {
- CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
- if ( !ptag )
- continue;
-
- if ( ptag->GetExit() )
- {
- return ptag;
- }
- }
- return NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *style -
-// maxlen -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::GetMovementStyle( char *style, int maxlen )
-{
- Assert( GetType() == MOVETO );
-
- style[0] = 0;
-
- const char *in = m_Parameters2.Get();
- char *out = style;
-
- while ( *in && *in != '\0' && *in != ' ' )
- {
- if ( out - style >= maxlen - 1 )
- break;
- *out++ = *in++;
- }
-
- *out = 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *style -
-// maxlen -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::GetDistanceStyle( char *style, int maxlen )
-{
- Assert( GetType() == MOVETO );
-
- style[0]= 0;
-
- const char *in = Q_strstr( m_Parameters2.Get(), " " );
- if ( !in )
- return;
-
- in++;
- char *out = style;
-
- while ( *in && *in != '\0' )
- {
- if ( out - style >= maxlen - 1 )
- break;
- *out++ = *in++;
- }
-
- *out = 0;
-}
-
-void CChoreoEvent::SetCloseCaptionType( CLOSECAPTION type )
-{
- Assert( m_fType == SPEAK );
- m_ccType = type;
-}
-
-CChoreoEvent::CLOSECAPTION CChoreoEvent::GetCloseCaptionType() const
-{
- Assert( m_fType == SPEAK );
- return (CLOSECAPTION)m_ccType;
-}
-
-void CChoreoEvent::SetCloseCaptionToken( char const *token )
-{
- Assert( m_fType == SPEAK );
- Assert( token );
- m_CCToken = token;
-}
-
-char const *CChoreoEvent::GetCloseCaptionToken() const
-{
- Assert( m_fType == SPEAK );
- return m_CCToken.Get();
-}
-
-bool CChoreoEvent::GetPlaybackCloseCaptionToken( char *dest, int destlen )
-{
- dest[0] = 0;
-
- Assert( m_fType == SPEAK );
-
- switch ( m_ccType )
- {
- default:
- case CC_DISABLED:
- {
- return false;
- }
- case CC_SLAVE:
- {
- // If it's a slave, then only disable if we're not using the combined wave
- if ( IsUsingCombinedFile() )
- {
- return false;
- }
-
- if ( m_CCToken[ 0 ] != 0 )
- {
- Q_strncpy( dest, m_CCToken.Get(), destlen );
- }
- else
- {
- Q_strncpy( dest, m_Parameters.Get(), destlen );
- }
- return true;
- }
- case CC_MASTER:
- {
- // Always use the override if we're the master, otherwise always use the default
- // parameter
- if ( m_CCToken[ 0 ] != 0 )
- {
- Q_strncpy( dest, m_CCToken.Get(), destlen );
- }
- else
- {
- Q_strncpy( dest, m_Parameters.Get(), destlen );
- }
- return true;
- }
- }
-
- return false;
-}
-
-
-void CChoreoEvent::SetUsingCombinedFile( bool isusing )
-{
- Assert( m_fType == SPEAK );
- m_bUsingCombinedSoundFile = isusing;
-}
-
-bool CChoreoEvent::IsUsingCombinedFile() const
-{
- Assert( m_fType == SPEAK );
- return m_bUsingCombinedSoundFile;
-}
-
-void CChoreoEvent::SetRequiredCombinedChecksum( unsigned int checksum )
-{
- Assert( m_fType == SPEAK );
- m_uRequiredCombinedChecksum = checksum;
-}
-
-unsigned int CChoreoEvent::GetRequiredCombinedChecksum()
-{
- Assert( m_fType == SPEAK );
- return m_uRequiredCombinedChecksum;
-}
-
-void CChoreoEvent::SetNumSlaves( int num )
-{
- Assert( m_fType == SPEAK );
- Assert( num >= 0 );
- m_nNumSlaves = num;
-}
-
-int CChoreoEvent::GetNumSlaves() const
-{
- Assert( m_fType == SPEAK );
- return m_nNumSlaves;
-}
-
-void CChoreoEvent::SetLastSlaveEndTime( float t )
-{
- Assert( m_fType == SPEAK );
- m_flLastSlaveEndTime = t;
-}
-
-float CChoreoEvent::GetLastSlaveEndTime() const
-{
- Assert( m_fType == SPEAK );
- return m_flLastSlaveEndTime;
-}
-
-void CChoreoEvent::SetCloseCaptionTokenValid( bool valid )
-{
- Assert( m_fType == SPEAK );
- m_bCCTokenValid = valid;
-}
-
-bool CChoreoEvent::GetCloseCaptionTokenValid() const
-{
- Assert( m_fType == SPEAK );
- return m_bCCTokenValid;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Removes characters which can't appear in windows filenames
-// Input : *in -
-// *dest -
-// destlen -
-// Output : static void
-//-----------------------------------------------------------------------------
-static void CleanupTokenName( char const *in, char *dest, int destlen )
-{
- char *out = dest;
- while ( *in && ( out - dest ) < destlen )
- {
- if ( V_isalnum( *in ) || // lowercase, uppercase, digits and underscore are valid
- *in == '_' )
- {
- *out++ = *in;
- }
- else
- {
- *out++ = '_'; // Put underscores in for bogus characters
- }
- in++;
- }
- *out = 0;
-}
-
-bool CChoreoEvent::ComputeCombinedBaseFileName( char *dest, int destlen, bool creategenderwildcard )
-{
- if ( m_fType != SPEAK )
- return false;
-
- if ( m_ccType != CC_MASTER )
- return false;
-
- if ( GetNumSlaves() == 0 )
- return false;
-
- if ( !m_pScene )
- return false;
-
- char vcdpath[ 512 ];
- char cleanedtoken[ MAX_CCTOKEN_STRING ];
- CleanupTokenName( m_CCToken.Get(), cleanedtoken, sizeof( cleanedtoken ) );
-
- if ( Q_strlen( cleanedtoken ) <= 0 )
- return false;
-
- Q_strncpy( vcdpath, m_pScene->GetFilename(), sizeof( vcdpath ) );
- Q_StripFilename( vcdpath );
- Q_FixSlashes( vcdpath, '/' );
-
- char *pvcd = vcdpath;
-
- char *offset = Q_strstr( vcdpath, "scenes" );
- if ( offset )
- {
- pvcd = offset + 6;
- if ( *pvcd == '/' )
- {
- ++pvcd;
- }
- }
-
- int len = Q_strlen( pvcd );
-
- if ( len > 0 && ( len + 1 ) < ( sizeof( vcdpath ) - 1 ) )
- {
- pvcd[ len ] = '/';
- pvcd[ len + 1 ] = 0;
- }
-
- Assert( !Q_strstr( pvcd, ":" ) );
-
- if ( creategenderwildcard )
- {
- Q_snprintf( dest, destlen, "sound/combined/%s%s_$gender.wav", pvcd, cleanedtoken );
- }
- else
- {
- Q_snprintf( dest, destlen, "sound/combined/%s%s.wav", pvcd, cleanedtoken );
- }
- return true;
-}
-
-bool CChoreoEvent::IsCombinedUsingGenderToken() const
-{
- return m_bCombinedUsingGenderToken;
-}
-
-void CChoreoEvent::SetCombinedUsingGenderToken( bool using_gender )
-{
- m_bCombinedUsingGenderToken = using_gender;
-}
-
-
-int CChoreoEvent::ValidateCombinedFile()
-{
-
- return 0;
-}
-
-bool CChoreoEvent::IsSuppressingCaptionAttenuation() const
-{
- return m_bSuppressCaptionAttenuation;
-}
-
-void CChoreoEvent::SetSuppressingCaptionAttenuation( bool suppress )
-{
- m_bSuppressCaptionAttenuation = suppress;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CChoreoEvent::ClearEventDependencies()
-{
- m_Dependencies.RemoveAll();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *other -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::AddEventDependency( CChoreoEvent *other )
-{
- if ( m_Dependencies.Find( other ) == m_Dependencies.InvalidIndex() )
- {
- m_Dependencies.AddToTail( other );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : list -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::GetEventDependencies( CUtlVector< CChoreoEvent * >& list )
-{
- int c = m_Dependencies.Count();
- for ( int i = 0; i < c; ++i )
- {
- list.AddToTail( m_Dependencies[ i ] );
- }
-}
-
-void CCurveData::SetEdgeInfo( bool leftEdge, int curveType, float zero )
-{
- int idx = leftEdge ? 0 : 1;
- m_RampEdgeInfo[ idx ].m_CurveType = curveType;
- m_RampEdgeInfo[ idx ].m_flZeroPos = zero;
-}
-
-void CCurveData::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
-{
- int idx = leftEdge ? 0 : 1;
- curveType = m_RampEdgeInfo[ idx ].m_CurveType;
- zero = m_RampEdgeInfo[ idx ].m_flZeroPos;
-}
-
-void CCurveData::SetEdgeActive( bool leftEdge, bool state )
-{
- int idx = leftEdge ? 0 : 1;
- m_RampEdgeInfo[ idx ].m_bActive = state;
-}
-
-bool CCurveData::IsEdgeActive( bool leftEdge ) const
-{
- int idx = leftEdge ? 0 : 1;
- return m_RampEdgeInfo[ idx ].m_bActive;
-}
-
-int CCurveData::GetEdgeCurveType( bool leftEdge ) const
-{
- if ( !IsEdgeActive( leftEdge ) )
- {
- return CURVE_DEFAULT;
- }
-
- int idx = leftEdge ? 0 : 1;
- return m_RampEdgeInfo[ idx ].m_CurveType;
-}
-
-float CCurveData::GetEdgeZeroValue( bool leftEdge ) const
-{
- if ( !IsEdgeActive( leftEdge ) )
- {
- return 0.0f;
- }
-
- int idx = leftEdge ? 0 : 1;
- return m_RampEdgeInfo[ idx ].m_flZeroPos;
-}
-
-
-void CChoreoEvent::SaveToBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
-{
- buf.PutChar( GetType() );
- buf.PutShort( pStringPool->FindOrAddString( GetName() ) );
-
- float st = GetStartTime();
- buf.PutFloat( st );
-
- float et = GetEndTime();
- buf.PutFloat( et );
-
- buf.PutShort( pStringPool->FindOrAddString( GetParameters() ) );
- buf.PutShort( pStringPool->FindOrAddString( GetParameters2() ) );
- buf.PutShort( pStringPool->FindOrAddString( GetParameters3() ) );
-
- m_Ramp.SaveToBuffer( buf, pStringPool );
-
- int flags = 0;
- flags |= IsResumeCondition() ? 1<<0 : 0;
- flags |= IsLockBodyFacing() ? 1<<1 : 0;
- flags |= IsFixedLength() ? 1<<2 : 0;
- flags |= GetActive() ? 1<<3 : 0;
- flags |= GetForceShortMovement() ? 1<<4 : 0;
- flags |= GetPlayOverScript() ? 1<<5 : 0;
-
- buf.PutUnsignedChar( flags );
-
- buf.PutFloat( GetDistanceToTarget() );
-
- int numRelativeTags = GetNumRelativeTags();
- Assert( numRelativeTags <= 255 );
- buf.PutUnsignedChar( numRelativeTags );
-
- for ( int t = 0; t < numRelativeTags; t++ )
- {
- CEventRelativeTag *rt = GetRelativeTag( t );
- Assert( rt );
- buf.PutShort( pStringPool->FindOrAddString( rt->GetName() ) );
-
- Assert( rt->GetPercentage() >= 0.0f && rt->GetPercentage() <= 1.0f );
- unsigned char p = rt->GetPercentage() * 255.0f;
- buf.PutUnsignedChar( p );
- }
-
- int numTimingTags = GetNumTimingTags();
- Assert( numTimingTags <= 255 );
- buf.PutUnsignedChar( numTimingTags );
-
- for ( int t = 0; t < numTimingTags; t++ )
- {
- CFlexTimingTag *tt = GetTimingTag( t );
- Assert( tt );
- buf.PutShort( pStringPool->FindOrAddString( tt->GetName() ) );
-
- // save as u0.8
- Assert( tt->GetPercentage() >= 0.0f && tt->GetPercentage() <= 1.0f );
- unsigned char p = tt->GetPercentage() * 255.0f;
- buf.PutUnsignedChar( p );
-
- // Don't save locked state, it's only used by the editor tt->GetLocked()
- }
-
- int tagtype;
- for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
- {
- int num = GetNumAbsoluteTags( (CChoreoEvent::AbsTagType)tagtype );
- Assert( num <= 255 );
- buf.PutUnsignedChar( num );
-
- for ( int i = 0; i < num ; ++i )
- {
- CEventAbsoluteTag *abstag = GetAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, i );
- Assert( abstag );
- buf.PutShort( pStringPool->FindOrAddString( abstag->GetName() ) );
-
- // save as u4.12
- Assert( abstag->GetPercentage() >= 0.0f && abstag->GetPercentage() <= 15.0f );
- unsigned short p = abstag->GetPercentage() * 4096.0f;
- buf.PutUnsignedShort( p );
- }
- }
-
- if ( GetType() == CChoreoEvent::GESTURE )
- {
- float duration;
- if ( GetGestureSequenceDuration( duration ) )
- {
- buf.PutFloat( duration );
- }
- else
- {
- buf.PutFloat( -1.0f );
- }
- }
-
- buf.PutChar( IsUsingRelativeTag() ? 1 : 0 );
- if ( IsUsingRelativeTag() )
- {
- buf.PutShort( pStringPool->FindOrAddString( GetRelativeTagName() ) );
- buf.PutShort( pStringPool->FindOrAddString( GetRelativeWavName() ) );
- }
-
- SaveFlexAnimationsToBuffer( buf, pStringPool );
-
- if ( GetType() == LOOP )
- {
- buf.PutChar( GetLoopCount() );
- }
-
- if ( GetType() == CChoreoEvent::SPEAK )
- {
- buf.PutChar( GetCloseCaptionType() );
- buf.PutShort( pStringPool->FindOrAddString( GetCloseCaptionToken() ) );
- flags = 0;
-
- if ( GetCloseCaptionType() != CChoreoEvent::CC_DISABLED &&
- IsUsingCombinedFile() )
- {
- flags |= ( 1<<0 );
- }
- if ( IsCombinedUsingGenderToken() )
- {
- flags |= ( 1<<1 );
- }
- if ( IsSuppressingCaptionAttenuation() )
- {
- flags |= ( 1<<2 );
- }
-
- buf.PutChar( flags );
- }
-}
-
-bool CChoreoEvent::RestoreFromBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
-{
- MEM_ALLOC_CREDIT();
-
- SetType( (EVENTTYPE)buf.GetChar() );
- char sz[ 256 ];
- pStringPool->GetString( buf.GetShort(), sz, sizeof( sz ) );
- SetName( sz );
-
- SetStartTime( buf.GetFloat() );
- SetEndTime( buf.GetFloat() );
-
- char params[ 2048 ];
- pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
- SetParameters( params );
- pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
- SetParameters2( params );
- pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
- SetParameters3( params );
-
- if ( !m_Ramp.RestoreFromBuffer( buf, pStringPool ) )
- return false;
-
- int flags = buf.GetUnsignedChar();
- SetResumeCondition( ( flags & ( 1<<0 ) ) ? true : false );
- SetLockBodyFacing( ( flags & ( 1<<1 ) ) ? true : false );
- SetFixedLength( ( flags & ( 1<<2 ) ) ? true : false );
- SetActive( ( flags & ( 1<<3 ) ) ? true : false );
- SetForceShortMovement( ( flags & ( 1<<4 ) ) ? true : false );
- SetPlayOverScript( ( flags & ( 1<<5 ) ) ? true : false );
-
- SetDistanceToTarget( buf.GetFloat() );
-
- int numRelTags = buf.GetUnsignedChar();
- for ( int i = 0; i < numRelTags; ++i )
- {
- char tagName[ 256 ];
- pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
- float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
- AddRelativeTag( tagName, percentage );
- }
-
- int numTimingTags = buf.GetUnsignedChar();
- for ( int i = 0; i < numTimingTags; ++i )
- {
- char tagName[ 256 ];
- pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
- float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
- // Don't parse locked state, only used by editors
- AddTimingTag( tagName, percentage, false );
- }
-
- int tagtype;
- for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
- {
- int num = buf.GetUnsignedChar();
- for ( int i = 0; i < num; ++i )
- {
- char tagName[ 256 ];
- pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
- float percentage = (float)buf.GetUnsignedShort() * 1.0f/4096.0f;
-
- // Don't parse locked state, only used by editors
- AddAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, tagName, percentage );
- }
- }
-
- if ( GetType() == CChoreoEvent::GESTURE )
- {
- float duration = buf.GetFloat();
- if ( duration != -1 )
- {
- SetGestureSequenceDuration( duration );
- }
- }
-
- if ( buf.GetChar() == 1 )
- {
- char tagname[ 256 ];
- char wavname[ 256 ];
- pStringPool->GetString( buf.GetShort(), tagname, sizeof( tagname ) );
- pStringPool->GetString( buf.GetShort(), wavname, sizeof( wavname ) );
-
- SetUsingRelativeTag( true, tagname, wavname );
- }
-
- if ( !RestoreFlexAnimationsFromBuffer( buf, pStringPool ) )
- return false;
-
- if ( GetType() == LOOP )
- {
- SetLoopCount( buf.GetChar() );
- }
-
- if ( GetType() == CChoreoEvent::SPEAK )
- {
- SetCloseCaptionType( (CLOSECAPTION)buf.GetChar() );
- char cctoken[ 256 ];
- pStringPool->GetString( buf.GetShort(), cctoken, sizeof( cctoken ) );
- SetCloseCaptionToken( cctoken );
- int flags = buf.GetChar();
- if ( flags & ( 1<<0 ) )
- {
- SetUsingCombinedFile( true );
- }
- if ( flags & ( 1<<1 ) )
- {
- SetCombinedUsingGenderToken( true );
- }
- if ( flags & ( 1<<2 ) )
- {
- SetSuppressingCaptionAttenuation( true );
- }
- }
-
- return true;
-}
-
-void CCurveData::SaveToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
-{
- int c = GetCount();
- Assert( c <= 255 );
- buf.PutUnsignedChar( c );
-
- for ( int i = 0; i < c; i++ )
- {
- CExpressionSample *sample = Get( i );
- buf.PutFloat( sample->time );
-
- Assert( sample->value >= 0.0f && sample->value <= 1.0f );
- unsigned char v = sample->value * 255.0f;
- buf.PutUnsignedChar( v );
- }
-}
-
-bool CCurveData::RestoreFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
-{
- int c = buf.GetUnsignedChar();
- for ( int i = 0; i < c; i++ )
- {
- float t, v;
- t = buf.GetFloat();
- v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
-
- Add( t, v, false );
- }
-
- return true;
-}
-
-void CChoreoEvent::SaveFlexAnimationsToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
-{
- int numFlexAnimationTracks = GetNumFlexAnimationTracks();
- Assert( numFlexAnimationTracks <= 255 );
- buf.PutUnsignedChar( numFlexAnimationTracks );
-
- for ( int i = 0; i < numFlexAnimationTracks; i++ )
- {
- CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
-
- buf.PutShort( pStringPool->FindOrAddString( track->GetFlexControllerName() ) );
-
- int flags = 0;
- flags |= track->IsTrackActive() ? 1<<0 : 0;
- flags |= track->IsComboType() ? 1<<1 : 0;
- buf.PutUnsignedChar( flags );
-
- buf.PutFloat( track->GetMin() );
- buf.PutFloat( track->GetMax() );
-
- buf.PutShort( track->GetNumSamples( 0 ) );
- for ( int j = 0 ; j < track->GetNumSamples( 0 ) ; j++ )
- {
- CExpressionSample *s = track->GetSample( j, 0 );
- if ( !s )
- continue;
-
- buf.PutFloat( s->time );
-
- Assert( s->value >= 0.0f && s->value <= 1.0f );
- unsigned char v = s->value * 255.0f;
- buf.PutUnsignedChar( v );
-
- buf.PutUnsignedShort( s->GetCurveType() );
- }
-
- // Write out combo samples
- if ( track->IsComboType() )
- {
- int numSamples = track->GetNumSamples( 1 );
- Assert( numSamples <= 32767 );
- buf.PutUnsignedShort( numSamples );
-
- for ( int j = 0; j < numSamples; j++ )
- {
- CExpressionSample *s = track->GetSample( j, 1 );
- if ( !s )
- continue;
-
- buf.PutFloat( s->time );
-
- Assert( s->value >= 0.0f && s->value <= 1.0f );
- unsigned char v = s->value * 255.0f;
- buf.PutUnsignedChar( v );
-
- buf.PutUnsignedShort( s->GetCurveType() );
- }
- }
- }
-}
-
-bool CChoreoEvent::RestoreFlexAnimationsFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
-{
- int numTracks = buf.GetUnsignedChar();
-
- for ( int i = 0; i < numTracks; i++ )
- {
- char name[ 256 ];
- pStringPool->GetString( buf.GetShort(), name, sizeof( name ) );
-
- CFlexAnimationTrack *track = AddTrack( name );
-
- int flags = buf.GetUnsignedChar();
- track->SetTrackActive( ( flags & ( 1<<0 ) ) ? true : false );
- track->SetComboType( ( flags & ( 1<<1 ) ) ? true : false );
-
- track->SetMin( buf.GetFloat() );
- track->SetMax( buf.GetFloat() );
-
- int s = buf.GetShort();
- for ( int j = 0; j < s; ++j )
- {
- float t, v;
- t = buf.GetFloat();
- v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
-
- CExpressionSample *pSample = track->AddSample( t, v, 0 );
- pSample->SetCurveType( buf.GetUnsignedShort() );
- }
-
- if ( track->IsComboType() )
- {
- int s = buf.GetUnsignedShort();
- for ( int j = 0; j < s; ++j )
- {
- float t, v;
- t = buf.GetFloat();
- v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
-
- CExpressionSample *pSample = track->AddSample( t, v, 1 );
- pSample->SetCurveType( buf.GetUnsignedShort() );
- }
- }
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Marks the event as enabled/disabled
-// Input : state -
-//-----------------------------------------------------------------------------
-void CChoreoEvent::SetActive( bool state )
-{
- m_bActive = state;
-}
-
-bool CChoreoEvent::GetActive() const
-{
- return m_bActive;
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "tier0/dbg.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "choreoevent.h"
+#include "choreoactor.h"
+#include "choreochannel.h"
+#include "minmax.h"
+#include "mathlib/mathlib.h"
+#include "tier1/strtools.h"
+#include "choreoscene.h"
+#include "ichoreoeventcallback.h"
+#include "tier1/utlbuffer.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+int CChoreoEvent::s_nGlobalID = 1;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *owner -
+// *name -
+// percentage -
+//-----------------------------------------------------------------------------
+CEventRelativeTag::CEventRelativeTag( CChoreoEvent *owner, const char *name, float percentage )
+{
+ Assert( owner );
+ Assert( name );
+ Assert( percentage >= 0.0f );
+ Assert( percentage <= 1.0f );
+
+ m_Name = name;
+ m_flPercentage = percentage;
+ m_pOwner = owner;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : src -
+//-----------------------------------------------------------------------------
+CEventRelativeTag::CEventRelativeTag( const CEventRelativeTag& src )
+{
+ m_Name = src.m_Name;
+ m_flPercentage = src.m_flPercentage;
+ m_pOwner = src.m_pOwner;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CEventRelativeTag::GetName( void )
+{
+ return m_Name.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CEventRelativeTag::GetPercentage( void )
+{
+ return m_flPercentage;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void CEventRelativeTag::SetPercentage( float percentage )
+{
+ m_flPercentage = percentage;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+CChoreoEvent *CEventRelativeTag::GetOwner( void )
+{
+ return m_pOwner;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventRelativeTag::SetOwner( CChoreoEvent *event )
+{
+ m_pOwner = event;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Returns the corrected time based on the owner's length and start time
+// Output : float
+//-----------------------------------------------------------------------------
+float CEventRelativeTag::GetStartTime( void )
+{
+ Assert( m_pOwner );
+ if ( !m_pOwner )
+ {
+ return 0.0f;
+ }
+
+ float ownerstart = m_pOwner->GetStartTime();
+ float ownerduration = m_pOwner->GetDuration();
+
+ return ( ownerstart + ownerduration * m_flPercentage );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *owner -
+// *name -
+// percentage -
+//-----------------------------------------------------------------------------
+CFlexTimingTag::CFlexTimingTag( CChoreoEvent *owner, const char *name, float percentage, bool locked )
+: BaseClass( owner, name, percentage )
+{
+ m_bLocked = locked;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : src -
+//-----------------------------------------------------------------------------
+CFlexTimingTag::CFlexTimingTag( const CFlexTimingTag& src )
+: BaseClass( src )
+{
+ m_bLocked = src.m_bLocked;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CFlexTimingTag::GetLocked( void )
+{
+ return m_bLocked;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : locked -
+//-----------------------------------------------------------------------------
+void CFlexTimingTag::SetLocked( bool locked )
+{
+ m_bLocked = locked;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *owner -
+// *name -
+// percentage -
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag::CEventAbsoluteTag( CChoreoEvent *owner, const char *name, float t )
+{
+ Assert( owner );
+ Assert( name );
+ Assert( t >= 0.0f );
+
+ m_Name = name;
+ m_flPercentage = t;
+ m_pOwner = owner;
+ m_bLocked = false;
+ m_bLinear = false;
+ m_bEntry = false;
+ m_bExit = false;
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : src -
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag::CEventAbsoluteTag( const CEventAbsoluteTag& src )
+{
+ m_Name = src.m_Name;
+ m_flPercentage = src.m_flPercentage;
+ m_pOwner = src.m_pOwner;
+ m_bLocked = src.m_bLocked;
+ m_bLinear = src.m_bLinear;
+ m_bEntry = src.m_bEntry;
+ m_bExit = src.m_bExit;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CEventAbsoluteTag::GetName( void )
+{
+ return m_Name.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CEventAbsoluteTag::GetPercentage( void )
+{
+ return m_flPercentage;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetPercentage( float percentage )
+{
+ m_flPercentage = percentage;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CEventAbsoluteTag::GetEventTime( void )
+{
+ Assert( m_pOwner );
+ if ( !m_pOwner )
+ {
+ return 0.0f;
+ }
+
+ float ownerduration = m_pOwner->GetDuration();
+
+ return (m_flPercentage * ownerduration);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetEventTime( float t )
+{
+ Assert( m_pOwner );
+ if ( !m_pOwner )
+ {
+ return;
+ }
+
+ float ownerduration = m_pOwner->GetDuration();
+
+ m_flPercentage = (t / ownerduration);
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CEventAbsoluteTag::GetAbsoluteTime( void )
+{
+ Assert( m_pOwner );
+ if ( !m_pOwner )
+ {
+ return 0.0f;
+ }
+
+ float ownerstart = m_pOwner->GetStartTime();
+ float ownerduration = m_pOwner->GetDuration();
+
+ return (ownerstart + m_flPercentage * ownerduration);
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : percentage -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetAbsoluteTime( float t )
+{
+ Assert( m_pOwner );
+ if ( !m_pOwner )
+ {
+ return;
+ }
+
+ float ownerstart = m_pOwner->GetStartTime();
+ float ownerduration = m_pOwner->GetDuration();
+
+ m_flPercentage = (t - ownerstart) / ownerduration;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+CChoreoEvent *CEventAbsoluteTag::GetOwner( void )
+{
+ return m_pOwner;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetOwner( CChoreoEvent *event )
+{
+ m_pOwner = event;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetLocked( bool bLocked )
+{
+ m_bLocked = bLocked;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+bool CEventAbsoluteTag::GetLocked( void )
+{
+ return m_bLocked;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetLinear( bool bLinear )
+{
+ m_bLinear = bLinear;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+bool CEventAbsoluteTag::GetLinear( void )
+{
+ return m_bLinear;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetEntry( bool bEntry )
+{
+ m_bEntry = bEntry;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+bool CEventAbsoluteTag::GetEntry( void )
+{
+ return m_bEntry;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CEventAbsoluteTag::SetExit( bool bExit )
+{
+ m_bExit = bExit;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+bool CEventAbsoluteTag::GetExit( void )
+{
+ return m_bExit;
+}
+
+
+
+
+// FLEX ANIMATIONS
+//-----------------------------------------------------------------------------
+// Purpose: Constructor
+// Input : *event -
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack::CFlexAnimationTrack( CChoreoEvent *event )
+{
+ m_pEvent = event;
+ m_pControllerName = NULL;
+ m_bActive = false;
+ m_bCombo = false;
+ m_bServerSide = false;
+ m_nFlexControllerIndex[ 0 ] = m_nFlexControllerIndex[ 1 ] = -1;
+ m_nFlexControllerIndexRaw[ 0 ] = m_nFlexControllerIndexRaw[ 1 ] = LocalFlexController_t(-1);
+
+ // base track has range, combo is always 0..1
+ m_flMin = 0.0f;
+ m_flMax = 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : src -
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack::CFlexAnimationTrack( const CFlexAnimationTrack* src )
+{
+ m_pControllerName = NULL;
+ SetFlexControllerName( src->m_pControllerName ? src->m_pControllerName : "" );
+
+ m_bActive = src->m_bActive;
+ m_bCombo = src->m_bCombo;
+ m_bServerSide = src->m_bServerSide;
+
+ for ( int t = 0; t < 2; t++ )
+ {
+ m_Samples[ t ].Purge();
+ for ( int i = 0 ;i < src->m_Samples[ t ].Size(); i++ )
+ {
+ CExpressionSample s = src->m_Samples[ t ][ i ];
+ m_Samples[ t ].AddToTail( s );
+ }
+ }
+
+ for ( int side = 0; side < 2; side++ )
+ {
+ m_nFlexControllerIndex[ side ] = src->m_nFlexControllerIndex[ side ];
+ m_nFlexControllerIndexRaw[ side ] = src->m_nFlexControllerIndexRaw[ side ];
+ }
+
+ m_flMin = src->m_flMin;
+ m_flMax = src->m_flMax;
+
+ m_EdgeInfo[ 0 ] = src->m_EdgeInfo[ 0 ];
+ m_EdgeInfo[ 1 ] = src->m_EdgeInfo[ 1 ];
+
+ m_pEvent = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack::~CFlexAnimationTrack( void )
+{
+ delete[] m_pControllerName;
+
+ for ( int t = 0; t < 2; t++ )
+ {
+ m_Samples[ t ].Purge();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *event -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetEvent( CChoreoEvent *event )
+{
+ m_pEvent = event;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::Clear( void )
+{
+ for ( int t = 0; t < 2; t++ )
+ {
+ m_Samples[ t ].RemoveAll();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::RemoveSample( int index, int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ m_Samples[ type ].Remove( index );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetFlexControllerName( const char *name )
+{
+ delete[] m_pControllerName;
+ int len = Q_strlen( name ) + 1;
+ m_pControllerName = new char[ len ];
+ Q_strncpy( m_pControllerName, name, len );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CFlexAnimationTrack::GetFlexControllerName( void )
+{
+ return m_pControllerName ? m_pControllerName : "";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CFlexAnimationTrack::GetNumSamples( int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ return m_Samples[ type ].Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+// Output : CExpressionSample
+//-----------------------------------------------------------------------------
+CExpressionSample *CFlexAnimationTrack::GetSample( int index, int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ if ( index < 0 || index >= GetNumSamples( type ) )
+ return NULL;
+ return &m_Samples[ type ][ index ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CFlexAnimationTrack::IsTrackActive( void )
+{
+ return m_bActive;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : active -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetTrackActive( bool active )
+{
+ m_bActive = active;
+}
+
+void CFlexAnimationTrack::SetEdgeInfo( bool leftEdge, int curveType, float zero )
+{
+ int idx = leftEdge ? 0 : 1;
+ m_EdgeInfo[ idx ].m_CurveType = curveType;
+ m_EdgeInfo[ idx ].m_flZeroPos = zero;
+}
+
+void CFlexAnimationTrack::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
+{
+ int idx = leftEdge ? 0 : 1;
+ curveType = m_EdgeInfo[ idx ].m_CurveType;
+ zero = m_EdgeInfo[ idx ].m_flZeroPos;
+}
+
+void CFlexAnimationTrack::SetEdgeActive( bool leftEdge, bool state )
+{
+ int idx = leftEdge ? 0 : 1;
+ m_EdgeInfo[ idx ].m_bActive = state;
+}
+
+bool CFlexAnimationTrack::IsEdgeActive( bool leftEdge ) const
+{
+ int idx = leftEdge ? 0 : 1;
+ return m_EdgeInfo[ idx ].m_bActive;
+}
+
+int CFlexAnimationTrack::GetEdgeCurveType( bool leftEdge ) const
+{
+ if ( !IsEdgeActive( leftEdge ) )
+ {
+ return CURVE_DEFAULT;
+ }
+
+ int idx = leftEdge ? 0 : 1;
+ return m_EdgeInfo[ idx ].m_CurveType;
+}
+
+float CFlexAnimationTrack::GetEdgeZeroValue( bool leftEdge ) const
+{
+ if ( !IsEdgeActive( leftEdge ) )
+ {
+ return 0.0f;
+ }
+
+ int idx = leftEdge ? 0 : 1;
+ return m_EdgeInfo[ idx ].m_flZeroPos;
+}
+
+float CFlexAnimationTrack::GetDefaultEdgeZeroPos() const
+{
+ float zero = 0.0f;
+ if ( m_flMin != m_flMax )
+ {
+ zero = ( 0.0f - m_flMin ) / ( m_flMax - m_flMin );
+ }
+ return zero;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetZeroValue( int type, bool leftSide )
+{
+ // Stereo track is always clamped to 0.5 and doesn't care about l/r settings
+ if ( type == 1 )
+ {
+ return 0.5f;
+ }
+
+ if ( IsEdgeActive( leftSide ) )
+ {
+ return GetEdgeZeroValue( leftSide );
+ }
+
+ return GetDefaultEdgeZeroPos();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : number -
+// Output : CExpressionSample
+//-----------------------------------------------------------------------------
+CExpressionSample *CFlexAnimationTrack::GetBoundedSample( int number, bool& bClamped, int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ if ( number < 0 )
+ {
+ // Search for two samples which span time f
+ static CExpressionSample nullstart;
+ nullstart.time = 0.0f;
+ nullstart.value = GetZeroValue( type, true );
+ if ( type == 0 )
+ {
+ nullstart.SetCurveType( GetEdgeCurveType( true ) );
+ }
+ else
+ {
+ nullstart.SetCurveType( CURVE_DEFAULT );
+ }
+ bClamped = true;
+ return &nullstart;
+ }
+ else if ( number >= GetNumSamples( type ) )
+ {
+ static CExpressionSample nullend;
+ nullend.time = m_pEvent->GetDuration();
+ nullend.value = GetZeroValue( type, false );
+ if ( type == 0 )
+ {
+ nullend.SetCurveType( GetEdgeCurveType( false ) );
+ }
+ else
+ {
+ nullend.SetCurveType( CURVE_DEFAULT );
+ }
+ bClamped = true;
+ return &nullend;
+ }
+
+ bClamped = false;
+ return GetSample( number, type );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// type -
+// Output : float
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetIntensityInternal( float time, int type )
+{
+ Assert( type == 0 || type == 1 );
+
+ float retval = 0.0f;
+
+ // find samples that span the time
+ if ( !m_pEvent || !m_pEvent->HasEndTime() || time < m_pEvent->GetStartTime() )
+ {
+ retval = GetZeroValue( type, true );;
+ }
+ else if ( time > m_pEvent->GetEndTime() )
+ {
+ retval = GetZeroValue( type, false );;
+ }
+ else
+ {
+ float elapsed = time - m_pEvent->GetStartTime();
+ retval = GetFracIntensity( elapsed, type );
+ }
+
+ // scale
+ if (type == 0 && m_flMin != m_flMax)
+ {
+ retval = retval * (m_flMax - m_flMin) + m_flMin;
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// type -
+// Output : float
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetFracIntensity( float time, int type )
+{
+ float zeroValueLeft = GetZeroValue( type, true );
+
+ Assert( type == 0 || type == 1 );
+
+ // find samples that span the time
+ if ( !m_pEvent || !m_pEvent->HasEndTime() )
+ return zeroValueLeft;
+
+ int rampCount = GetNumSamples( type );
+ if ( rampCount < 1 )
+ {
+ return zeroValueLeft;
+ }
+
+ CExpressionSample *esStart = NULL;
+ CExpressionSample *esEnd = NULL;
+
+ // do binary search for sample in time period
+ int j = MAX( rampCount / 2, 1 );
+ int i = j;
+ while ( i > -2 && i < rampCount + 1 )
+ {
+ bool dummy;
+ esStart = GetBoundedSample( i, dummy, type );
+ esEnd = GetBoundedSample( i + 1, dummy, type );
+
+ j = MAX( j / 2, 1 );
+ if ( time < esStart->time)
+ {
+ i -= j;
+ }
+ else if ( time > esEnd->time)
+ {
+ i += j;
+ }
+ else
+ {
+ if ( time == esEnd->time )
+ {
+ ++i;
+ esStart = GetBoundedSample( i, dummy, type );
+ esEnd = GetBoundedSample( i + 1, dummy, type );
+ }
+ break;
+ }
+ }
+
+ if (!esStart)
+ {
+ return zeroValueLeft;
+ }
+
+ int prev = i - 1;
+ int next = i + 2;
+
+ prev = MAX( -1, prev );
+ next = MIN( next, rampCount );
+
+ bool bclamp[ 2 ];
+ CExpressionSample *esPre = GetBoundedSample( prev, bclamp[ 0 ], type );
+ CExpressionSample *esNext = GetBoundedSample( next, bclamp[ 1 ], type );
+
+ float dt = esEnd->time - esStart->time;
+
+ Vector vPre( esPre->time, esPre->value, 0 );
+ Vector vStart( esStart->time, esStart->value, 0 );
+ Vector vEnd( esEnd->time, esEnd->value, 0 );
+ Vector vNext( esNext->time, esNext->value, 0 );
+
+ float f2 = 0.0f;
+ if ( dt > 0.0f )
+ {
+ f2 = ( time - esStart->time ) / ( dt );
+ }
+ f2 = clamp( f2, 0.0f, 1.0f );
+
+ Vector vOut;
+ int dummy;
+ int earlypart, laterpart;
+
+ // Not holding out value of previous curve...
+ Interpolator_CurveInterpolatorsForType( esStart->GetCurveType(), dummy, earlypart );
+ Interpolator_CurveInterpolatorsForType( esEnd->GetCurveType(), laterpart, dummy );
+
+ if ( earlypart == INTERPOLATE_HOLD )
+ {
+ // Hold "out" of previous sample (can cause a discontinuity)
+ VectorLerp( vStart, vEnd, f2, vOut );
+ vOut.y = vStart.y;
+ }
+ else if ( laterpart == INTERPOLATE_HOLD )
+ {
+ // Hold "out" of previous sample (can cause a discontinuity)
+ VectorLerp( vStart, vEnd, f2, vOut );
+ vOut.y = vEnd.y;
+ }
+ else
+ {
+ bool sameCurveType = earlypart == laterpart ? true : false;
+ if ( sameCurveType )
+ {
+ Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
+ }
+ else // curves differ, sigh
+ {
+ Vector vOut1, vOut2;
+
+ Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
+ Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
+
+ VectorLerp( vOut1, vOut2, f2, vOut );
+ }
+ }
+
+ float retval = clamp( vOut.y, 0.0f, 1.0f );
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// Output : float
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetSampleIntensity( float time )
+{
+ return GetIntensityInternal( time, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// Output : float
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetBalanceIntensity( float time )
+{
+ if ( IsComboType() )
+ {
+ return GetIntensityInternal( time, 1 );
+ }
+
+ return 1.0f;
+}
+
+// For a given time, computes 0->1 intensity value for the slider
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// Output : float
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetIntensity( float time, int side )
+{
+ float mag = GetSampleIntensity( time );
+
+ float scale = 1.0f;
+
+ if ( IsComboType() )
+ {
+ float balance = GetBalanceIntensity( time );
+
+ // Asking for left but balance is to right, then fall off as we go
+ // further right
+ if ( side == 0 && balance > 0.5f )
+ {
+ scale = (1.0f - balance ) / 0.5f;
+ }
+ // Asking for right, but balance is left, fall off as we go left.
+ else if ( side == 1 && balance < 0.5f )
+ {
+ scale = ( balance / 0.5f );
+ }
+ }
+
+ return mag * scale;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : time -
+// value -
+//-----------------------------------------------------------------------------
+CExpressionSample *CFlexAnimationTrack::AddSample( float time, float value, int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ CExpressionSample sample;
+ sample.time = time;
+ sample.value = value;
+ sample.selected = false;
+
+ int idx = m_Samples[ type ].AddToTail( sample );
+
+ // Resort( type );
+ return &m_Samples[ type ][ idx ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::Resort( int type /*=0*/ )
+{
+ Assert( type == 0 || type == 1 );
+
+ for ( int i = 0; i < m_Samples[ type ].Size(); i++ )
+ {
+ for ( int j = i + 1; j < m_Samples[ type ].Size(); j++ )
+ {
+ CExpressionSample src = m_Samples[ type ][ i ];
+ CExpressionSample dest = m_Samples[ type ][ j ];
+
+ if ( src.time > dest.time )
+ {
+ m_Samples[ type ][ i ] = dest;
+ m_Samples[ type ][ j ] = src;
+ }
+ }
+ }
+
+ // Make sure nothing is out of range
+ RemoveOutOfRangeSamples( 0 );
+ RemoveOutOfRangeSamples( 1 );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoEvent
+//-----------------------------------------------------------------------------
+CChoreoEvent *CFlexAnimationTrack::GetEvent( void )
+{
+ return m_pEvent;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : side -
+// Output : int
+//-----------------------------------------------------------------------------
+int CFlexAnimationTrack::GetFlexControllerIndex( int side /*= 0*/ )
+{
+ Assert( side == 0 || side == 1 );
+
+ if ( IsComboType() )
+ {
+ return m_nFlexControllerIndex[ side ];
+ }
+
+ return m_nFlexControllerIndex[ 0 ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : side -
+// Output : int
+//-----------------------------------------------------------------------------
+LocalFlexController_t CFlexAnimationTrack::GetRawFlexControllerIndex( int side /*= 0*/ )
+{
+ Assert( side == 0 || side == 1 );
+
+ if ( IsComboType() )
+ {
+ return m_nFlexControllerIndexRaw[ side ];
+ }
+
+ return m_nFlexControllerIndexRaw[ 0 ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+// side -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetFlexControllerIndex( LocalFlexController_t raw, int index, int side /*= 0*/ )
+{
+ Assert( side == 0 || side == 1 );
+
+ m_nFlexControllerIndex[ side ] = index;
+ // Model specific
+ m_nFlexControllerIndexRaw[ side ] = raw;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : combo -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetComboType( bool combo )
+{
+ m_bCombo = combo;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CFlexAnimationTrack::IsComboType( void )
+{
+ return m_bCombo;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: True if this should be simulated on the server side always
+// Input : state -
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetServerSide( bool state )
+{
+ m_bServerSide = state;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CFlexAnimationTrack::IsServerSide() const
+{
+ return m_bServerSide;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetMin( float value )
+{
+ m_flMin = value;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetMax( float value )
+{
+ m_flMax = value;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetMin( int type )
+{
+ if (type == 0)
+ return m_flMin;
+ else
+ return 0.0f;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+float CFlexAnimationTrack::GetMax( int type )
+{
+ if (type == 0)
+ return m_flMax;
+ else
+ return 1.0f;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CFlexAnimationTrack::IsInverted( void )
+{
+ if (m_bInverted)
+ return true;
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::SetInverted( bool isInverted )
+{
+ m_bInverted = isInverted;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+void CFlexAnimationTrack::RemoveOutOfRangeSamples( int type )
+{
+ Assert( m_pEvent );
+ if ( !m_pEvent )
+ return;
+
+ Assert( m_pEvent->HasEndTime() );
+ float duration = m_pEvent->GetDuration();
+
+ int c = m_Samples[ type ].Size();
+ for ( int i = c-1; i >= 0; i-- )
+ {
+ CExpressionSample src = m_Samples[ type ][ i ];
+ if ( src.time < 0 ||
+ src.time > duration )
+ {
+ m_Samples[ type ].Remove( i );
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CChoreoEvent::CChoreoEvent( CChoreoScene *scene )
+{
+ Init( scene );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *name -
+//-----------------------------------------------------------------------------
+CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name )
+{
+ Init( scene );
+ SetType( type );
+ SetName( name );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *name -
+// *param -
+//-----------------------------------------------------------------------------
+CChoreoEvent::CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name, const char *param )
+{
+ Init( scene );
+ SetType( type );
+ SetName( name );
+ SetParameters( param );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+CChoreoEvent::~CChoreoEvent( void )
+{
+ RemoveAllTracks();
+ ClearEventDependencies();
+ delete m_pSubScene;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Assignment
+// Input : src -
+// Output : CChoreoEvent&
+//-----------------------------------------------------------------------------
+CChoreoEvent& CChoreoEvent::operator=( const CChoreoEvent& src )
+{
+ MEM_ALLOC_CREDIT();
+
+ // Copy global id when copying entity
+ m_nGlobalID = src.m_nGlobalID;
+
+ m_pActor = NULL;
+ m_pChannel = NULL;
+
+ m_nDefaultCurveType = src.m_nDefaultCurveType;
+ m_fType = src.m_fType;
+ m_Name = src.m_Name;
+ m_Parameters = src.m_Parameters;
+ m_Parameters2= src.m_Parameters2;
+ m_Parameters3= src.m_Parameters3;
+ m_flStartTime = src.m_flStartTime;
+ m_flEndTime = src.m_flEndTime;
+
+ m_bFixedLength = src.m_bFixedLength;
+ m_flGestureSequenceDuration = src.m_flGestureSequenceDuration;
+ m_bResumeCondition = src.m_bResumeCondition;
+ m_bLockBodyFacing = src.m_bLockBodyFacing;
+ m_flDistanceToTarget = src.m_flDistanceToTarget;
+ m_bForceShortMovement = src.m_bForceShortMovement;
+ m_bSyncToFollowingGesture = src.m_bSyncToFollowingGesture;
+ m_bPlayOverScript = src.m_bPlayOverScript;
+ m_bUsesTag = src.m_bUsesTag;
+ m_TagName = src.m_TagName;
+ m_TagWavName = src.m_TagWavName;
+
+ ClearAllRelativeTags();
+ ClearAllTimingTags();
+ int t;
+ for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
+ {
+ ClearAllAbsoluteTags( (AbsTagType)t );
+ }
+
+ int i;
+ for ( i = 0; i < src.m_RelativeTags.Size(); i++ )
+ {
+ CEventRelativeTag newtag( src.m_RelativeTags[ i ] );
+ newtag.SetOwner( this );
+ m_RelativeTags.AddToTail( newtag );
+ }
+
+ for ( i = 0; i < src.m_TimingTags.Size(); i++ )
+ {
+ CFlexTimingTag newtag( src.m_TimingTags[ i ] );
+ newtag.SetOwner( this );
+ m_TimingTags.AddToTail( newtag );
+ }
+ for ( t = 0; t < NUM_ABS_TAG_TYPES; t++ )
+ {
+ for ( i = 0; i < src.m_AbsoluteTags[ t ].Size(); i++ )
+ {
+ CEventAbsoluteTag newtag( src.m_AbsoluteTags[ t ][ i ] );
+ newtag.SetOwner( this );
+ m_AbsoluteTags[ t ].AddToTail( newtag );
+ }
+ }
+
+ RemoveAllTracks();
+
+ for ( i = 0 ; i < src.m_FlexAnimationTracks.Size(); i++ )
+ {
+ CFlexAnimationTrack *newtrack = new CFlexAnimationTrack( src.m_FlexAnimationTracks[ i ] );
+ newtrack->SetEvent( this );
+ m_FlexAnimationTracks.AddToTail( newtrack );
+ }
+
+ m_bTrackLookupSet = src.m_bTrackLookupSet;
+
+ // FIXME: Use a safe handle?
+ //m_pSubScene = src.m_pSubScene;
+
+ m_bProcessing = src.m_bProcessing;
+ m_pMixer = src.m_pMixer;
+
+ m_pScene = src.m_pScene;
+
+ m_nPitch = src.m_nPitch;
+ m_nYaw = src.m_nYaw;
+
+ m_nNumLoops = src.m_nNumLoops;
+ m_nLoopsRemaining = src.m_nLoopsRemaining;
+
+ // Copy ramp over
+ m_Ramp = src.m_Ramp;
+
+ m_ccType = src.m_ccType;
+ m_CCToken = src.m_CCToken;
+ m_bUsingCombinedSoundFile = src.m_bUsingCombinedSoundFile;
+ m_uRequiredCombinedChecksum = src.m_uRequiredCombinedChecksum;
+ m_nNumSlaves = src.m_nNumSlaves;
+ m_flLastSlaveEndTime = src.m_flLastSlaveEndTime;
+ m_bCCTokenValid = src.m_bCCTokenValid;
+ m_bCombinedUsingGenderToken = src.m_bCombinedUsingGenderToken;
+
+ m_bSuppressCaptionAttenuation = src.m_bSuppressCaptionAttenuation;
+
+ m_bActive = src.m_bActive;
+
+ return *this;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::Init( CChoreoScene *scene )
+{
+ m_nGlobalID = s_nGlobalID++;
+ m_nDefaultCurveType = CURVE_CATMULL_ROM_TO_CATMULL_ROM;
+ m_fType = UNSPECIFIED;
+ m_Name.Set("");
+ m_Parameters.Set("");
+ m_Parameters2.Set("");
+ m_Parameters3.Set("");
+
+ m_flStartTime = 0.0f;
+ m_flEndTime = -1.0f;
+
+ m_pActor = NULL;
+ m_pChannel = NULL;
+ m_pScene = scene;
+
+ m_bFixedLength = false;
+ m_bResumeCondition = false;
+ SetUsingRelativeTag( false, 0, 0 );
+
+ m_bTrackLookupSet = false;
+
+ m_bLockBodyFacing = false;
+ m_flDistanceToTarget = 0.0f;
+ m_bForceShortMovement = false;
+ m_bSyncToFollowingGesture = false;
+ m_bPlayOverScript = false;
+
+ m_pSubScene = NULL;
+ m_bProcessing = false;
+ m_pMixer = NULL;
+ m_flGestureSequenceDuration = 0.0f;
+
+ m_nPitch = m_nYaw = 0;
+
+ m_nNumLoops = -1;
+ m_nLoopsRemaining = 0;
+
+ // Close captioning/localization support
+ m_CCToken.Set("");
+ m_ccType = CC_MASTER;
+ m_bUsingCombinedSoundFile = false;
+ m_uRequiredCombinedChecksum = 0;
+ m_nNumSlaves = 0;
+ m_flLastSlaveEndTime = 0.0f;
+ m_bCCTokenValid = false;
+ m_bCombinedUsingGenderToken = false;
+ m_bSuppressCaptionAttenuation = false;
+ m_bActive = true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+CChoreoEvent::EVENTTYPE CChoreoEvent::GetType( void )
+{
+ return (EVENTTYPE)m_fType;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetType( EVENTTYPE type )
+{
+ m_fType = type;
+
+ if ( m_fType == SPEAK ||
+ m_fType == SUBSCENE )
+ {
+ m_bFixedLength = true;
+ }
+ else
+ {
+ m_bFixedLength = false;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetName( const char *name )
+{
+ m_Name = name;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetName( void )
+{
+ return m_Name.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *param -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetParameters( const char *param )
+{
+ m_Parameters = param;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetParameters( void )
+{
+ return m_Parameters.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *param -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetParameters2( const char *param )
+{
+ int iLength = Q_strlen( param );
+ m_Parameters2 = param;
+
+ // HACK: Remove trailing " " until faceposer is fixed
+ if ( iLength > 0 )
+ {
+ if ( param[iLength-1] == ' ' )
+ {
+ char tmp[1024];
+ Q_strncpy( tmp, param, sizeof(tmp) );
+ tmp[iLength-1] = 0;
+ m_Parameters2.Set(tmp);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetParameters2( void )
+{
+ return m_Parameters2.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *param -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetParameters3( const char *param )
+{
+ int iLength = Q_strlen( param );
+ m_Parameters3 = param;
+
+ // HACK: Remove trailing " " until faceposer is fixed
+ if ( iLength > 0 )
+ {
+ if ( param[iLength-1] == ' ' )
+ {
+ char tmp[1024];
+ Q_strncpy( tmp, param, sizeof(tmp) );
+ tmp[iLength-1] = 0;
+ m_Parameters3.Set(tmp);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetParameters3( void )
+{
+ return m_Parameters3.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: debugging description
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetDescription( void )
+{
+ static char description[ 256 ];
+
+ description[ 0 ] = 0;
+
+ if ( !GetActor() )
+ {
+ Q_snprintf( description,sizeof(description), "global %s", m_Name.Get() );
+ }
+ else
+ {
+ Assert( m_pChannel );
+ Q_snprintf( description,sizeof(description), "%s : %s : %s -- %s \"%s\"", m_pActor->GetName(), m_pChannel->GetName(), GetName(), NameForType( GetType() ), GetParameters() );
+ if ( GetType() == EXPRESSION )
+ {
+ char sz[ 256 ];
+
+ Q_snprintf( sz,sizeof(sz), " \"%s\"", GetParameters2() );
+ Q_strncat( description, sz, sizeof(description), COPY_ALL_CHARACTERS );
+ }
+ }
+
+ return description;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : starttime -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetStartTime( float starttime )
+{
+ m_flStartTime = starttime;
+ if ( m_flEndTime != -1.0f )
+ {
+ if ( m_flEndTime < m_flStartTime )
+ {
+ m_flEndTime = m_flStartTime;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetStartTime( )
+{
+ return m_flStartTime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : endtime -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetEndTime( float endtime )
+{
+ bool changed = m_flEndTime != endtime;
+
+ m_flEndTime = endtime;
+
+ if ( endtime != -1.0f )
+ {
+ if ( m_flEndTime < m_flStartTime )
+ {
+ m_flEndTime = m_flStartTime;
+ }
+
+ if ( changed )
+ {
+ OnEndTimeChanged();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetEndTime( )
+{
+ return m_flEndTime;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::HasEndTime( void )
+{
+ return m_flEndTime != -1.0f ? true : false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetCompletion( float time )
+{
+ float t = (time - GetStartTime()) / (GetEndTime() - GetStartTime());
+
+ if (t < 0.0f)
+ return 0.0f;
+ else if (t > 1.0f)
+ return 1.0f;
+
+ return t;
+}
+
+// ICurveDataAccessor method
+bool CChoreoEvent::CurveHasEndTime()
+{
+ return HasEndTime();
+}
+
+//-----------------------------------------------------------------------------
+// Default curve type
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetDefaultCurveType( int nCurveType )
+{
+ m_nDefaultCurveType = nCurveType;
+}
+
+int CChoreoEvent::GetDefaultCurveType()
+{
+ return m_nDefaultCurveType;
+}
+
+float CCurveData::GetIntensity( ICurveDataAccessor *data, float time )
+{
+ float zeroValue = 0.0f;
+
+ // find samples that span the time
+ if ( !data->CurveHasEndTime() )
+ {
+ return zeroValue;
+ }
+
+ int rampCount = GetCount();
+ if ( rampCount < 1 )
+ {
+ // Full intensity
+ return 1.0f;
+ }
+
+ CExpressionSample *esStart = NULL;
+ CExpressionSample *esEnd = NULL;
+
+ // do binary search for sample in time period
+ int j = MAX( rampCount / 2, 1 );
+ int i = j;
+ while ( i > -2 && i < rampCount + 1 )
+ {
+ bool dummy;
+ esStart = GetBoundedSample( data, i, dummy );
+ esEnd = GetBoundedSample( data, i + 1, dummy );
+
+ j = MAX( j / 2, 1 );
+ if ( time < esStart->time)
+ {
+ i -= j;
+ }
+ else if ( time > esEnd->time)
+ {
+ i += j;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (!esStart)
+ {
+ return 1.0f;
+ }
+
+ int prev = i - 1;
+ int next = i + 2;
+
+ prev = MAX( -1, prev );
+ next = MIN( next, rampCount );
+
+ bool bclamp[ 2 ];
+ CExpressionSample *esPre = GetBoundedSample( data, prev, bclamp[ 0 ] );
+ CExpressionSample *esNext = GetBoundedSample( data, next, bclamp[ 1 ] );
+
+ float dt = esEnd->time - esStart->time;
+
+ Vector vPre( esPre->time, esPre->value, 0 );
+ Vector vStart( esStart->time, esStart->value, 0 );
+ Vector vEnd( esEnd->time, esEnd->value, 0 );
+ Vector vNext( esNext->time, esNext->value, 0 );
+
+ if ( bclamp[ 0 ] )
+ {
+ vPre.x = vStart.x;
+ }
+
+ if ( bclamp[ 1 ] )
+ {
+ vNext.x = vEnd.x;
+ }
+
+ float f2 = 0.0f;
+ if ( dt > 0.0f )
+ {
+ f2 = ( time - esStart->time ) / ( dt );
+ }
+ f2 = clamp( f2, 0.0f, 1.0f );
+
+ Vector vOut;
+ int dummy;
+ int earlypart, laterpart;
+
+ int startCurve = esStart->GetCurveType();
+ int endCurve = esEnd->GetCurveType();
+
+ if ( startCurve == CURVE_DEFAULT )
+ {
+ startCurve = data->GetDefaultCurveType();
+ }
+ if ( endCurve == CURVE_DEFAULT )
+ {
+ endCurve = data->GetDefaultCurveType();
+ }
+
+ // Not holding out value of previous curve...
+ Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
+ Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
+
+ if ( earlypart == INTERPOLATE_HOLD )
+ {
+ // Hold "out" of previous sample (can cause a discontinuity)
+ VectorLerp( vStart, vEnd, f2, vOut );
+ vOut.y = vStart.y;
+ }
+ else if ( laterpart == INTERPOLATE_HOLD )
+ {
+ // Hold "out" of previous sample (can cause a discontinuity)
+ VectorLerp( vStart, vEnd, f2, vOut );
+ vOut.y = vEnd.y;
+ }
+ else
+ {
+ bool sameCurveType = earlypart == laterpart ? true : false;
+ if ( sameCurveType )
+ {
+ Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut );
+ }
+ else // curves differ, sigh
+ {
+ Vector vOut1, vOut2;
+
+ Interpolator_CurveInterpolate( earlypart, vPre, vStart, vEnd, vNext, f2, vOut1 );
+ Interpolator_CurveInterpolate( laterpart, vPre, vStart, vEnd, vNext, f2, vOut2 );
+
+ VectorLerp( vOut1, vOut2, f2, vOut );
+ }
+ }
+
+ float retval = clamp( vOut.y, 0.0f, 1.0f );
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Get intensity for event, bounded by scene global intensity
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetIntensity( float scenetime )
+{
+ float global_intensity = 1.0f;
+ if ( m_pScene )
+ {
+ global_intensity = m_pScene->GetSceneRampIntensity( scenetime );
+ }
+ else
+ {
+ Assert( 0 );
+ }
+
+ float event_intensity = _GetIntensity( scenetime );
+
+ return global_intensity * event_intensity;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::_GetIntensity( float scenetime )
+{
+ // Convert to event local time
+ float time = scenetime - GetStartTime();
+ return m_Ramp.GetIntensity( this, time );
+}
+
+
+float CChoreoEvent::GetIntensityArea( float scenetime )
+{
+ // Convert to event local time
+ float time = scenetime - GetStartTime();
+ return m_Ramp.GetIntensityArea( this, time );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CCurveData::GetIntensityArea( ICurveDataAccessor *data, float time )
+{
+ float zeroValue = 0.0f;
+
+ // find samples that span the time
+ if ( !data->CurveHasEndTime() )
+ {
+ return zeroValue;
+ }
+
+ int rampCount = GetCount();
+ if ( rampCount < 1 )
+ {
+ // Full intensity
+ return 1.0f;
+ }
+
+ CExpressionSample *esStart = NULL;
+ CExpressionSample *esEnd = NULL;
+
+ // do binary search for sample in time period
+ int j = MAX( rampCount / 2, 1 );
+ int i = j;
+ while ( i > -2 && i < rampCount + 1 )
+ {
+ bool dummy;
+ esStart = GetBoundedSample( data, i, dummy );
+ esEnd = GetBoundedSample( data, i + 1, dummy );
+
+ j = MAX( j / 2, 1 );
+ if ( time < esStart->time)
+ {
+ i -= j;
+ }
+ else if ( time > esEnd->time)
+ {
+ i += j;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ UpdateIntensityArea( data );
+
+ float flTotal = 0.0f;
+ flTotal = m_RampAccumulator[i+1];
+
+ int prev = i - 1;
+ int next = i + 2;
+
+ prev = MAX( -1, prev );
+ next = MIN( next, rampCount );
+
+ bool bclamp[ 2 ];
+ CExpressionSample *esPre = GetBoundedSample( data, prev, bclamp[ 0 ] );
+ CExpressionSample *esNext = GetBoundedSample( data, next, bclamp[ 1 ] );
+
+ float dt = esEnd->time - esStart->time;
+
+ Vector vPre( esPre->time, esPre->value, 0 );
+ Vector vStart( esStart->time, esStart->value, 0 );
+ Vector vEnd( esEnd->time, esEnd->value, 0 );
+ Vector vNext( esNext->time, esNext->value, 0 );
+
+ if ( bclamp[ 0 ] )
+ {
+ vPre.x = vStart.x;
+ }
+
+ if ( bclamp[ 1 ] )
+ {
+ vNext.x = vEnd.x;
+ }
+
+ float f2 = 0.0f;
+ if ( dt > 0.0f )
+ {
+ f2 = ( time - esStart->time ) / ( dt );
+ }
+ f2 = clamp( f2, 0.0f, 1.0f );
+
+ Vector vOut;
+ int dummy;
+ int earlypart, laterpart;
+
+ int startCurve = esStart->GetCurveType();
+ int endCurve = esEnd->GetCurveType();
+
+ if ( startCurve == CURVE_DEFAULT )
+ {
+ startCurve = data->GetDefaultCurveType();
+ }
+ if ( endCurve == CURVE_DEFAULT )
+ {
+ endCurve = data->GetDefaultCurveType();
+ }
+
+ // Not holding out value of previous curve...
+ Interpolator_CurveInterpolatorsForType( startCurve, dummy, earlypart );
+ Interpolator_CurveInterpolatorsForType( endCurve, laterpart, dummy );
+
+ // FIXME: needs other curve types
+ Catmull_Rom_Spline_Integral_Normalize(
+ vPre,
+ vStart,
+ vEnd,
+ vNext,
+ f2,
+ vOut );
+
+ // Con_Printf( "Accum %f : Partial %f\n", flTotal, vOut.y * (vEnd.x - vStart.x) * f2 );
+ flTotal = flTotal + clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
+ return flTotal;
+}
+
+
+void CCurveData::UpdateIntensityArea( ICurveDataAccessor *data )
+{
+ int rampCount = GetCount();;
+ if ( rampCount < 1 )
+ {
+ return;
+ }
+
+ if (m_RampAccumulator.Count() == rampCount + 2)
+ {
+ return;
+ }
+
+ m_RampAccumulator.SetCount( rampCount + 2 );
+
+ int i = -1;
+
+ bool dummy;
+ CExpressionSample *esPre = GetBoundedSample( data, i - 1, dummy );
+ CExpressionSample *esStart = GetBoundedSample( data, i, dummy );
+ CExpressionSample *esEnd = GetBoundedSample( data, MIN( i + 1, rampCount ), dummy );
+
+ Vector vPre( esPre->time, esPre->value, 0 );
+ Vector vStart( esStart->time, esStart->value, 0 );
+ Vector vEnd( esEnd->time, esEnd->value, 0 );
+
+ Vector vOut;
+ for (i = -1; i < rampCount; i++)
+ {
+ CExpressionSample *esNext = GetBoundedSample( data, MIN( i + 2, rampCount ), dummy );
+ Vector vNext( esNext->time, esNext->value, 0 );
+
+ Catmull_Rom_Spline_Integral_Normalize(
+ vPre,
+ vStart,
+ vEnd,
+ vNext,
+ 1.0f,
+ vOut );
+
+ m_RampAccumulator[i+1] = clamp( vOut.y, 0.0f, 1.0f ) * (vEnd.x - vStart.x);
+
+ vPre = vStart;
+ vStart = vEnd;
+ vEnd = vNext;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dt -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::OffsetStartTime( float dt )
+{
+ SetStartTime( GetStartTime() + dt );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dt -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::OffsetEndTime( float dt )
+{
+ if ( HasEndTime() )
+ {
+ SetEndTime( GetEndTime() + dt );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : dt -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::OffsetTime( float dt )
+{
+ if ( HasEndTime() )
+ {
+ m_flEndTime += dt;
+ }
+ m_flStartTime += dt;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *actor -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetActor( CChoreoActor *actor )
+{
+ m_pActor = actor;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoActor
+//-----------------------------------------------------------------------------
+CChoreoActor *CChoreoEvent::GetActor( void )
+{
+ return m_pActor;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *channel -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetChannel( CChoreoChannel *channel )
+{
+ m_pChannel = channel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoChannel
+//-----------------------------------------------------------------------------
+CChoreoChannel *CChoreoEvent::GetChannel( void )
+{
+ return m_pChannel;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *scene -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetSubScene( CChoreoScene *scene )
+{
+ m_pSubScene = scene;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoScene
+//-----------------------------------------------------------------------------
+CChoreoScene *CChoreoEvent::GetSubScene( void )
+{
+ return m_pSubScene;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+struct EventNameMap_t
+{
+ CChoreoEvent::EVENTTYPE type;
+ char const *name;
+};
+
+static EventNameMap_t g_NameMap[] =
+{
+ { CChoreoEvent::UNSPECIFIED, "unspecified" }, // error condition!!!
+ { CChoreoEvent::SECTION, "section" },
+ { CChoreoEvent::EXPRESSION, "expression" },
+ { CChoreoEvent::LOOKAT, "lookat" },
+ { CChoreoEvent::MOVETO, "moveto" },
+ { CChoreoEvent::SPEAK, "speak" },
+ { CChoreoEvent::GESTURE, "gesture" },
+ { CChoreoEvent::SEQUENCE, "sequence" },
+ { CChoreoEvent::FACE, "face" },
+ { CChoreoEvent::FIRETRIGGER, "firetrigger" },
+ { CChoreoEvent::FLEXANIMATION, "flexanimation" },
+ { CChoreoEvent::SUBSCENE, "subscene" },
+ { CChoreoEvent::LOOP, "loop" },
+ { CChoreoEvent::INTERRUPT, "interrupt" },
+ { CChoreoEvent::STOPPOINT, "stoppoint" },
+ { CChoreoEvent::PERMIT_RESPONSES, "permitresponses" },
+ { CChoreoEvent::GENERIC, "generic" },
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: A simple class to verify the names data above at runtime
+//-----------------------------------------------------------------------------
+class CCheckEventNames
+{
+public:
+ CCheckEventNames()
+ {
+ if ( ARRAYSIZE( g_NameMap ) != CChoreoEvent::NUM_TYPES )
+ {
+ Error( "g_NameMap contains %i entries, CChoreoEvent::NUM_TYPES == %i!",
+ ARRAYSIZE( g_NameMap ), CChoreoEvent::NUM_TYPES );
+ }
+ for ( int i = 0; i < CChoreoEvent::NUM_TYPES; ++i )
+ {
+ if ( !g_NameMap[ i ].name )
+ {
+ Error( "g_NameMap: Event type at %i has NULL name string!", i );
+ }
+
+ if ( (CChoreoEvent::EVENTTYPE)(i) == g_NameMap[ i ].type )
+ continue;
+
+ Error( "g_NameMap: Event type at %i has wrong value (%i)!",
+ i, (int)g_NameMap[ i ].type );
+ }
+ }
+};
+static CCheckEventNames g_CheckNamesSingleton;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+// Output : int
+//-----------------------------------------------------------------------------
+CChoreoEvent::EVENTTYPE CChoreoEvent::TypeForName( const char *name )
+{
+ for ( int i = 0; i < NUM_TYPES; ++i )
+ {
+ EventNameMap_t *slot = &g_NameMap[ i ];
+ if ( !Q_stricmp( name, slot->name ) )
+ return slot->type;
+ }
+
+ Assert( !"CChoreoEvent::TypeForName failed!!!" );
+ return UNSPECIFIED;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::NameForType( EVENTTYPE type )
+{
+ int i = (int)type;
+ if ( i < 0 || i >= NUM_TYPES )
+ {
+ Assert( "!CChoreoEvent::NameForType: bogus type!" );
+ // returns "unspecified!!!";
+ return g_NameMap[ 0 ].name;
+ }
+
+ return g_NameMap[ i ].name;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+struct CCNameMap_t
+{
+ CChoreoEvent::CLOSECAPTION type;
+ char const *name;
+};
+
+static CCNameMap_t g_CCNameMap[] =
+{
+ { CChoreoEvent::CC_MASTER, "cc_master" }, // error condition!!!
+ { CChoreoEvent::CC_SLAVE, "cc_slave" },
+ { CChoreoEvent::CC_DISABLED, "cc_disabled" },
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: A simple class to verify the names data above at runtime
+//-----------------------------------------------------------------------------
+class CCheckCCNames
+{
+public:
+ CCheckCCNames()
+ {
+ if ( ARRAYSIZE( g_CCNameMap ) != CChoreoEvent::NUM_CC_TYPES )
+ {
+ Error( "g_CCNameMap contains %i entries, CChoreoEvent::NUM_CC_TYPES == %i!",
+ ARRAYSIZE( g_CCNameMap ), CChoreoEvent::NUM_CC_TYPES );
+ }
+ for ( int i = 0; i < CChoreoEvent::NUM_CC_TYPES; ++i )
+ {
+ if ( !g_CCNameMap[ i ].name )
+ {
+ Error( "g_NameMap: CC type at %i has NULL name string!", i );
+ }
+
+ if ( (CChoreoEvent::CLOSECAPTION)(i) == g_CCNameMap[ i ].type )
+ continue;
+
+ Error( "g_CCNameMap: Event type at %i has wrong value (%i)!",
+ i, (int)g_CCNameMap[ i ].type );
+ }
+ }
+};
+static CCheckCCNames g_CheckCCNamesSingleton;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+// Output : CLOSECAPTION
+//-----------------------------------------------------------------------------
+CChoreoEvent::CLOSECAPTION CChoreoEvent::CCTypeForName( const char *name )
+{
+ for ( int i = 0; i < NUM_CC_TYPES; ++i )
+ {
+ CCNameMap_t *slot = &g_CCNameMap[ i ];
+ if ( !Q_stricmp( name, slot->name ) )
+ return slot->type;
+ }
+
+ Assert( !"CChoreoEvent::TypeForName failed!!!" );
+ return CC_MASTER;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::NameForCCType( CLOSECAPTION type )
+{
+ int i = (int)type;
+ if ( i < 0 || i >= NUM_CC_TYPES )
+ {
+ Assert( "!CChoreoEvent::NameForType: bogus type!" );
+ // returns "unspecified!!!";
+ return g_CCNameMap[ 0 ].name;
+ }
+
+ return g_CCNameMap[ i ].name;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Is the event something that can be sized ( a wave file, e.g. )
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::IsFixedLength( void )
+{
+ return m_bFixedLength;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : isfixedlength -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetFixedLength( bool isfixedlength )
+{
+ m_bFixedLength = isfixedlength;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : resumecondition -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetResumeCondition( bool resumecondition )
+{
+ m_bResumeCondition = resumecondition;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::IsResumeCondition( void )
+{
+ return m_bResumeCondition;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : lockbodyfacing -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetLockBodyFacing( bool lockbodyfacing )
+{
+ m_bLockBodyFacing = lockbodyfacing;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::IsLockBodyFacing( void )
+{
+ return m_bLockBodyFacing;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : distancetotarget -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetDistanceToTarget( float distancetotarget )
+{
+ m_flDistanceToTarget = distancetotarget;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns ideal distance to target
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetDistanceToTarget( void )
+{
+ return m_flDistanceToTarget;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : set if small (sub-1/2 bbox) movements are forced
+//-----------------------------------------------------------------------------
+
+void CChoreoEvent::SetForceShortMovement( bool bForceShortMovement )
+{
+ m_bForceShortMovement = bForceShortMovement;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : get if small (sub-1/2 bbox) movements are forced
+//-----------------------------------------------------------------------------
+
+bool CChoreoEvent::GetForceShortMovement( void )
+{
+ return m_bForceShortMovement;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : set if the gesture should sync its exit tag with the following gestures entry tag
+//-----------------------------------------------------------------------------
+
+void CChoreoEvent::SetSyncToFollowingGesture( bool bSyncToFollowingGesture )
+{
+ m_bSyncToFollowingGesture = bSyncToFollowingGesture;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : get if the gesture should sync its exit tag with the following gestures entry tag
+//-----------------------------------------------------------------------------
+
+bool CChoreoEvent::GetSyncToFollowingGesture( void )
+{
+ return m_bSyncToFollowingGesture;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : set if the sequence should player overtop of an underlying SS
+//-----------------------------------------------------------------------------
+
+void CChoreoEvent::SetPlayOverScript( bool bPlayOverScript )
+{
+ m_bPlayOverScript = bPlayOverScript;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : get if the sequence should player overtop of an underlying SS
+//-----------------------------------------------------------------------------
+
+bool CChoreoEvent::GetPlayOverScript( void )
+{
+ return m_bPlayOverScript;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetDuration( void )
+{
+ if ( HasEndTime() )
+ {
+ return GetEndTime() - GetStartTime();
+ }
+
+ return 0.0f;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ClearAllRelativeTags( void )
+{
+ m_RelativeTags.Purge();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetNumRelativeTags( void )
+{
+ return m_RelativeTags.Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : tagnum -
+// Output : CEventRelativeTag
+//-----------------------------------------------------------------------------
+CEventRelativeTag *CChoreoEvent::GetRelativeTag( int tagnum )
+{
+ Assert( tagnum >= 0 && tagnum < m_RelativeTags.Size() );
+ return &m_RelativeTags[ tagnum ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+// percentage -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::AddRelativeTag( const char *tagname, float percentage )
+{
+ CEventRelativeTag rt( this, tagname, percentage );
+ m_RelativeTags.AddToTail( rt );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RemoveRelativeTag( const char *tagname )
+{
+ for ( int i = 0; i < m_RelativeTags.Size(); i++ )
+ {
+ CEventRelativeTag *prt = &m_RelativeTags[ i ];
+ if ( !prt )
+ continue;
+
+ if ( !stricmp( prt->GetName(), tagname ) )
+ {
+ m_RelativeTags.Remove( i );
+ return;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+// Output : CEventRelativeTag *
+//-----------------------------------------------------------------------------
+CEventRelativeTag * CChoreoEvent::FindRelativeTag( const char *tagname )
+{
+ for ( int i = 0; i < m_RelativeTags.Size(); i++ )
+ {
+ CEventRelativeTag *prt = &m_RelativeTags[ i ];
+ if ( !prt )
+ continue;
+
+ if ( !stricmp( prt->GetName(), tagname ) )
+ {
+ return prt;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::IsUsingRelativeTag( void )
+{
+ return m_bUsesTag;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : usetag -
+// 0 -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetUsingRelativeTag( bool usetag, const char *tagname /*= 0*/,
+ const char *wavname /* = 0 */ )
+{
+ m_bUsesTag = usetag;
+ if ( tagname )
+ {
+ m_TagName = tagname;
+ }
+ else
+ {
+ m_TagName.Set("");
+ }
+ if ( wavname )
+ {
+ m_TagWavName = wavname;
+ }
+ else
+ {
+ m_TagWavName.Set("");
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetRelativeTagName( void )
+{
+ return m_TagName.Get();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::GetRelativeWavName( void )
+{
+ return m_TagWavName.Get();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ClearAllTimingTags( void )
+{
+ m_TimingTags.Purge();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetNumTimingTags( void )
+{
+ return m_TimingTags.Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : tagnum -
+// Output : CEventRelativeTag
+//-----------------------------------------------------------------------------
+CFlexTimingTag *CChoreoEvent::GetTimingTag( int tagnum )
+{
+ Assert( tagnum >= 0 && tagnum < m_TimingTags.Size() );
+ return &m_TimingTags[ tagnum ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+// percentage -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::AddTimingTag( const char *tagname, float percentage, bool locked )
+{
+ CFlexTimingTag tt( this, tagname, percentage, locked );
+ m_TimingTags.AddToTail( tt );
+
+ // Sort tags
+ CFlexTimingTag temp( (CChoreoEvent *)0x1, "", 0.0f, false );
+
+ // ugly bubble sort
+ for ( int i = 0; i < m_TimingTags.Size(); i++ )
+ {
+ for ( int j = i + 1; j < m_TimingTags.Size(); j++ )
+ {
+ CFlexTimingTag *t1 = &m_TimingTags[ i ];
+ CFlexTimingTag *t2 = &m_TimingTags[ j ];
+
+ if ( t1->GetPercentage() > t2->GetPercentage() )
+ {
+ temp = *t1;
+ *t1 = *t2;
+ *t2 = temp;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RemoveTimingTag( const char *tagname )
+{
+ for ( int i = 0; i < m_TimingTags.Size(); i++ )
+ {
+ CFlexTimingTag *ptt = &m_TimingTags[ i ];
+ if ( !ptt )
+ continue;
+
+ if ( !stricmp( ptt->GetName(), tagname ) )
+ {
+ m_TimingTags.Remove( i );
+ return;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *tagname -
+// Output : CEventRelativeTag *
+//-----------------------------------------------------------------------------
+CFlexTimingTag * CChoreoEvent::FindTimingTag( const char *tagname )
+{
+ for ( int i = 0; i < m_TimingTags.Size(); i++ )
+ {
+ CFlexTimingTag *ptt = &m_TimingTags[ i ];
+ if ( !ptt )
+ continue;
+
+ if ( !stricmp( ptt->GetName(), tagname ) )
+ {
+ return ptt;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::OnEndTimeChanged( void )
+{
+ int c = GetNumFlexAnimationTracks();
+ for ( int i = 0; i < c; i++ )
+ {
+ CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
+ Assert( track );
+ if ( !track )
+ continue;
+
+ track->Resort( 0 );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetNumFlexAnimationTracks( void )
+{
+ return m_FlexAnimationTracks.Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+// Output : CFlexAnimationTrack
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack *CChoreoEvent::GetFlexAnimationTrack( int index )
+{
+ if ( index < 0 || index >= GetNumFlexAnimationTracks() )
+ return NULL;
+ return m_FlexAnimationTracks[ index ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *controllername -
+// Output : CFlexAnimationTrack
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack *CChoreoEvent::AddTrack( const char *controllername )
+{
+ CFlexAnimationTrack *newTrack = new CFlexAnimationTrack( this );
+ newTrack->SetFlexControllerName( controllername );
+
+ m_FlexAnimationTracks.AddToTail( newTrack );
+
+ return newTrack;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RemoveTrack( int index )
+{
+ CFlexAnimationTrack *track = GetFlexAnimationTrack( index );
+ if ( !track )
+ return;
+
+ m_FlexAnimationTracks.Remove( index );
+ delete track;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RemoveAllTracks( void )
+{
+ while ( GetNumFlexAnimationTracks() > 0 )
+ {
+ RemoveTrack( 0 );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *controllername -
+// Output : CFlexAnimationTrack
+//-----------------------------------------------------------------------------
+CFlexAnimationTrack *CChoreoEvent::FindTrack( const char *controllername )
+{
+ for ( int i = 0; i < GetNumFlexAnimationTracks(); i++ )
+ {
+ CFlexAnimationTrack *t = GetFlexAnimationTrack( i );
+ if ( t && !stricmp( t->GetFlexControllerName(), controllername ) )
+ {
+ return t;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::GetTrackLookupSet( void )
+{
+ return m_bTrackLookupSet;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : set -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetTrackLookupSet( bool set )
+{
+ m_bTrackLookupSet = set;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::IsProcessing( void ) const
+{
+ return m_bProcessing;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *cb -
+// t -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::StartProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
+{
+ Assert( !m_bProcessing );
+ m_bProcessing = true;
+ if ( cb )
+ {
+ cb->StartEvent( t, scene, this );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *cb -
+// t -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ContinueProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
+{
+ Assert( m_bProcessing );
+ if ( cb )
+ {
+ cb->ProcessEvent( t, scene, this );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *cb -
+// t -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::StopProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
+{
+ Assert( m_bProcessing );
+ if ( cb )
+ {
+ cb->EndEvent( t, scene, this );
+ }
+ m_bProcessing = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *cb -
+// t -
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::CheckProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t )
+{
+ //Assert( !m_bProcessing );
+ if ( cb )
+ {
+ return cb->CheckEvent( t, scene, this );
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ResetProcessing( void )
+{
+ if ( GetType() == LOOP )
+ {
+ m_nLoopsRemaining = m_nNumLoops;
+ }
+
+ m_bProcessing = false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *mixer -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetMixer( CAudioMixer *mixer )
+{
+ m_pMixer = mixer;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CAudioMixer
+//-----------------------------------------------------------------------------
+CAudioMixer *CChoreoEvent::GetMixer( void ) const
+{
+ return m_pMixer;
+}
+
+// Snap to scene framerate
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SnapTimes()
+{
+ if ( HasEndTime() && !IsFixedLength() )
+ {
+ m_flEndTime = SnapTime( m_flEndTime );
+ }
+ float oldstart = m_flStartTime;
+ m_flStartTime = SnapTime( m_flStartTime );
+
+ // Don't snap end time for fixed length events, just set based on new start time
+ if ( IsFixedLength() )
+ {
+ float dt = m_flStartTime - oldstart;
+ m_flEndTime += dt;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : t -
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::SnapTime( float t )
+{
+ CChoreoScene *scene = GetScene();
+ if ( !scene)
+ {
+ Assert( 0 );
+ return t;
+ }
+
+ return scene->SnapTime( t );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : CChoreoScene
+//-----------------------------------------------------------------------------
+CChoreoScene *CChoreoEvent::GetScene( void )
+{
+ return m_pScene;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *scene -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetScene( CChoreoScene *scene )
+{
+ m_pScene = scene;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : t -
+// Output : char const
+//-----------------------------------------------------------------------------
+const char *CChoreoEvent::NameForAbsoluteTagType( AbsTagType t )
+{
+ switch ( t )
+ {
+ case PLAYBACK:
+ return "playback_time";
+ case ORIGINAL:
+ return "shifted_time";
+ default:
+ break;
+ }
+
+ return "AbsTagType(unknown)";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *name -
+// Output : AbsTagType
+//-----------------------------------------------------------------------------
+CChoreoEvent::AbsTagType CChoreoEvent::TypeForAbsoluteTagName( const char *name )
+{
+ if ( !Q_strcasecmp( name, "playback_time" ) )
+ {
+ return PLAYBACK;
+ }
+ else if ( !Q_strcasecmp( name, "shifted_time" ) )
+ {
+ return ORIGINAL;
+ }
+
+ return (AbsTagType)-1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ClearAllAbsoluteTags( AbsTagType type )
+{
+ m_AbsoluteTags[ type ].Purge();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetNumAbsoluteTags( AbsTagType type )
+{
+ return m_AbsoluteTags[ type ].Size();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// tagnum -
+// Output : CEventAbsoluteTag
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag *CChoreoEvent::GetAbsoluteTag( AbsTagType type, int tagnum )
+{
+ Assert( tagnum >= 0 && tagnum < m_AbsoluteTags[ type ].Size() );
+ return &m_AbsoluteTags[ type ][ tagnum ];
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *tagname -
+// Output : CEventAbsoluteTag
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag *CChoreoEvent::FindAbsoluteTag( AbsTagType type, const char *tagname )
+{
+ for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
+ {
+ CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
+ if ( !ptag )
+ continue;
+
+ if ( !stricmp( ptag->GetName(), tagname ) )
+ {
+ return ptag;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *tagname -
+// t -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::AddAbsoluteTag( AbsTagType type, const char *tagname, float t )
+{
+ CEventAbsoluteTag at( this, tagname, t );
+ m_AbsoluteTags[ type ].AddToTail( at );
+
+ // Sort tags
+ CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
+
+ // ugly bubble sort
+ for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
+ {
+ for ( int j = i + 1; j < m_AbsoluteTags[ type ].Size(); j++ )
+ {
+ CEventAbsoluteTag *t1 = &m_AbsoluteTags[ type ][ i ];
+ CEventAbsoluteTag *t2 = &m_AbsoluteTags[ type ][ j ];
+
+ if ( t1->GetPercentage() > t2->GetPercentage() )
+ {
+ temp = *t1;
+ *t1 = *t2;
+ *t2 = temp;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *tagname -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RemoveAbsoluteTag( AbsTagType type, const char *tagname )
+{
+ for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
+ {
+ CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
+ if ( !ptag )
+ continue;
+
+ if ( !stricmp( ptag->GetName(), tagname ) )
+ {
+ m_AbsoluteTags[ type ].Remove( i );
+ return;
+ }
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose: makes sure tags in PLAYBACK are in the same order as ORIGINAL
+// Input :
+// Output : true if they were in order, false if it has to reorder them
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::VerifyTagOrder( )
+{
+ bool bInOrder = true;
+
+ // Sort tags
+ CEventAbsoluteTag temp( (CChoreoEvent *)0x1, "", 0.0f );
+
+ for ( int i = 0; i < m_AbsoluteTags[ CChoreoEvent::ORIGINAL ].Size(); i++ )
+ {
+ CEventAbsoluteTag *ptag = &m_AbsoluteTags[ CChoreoEvent::ORIGINAL ][ i ];
+ if ( !ptag )
+ continue;
+
+ CEventAbsoluteTag *t1 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ i ];
+
+ if ( stricmp( ptag->GetName(), t1->GetName() ) == 0)
+ continue;
+
+ bInOrder = false;
+ for ( int j = i + 1; j < m_AbsoluteTags[ CChoreoEvent::PLAYBACK ].Size(); j++ )
+ {
+ CEventAbsoluteTag *t2 = &m_AbsoluteTags[ CChoreoEvent::PLAYBACK ][ j ];
+
+ if ( stricmp( ptag->GetName(), t2->GetName() ) == 0 )
+ {
+ temp = *t1;
+ *t1 = *t2;
+ *t2 = temp;
+ break;
+ }
+ }
+ }
+ return bInOrder;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// *tagname -
+//-----------------------------------------------------------------------------
+
+float CChoreoEvent::GetBoundedAbsoluteTagPercentage( AbsTagType type, int tagnum )
+{
+ if ( tagnum <= -2 )
+ {
+ /*
+ if (GetNumAbsoluteTags( type ) >= 1)
+ {
+ CEventAbsoluteTag *tag = GetAbsoluteTag( type, 0 );
+ Assert( tag );
+ return -tag->GetTime();
+ }
+ */
+ return 0.0f; // -0.5f;
+ }
+ else if ( tagnum == -1 )
+ {
+ return 0.0f;
+ }
+ else if ( tagnum == GetNumAbsoluteTags( type ) )
+ {
+ return 1.0;
+ }
+ else if ( tagnum > GetNumAbsoluteTags( type ) )
+ {
+ /*
+ if (GetNumAbsoluteTags( type ) >= 1)
+ {
+ CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum - 2 );
+ Assert( tag );
+ return 2.0 - tag->GetTime();
+ }
+ */
+ return 1.0; // 1.5;
+ }
+
+ /*
+ {
+ float duration = GetDuration();
+
+ if ( type == SHIFTED )
+ {
+ float seqduration;
+ GetGestureSequenceDuration( seqduration );
+ return seqduration;
+ }
+ return duration;
+ }
+ */
+
+ CEventAbsoluteTag *tag = GetAbsoluteTag( type, tagnum );
+ Assert( tag );
+ return tag->GetPercentage();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : t -
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetOriginalPercentageFromPlaybackPercentage( float t )
+{
+ Assert( GetType() == GESTURE );
+ if ( GetType() != GESTURE )
+ return t;
+
+ int count = GetNumAbsoluteTags( PLAYBACK );
+
+ if ( count != GetNumAbsoluteTags( ORIGINAL ) )
+ {
+ return t;
+ }
+
+ if ( count <= 0 )
+ {
+ return t;
+ }
+
+ if ( t <= 0.0f )
+ return 0.0f;
+
+ float s = 0.0f, n = 0.0f;
+
+ // find what tags this is between
+ int i;
+ for ( i = -1 ; i < count; i++ )
+ {
+ s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
+ n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
+
+ if ( t >= s && t <= n )
+ {
+ break;
+ }
+ }
+
+ int prev = i - 1;
+ int start = i;
+ int end = i + 1;
+ int next = i + 2;
+
+ prev = MAX( -2, prev );
+ start = MAX( -1, start );
+ end = MIN( end, count );
+ next = MIN( next, count + 1 );
+
+ CEventAbsoluteTag *pStartTag = NULL;
+ CEventAbsoluteTag *pEndTag = NULL;
+
+ // check for linear portion of lookup
+ if (start >= 0 && start < count)
+ {
+ pStartTag = GetAbsoluteTag( PLAYBACK, start );
+ }
+ if (end >= 0 && end < count)
+ {
+ pEndTag = GetAbsoluteTag( PLAYBACK, end );
+ }
+
+ if (pStartTag && pEndTag)
+ {
+ if (pStartTag->GetLinear() && pEndTag->GetLinear())
+ {
+ CEventAbsoluteTag *pOrigStartTag = GetAbsoluteTag( ORIGINAL, start );
+ CEventAbsoluteTag *pOrigEndTag = GetAbsoluteTag( ORIGINAL, end );
+
+ if (pOrigStartTag && pOrigEndTag)
+ {
+ s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
+ return (1 - s) * pOrigStartTag->GetPercentage() + s * pOrigEndTag->GetPercentage();
+ }
+ }
+ }
+
+ float dt = n - s;
+
+ Vector vPre( GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), 0 );
+ Vector vStart( GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), 0 );
+ Vector vEnd( GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), 0 );
+ Vector vNext( GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), 0 );
+
+ // simulate sections of either side of "linear" portion of ramp as linear slope
+ if (pStartTag && pStartTag->GetLinear())
+ {
+ vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
+ }
+
+ if (pEndTag && pEndTag->GetLinear())
+ {
+ vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
+ }
+
+
+ float f2 = 0.0f;
+ if ( dt > 0.0f )
+ {
+ f2 = ( t - s ) / ( dt );
+ }
+ f2 = clamp( f2, 0.0f, 1.0f );
+
+ Vector vOut;
+ Catmull_Rom_Spline_NormalizeX(
+ vPre,
+ vStart,
+ vEnd,
+ vNext,
+ f2,
+ vOut );
+
+ return vOut.y;
+
+ /*
+ float duration;
+ GetGestureSequenceDuration( duration );
+
+ float retval = clamp( vOut.y, 0.0f, duration );
+ return retval;
+ */
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : t -
+// Output : float
+//-----------------------------------------------------------------------------
+float CChoreoEvent::GetPlaybackPercentageFromOriginalPercentage( float t )
+{
+ Assert( GetType() == GESTURE );
+ if ( GetType() != GESTURE )
+ return t;
+
+ int count = GetNumAbsoluteTags( PLAYBACK );
+
+ if ( count != GetNumAbsoluteTags( ORIGINAL ) )
+ {
+ return t;
+ }
+
+ if ( count <= 0 )
+ {
+ return t;
+ }
+
+ if ( t <= 0.0f )
+ return 0.0f;
+
+ float s = 0.0f, n = 0.0f;
+
+ // find what tags this is between
+ int i;
+ for ( i = -1 ; i < count; i++ )
+ {
+ s = GetBoundedAbsoluteTagPercentage( PLAYBACK, i );
+ n = GetBoundedAbsoluteTagPercentage( PLAYBACK, i + 1 );
+
+ if ( t >= s && t <= n )
+ {
+ break;
+ }
+ }
+
+ int prev = i - 1;
+ int start = i;
+ int end = i + 1;
+ int next = i + 2;
+
+ prev = MAX( -2, prev );
+ start = MAX( -1, start );
+ end = MIN( end, count );
+ next = MIN( next, count + 1 );
+
+ CEventAbsoluteTag *pStartTag = NULL;
+ CEventAbsoluteTag *pEndTag = NULL;
+
+ // check for linear portion of lookup
+ if (start >= 0 && start < count)
+ {
+ pStartTag = GetAbsoluteTag( ORIGINAL, start );
+ }
+ if (end >= 0 && end < count)
+ {
+ pEndTag = GetAbsoluteTag( ORIGINAL, end );
+ }
+
+ // check for linear portion of lookup
+ if (pStartTag && pEndTag)
+ {
+ if (pStartTag->GetLinear() && pEndTag->GetLinear())
+ {
+ CEventAbsoluteTag *pPlaybackStartTag = GetAbsoluteTag( PLAYBACK, start );
+ CEventAbsoluteTag *pPlaybackEndTag = GetAbsoluteTag( PLAYBACK, end );
+
+ if (pPlaybackStartTag && pPlaybackEndTag)
+ {
+ s = ( t - pStartTag->GetPercentage() ) / (pEndTag->GetPercentage() - pStartTag->GetPercentage());
+ return (1 - s) * pPlaybackStartTag->GetPercentage() + s * pPlaybackEndTag->GetPercentage();
+ }
+ }
+ }
+
+ float dt = n - s;
+
+ Vector vPre( GetBoundedAbsoluteTagPercentage( ORIGINAL, prev ), GetBoundedAbsoluteTagPercentage( PLAYBACK, prev ), 0 );
+ Vector vStart( GetBoundedAbsoluteTagPercentage( ORIGINAL, start ), GetBoundedAbsoluteTagPercentage( PLAYBACK, start ), 0 );
+ Vector vEnd( GetBoundedAbsoluteTagPercentage( ORIGINAL, end ), GetBoundedAbsoluteTagPercentage( PLAYBACK, end ), 0 );
+ Vector vNext( GetBoundedAbsoluteTagPercentage( ORIGINAL, next ), GetBoundedAbsoluteTagPercentage( PLAYBACK, next ), 0 );
+
+ // simulate sections of either side of "linear" portion of ramp as linear slope
+ if (pStartTag && pStartTag->GetLinear())
+ {
+ vPre.Init( vStart.x - (vEnd.x - vStart.x), vStart.y - (vEnd.y - vStart.y), 0 );
+ }
+
+ if (pEndTag && pEndTag->GetLinear())
+ {
+ vNext.Init( vEnd.x + (vEnd.x - vStart.x), vEnd.y + (vEnd.y - vStart.y), 0 );
+ }
+
+ float f2 = 0.0f;
+ if ( dt > 0.0f )
+ {
+ f2 = ( t - s ) / ( dt );
+ }
+ f2 = clamp( f2, 0.0f, 1.0f );
+
+ Vector vOut;
+ Catmull_Rom_Spline_NormalizeX(
+ vPre,
+ vStart,
+ vEnd,
+ vNext,
+ f2,
+ vOut );
+
+ return vOut.y;
+
+ /*
+ float duration;
+ GetGestureSequenceDuration( duration );
+
+ float retval = clamp( vOut.y, 0.0f, duration );
+ return retval;
+ */
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : duration -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetGestureSequenceDuration( float duration )
+{
+ m_flGestureSequenceDuration = duration;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : duration -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::GetGestureSequenceDuration( float& duration )
+{
+ bool valid = m_flGestureSequenceDuration != 0.0f;
+
+ if ( !valid )
+ {
+ duration = GetDuration();
+ }
+ else
+ {
+ duration = m_flGestureSequenceDuration;
+ }
+
+ return valid;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pitch -
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetPitch( void ) const
+{
+ return m_nPitch;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pitch -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetPitch( int pitch )
+{
+ m_nPitch = pitch;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : yaw -
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetYaw( void ) const
+{
+ return m_nYaw;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : yaw -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetYaw( int yaw )
+{
+ m_nYaw = yaw;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : t -
+// -1 -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetLoopCount( int numloops )
+{
+ Assert( GetType() == LOOP );
+ // Never below -1
+ m_nNumLoops = MAX( numloops, -1 );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetNumLoopsRemaining( void )
+{
+ Assert( GetType() == LOOP );
+
+ return m_nLoopsRemaining;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : loops -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetNumLoopsRemaining( int loops )
+{
+ Assert( GetType() == LOOP );
+
+ m_nLoopsRemaining = loops;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : int
+//-----------------------------------------------------------------------------
+int CChoreoEvent::GetLoopCount( void )
+{
+ Assert( GetType() == LOOP );
+ return m_nNumLoops;
+}
+
+EdgeInfo_t *CCurveData::GetEdgeInfo( int idx )
+{
+ return &m_RampEdgeInfo[ idx ];
+}
+
+int CCurveData::GetCount( void )
+{
+ return m_Ramp.Count();
+}
+
+CExpressionSample *CCurveData::Get( int index )
+{
+ if ( index < 0 || index >= GetCount() )
+ return NULL;
+
+ return &m_Ramp[ index ];
+}
+
+CExpressionSample *CCurveData::Add( float time, float value, bool selected )
+{
+ CExpressionSample sample;
+
+ sample.time = time;
+ sample.value = value;
+ sample.selected = selected;
+
+ int idx = m_Ramp.AddToTail( sample );
+ return &m_Ramp[ idx ];
+}
+
+void CCurveData::Delete( int index )
+{
+ if ( index < 0 || index >= GetCount() )
+ return;
+
+ m_Ramp.Remove( index );
+}
+
+void CCurveData::Clear( void )
+{
+ m_Ramp.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCurveData::Resort( ICurveDataAccessor *data )
+{
+ for ( int i = 0; i < m_Ramp.Size(); i++ )
+ {
+ for ( int j = i + 1; j < m_Ramp.Size(); j++ )
+ {
+ CExpressionSample src = m_Ramp[ i ];
+ CExpressionSample dest = m_Ramp[ j ];
+
+ if ( src.time > dest.time )
+ {
+ m_Ramp[ i ] = dest;
+ m_Ramp[ j ] = src;
+ }
+ }
+ }
+
+ RemoveOutOfRangeSamples( data );
+
+ // m_RampAccumulator.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : number -
+// Output : CExpressionSample
+//-----------------------------------------------------------------------------
+CExpressionSample *CCurveData::GetBoundedSample( ICurveDataAccessor *data, int number, bool& bClamped )
+{
+ // Search for two samples which span time f
+ if ( number < 0 )
+ {
+ static CExpressionSample nullstart;
+ nullstart.time = 0.0f;
+ nullstart.value = GetEdgeZeroValue( true );
+ nullstart.SetCurveType( GetEdgeCurveType( true ) );
+ bClamped = true;
+ return &nullstart;
+ }
+ else if ( number >= GetCount() )
+ {
+ static CExpressionSample nullend;
+ nullend.time = data->GetDuration();
+ nullend.value = GetEdgeZeroValue( false );
+ nullend.SetCurveType( GetEdgeCurveType( false ) );
+ bClamped = true;
+ return &nullend;
+ }
+
+ bClamped = false;
+ return Get( number );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CCurveData::RemoveOutOfRangeSamples( ICurveDataAccessor *data )
+{
+ float duration = data->GetDuration();
+
+ int c = GetCount();
+ for ( int i = c-1; i >= 0; i-- )
+ {
+ CExpressionSample src = m_Ramp[ i ];
+ if ( src.time < 0 ||
+ src.time > duration + 0.01 )
+ {
+ m_Ramp.Remove( i );
+ }
+ }
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::RescaleGestureTimes( float newstart, float newend, bool bMaintainAbsoluteTagPositions )
+{
+ if ( GetType() != CChoreoEvent::GESTURE )
+ return;
+
+ // Did it actually change
+ if ( newstart == GetStartTime() &&
+ newend == GetEndTime() )
+ {
+ return;
+ }
+
+ float newduration = newend - newstart;
+
+ float dt = 0.0f;
+ //If the end is moving, leave tags stay where they are (dt == 0.0f)
+ if ( newstart != GetStartTime() )
+ {
+ // Otherwise, if the new start is later, then tags need to be shifted backwards
+ dt -= ( newstart - GetStartTime() );
+ }
+
+ if ( bMaintainAbsoluteTagPositions )
+ {
+ int i;
+ int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
+ for ( i = 0; i < count; i++ )
+ {
+ CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
+ float tagtime = tag->GetPercentage() * GetDuration();
+
+ tagtime += dt;
+
+ tagtime = clamp( tagtime / newduration, 0.0f, 1.0f );
+
+ tag->SetPercentage( tagtime );
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Make sure tags aren't co-located or out of order
+//-----------------------------------------------------------------------------
+bool CChoreoEvent::PreventTagOverlap( void )
+{
+ bool bHadOverlap = false;
+
+ // FIXME: limit to single frame?
+ float minDp = 0.01;
+
+ float minP = 1.00;
+
+ int count = GetNumAbsoluteTags( CChoreoEvent::PLAYBACK );
+ for ( int i = count - 1; i >= 0; i-- )
+ {
+ CEventAbsoluteTag *tag = GetAbsoluteTag( CChoreoEvent::PLAYBACK, i );
+
+ if (tag->GetPercentage() > minP)
+ {
+ tag->SetPercentage( minP );
+
+ minDp = MIN( 0.01, minP / (i + 1) );
+ bHadOverlap = true;
+ }
+ else
+ {
+ minP = tag->GetPercentage();
+ }
+ minP = MAX( minP - minDp, 0 );
+ }
+
+ return bHadOverlap;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// Output : CEventAbsoluteTag
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag *CChoreoEvent::FindEntryTag( AbsTagType type )
+{
+ for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
+ {
+ CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
+ if ( !ptag )
+ continue;
+
+ if ( ptag->GetEntry() )
+ {
+ return ptag;
+ }
+ }
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : type -
+// Output : CEventAbsoluteTag
+//-----------------------------------------------------------------------------
+CEventAbsoluteTag *CChoreoEvent::FindExitTag( AbsTagType type )
+{
+ for ( int i = 0; i < m_AbsoluteTags[ type ].Size(); i++ )
+ {
+ CEventAbsoluteTag *ptag = &m_AbsoluteTags[ type ][ i ];
+ if ( !ptag )
+ continue;
+
+ if ( ptag->GetExit() )
+ {
+ return ptag;
+ }
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *style -
+// maxlen -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::GetMovementStyle( char *style, int maxlen )
+{
+ Assert( GetType() == MOVETO );
+
+ style[0] = 0;
+
+ const char *in = m_Parameters2.Get();
+ char *out = style;
+
+ while ( *in && *in != '\0' && *in != ' ' )
+ {
+ if ( out - style >= maxlen - 1 )
+ break;
+ *out++ = *in++;
+ }
+
+ *out = 0;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *style -
+// maxlen -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::GetDistanceStyle( char *style, int maxlen )
+{
+ Assert( GetType() == MOVETO );
+
+ style[0]= 0;
+
+ const char *in = Q_strstr( m_Parameters2.Get(), " " );
+ if ( !in )
+ return;
+
+ in++;
+ char *out = style;
+
+ while ( *in && *in != '\0' )
+ {
+ if ( out - style >= maxlen - 1 )
+ break;
+ *out++ = *in++;
+ }
+
+ *out = 0;
+}
+
+void CChoreoEvent::SetCloseCaptionType( CLOSECAPTION type )
+{
+ Assert( m_fType == SPEAK );
+ m_ccType = type;
+}
+
+CChoreoEvent::CLOSECAPTION CChoreoEvent::GetCloseCaptionType() const
+{
+ Assert( m_fType == SPEAK );
+ return (CLOSECAPTION)m_ccType;
+}
+
+void CChoreoEvent::SetCloseCaptionToken( char const *token )
+{
+ Assert( m_fType == SPEAK );
+ Assert( token );
+ m_CCToken = token;
+}
+
+char const *CChoreoEvent::GetCloseCaptionToken() const
+{
+ Assert( m_fType == SPEAK );
+ return m_CCToken.Get();
+}
+
+bool CChoreoEvent::GetPlaybackCloseCaptionToken( char *dest, int destlen )
+{
+ dest[0] = 0;
+
+ Assert( m_fType == SPEAK );
+
+ switch ( m_ccType )
+ {
+ default:
+ case CC_DISABLED:
+ {
+ return false;
+ }
+ case CC_SLAVE:
+ {
+ // If it's a slave, then only disable if we're not using the combined wave
+ if ( IsUsingCombinedFile() )
+ {
+ return false;
+ }
+
+ if ( m_CCToken[ 0 ] != 0 )
+ {
+ Q_strncpy( dest, m_CCToken.Get(), destlen );
+ }
+ else
+ {
+ Q_strncpy( dest, m_Parameters.Get(), destlen );
+ }
+ return true;
+ }
+ case CC_MASTER:
+ {
+ // Always use the override if we're the master, otherwise always use the default
+ // parameter
+ if ( m_CCToken[ 0 ] != 0 )
+ {
+ Q_strncpy( dest, m_CCToken.Get(), destlen );
+ }
+ else
+ {
+ Q_strncpy( dest, m_Parameters.Get(), destlen );
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void CChoreoEvent::SetUsingCombinedFile( bool isusing )
+{
+ Assert( m_fType == SPEAK );
+ m_bUsingCombinedSoundFile = isusing;
+}
+
+bool CChoreoEvent::IsUsingCombinedFile() const
+{
+ Assert( m_fType == SPEAK );
+ return m_bUsingCombinedSoundFile;
+}
+
+void CChoreoEvent::SetRequiredCombinedChecksum( unsigned int checksum )
+{
+ Assert( m_fType == SPEAK );
+ m_uRequiredCombinedChecksum = checksum;
+}
+
+unsigned int CChoreoEvent::GetRequiredCombinedChecksum()
+{
+ Assert( m_fType == SPEAK );
+ return m_uRequiredCombinedChecksum;
+}
+
+void CChoreoEvent::SetNumSlaves( int num )
+{
+ Assert( m_fType == SPEAK );
+ Assert( num >= 0 );
+ m_nNumSlaves = num;
+}
+
+int CChoreoEvent::GetNumSlaves() const
+{
+ Assert( m_fType == SPEAK );
+ return m_nNumSlaves;
+}
+
+void CChoreoEvent::SetLastSlaveEndTime( float t )
+{
+ Assert( m_fType == SPEAK );
+ m_flLastSlaveEndTime = t;
+}
+
+float CChoreoEvent::GetLastSlaveEndTime() const
+{
+ Assert( m_fType == SPEAK );
+ return m_flLastSlaveEndTime;
+}
+
+void CChoreoEvent::SetCloseCaptionTokenValid( bool valid )
+{
+ Assert( m_fType == SPEAK );
+ m_bCCTokenValid = valid;
+}
+
+bool CChoreoEvent::GetCloseCaptionTokenValid() const
+{
+ Assert( m_fType == SPEAK );
+ return m_bCCTokenValid;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Removes characters which can't appear in windows filenames
+// Input : *in -
+// *dest -
+// destlen -
+// Output : static void
+//-----------------------------------------------------------------------------
+static void CleanupTokenName( char const *in, char *dest, int destlen )
+{
+ char *out = dest;
+ while ( *in && ( out - dest ) < destlen )
+ {
+ if ( V_isalnum( *in ) || // lowercase, uppercase, digits and underscore are valid
+ *in == '_' )
+ {
+ *out++ = *in;
+ }
+ else
+ {
+ *out++ = '_'; // Put underscores in for bogus characters
+ }
+ in++;
+ }
+ *out = 0;
+}
+
+bool CChoreoEvent::ComputeCombinedBaseFileName( char *dest, int destlen, bool creategenderwildcard )
+{
+ if ( m_fType != SPEAK )
+ return false;
+
+ if ( m_ccType != CC_MASTER )
+ return false;
+
+ if ( GetNumSlaves() == 0 )
+ return false;
+
+ if ( !m_pScene )
+ return false;
+
+ char vcdpath[ 512 ];
+ char cleanedtoken[ MAX_CCTOKEN_STRING ];
+ CleanupTokenName( m_CCToken.Get(), cleanedtoken, sizeof( cleanedtoken ) );
+
+ if ( Q_strlen( cleanedtoken ) <= 0 )
+ return false;
+
+ Q_strncpy( vcdpath, m_pScene->GetFilename(), sizeof( vcdpath ) );
+ Q_StripFilename( vcdpath );
+ Q_FixSlashes( vcdpath, '/' );
+
+ char *pvcd = vcdpath;
+
+ char *offset = Q_strstr( vcdpath, "scenes" );
+ if ( offset )
+ {
+ pvcd = offset + 6;
+ if ( *pvcd == '/' )
+ {
+ ++pvcd;
+ }
+ }
+
+ int len = Q_strlen( pvcd );
+
+ if ( len > 0 && ( len + 1 ) < ( sizeof( vcdpath ) - 1 ) )
+ {
+ pvcd[ len ] = '/';
+ pvcd[ len + 1 ] = 0;
+ }
+
+ Assert( !Q_strstr( pvcd, ":" ) );
+
+ if ( creategenderwildcard )
+ {
+ Q_snprintf( dest, destlen, "sound/combined/%s%s_$gender.wav", pvcd, cleanedtoken );
+ }
+ else
+ {
+ Q_snprintf( dest, destlen, "sound/combined/%s%s.wav", pvcd, cleanedtoken );
+ }
+ return true;
+}
+
+bool CChoreoEvent::IsCombinedUsingGenderToken() const
+{
+ return m_bCombinedUsingGenderToken;
+}
+
+void CChoreoEvent::SetCombinedUsingGenderToken( bool using_gender )
+{
+ m_bCombinedUsingGenderToken = using_gender;
+}
+
+
+int CChoreoEvent::ValidateCombinedFile()
+{
+
+ return 0;
+}
+
+bool CChoreoEvent::IsSuppressingCaptionAttenuation() const
+{
+ return m_bSuppressCaptionAttenuation;
+}
+
+void CChoreoEvent::SetSuppressingCaptionAttenuation( bool suppress )
+{
+ m_bSuppressCaptionAttenuation = suppress;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CChoreoEvent::ClearEventDependencies()
+{
+ m_Dependencies.RemoveAll();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *other -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::AddEventDependency( CChoreoEvent *other )
+{
+ if ( m_Dependencies.Find( other ) == m_Dependencies.InvalidIndex() )
+ {
+ m_Dependencies.AddToTail( other );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : list -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::GetEventDependencies( CUtlVector< CChoreoEvent * >& list )
+{
+ int c = m_Dependencies.Count();
+ for ( int i = 0; i < c; ++i )
+ {
+ list.AddToTail( m_Dependencies[ i ] );
+ }
+}
+
+void CCurveData::SetEdgeInfo( bool leftEdge, int curveType, float zero )
+{
+ int idx = leftEdge ? 0 : 1;
+ m_RampEdgeInfo[ idx ].m_CurveType = curveType;
+ m_RampEdgeInfo[ idx ].m_flZeroPos = zero;
+}
+
+void CCurveData::GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const
+{
+ int idx = leftEdge ? 0 : 1;
+ curveType = m_RampEdgeInfo[ idx ].m_CurveType;
+ zero = m_RampEdgeInfo[ idx ].m_flZeroPos;
+}
+
+void CCurveData::SetEdgeActive( bool leftEdge, bool state )
+{
+ int idx = leftEdge ? 0 : 1;
+ m_RampEdgeInfo[ idx ].m_bActive = state;
+}
+
+bool CCurveData::IsEdgeActive( bool leftEdge ) const
+{
+ int idx = leftEdge ? 0 : 1;
+ return m_RampEdgeInfo[ idx ].m_bActive;
+}
+
+int CCurveData::GetEdgeCurveType( bool leftEdge ) const
+{
+ if ( !IsEdgeActive( leftEdge ) )
+ {
+ return CURVE_DEFAULT;
+ }
+
+ int idx = leftEdge ? 0 : 1;
+ return m_RampEdgeInfo[ idx ].m_CurveType;
+}
+
+float CCurveData::GetEdgeZeroValue( bool leftEdge ) const
+{
+ if ( !IsEdgeActive( leftEdge ) )
+ {
+ return 0.0f;
+ }
+
+ int idx = leftEdge ? 0 : 1;
+ return m_RampEdgeInfo[ idx ].m_flZeroPos;
+}
+
+
+void CChoreoEvent::SaveToBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
+{
+ buf.PutChar( GetType() );
+ buf.PutShort( pStringPool->FindOrAddString( GetName() ) );
+
+ float st = GetStartTime();
+ buf.PutFloat( st );
+
+ float et = GetEndTime();
+ buf.PutFloat( et );
+
+ buf.PutShort( pStringPool->FindOrAddString( GetParameters() ) );
+ buf.PutShort( pStringPool->FindOrAddString( GetParameters2() ) );
+ buf.PutShort( pStringPool->FindOrAddString( GetParameters3() ) );
+
+ m_Ramp.SaveToBuffer( buf, pStringPool );
+
+ int flags = 0;
+ flags |= IsResumeCondition() ? 1<<0 : 0;
+ flags |= IsLockBodyFacing() ? 1<<1 : 0;
+ flags |= IsFixedLength() ? 1<<2 : 0;
+ flags |= GetActive() ? 1<<3 : 0;
+ flags |= GetForceShortMovement() ? 1<<4 : 0;
+ flags |= GetPlayOverScript() ? 1<<5 : 0;
+
+ buf.PutUnsignedChar( flags );
+
+ buf.PutFloat( GetDistanceToTarget() );
+
+ int numRelativeTags = GetNumRelativeTags();
+ Assert( numRelativeTags <= 255 );
+ buf.PutUnsignedChar( numRelativeTags );
+
+ for ( int t = 0; t < numRelativeTags; t++ )
+ {
+ CEventRelativeTag *rt = GetRelativeTag( t );
+ Assert( rt );
+ buf.PutShort( pStringPool->FindOrAddString( rt->GetName() ) );
+
+ Assert( rt->GetPercentage() >= 0.0f && rt->GetPercentage() <= 1.0f );
+ unsigned char p = rt->GetPercentage() * 255.0f;
+ buf.PutUnsignedChar( p );
+ }
+
+ int numTimingTags = GetNumTimingTags();
+ Assert( numTimingTags <= 255 );
+ buf.PutUnsignedChar( numTimingTags );
+
+ for ( int t = 0; t < numTimingTags; t++ )
+ {
+ CFlexTimingTag *tt = GetTimingTag( t );
+ Assert( tt );
+ buf.PutShort( pStringPool->FindOrAddString( tt->GetName() ) );
+
+ // save as u0.8
+ Assert( tt->GetPercentage() >= 0.0f && tt->GetPercentage() <= 1.0f );
+ unsigned char p = tt->GetPercentage() * 255.0f;
+ buf.PutUnsignedChar( p );
+
+ // Don't save locked state, it's only used by the editor tt->GetLocked()
+ }
+
+ int tagtype;
+ for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
+ {
+ int num = GetNumAbsoluteTags( (CChoreoEvent::AbsTagType)tagtype );
+ Assert( num <= 255 );
+ buf.PutUnsignedChar( num );
+
+ for ( int i = 0; i < num ; ++i )
+ {
+ CEventAbsoluteTag *abstag = GetAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, i );
+ Assert( abstag );
+ buf.PutShort( pStringPool->FindOrAddString( abstag->GetName() ) );
+
+ // save as u4.12
+ Assert( abstag->GetPercentage() >= 0.0f && abstag->GetPercentage() <= 15.0f );
+ unsigned short p = abstag->GetPercentage() * 4096.0f;
+ buf.PutUnsignedShort( p );
+ }
+ }
+
+ if ( GetType() == CChoreoEvent::GESTURE )
+ {
+ float duration;
+ if ( GetGestureSequenceDuration( duration ) )
+ {
+ buf.PutFloat( duration );
+ }
+ else
+ {
+ buf.PutFloat( -1.0f );
+ }
+ }
+
+ buf.PutChar( IsUsingRelativeTag() ? 1 : 0 );
+ if ( IsUsingRelativeTag() )
+ {
+ buf.PutShort( pStringPool->FindOrAddString( GetRelativeTagName() ) );
+ buf.PutShort( pStringPool->FindOrAddString( GetRelativeWavName() ) );
+ }
+
+ SaveFlexAnimationsToBuffer( buf, pStringPool );
+
+ if ( GetType() == LOOP )
+ {
+ buf.PutChar( GetLoopCount() );
+ }
+
+ if ( GetType() == CChoreoEvent::SPEAK )
+ {
+ buf.PutChar( GetCloseCaptionType() );
+ buf.PutShort( pStringPool->FindOrAddString( GetCloseCaptionToken() ) );
+ flags = 0;
+
+ if ( GetCloseCaptionType() != CChoreoEvent::CC_DISABLED &&
+ IsUsingCombinedFile() )
+ {
+ flags |= ( 1<<0 );
+ }
+ if ( IsCombinedUsingGenderToken() )
+ {
+ flags |= ( 1<<1 );
+ }
+ if ( IsSuppressingCaptionAttenuation() )
+ {
+ flags |= ( 1<<2 );
+ }
+
+ buf.PutChar( flags );
+ }
+}
+
+bool CChoreoEvent::RestoreFromBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool )
+{
+ MEM_ALLOC_CREDIT();
+
+ SetType( (EVENTTYPE)buf.GetChar() );
+ char sz[ 256 ];
+ pStringPool->GetString( buf.GetShort(), sz, sizeof( sz ) );
+ SetName( sz );
+
+ SetStartTime( buf.GetFloat() );
+ SetEndTime( buf.GetFloat() );
+
+ char params[ 2048 ];
+ pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
+ SetParameters( params );
+ pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
+ SetParameters2( params );
+ pStringPool->GetString( buf.GetShort(), params, sizeof( params ) );
+ SetParameters3( params );
+
+ if ( !m_Ramp.RestoreFromBuffer( buf, pStringPool ) )
+ return false;
+
+ int flags = buf.GetUnsignedChar();
+ SetResumeCondition( ( flags & ( 1<<0 ) ) ? true : false );
+ SetLockBodyFacing( ( flags & ( 1<<1 ) ) ? true : false );
+ SetFixedLength( ( flags & ( 1<<2 ) ) ? true : false );
+ SetActive( ( flags & ( 1<<3 ) ) ? true : false );
+ SetForceShortMovement( ( flags & ( 1<<4 ) ) ? true : false );
+ SetPlayOverScript( ( flags & ( 1<<5 ) ) ? true : false );
+
+ SetDistanceToTarget( buf.GetFloat() );
+
+ int numRelTags = buf.GetUnsignedChar();
+ for ( int i = 0; i < numRelTags; ++i )
+ {
+ char tagName[ 256 ];
+ pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
+ float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
+ AddRelativeTag( tagName, percentage );
+ }
+
+ int numTimingTags = buf.GetUnsignedChar();
+ for ( int i = 0; i < numTimingTags; ++i )
+ {
+ char tagName[ 256 ];
+ pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
+ float percentage = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
+ // Don't parse locked state, only used by editors
+ AddTimingTag( tagName, percentage, false );
+ }
+
+ int tagtype;
+ for ( tagtype = 0; tagtype < CChoreoEvent::NUM_ABS_TAG_TYPES; tagtype++ )
+ {
+ int num = buf.GetUnsignedChar();
+ for ( int i = 0; i < num; ++i )
+ {
+ char tagName[ 256 ];
+ pStringPool->GetString( buf.GetShort(), tagName, sizeof( tagName ) );
+ float percentage = (float)buf.GetUnsignedShort() * 1.0f/4096.0f;
+
+ // Don't parse locked state, only used by editors
+ AddAbsoluteTag( (CChoreoEvent::AbsTagType)tagtype, tagName, percentage );
+ }
+ }
+
+ if ( GetType() == CChoreoEvent::GESTURE )
+ {
+ float duration = buf.GetFloat();
+ if ( duration != -1 )
+ {
+ SetGestureSequenceDuration( duration );
+ }
+ }
+
+ if ( buf.GetChar() == 1 )
+ {
+ char tagname[ 256 ];
+ char wavname[ 256 ];
+ pStringPool->GetString( buf.GetShort(), tagname, sizeof( tagname ) );
+ pStringPool->GetString( buf.GetShort(), wavname, sizeof( wavname ) );
+
+ SetUsingRelativeTag( true, tagname, wavname );
+ }
+
+ if ( !RestoreFlexAnimationsFromBuffer( buf, pStringPool ) )
+ return false;
+
+ if ( GetType() == LOOP )
+ {
+ SetLoopCount( buf.GetChar() );
+ }
+
+ if ( GetType() == CChoreoEvent::SPEAK )
+ {
+ SetCloseCaptionType( (CLOSECAPTION)buf.GetChar() );
+ char cctoken[ 256 ];
+ pStringPool->GetString( buf.GetShort(), cctoken, sizeof( cctoken ) );
+ SetCloseCaptionToken( cctoken );
+ int flags = buf.GetChar();
+ if ( flags & ( 1<<0 ) )
+ {
+ SetUsingCombinedFile( true );
+ }
+ if ( flags & ( 1<<1 ) )
+ {
+ SetCombinedUsingGenderToken( true );
+ }
+ if ( flags & ( 1<<2 ) )
+ {
+ SetSuppressingCaptionAttenuation( true );
+ }
+ }
+
+ return true;
+}
+
+void CCurveData::SaveToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
+{
+ int c = GetCount();
+ Assert( c <= 255 );
+ buf.PutUnsignedChar( c );
+
+ for ( int i = 0; i < c; i++ )
+ {
+ CExpressionSample *sample = Get( i );
+ buf.PutFloat( sample->time );
+
+ Assert( sample->value >= 0.0f && sample->value <= 1.0f );
+ unsigned char v = sample->value * 255.0f;
+ buf.PutUnsignedChar( v );
+ }
+}
+
+bool CCurveData::RestoreFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
+{
+ int c = buf.GetUnsignedChar();
+ for ( int i = 0; i < c; i++ )
+ {
+ float t, v;
+ t = buf.GetFloat();
+ v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
+
+ Add( t, v, false );
+ }
+
+ return true;
+}
+
+void CChoreoEvent::SaveFlexAnimationsToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
+{
+ int numFlexAnimationTracks = GetNumFlexAnimationTracks();
+ Assert( numFlexAnimationTracks <= 255 );
+ buf.PutUnsignedChar( numFlexAnimationTracks );
+
+ for ( int i = 0; i < numFlexAnimationTracks; i++ )
+ {
+ CFlexAnimationTrack *track = GetFlexAnimationTrack( i );
+
+ buf.PutShort( pStringPool->FindOrAddString( track->GetFlexControllerName() ) );
+
+ int flags = 0;
+ flags |= track->IsTrackActive() ? 1<<0 : 0;
+ flags |= track->IsComboType() ? 1<<1 : 0;
+ buf.PutUnsignedChar( flags );
+
+ buf.PutFloat( track->GetMin() );
+ buf.PutFloat( track->GetMax() );
+
+ buf.PutShort( track->GetNumSamples( 0 ) );
+ for ( int j = 0 ; j < track->GetNumSamples( 0 ) ; j++ )
+ {
+ CExpressionSample *s = track->GetSample( j, 0 );
+ if ( !s )
+ continue;
+
+ buf.PutFloat( s->time );
+
+ Assert( s->value >= 0.0f && s->value <= 1.0f );
+ unsigned char v = s->value * 255.0f;
+ buf.PutUnsignedChar( v );
+
+ buf.PutUnsignedShort( s->GetCurveType() );
+ }
+
+ // Write out combo samples
+ if ( track->IsComboType() )
+ {
+ int numSamples = track->GetNumSamples( 1 );
+ Assert( numSamples <= 32767 );
+ buf.PutUnsignedShort( numSamples );
+
+ for ( int j = 0; j < numSamples; j++ )
+ {
+ CExpressionSample *s = track->GetSample( j, 1 );
+ if ( !s )
+ continue;
+
+ buf.PutFloat( s->time );
+
+ Assert( s->value >= 0.0f && s->value <= 1.0f );
+ unsigned char v = s->value * 255.0f;
+ buf.PutUnsignedChar( v );
+
+ buf.PutUnsignedShort( s->GetCurveType() );
+ }
+ }
+ }
+}
+
+bool CChoreoEvent::RestoreFlexAnimationsFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool )
+{
+ int numTracks = buf.GetUnsignedChar();
+
+ for ( int i = 0; i < numTracks; i++ )
+ {
+ char name[ 256 ];
+ pStringPool->GetString( buf.GetShort(), name, sizeof( name ) );
+
+ CFlexAnimationTrack *track = AddTrack( name );
+
+ int flags = buf.GetUnsignedChar();
+ track->SetTrackActive( ( flags & ( 1<<0 ) ) ? true : false );
+ track->SetComboType( ( flags & ( 1<<1 ) ) ? true : false );
+
+ track->SetMin( buf.GetFloat() );
+ track->SetMax( buf.GetFloat() );
+
+ int s = buf.GetShort();
+ for ( int j = 0; j < s; ++j )
+ {
+ float t, v;
+ t = buf.GetFloat();
+ v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
+
+ CExpressionSample *pSample = track->AddSample( t, v, 0 );
+ pSample->SetCurveType( buf.GetUnsignedShort() );
+ }
+
+ if ( track->IsComboType() )
+ {
+ int s = buf.GetUnsignedShort();
+ for ( int j = 0; j < s; ++j )
+ {
+ float t, v;
+ t = buf.GetFloat();
+ v = (float)buf.GetUnsignedChar() * 1.0f/255.0f;
+
+ CExpressionSample *pSample = track->AddSample( t, v, 1 );
+ pSample->SetCurveType( buf.GetUnsignedShort() );
+ }
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Marks the event as enabled/disabled
+// Input : state -
+//-----------------------------------------------------------------------------
+void CChoreoEvent::SetActive( bool state )
+{
+ m_bActive = state;
+}
+
+bool CChoreoEvent::GetActive() const
+{
+ return m_bActive;
+}