207 lines
5.8 KiB
C++
207 lines
5.8 KiB
C++
#ifndef _CRY_ANIMATION_CRY_ANIMATION_INFO_HDR_
|
|
#define _CRY_ANIMATION_CRY_ANIMATION_INFO_HDR_
|
|
|
|
struct AnimEvent { AnimSinkEventData UserData; float fTime; };
|
|
inline bool operator < (const AnimEvent& left, const AnimEvent& right)
|
|
{
|
|
return left.fTime < right.fTime;
|
|
}
|
|
// returns true if the given events are equal with the given time tolerance
|
|
inline bool isEqual (const AnimEvent& left, const AnimEvent& right, float fTolerance = 1e-3f)
|
|
{
|
|
return left.UserData == right.UserData
|
|
&& fabs(left.fTime - right.fTime) < fTolerance;
|
|
}
|
|
|
|
//! this structure contains info about loaded animations
|
|
struct AnimData
|
|
{
|
|
string strName; // the name of the animation (not the name of the file) - unique per-model
|
|
float fStart, fStop; // start and stop time, in seconds
|
|
int nGlobalAnimId;
|
|
bool bLoop;
|
|
|
|
AnimData():
|
|
fStart(0), fStop(0), bLoop(false),
|
|
nGlobalAnimId (-1)
|
|
{
|
|
}
|
|
bool isStatic () const {return fStart == fStop;}
|
|
float getLength() const {return fStop - fStart;}
|
|
|
|
size_t sizeofThis()const
|
|
{
|
|
return sizeof(*this) + strName.capacity();
|
|
}
|
|
};
|
|
|
|
struct MiniRangeEntity {
|
|
int start;
|
|
int end;
|
|
MiniRangeEntity()
|
|
{
|
|
start = end = 0;
|
|
}
|
|
void operator = (const RANGE_ENTITY& right)
|
|
{
|
|
this->start = right.start;
|
|
this->end = right.end;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// this is the animation information on the module level (not on the per-model level)
|
|
// it doesn't know the name of the animation (which is model-specific), but does know the file name
|
|
// Implements some services for bone binding and ref counting
|
|
struct GlobalAnimation
|
|
{
|
|
// Since we know the number of controllers per animation from the beginning and don't
|
|
// change it, we could use more econimical TFixedArray here instead of STL or other array.
|
|
typedef IController_AutoArray ControllerArray;
|
|
|
|
// the flags used in the nFlags member
|
|
enum
|
|
{
|
|
// if this is true, then the animation has valid info data (has been loaded at least once)
|
|
FLAGS_INFO_LOADED = 1,
|
|
// this doesn't allow the auto-unloading to happen
|
|
FLAGS_DISABLE_AUTO_UNLOAD = 1 << 1,
|
|
// this forces the animation to be loaded immediately
|
|
FLAGS_DISABLE_DELAY_LOAD = 1 << 2,
|
|
// this disables the error log in LoadAnimation() in case the animation wasn't found on disk
|
|
FLAGS_DISABLE_LOAD_ERROR_LOG = 1 << 3,
|
|
|
|
// if this flag is set, it means that the animation is being loaded right now via asynchronous operation
|
|
// and shouldn't be attempted to be played back or loaded
|
|
FLAGS_LOAD_PENDING = 1 << 4,
|
|
|
|
// this is the flag combination that should be applied only to default animations
|
|
FLAGS_DEFAULT_ANIMATION = FLAGS_DISABLE_DELAY_LOAD|FLAGS_DISABLE_LOAD_ERROR_LOG,
|
|
|
|
// combination of all possible flags
|
|
FLAGS_ALL_FLAGS = (1<<5) - 1,
|
|
|
|
// the flags by default
|
|
FLAGS_DEFAULT_FLAGS = 0
|
|
};
|
|
|
|
GlobalAnimation ()
|
|
{
|
|
// some standard values to fill in before the animation will be loaded
|
|
nRefCount = 0;
|
|
nFlags = FLAGS_DEFAULT_FLAGS;
|
|
fSecsPerTick = 0.000208f;
|
|
nLastAccessFrameId = g_nFrameID;
|
|
nTickCount = nStartCount = nApplyCount = 0;
|
|
nTicksPerFrame = 160;
|
|
// the defaults that are anyway immediately overridden
|
|
fScale = 0.01f;
|
|
rangeGlobal.end = 900; // this is in ticks, means 30 frames
|
|
}
|
|
|
|
IController*GetController(unsigned nControllerID)
|
|
{
|
|
ControllerArray::iterator it = std::lower_bound(arrCtrls.begin(), arrCtrls.end(), nControllerID, AnimCtrlSortPred());
|
|
if (it != arrCtrls.end() && (*it)->GetID() == nControllerID)
|
|
{
|
|
IController *c = *it;
|
|
#ifdef _DEBUG
|
|
// set this to true in the debugger to obtain the 0th frame p and q
|
|
bool bCheck = false;
|
|
if (bCheck)
|
|
{
|
|
CryQuat q; Vec3d p;
|
|
c->GetValue(0, q, p);
|
|
}
|
|
#endif
|
|
return c;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
bool IsLoaded()const {return !arrCtrls.empty();}
|
|
|
|
bool IsInfoLoaded()const {return (nFlags&FLAGS_INFO_LOADED) != 0;}
|
|
void OnInfoLoaded() {nFlags |= FLAGS_INFO_LOADED;}
|
|
bool IsAutoUnload()const {return (nFlags&FLAGS_DISABLE_AUTO_UNLOAD)== 0;}
|
|
|
|
void OnTick ()
|
|
{
|
|
++nTickCount;
|
|
nLastAccessFrameId = g_nFrameID;
|
|
}
|
|
void OnStart()
|
|
{
|
|
++nStartCount;
|
|
nLastAccessFrameId = g_nFrameID;
|
|
}
|
|
void OnApply()
|
|
{
|
|
++nApplyCount;
|
|
nLastAccessFrameId = g_nFrameID;
|
|
}
|
|
|
|
void AddRef()
|
|
{
|
|
++nRefCount;
|
|
}
|
|
|
|
void Release()
|
|
{
|
|
if (!--nRefCount)
|
|
{
|
|
#ifdef _DEBUG
|
|
for (ControllerArray::iterator it = arrCtrls.begin(); it!= arrCtrls.end(); ++it)
|
|
assert ((*it)->NumRefs()==1); // only this object references the controllers now
|
|
#endif
|
|
arrCtrls.clear(); // nobody uses the controllers; clean them up. This makes the animation effectively unloaded
|
|
}
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
// returns the maximum reference counter from all controllers. 1 means that nobody but this animation
|
|
// structure refers to them
|
|
int MaxControllerRefCount()
|
|
{
|
|
if (arrCtrls.empty())
|
|
return 0;
|
|
int nMax = arrCtrls[0]->NumRefs();
|
|
for (ControllerArray::iterator it = arrCtrls.begin()+1; it!= arrCtrls.end(); ++it)
|
|
if((*it)->NumRefs() > nMax)
|
|
nMax = (*it)->NumRefs();
|
|
return nMax;
|
|
}
|
|
#endif
|
|
size_t sizeofThis ()const;
|
|
|
|
|
|
|
|
// controllers comprising the animation; within the animation, they're sorted by ids
|
|
ControllerArray arrCtrls;
|
|
// timing data, retrieved from the timing_chunk_desc
|
|
int nTicksPerFrame;
|
|
float fSecsPerTick;
|
|
float fScale; // the parameter from the initial load animation, used for reloadin
|
|
|
|
MiniRangeEntity rangeGlobal;
|
|
|
|
// the file name of the animation
|
|
string strFileName;
|
|
|
|
// the number of times this animation has been accessed
|
|
unsigned nTickCount;
|
|
// the number of times this animation has been started
|
|
unsigned nStartCount;
|
|
// the number of times this animation has been applied to bones
|
|
unsigned nApplyCount;
|
|
// the last time the animation has been accessed
|
|
int nLastAccessFrameId;
|
|
// the number of referrers to this global animation record (doesn't matter if the controllers are currently loaded)
|
|
int nRefCount;
|
|
// the flags (see the enum in the top of the declaration)
|
|
unsigned nFlags;
|
|
};
|
|
|
|
#endif |