Seaside/SpyCustom/c_baseflex.h
2021-06-16 16:08:23 +03:00

285 lines
7.9 KiB
C++

#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"
class CFlexSceneFile
{
public:
enum
{
MAX_FLEX_FILENAME = 128,
};
char filename[MAX_FLEX_FILENAME];
void* buffer;
};
struct Emphasized_Phoneme;
class CSentence;
enum
{
PHONEME_CLASS_WEAK = 0,
PHONEME_CLASS_NORMAL,
PHONEME_CLASS_STRONG,
NUM_PHONEME_CLASSES
};
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;
};
struct Emphasized_Phoneme
{
char classname[64];
bool required;
bool basechecked;
const flexsettinghdr_t* base;
const flexsetting_t* exp;
bool valid;
float amount;
};
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();
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);
void AddFlexAnimation(CSceneEventInfo* info);
void SetFlexWeight(LocalFlexController_t index, float value);
float GetFlexWeight(LocalFlexController_t index);
LocalFlexController_t FindFlexController(const char* szName);
public:
Vector m_viewtarget;
CInterpolatedVar< Vector > m_iv_viewtarget;
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);
public:
void StartChoreoScene(CChoreoScene* scene);
void RemoveChoreoScene(CChoreoScene* scene);
virtual bool StartSceneEvent(CSceneEventInfo* info, CChoreoScene* scene, CChoreoEvent* event, CChoreoActor* actor, C_BaseEntity* pTarget);
virtual void ProcessSceneEvents(bool bFlexEvents);
virtual bool ProcessSceneEvent(bool bFlexEvents, CSceneEventInfo* info, CChoreoScene* scene, CChoreoEvent* event);
virtual bool ProcessSequenceSceneEvent(CSceneEventInfo* info, CChoreoScene* scene, CChoreoEvent* event);
void ClearSceneEvents(CChoreoScene* scene, bool canceled);
virtual bool ClearSceneEvent(CSceneEventInfo* info, bool fastKill, bool canceled);
void AddSceneEvent(CChoreoScene* scene, CChoreoEvent* event, C_BaseEntity* pTarget = NULL, bool bClientSide = false);
void RemoveSceneEvent(CChoreoScene* scene, CChoreoEvent* event, bool fastKill);
bool CheckSceneEvent(float currenttime, CChoreoScene* scene, CChoreoEvent* event);
virtual bool CheckSceneEventCompletion(CSceneEventInfo* info, float currenttime, CChoreoScene* scene, CChoreoEvent* event);
int FlexControllerLocalToGlobal(const flexsettinghdr_t* pSettinghdr, int key);
virtual void EnsureTranslations(const flexsettinghdr_t* pSettinghdr);
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);
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;
static int g_numflexcontrollers;
static char* g_flexcontroller[MAXSTUDIOFLEXCTRL * 4];
static float g_flexweight[MAXSTUDIOFLEXDESC];
protected:
Emphasized_Phoneme m_PhonemeClasses[NUM_PHONEME_CLASSES];
private:
C_BaseFlex(const C_BaseFlex&);
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
};
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;
};
inline bool C_BaseFlex::HasSceneEvents() const
{
return m_SceneEvents.Count() != 0;
}
EXTERN_RECV_TABLE(DT_BaseFlex);
float* GetVisemeWeights(int phoneme);
#endif