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.
341 lines
10 KiB
341 lines
10 KiB
//========= 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 = NULL; |
|
}; |
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|