410 lines
13 KiB
C++
410 lines
13 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#ifndef CHOREOSCENE_H
|
|
#define CHOREOSCENE_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
class CChoreoEvent;
|
|
class CChoreoChannel;
|
|
class CChoreoActor;
|
|
class IChoreoEventCallback;
|
|
class CEventRelativeTag;
|
|
class CUtlBuffer;
|
|
class CFlexAnimationTrack;
|
|
class ISceneTokenProcessor;
|
|
class IChoreoStringPool;
|
|
|
|
#include "bitvec.h"
|
|
#include "choreoevent.h"
|
|
#include "expressionsample.h"
|
|
#include "tier1/utldict.h"
|
|
#include "tier1/utlvector.h"
|
|
|
|
#define DEFAULT_SCENE_FPS 60
|
|
#define MIN_SCENE_FPS 10
|
|
#define MAX_SCENE_FPS 240
|
|
|
|
#define SCENE_BINARY_TAG MAKEID('b', 'v', 'c', 'd')
|
|
#define SCENE_BINARY_VERSION 0x04
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Container for choreographed scene of events for actors
|
|
//-----------------------------------------------------------------------------
|
|
class CChoreoScene : public ICurveDataAccessor {
|
|
typedef enum {
|
|
PROCESSING_TYPE_IGNORE = 0,
|
|
PROCESSING_TYPE_START,
|
|
PROCESSING_TYPE_START_RESUMECONDITION,
|
|
PROCESSING_TYPE_CONTINUE,
|
|
PROCESSING_TYPE_STOP,
|
|
} PROCESSING_TYPE;
|
|
|
|
struct ActiveList {
|
|
PROCESSING_TYPE pt;
|
|
CChoreoEvent *e;
|
|
};
|
|
|
|
public:
|
|
// Construction
|
|
CChoreoScene(IChoreoEventCallback *callback);
|
|
~CChoreoScene(void);
|
|
|
|
// Assignment
|
|
CChoreoScene &operator=(const CChoreoScene &src);
|
|
|
|
// ICurveDataAccessor methods
|
|
virtual float GetDuration() { return FindStopTime(); };
|
|
virtual bool CurveHasEndTime();
|
|
virtual int GetDefaultCurveType();
|
|
|
|
// Binary serialization
|
|
bool SaveBinary(char const *pszBinaryFileName, char const *pPathID,
|
|
unsigned int nTextVersionCRC,
|
|
IChoreoStringPool *pStringPool);
|
|
void SaveToBinaryBuffer(CUtlBuffer &buf, unsigned int nTextVersionCRC,
|
|
IChoreoStringPool *pStringPool);
|
|
bool RestoreFromBinaryBuffer(CUtlBuffer &buf, char const *filename,
|
|
IChoreoStringPool *pStringPool);
|
|
static bool GetCRCFromBinaryBuffer(CUtlBuffer &buf, unsigned int &crc);
|
|
|
|
// We do some things differently while restoring from a save.
|
|
inline void SetRestoring(bool bRestoring);
|
|
inline bool IsRestoring();
|
|
|
|
enum {
|
|
MAX_SCENE_FILENAME = 128,
|
|
};
|
|
|
|
// Event callback handler
|
|
void SetEventCallbackInterface(IChoreoEventCallback *callback);
|
|
|
|
// Loading
|
|
bool ParseFromBuffer(char const *pFilename,
|
|
ISceneTokenProcessor *tokenizer);
|
|
void SetPrintFunc(void (*pfn)(PRINTF_FORMAT_STRING const char *fmt, ...));
|
|
|
|
// Saving
|
|
bool SaveToFile(const char *filename);
|
|
bool ExportMarkedToFile(const char *filename);
|
|
void MarkForSaveAll(bool mark);
|
|
|
|
// Merges two .vcd's together, returns true if any data was merged
|
|
bool Merge(CChoreoScene *other);
|
|
|
|
static void FileSaveFlexAnimationTrack(CUtlBuffer &buf, int level,
|
|
CFlexAnimationTrack *track,
|
|
int nDefaultCurveType);
|
|
static void FileSaveFlexAnimations(CUtlBuffer &buf, int level,
|
|
CChoreoEvent *e);
|
|
static void FileSaveRamp(CUtlBuffer &buf, int level, CChoreoEvent *e);
|
|
void FileSaveSceneRamp(CUtlBuffer &buf, int level);
|
|
static void FileSaveScaleSettings(CUtlBuffer &buf, int level,
|
|
CChoreoScene *scene);
|
|
|
|
static void ParseFlexAnimations(ISceneTokenProcessor *tokenizer,
|
|
CChoreoEvent *e, bool removeold = true);
|
|
static void ParseRamp(ISceneTokenProcessor *tokenizer, CChoreoEvent *e);
|
|
static void ParseSceneRamp(ISceneTokenProcessor *tokenizer,
|
|
CChoreoScene *scene);
|
|
static void ParseScaleSettings(ISceneTokenProcessor *tokenizer,
|
|
CChoreoScene *scene);
|
|
static void ParseEdgeInfo(ISceneTokenProcessor *tokenizer,
|
|
EdgeInfo_t *edgeinfo);
|
|
|
|
// Debugging
|
|
void SceneMsg(PRINTF_FORMAT_STRING const char *pFormat, ...);
|
|
void Print(void);
|
|
|
|
// Sound system needs to have sounds pre-queued by this much time
|
|
void SetSoundFileStartupLatency(float time);
|
|
|
|
// Simulation
|
|
void Think(float curtime);
|
|
float LoopThink(float curtime);
|
|
void ProcessActiveListEntry(ActiveList *entry);
|
|
// Retrieves time in simulation
|
|
float GetTime(void);
|
|
// Retrieves start/stop time for looped/debug scene
|
|
void GetSceneTimes(float &start, float &end);
|
|
|
|
void SetTime(float t);
|
|
void LoopToTime(float t);
|
|
|
|
// Has simulation finished
|
|
bool SimulationFinished(void);
|
|
// Reset simulation
|
|
void ResetSimulation(bool forward = true, float starttime = 0.0f,
|
|
float endtime = 0.0f);
|
|
// Find time at which last simulation event is triggered
|
|
float FindStopTime(void);
|
|
|
|
void ResumeSimulation(void);
|
|
|
|
// Have all the pause events happened
|
|
bool CheckEventCompletion(void);
|
|
|
|
// Find named actor in scene data
|
|
CChoreoActor *FindActor(const char *name);
|
|
// Remove actor from scene
|
|
void RemoveActor(CChoreoActor *actor);
|
|
// Find index for actor
|
|
int FindActorIndex(CChoreoActor *actor);
|
|
|
|
// Swap actors in the data
|
|
void SwapActors(int a1, int a2);
|
|
|
|
// General data access
|
|
int GetNumEvents(void);
|
|
CChoreoEvent *GetEvent(int event);
|
|
|
|
int GetNumActors(void);
|
|
CChoreoActor *GetActor(int actor);
|
|
|
|
int GetNumChannels(void);
|
|
CChoreoChannel *GetChannel(int channel);
|
|
|
|
// Object allocation/destruction
|
|
void DeleteReferencedObjects(CChoreoActor *actor);
|
|
void DeleteReferencedObjects(CChoreoChannel *channel);
|
|
void DeleteReferencedObjects(CChoreoEvent *event);
|
|
|
|
CChoreoActor *AllocActor(void);
|
|
CChoreoChannel *AllocChannel(void);
|
|
CChoreoEvent *AllocEvent(void);
|
|
|
|
void AddEventToScene(CChoreoEvent *event);
|
|
void AddActorToScene(CChoreoActor *actor);
|
|
void AddChannelToScene(CChoreoChannel *channel);
|
|
|
|
// Fixup simulation times for channel gestures
|
|
void ReconcileGestureTimes(void);
|
|
|
|
// Go through all elements and update relative tags, removing any orphaned
|
|
// tags and updating the timestamp of normal tags
|
|
void ReconcileTags(void);
|
|
CEventRelativeTag *FindTagByName(const char *wavname, const char *name);
|
|
CChoreoEvent *FindTargetingEvent(const char *wavname, const char *name);
|
|
|
|
// Used by UI to provide target actor names
|
|
char const *GetMapname(void);
|
|
void SetMapname(const char *name);
|
|
|
|
void ExportEvents(const char *filename, CUtlVector<CChoreoEvent *> &events);
|
|
void ImportEvents(ISceneTokenProcessor *tokenizer, CChoreoActor *actor,
|
|
CChoreoChannel *channel);
|
|
|
|
// Subscene support
|
|
void SetSubScene(bool sub);
|
|
bool IsSubScene(void) const;
|
|
|
|
int GetSceneFPS(void) const;
|
|
void SetSceneFPS(int fps);
|
|
bool IsUsingFrameSnap(void) const;
|
|
void SetUsingFrameSnap(bool snap);
|
|
|
|
float SnapTime(float t);
|
|
|
|
int GetSceneRampCount(void) { return m_SceneRamp.GetCount(); };
|
|
CExpressionSample *GetSceneRamp(int index) {
|
|
return m_SceneRamp.Get(index);
|
|
};
|
|
CExpressionSample *AddSceneRamp(float time, float value, bool selected) {
|
|
return m_SceneRamp.Add(time, value, selected);
|
|
};
|
|
void DeleteSceneRamp(int index) { m_SceneRamp.Delete(index); };
|
|
void ClearSceneRamp(void) { m_SceneRamp.Clear(); };
|
|
void ResortSceneRamp(void) { m_SceneRamp.Resort(this); };
|
|
|
|
CCurveData *GetSceneRamp(void) { return &m_SceneRamp; };
|
|
|
|
// Global intensity for scene
|
|
float GetSceneRampIntensity(float time) {
|
|
return m_SceneRamp.GetIntensity(this, time);
|
|
}
|
|
|
|
int GetTimeZoom(char const *tool);
|
|
void SetTimeZoom(char const *tool, int tz);
|
|
int TimeZoomFirst();
|
|
int TimeZoomNext(int i);
|
|
int TimeZoomInvalid() const;
|
|
char const *TimeZoomName(int i);
|
|
|
|
void ReconcileCloseCaption();
|
|
|
|
char const *GetFilename() const;
|
|
void SetFileName(char const *fn);
|
|
|
|
bool GetPlayingSoundName(char *pchBuff, int iBuffLength);
|
|
bool HasUnplayedSpeech();
|
|
bool HasFlexAnimation();
|
|
void SetBackground(bool bIsBackground);
|
|
bool IsBackground(void);
|
|
|
|
void ClearPauseEventDependencies();
|
|
|
|
bool HasEventsOfType(CChoreoEvent::EVENTTYPE type) const;
|
|
void RemoveEventsExceptTypes(int *typeList, int count);
|
|
|
|
void IgnorePhonemes(bool bIgnore);
|
|
bool ShouldIgnorePhonemes() const;
|
|
|
|
// This is set by the engine to signify that we're not modifying the data
|
|
// and
|
|
// therefore we can precompute the end time
|
|
static bool s_bEditingDisabled;
|
|
|
|
private:
|
|
// Simulation stuff
|
|
enum { IN_RANGE = 0, BEFORE_RANGE, AFTER_RANGE };
|
|
|
|
int IsTimeInRange(float t, float starttime, float endtime);
|
|
|
|
static bool EventLess(const CChoreoScene::ActiveList &al0,
|
|
const CChoreoScene::ActiveList &al1);
|
|
|
|
int EventThink(CChoreoEvent *e, float frame_start_time,
|
|
float frame_end_time, bool playing_forward,
|
|
PROCESSING_TYPE &disposition);
|
|
|
|
// Prints to debug console, etc
|
|
void choreoprintf(int level, PRINTF_FORMAT_STRING const char *fmt, ...);
|
|
|
|
// Initialize scene
|
|
void Init(IChoreoEventCallback *callback);
|
|
|
|
float FindAdjustedStartTime(void);
|
|
float FindAdjustedEndTime(void);
|
|
|
|
CChoreoEvent *FindPauseBetweenTimes(float starttime, float endtime);
|
|
|
|
// Parse scenes from token buffer
|
|
CChoreoEvent *ParseEvent(CChoreoActor *actor, CChoreoChannel *channel);
|
|
CChoreoChannel *ParseChannel(CChoreoActor *actor);
|
|
CChoreoActor *ParseActor(void);
|
|
|
|
void ParseFPS(void);
|
|
void ParseSnap(void);
|
|
void ParseIgnorePhonemes(void);
|
|
|
|
// Map file for retrieving named objects
|
|
void ParseMapname(void);
|
|
// When previewing actor in hlfaceposer, this is the model to associate
|
|
void ParseFacePoserModel(CChoreoActor *actor);
|
|
|
|
// Print to printfunc
|
|
void PrintEvent(int level, CChoreoEvent *e);
|
|
void PrintChannel(int level, CChoreoChannel *c);
|
|
void PrintActor(int level, CChoreoActor *a);
|
|
|
|
// File I/O
|
|
public:
|
|
static void FilePrintf(CUtlBuffer &buf, int level,
|
|
PRINTF_FORMAT_STRING const char *fmt, ...);
|
|
|
|
private:
|
|
void FileSaveEvent(CUtlBuffer &buf, int level, CChoreoEvent *e);
|
|
void FileSaveChannel(CUtlBuffer &buf, int level, CChoreoChannel *c);
|
|
void FileSaveActor(CUtlBuffer &buf, int level, CChoreoActor *a);
|
|
void FileSaveHeader(CUtlBuffer &buf);
|
|
|
|
// Object destruction
|
|
void DestroyActor(CChoreoActor *actor);
|
|
void DestroyChannel(CChoreoChannel *channel);
|
|
void DestroyEvent(CChoreoEvent *event);
|
|
|
|
void AddPauseEventDependency(CChoreoEvent *pauseEvent,
|
|
CChoreoEvent *suppressed);
|
|
|
|
void InternalDetermineEventTypes();
|
|
|
|
// Global object storage
|
|
CUtlVector<CChoreoEvent *> m_Events;
|
|
CUtlVector<CChoreoActor *> m_Actors;
|
|
CUtlVector<CChoreoChannel *> m_Channels;
|
|
|
|
// These are just pointers, the actual objects are in m_Events
|
|
CUtlVector<CChoreoEvent *> m_ResumeConditions;
|
|
// These are just pointers, the actual objects are in m_Events
|
|
CUtlVector<CChoreoEvent *> m_ActiveResumeConditions;
|
|
// These are just pointers, the actual objects are in m_Events
|
|
CUtlVector<CChoreoEvent *> m_PauseEvents;
|
|
|
|
// Current simulation time
|
|
float m_flCurrentTime;
|
|
|
|
float m_flStartLoopTime;
|
|
|
|
float m_flStartTime;
|
|
float m_flEndTime;
|
|
|
|
float m_flEarliestTime;
|
|
float m_flLatestTime;
|
|
int m_nActiveEvents;
|
|
|
|
// Wave file playback needs to issue play commands a bit ahead of time
|
|
// in order to hit exact marks
|
|
float m_flSoundSystemLatency;
|
|
|
|
// Scene's linger a bit after finishing to let blends reset themselves
|
|
float m_flLastActiveTime;
|
|
|
|
// Print callback function
|
|
void (*m_pfnPrint)(PRINTF_FORMAT_STRING const char *fmt, ...);
|
|
|
|
IChoreoEventCallback *m_pIChoreoEventCallback;
|
|
|
|
ISceneTokenProcessor *m_pTokenizer;
|
|
|
|
enum { MAX_MAPNAME = 128 };
|
|
|
|
char m_szMapname[MAX_MAPNAME];
|
|
|
|
int m_nSceneFPS;
|
|
|
|
CCurveData m_SceneRamp;
|
|
|
|
CUtlDict<int, int> m_TimeZoomLookup;
|
|
char m_szFileName[MAX_SCENE_FILENAME];
|
|
|
|
CBitVec<CChoreoEvent::NUM_TYPES> m_bitvecHasEventOfType;
|
|
|
|
// tag to suppress vcd when others are playing
|
|
bool m_bIsBackground : 1;
|
|
bool m_bIgnorePhonemes : 1;
|
|
bool m_bSubScene : 1;
|
|
bool m_bUseFrameSnap : 1;
|
|
bool m_bRestoring : 1;
|
|
|
|
int m_nLastPauseEvent;
|
|
// This only gets updated if it's loaded from a buffer which means we're not
|
|
// in an editor
|
|
float m_flPrecomputedStopTime;
|
|
};
|
|
|
|
bool CChoreoScene::IsRestoring() { return m_bRestoring; }
|
|
|
|
void CChoreoScene::SetRestoring(bool bRestoring) { m_bRestoring = bRestoring; }
|
|
|
|
abstract_class IChoreoStringPool {
|
|
public:
|
|
virtual short FindOrAddString(const char *pString) = 0;
|
|
virtual bool GetString(short stringId, char *buff, int buffSize) = 0;
|
|
};
|
|
|
|
CChoreoScene *ChoreoLoadScene(char const *filename,
|
|
IChoreoEventCallback *callback,
|
|
ISceneTokenProcessor *tokenizer,
|
|
void (*pfn)(PRINTF_FORMAT_STRING const char *fmt,
|
|
...));
|
|
|
|
bool IsBufferBinaryVCD(char *pBuffer, int bufferSize);
|
|
|
|
#endif // CHOREOSCENE_H
|