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.
342 lines
10 KiB
342 lines
10 KiB
![]()
4 years ago
|
//========= 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
|
||
|
|
||
|
|
||
|
|
||
|
|