diff options
Diffstat (limited to 'game/client/c_baseflex.h')
| -rw-r--r-- | game/client/c_baseflex.h | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/game/client/c_baseflex.h b/game/client/c_baseflex.h new file mode 100644 index 0000000..71cee3d --- /dev/null +++ b/game/client/c_baseflex.h @@ -0,0 +1,341 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +// Client-side CBasePlayer + +#ifndef C_STUDIOFLEX_H +#define C_STUDIOFLEX_H +#pragma once + + +#include "c_baseanimating.h" +#include "c_baseanimatingoverlay.h" +#include "sceneentity_shared.h" + +#include "utlvector.h" + +//----------------------------------------------------------------------------- +// Purpose: Item in list of loaded scene files +//----------------------------------------------------------------------------- +class CFlexSceneFile +{ +public: + enum + { + MAX_FLEX_FILENAME = 128, + }; + + char filename[ MAX_FLEX_FILENAME ]; + void *buffer; +}; + +// For phoneme emphasis track +struct Emphasized_Phoneme; +class CSentence; + +enum +{ + PHONEME_CLASS_WEAK = 0, + PHONEME_CLASS_NORMAL, + PHONEME_CLASS_STRONG, + + NUM_PHONEME_CLASSES +}; + +// Mapping for each loaded scene file used by this actor +struct FS_LocalToGlobal_t +{ + explicit FS_LocalToGlobal_t() : + m_Key( 0 ), + m_nCount( 0 ), + m_Mapping( 0 ) + { + } + + explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) : + m_Key( key ), + m_nCount( 0 ), + m_Mapping( 0 ) + { + } + + void SetCount( int count ) + { + Assert( !m_Mapping ); + Assert( count > 0 ); + m_nCount = count; + m_Mapping = new int[ m_nCount ]; + Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) ); + } + + FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src ) + { + m_Key = src.m_Key; + delete m_Mapping; + m_Mapping = new int[ src.m_nCount ]; + Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) ); + + m_nCount = src.m_nCount; + } + + ~FS_LocalToGlobal_t() + { + delete m_Mapping; + m_nCount = 0; + m_Mapping = 0; + } + + const flexsettinghdr_t *m_Key; + int m_nCount; + int *m_Mapping; +}; + +bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs ); + +class IHasLocalToGlobalFlexSettings +{ +public: + virtual void EnsureTranslations( const flexsettinghdr_t *pSettinghdr ) = 0; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +struct Emphasized_Phoneme +{ + // Global fields, setup at start + char classname[ 64 ]; + bool required; + // Global fields setup first time tracks played + bool basechecked; + const flexsettinghdr_t *base; + const flexsetting_t *exp; + + // Local fields, processed for each sentence + bool valid; + float amount; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class C_BaseFlex : public C_BaseAnimatingOverlay, public IHasLocalToGlobalFlexSettings +{ + DECLARE_CLASS( C_BaseFlex, C_BaseAnimatingOverlay ); +public: + DECLARE_CLIENTCLASS(); + DECLARE_PREDICTABLE(); + DECLARE_INTERPOLATION(); + + C_BaseFlex(); + virtual ~C_BaseFlex(); + + virtual void Spawn(); + + virtual void InitPhonemeMappings(); + + void SetupMappings( char const *pchFileRoot ); + + virtual CStudioHdr *OnNewModel( void ); + + virtual void StandardBlendingRules( CStudioHdr *hdr, Vector pos[], Quaternion q[], float currentTime, int boneMask ); + + virtual void OnThreadedDrawSetup(); + + // model specific + virtual void BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed ); + static void LinkToGlobalFlexControllers( CStudioHdr *hdr ); + virtual void SetupWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ); + virtual bool SetupGlobalWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ); + static void RunFlexDelay( int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights, float &flFlexDelayTime ); + virtual void SetupLocalWeights( const matrix3x4_t *pBoneToWorld, int nFlexWeightCount, float *pFlexWeights, float *pFlexDelayedWeights ); + virtual bool UsesFlexDelayedWeights(); + + static void RunFlexRules( CStudioHdr *pStudioHdr, float *dest ); + + virtual Vector SetViewTarget( CStudioHdr *pStudioHdr ); + + virtual bool GetSoundSpatialization( SpatializationInfo_t& info ); + + virtual void GetToolRecordingState( KeyValues *msg ); + + // Called at the lowest level to actually apply a flex animation + void AddFlexAnimation( CSceneEventInfo *info ); + + void SetFlexWeight( LocalFlexController_t index, float value ); + float GetFlexWeight( LocalFlexController_t index ); + + // Look up flex controller index by global name + LocalFlexController_t FindFlexController( const char *szName ); + +public: + Vector m_viewtarget; + CInterpolatedVar< Vector > m_iv_viewtarget; + // indexed by model local flexcontroller + float m_flexWeight[MAXSTUDIOFLEXCTRL]; + CInterpolatedVarArray< float, MAXSTUDIOFLEXCTRL > m_iv_flexWeight; + + int m_blinktoggle; + + static int AddGlobalFlexController( const char *szName ); + static char const *GetGlobalFlexControllerName( int idx ); + + // bah, this should be unified with all prev/current stuff. + +public: + + // Keep track of what scenes are being played + void StartChoreoScene( CChoreoScene *scene ); + void RemoveChoreoScene( CChoreoScene *scene ); + + // Start the specifics of an scene event + virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, C_BaseEntity *pTarget ); + + // Manipulation of events for the object + // Should be called by think function to process all scene events + // The default implementation resets m_flexWeight array and calls + // AddSceneEvents + virtual void ProcessSceneEvents( bool bFlexEvents ); + + // Assumes m_flexWeight array has been set up, this adds the actual currently playing + // expressions to the flex weights and adds other scene events as needed + virtual bool ProcessSceneEvent( bool bFlexEvents, CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); + + virtual bool ProcessSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); + + // Remove all playing events + void ClearSceneEvents( CChoreoScene *scene, bool canceled ); + + // Stop specifics of event + virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled ); + + // Add the event to the queue for this actor + void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, C_BaseEntity *pTarget = NULL, bool bClientSide = false ); + + // Remove the event from the queue for this actor + void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill ); + + // Checks to see if the event should be considered "completed" + bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ); + + // Checks to see if a event should be considered "completed" + virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event ); + + int FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key ); + + // IHasLocalToGlobalFlexSettings + virtual void EnsureTranslations( const flexsettinghdr_t *pSettinghdr ); + + // For handling scene files + void *FindSceneFile( const char *filename ); + +private: + + bool RequestStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); + + bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); + bool ProcessFlexSettingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); + void AddFlexSetting( const char *expr, float scale, + const flexsettinghdr_t *pSettinghdr, bool newexpression ); + + // Array of active SceneEvents, in order oldest to newest + CUtlVector < CSceneEventInfo > m_SceneEvents; + CUtlVector < CChoreoScene * > m_ActiveChoreoScenes; + + bool HasSceneEvents() const; + +private: + CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal; + + float m_blinktime; + int m_prevblinktoggle; + + int m_iBlink; + LocalFlexController_t m_iEyeUpdown; + LocalFlexController_t m_iEyeRightleft; + bool m_bSearchedForEyeFlexes; + int m_iMouthAttachment; + + float m_flFlexDelayTime; + float *m_flFlexDelayedWeight; + int m_cFlexDelayedWeight; + + // shared flex controllers + static int g_numflexcontrollers; + static char *g_flexcontroller[MAXSTUDIOFLEXCTRL*4]; // room for global set of flexcontrollers + static float g_flexweight[MAXSTUDIOFLEXDESC]; + +protected: + + Emphasized_Phoneme m_PhonemeClasses[ NUM_PHONEME_CLASSES ]; + +private: + + C_BaseFlex( const C_BaseFlex & ); // not defined, not accessible + + const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr ); + + void ProcessVisemes( Emphasized_Phoneme *classes ); + void AddVisemesForSentence( Emphasized_Phoneme *classes, float emphasis_intensity, CSentence *sentence, float t, float dt, bool juststarted ); + void AddViseme( Emphasized_Phoneme *classes, float emphasis_intensity, int phoneme, float scale, bool newexpression ); + bool SetupEmphasisBlend( Emphasized_Phoneme *classes, int phoneme ); + void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity ); + +#ifdef HL2_CLIENT_DLL +public: + + Vector m_vecLean; + CInterpolatedVar< Vector > m_iv_vecLean; + Vector m_vecShift; + CInterpolatedVar< Vector > m_iv_vecShift; +#endif +}; + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class CFlexSceneFileManager : CAutoGameSystem +{ +public: + + CFlexSceneFileManager() : CAutoGameSystem( "CFlexSceneFileManager" ) + { + } + + virtual bool Init(); + virtual void Shutdown(); + + void EnsureTranslations( IHasLocalToGlobalFlexSettings *instance, const flexsettinghdr_t *pSettinghdr ); + void *FindSceneFile( IHasLocalToGlobalFlexSettings *instance, const char *filename, bool allowBlockingIO ); + +private: + void DeleteSceneFiles(); + + CUtlVector< CFlexSceneFile * > m_FileList; +}; + + +//----------------------------------------------------------------------------- +// Do we have active expressions? +//----------------------------------------------------------------------------- +inline bool C_BaseFlex::HasSceneEvents() const +{ + return m_SceneEvents.Count() != 0; +} + + +EXTERN_RECV_TABLE(DT_BaseFlex); + +float *GetVisemeWeights( int phoneme ); + + +#endif // C_STUDIOFLEX_H + + + + |