Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

708 lines
20 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef CHOREOEVENT_H
#define CHOREOEVENT_H
#ifdef _WIN32
#pragma once
#endif
class CChoreoActor;
class CChoreoChannel;
class CChoreoEvent;
class CChoreoScene;
class IChoreoEventCallback;
class CAudioMixer;
class CUtlBuffer;
class IChoreoStringPool;
#include "tier1/utlstring.h"
#include "tier1/utlvector.h"
#include "expressionsample.h"
#include "networkvar.h"
#include "localflexcontroller.h"
typedef CUtlString ChoreoStr_t;
//-----------------------------------------------------------------------------
// Purpose: SPEAK events can have "relative tags" that other objects can reference
// to specify their start times off of
//-----------------------------------------------------------------------------
class CEventRelativeTag
{
public:
DECLARE_CLASS_NOBASE( CEventRelativeTag );
enum
{
MAX_EVENTTAG_LENGTH = 128,
};
CEventRelativeTag( CChoreoEvent *owner, const char *name, float percentage );
CEventRelativeTag( const CEventRelativeTag& src );
const char *GetName( void );
float GetPercentage( void );
void SetPercentage( float percentage );
// Returns the corrected time based on the owner's length and start time
float GetStartTime( void );
CChoreoEvent *GetOwner( void );
void SetOwner( CChoreoEvent *event );
protected:
ChoreoStr_t m_Name;
float m_flPercentage;
CChoreoEvent *m_pOwner;
};
//-----------------------------------------------------------------------------
// Purpose: GESTURE events can have "absolute tags" (where the value is not a
// percentage, but an actual timestamp from the start of the event)
//-----------------------------------------------------------------------------
class CEventAbsoluteTag
{
public:
enum
{
MAX_EVENTTAG_LENGTH = 128,
};
CEventAbsoluteTag( CChoreoEvent *owner, const char *name, float percentage );
CEventAbsoluteTag( const CEventAbsoluteTag& src );
const char *GetName( void );
float GetPercentage( void );
void SetPercentage( float percentage );
float GetEventTime( void );
void SetEventTime( float t );
float GetAbsoluteTime( void );
void SetAbsoluteTime( float t );
CChoreoEvent *GetOwner( void );
void SetOwner( CChoreoEvent *event );
void SetLocked( bool bLocked );
bool GetLocked( void );
void SetLinear( bool bLinear );
bool GetLinear( void );
void SetEntry( bool bEntry );
bool GetEntry( void );
void SetExit( bool bExit );
bool GetExit( void );
protected:
ChoreoStr_t m_Name;
float m_flPercentage;
bool m_bLocked:1;
bool m_bLinear:1;
bool m_bEntry:1;
bool m_bExit:1;
CChoreoEvent *m_pOwner;
};
//-----------------------------------------------------------------------------
// Purpose: FLEXANIMATION events can have "timing tags" that are used to align and
// manipulate flex animation curves
//-----------------------------------------------------------------------------
class CFlexTimingTag : public CEventRelativeTag
{
DECLARE_CLASS( CFlexTimingTag, CEventRelativeTag );
public:
CFlexTimingTag( CChoreoEvent *owner, const char *name, float percentage, bool locked );
CFlexTimingTag( const CFlexTimingTag& src );
bool GetLocked( void );
void SetLocked( bool locked );
protected:
bool m_bLocked;
};
//-----------------------------------------------------------------------------
// Purpose: A flex controller position can be animated over a period of time
//-----------------------------------------------------------------------------
class CFlexAnimationTrack
{
public:
enum
{
MAX_CONTROLLER_NAME = 128,
};
CFlexAnimationTrack( CChoreoEvent *event );
CFlexAnimationTrack( const CFlexAnimationTrack* src );
virtual ~CFlexAnimationTrack( void );
void SetEvent( CChoreoEvent *event );
CChoreoEvent *GetEvent( void );
void SetFlexControllerName( const char *name );
char const *GetFlexControllerName( void );
void SetComboType( bool combo );
bool IsComboType( void );
void SetMin( float value );
void SetMax( float value );
float GetMin( int type = 0 );
float GetMax( int type = 0 );
bool IsInverted( void );
void SetInverted( bool isInverted );
int GetNumSamples( int type = 0 );
CExpressionSample *GetSample( int index, int type = 0 );
bool IsTrackActive( void );
void SetTrackActive( bool active );
// returns scaled value for absolute time per left/right side
float GetIntensity( float time, int side = 0 );
CExpressionSample *AddSample( float time, float value, int type = 0 );
void RemoveSample( int index, int type = 0 );
void Clear( void );
void Resort( int type = 0 );
// Puts in dummy start/end samples to spline to zero ( or 0.5 for
// left/right data) at the origins
CExpressionSample *GetBoundedSample( int number, bool& bClamped, int type = 0 );
int GetFlexControllerIndex( int side = 0 );
LocalFlexController_t GetRawFlexControllerIndex( int side = 0 );
void SetFlexControllerIndex( LocalFlexController_t raw, int index, int side = 0 );
// returns 0..1 value for 0..1 time fraction per mag/balance
float GetFracIntensity( float time, int type );
// retrieves raw intensity values (for mag vs. left/right slider setting)
float GetSampleIntensity( float time );
float GetBalanceIntensity( float time );
void SetEdgeInfo( bool leftEdge, int curveType, float zero );
void GetEdgeInfo( bool leftEdge, int& curveType, float& zero ) const;
void SetEdgeActive( bool leftEdge, bool state );
bool IsEdgeActive( bool leftEdge ) const;
int GetEdgeCurveType( bool leftEdge ) const;
float GetEdgeZeroValue( bool leftEdge ) const;
float GetDefaultEdgeZeroPos() const;
void SetServerSide( bool state );
bool IsServerSide() const;
private:
// remove any samples after endtime
void RemoveOutOfRangeSamples( int type );
// returns scaled value for absolute time per mag/balance
float GetIntensityInternal( float time, int type );
public:
// returns the fractional (0..1) value for "zero" based on Min/Max ranges
float GetZeroValue( int type, bool leftSide );
private:
char *m_pControllerName;
// base track has range, combo is always 0..1
float m_flMin;
float m_flMax;
// 0 == magnitude
// 1 == left/right
CUtlVector< CExpressionSample > m_Samples[ 2 ];
int m_nFlexControllerIndex[ 2 ];
LocalFlexController_t m_nFlexControllerIndexRaw[ 2 ];
// For left and right edge of type 0 flex data ( magnitude track )
EdgeInfo_t m_EdgeInfo[ 2 ];
CChoreoEvent *m_pEvent;
// Is track active
bool m_bActive:1;
// Is this a combo (magnitude + stereo) track
bool m_bCombo:1;
bool m_bServerSide:1;
bool m_bInverted; // track is displayed 1..0 instead of 0..1
};
//-----------------------------------------------------------------------------
// Purpose: The generic scene event type
//-----------------------------------------------------------------------------
class CChoreoEvent : public ICurveDataAccessor
{
public:
// Type of event this object represents
typedef enum
{
// Don't know yet
UNSPECIFIED = 0,
// Section start/end
SECTION,
// Play an expression
EXPRESSION,
// Look at another actor
LOOKAT,
// Move to a location
MOVETO,
// Speak/visemes a wave file
SPEAK,
// Play a gesture
GESTURE,
// Play a sequence
SEQUENCE,
// Face another actor
FACE,
// Fire a trigger
FIRETRIGGER,
// One or more flex sliders animated over the course of the event time period
FLEXANIMATION,
// A contained .vcd file
SUBSCENE,
// Loop back to previous time (forever or up to N times)
LOOP,
// A time span during which the scene may be temporarily interrupted
INTERRUPT,
// A dummy event that is used to mark the .vcd end time
STOPPOINT,
// A time span during which this actor can respond to events happening in the world, etc.
PERMIT_RESPONSES,
// A string passed to the game code for interpretation
GENERIC,
// THIS MUST BE LAST!!!
NUM_TYPES,
} EVENTTYPE;
enum
{
MAX_TAGNAME_STRING = 128,
MAX_CCTOKEN_STRING = 64,
};
typedef enum
{
DEFAULT = 0,
SIMULATION,
DISPLAY,
} TIMETYPE;
typedef enum
{
CC_MASTER = 0, // default, implied
CC_SLAVE,
CC_DISABLED,
NUM_CC_TYPES,
} CLOSECAPTION;
static int s_nGlobalID;
// Construction
CChoreoEvent( CChoreoScene *scene );
CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name );
CChoreoEvent( CChoreoScene *scene, EVENTTYPE type, const char *name, const char *param );
// Assignment
CChoreoEvent& operator=(const CChoreoEvent& src );
~CChoreoEvent( void );
// ICurveDataAccessor methods
virtual bool CurveHasEndTime();
virtual int GetDefaultCurveType();
// Binary serialization
void SaveToBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool );
bool RestoreFromBuffer( CUtlBuffer& buf, CChoreoScene *pScene, IChoreoStringPool *pStringPool );
// Accessors
EVENTTYPE GetType( void );
void SetType( EVENTTYPE type );
void SetName( const char *name );
const char *GetName( void );
void SetParameters( const char *target );
const char *GetParameters( void );
void SetParameters2( const char *target );
const char *GetParameters2( void );
void SetParameters3( const char *target );
const char *GetParameters3( void );
void SetStartTime( float starttime );
float GetStartTime( void );
void SetEndTime( float endtime );
float GetEndTime( void );
float GetDuration( void );
void SetResumeCondition( bool resumecondition );
bool IsResumeCondition( void );
void SetLockBodyFacing( bool lockbodyfacing );
bool IsLockBodyFacing( void );
void SetDistanceToTarget( float distancetotarget );
float GetDistanceToTarget( void );
void SetForceShortMovement( bool bForceShortMovement );
bool GetForceShortMovement( void );
void SetSyncToFollowingGesture( bool bSyncToFollowingGesture );
bool GetSyncToFollowingGesture( void );
void SetPlayOverScript( bool bPlayOverScript );
bool GetPlayOverScript( void );
int GetRampCount( void ) { return m_Ramp.GetCount(); };
CExpressionSample *GetRamp( int index ) { return m_Ramp.Get( index ); };
CExpressionSample *AddRamp( float time, float value, bool selected ) { return m_Ramp.Add( time, value, selected ); };
void DeleteRamp( int index ) { m_Ramp.Delete( index ); };
void ClearRamp( void ) { m_Ramp.Clear(); };
void ResortRamp( void ) { m_Ramp.Resort( this ); };
CCurveData *GetRamp( void ) { return &m_Ramp; };
float GetRampIntensity( float time ) { return m_Ramp.GetIntensity( this, time ); };
// Calculates weighting for a given time
float GetIntensity( float scenetime );
float GetIntensityArea( float scenetime );
// Calculates 0..1 completion for a given time
float GetCompletion( float time );
// An end time of -1.0f means that the events is just triggered at the leading edge
bool HasEndTime( void );
// Is the event something that can be sized ( a wave file, e.g. )
bool IsFixedLength( void );
void SetFixedLength( bool isfixedlength );
// Move the start/end/both times by the specified dt (fixes up -1.0f endtimes)
void OffsetStartTime( float dt );
void OffsetEndTime( float dt );
void OffsetTime( float dt );
// Snap to scene framerate
void SnapTimes( void );
float SnapTime( float t );
CChoreoScene *GetScene( void );
void SetScene( CChoreoScene *scene );
// The actor the event is associated with
void SetActor( CChoreoActor *actor );
CChoreoActor *GetActor( void );
// The channel the event is associated with
void SetChannel( CChoreoChannel *channel );
CChoreoChannel *GetChannel( void );
// Get a more involved description of the event
const char *GetDescription( void );
void ClearAllRelativeTags( void );
int GetNumRelativeTags( void );
CEventRelativeTag *GetRelativeTag( int tagnum );
CEventRelativeTag *FindRelativeTag( const char *tagname );
void AddRelativeTag( const char *tagname, float percentage );
void RemoveRelativeTag( const char *tagname );
bool IsUsingRelativeTag( void );
void SetUsingRelativeTag( bool usetag, const char *tagname = 0, const char *wavname = 0);
const char *GetRelativeTagName( void );
const char *GetRelativeWavName( void );
// Absolute tags
typedef enum
{
PLAYBACK = 0, // new timeline - FIXME: should be stored as an absolute time
ORIGINAL, // original timeline - FIXME: should be stored at a fixed percentage of event
NUM_ABS_TAG_TYPES,
} AbsTagType;
void SetGestureSequenceDuration( float duration );
bool GetGestureSequenceDuration( float& duration );
void ClearAllAbsoluteTags( AbsTagType type );
int GetNumAbsoluteTags( AbsTagType type );
CEventAbsoluteTag *GetAbsoluteTag( AbsTagType type, int tagnum );
CEventAbsoluteTag *FindAbsoluteTag( AbsTagType type, const char *tagname );
void AddAbsoluteTag( AbsTagType type, const char *tagname, float t );
void RemoveAbsoluteTag( AbsTagType type, const char *tagname );
bool VerifyTagOrder( void );
float GetOriginalPercentageFromPlaybackPercentage( float t );
float GetPlaybackPercentageFromOriginalPercentage( float t );
static const char *NameForAbsoluteTagType( AbsTagType t );
static AbsTagType TypeForAbsoluteTagName( const char *name );
void RescaleGestureTimes( float newstart, float newend, bool bMaintainAbsoluteTagPositions );
bool PreventTagOverlap( void );
CEventAbsoluteTag *FindEntryTag( AbsTagType type );
CEventAbsoluteTag *FindExitTag( AbsTagType type );
// Flex animation type
int GetNumFlexAnimationTracks( void );
CFlexAnimationTrack *GetFlexAnimationTrack( int index );
CFlexAnimationTrack *AddTrack( const char *controllername );
CFlexAnimationTrack *FindTrack( const char *controllername );
void RemoveTrack( int index );
void RemoveAllTracks( void );
void OnEndTimeChanged( void );
bool GetTrackLookupSet( void );
void SetTrackLookupSet( bool set );
// Flex Timing Tags (used by editor only)
void ClearAllTimingTags( void );
int GetNumTimingTags( void );
CFlexTimingTag *GetTimingTag( int tagnum );
CFlexTimingTag *FindTimingTag( const char *tagname );
void AddTimingTag( const char *tagname, float percentage, bool locked );
void RemoveTimingTag( const char *tagname );
// Subscene ( embedded .vcd ) support
void SetSubScene( CChoreoScene *scene );
CChoreoScene *GetSubScene( void );
bool IsProcessing( void ) const;
void StartProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t );
void ContinueProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t );
void StopProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t );
bool CheckProcessing( IChoreoEventCallback *cb, CChoreoScene *scene, float t );
void ResetProcessing( void );
void SetMixer( CAudioMixer *mixer );
CAudioMixer *GetMixer( void ) const;
// Hack for LOOKAT in editor
int GetPitch( void ) const;
void SetPitch( int pitch );
int GetYaw( void ) const;
void SetYaw( int yaw );
// For LOOP events
void SetLoopCount( int numloops );
int GetLoopCount( void );
int GetNumLoopsRemaining( void );
void SetNumLoopsRemaining( int loops );
bool IsMarkedForSave() const { return m_bMarkedForSave; }
void SetMarkedForSave( bool mark ) { m_bMarkedForSave = mark; }
void GetMovementStyle( char *style, int maxlen );
void GetDistanceStyle( char *style, int maxlen );
int GetGlobalID() const { return m_nGlobalID; }
// Localization/CC support (close captioning and multiple wave file recombination)
void SetCloseCaptionType( CLOSECAPTION type );
CLOSECAPTION GetCloseCaptionType() const;
void SetCloseCaptionToken( char const *token );
char const *GetCloseCaptionToken() const;
void SetUsingCombinedFile( bool isusing );
bool IsUsingCombinedFile() const;
void SetRequiredCombinedChecksum( unsigned int checksum );
unsigned int GetRequiredCombinedChecksum();
void SetNumSlaves( int num );
int GetNumSlaves() const;
void SetLastSlaveEndTime( float t );
float GetLastSlaveEndTime() const;
void SetCloseCaptionTokenValid( bool valid );
bool GetCloseCaptionTokenValid() const;
bool ComputeCombinedBaseFileName( char *dest, int destlen, bool creategenderwildcard );
bool IsCombinedUsingGenderToken() const;
void SetCombinedUsingGenderToken( bool using_gender );
bool IsSuppressingCaptionAttenuation() const;
void SetSuppressingCaptionAttenuation( bool suppress );
int ValidateCombinedFile();
// This returns false if the wave is CC_DISABLED or is a CC_SLAVE,
// otherwise it returns the actual m_szCCToken value, or if that's
// blank it'll return the sounds.txt entry name (m_szParameters)
bool GetPlaybackCloseCaptionToken( char *dest, int destlen );
void ClearEventDependencies();
void AddEventDependency( CChoreoEvent *other );
void GetEventDependencies( CUtlVector< CChoreoEvent * >& list );
void SetActive( bool state );
bool GetActive() const;
void SetDefaultCurveType( int nCurveType );
// Turn enum into string and vice versa
static EVENTTYPE TypeForName( const char *name );
static const char *NameForType( EVENTTYPE type );
// Turn enum into string and vice versa
static CLOSECAPTION CCTypeForName( const char *name );
static const char *NameForCCType( CLOSECAPTION type );
private:
// Declare copy constructor private to prevent accidental usage...
CChoreoEvent(const CChoreoEvent& src );
void SaveFlexAnimationsToBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool );
bool RestoreFlexAnimationsFromBuffer( CUtlBuffer& buf, IChoreoStringPool *pStringPool );
float GetBoundedAbsoluteTagPercentage( AbsTagType type, int tagnum );
float _GetIntensity( float time );
// String bounds
enum
{
MAX_CHOREOEVENT_NAME = 128,
MAX_PARAMETERS_STRING = 128,
};
// Base initialization
void Init( CChoreoScene *scene );
// Type of event
byte m_fType;
// Close caption type
byte m_ccType;
// Name of event
ChoreoStr_t m_Name;
// Event parameters
ChoreoStr_t m_Parameters;
ChoreoStr_t m_Parameters2;
ChoreoStr_t m_Parameters3;
// Event start time
float m_flStartTime;
// Event end time ( -1.0f means no ending, just leading edge triggered )
float m_flEndTime;
// Duration of underlying gesture sequence
float m_flGestureSequenceDuration;
// For CChoreoEvent::LOOP
int m_nNumLoops; // -1 == no limit
int m_nLoopsRemaining;
// Overall intensity curve
CCurveData m_Ramp;
// Start time is computed based on length of item referenced by tagged name
ChoreoStr_t m_TagName;
ChoreoStr_t m_TagWavName;
// Associated actor
CChoreoActor *m_pActor;
// Associated channel
CChoreoChannel *m_pChannel;
CUtlVector < CEventRelativeTag > m_RelativeTags;
CUtlVector < CFlexTimingTag > m_TimingTags;
CUtlVector < CEventAbsoluteTag > m_AbsoluteTags[ NUM_ABS_TAG_TYPES ];
CUtlVector < CFlexAnimationTrack * > m_FlexAnimationTracks;
CChoreoScene *m_pSubScene;
CAudioMixer *m_pMixer;
// Scene which owns this event
CChoreoScene *m_pScene;
int m_nPitch;
int m_nYaw;
float m_flDistanceToTarget;
int m_nGlobalID;
ChoreoStr_t m_CCToken;
unsigned int m_uRequiredCombinedChecksum;
// on master only, the combined file must have the same checksum to be useable
int m_nNumSlaves;
// Only set on master, helps UI draw underbar
float m_flLastSlaveEndTime;
// true if the cc token was found in the cc manager's database
CUtlVector< CChoreoEvent * > m_Dependencies;
int m_nDefaultCurveType;
public:
// used only during scrubbing of looping sequences
float m_flPrevCycle;
float m_flPrevTime;
// Flags
bool m_bFixedLength:1;
// True if this event must be "finished" before the next section can be started
// after playback is paused from a globalevent
bool m_bResumeCondition:1;
bool m_bUsesTag:1;
bool m_bTrackLookupSet:1;
bool m_bProcessing:1;
bool m_bLockBodyFacing:1;
// Purely for save/load
bool m_bMarkedForSave:1;
bool m_bUsingCombinedSoundFile:1;
bool m_bCCTokenValid:1;
bool m_bCombinedUsingGenderToken:1;
bool m_bSuppressCaptionAttenuation:1;
bool m_bForceShortMovement:1;
bool m_bSyncToFollowingGesture:1;
bool m_bActive:1;
bool m_bPlayOverScript:1;
};
#endif // CHOREOEVENT_H