|
|
//========= Copyright � 1996-2005, 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,
// Camera control
CAMERA,
// Script function call
SCRIPT,
// 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 { INVALID = -1,
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; bool HasStopped() 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_bHasStopped : 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
|