123
This commit is contained in:
189
CryAnimation/ControllerManager.h
Normal file
189
CryAnimation/ControllerManager.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Crytek Character Animation source code
|
||||
//
|
||||
// History:
|
||||
// Created by Sergiy Migdalskiy
|
||||
//
|
||||
// Notes:
|
||||
// CControllerManager class declaration extracted from File:CryModelState.h
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CRYTEK_CONTROLLER_MANAGER_HEADER_
|
||||
#define _CRYTEK_CONTROLLER_MANAGER_HEADER_
|
||||
|
||||
#include "Controller.h"
|
||||
#include "CryAnimationInfo.h"
|
||||
#include "FileMapping.h"
|
||||
#include "IStreamEngine.h"
|
||||
|
||||
class CryModelAnimationContainer;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class CControllerManager
|
||||
// Responsible for creation of multiple animations, subsequently bind to the character bones
|
||||
// There is one instance of this class per a game.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CControllerManager : public IStreamCallback
|
||||
{
|
||||
public:
|
||||
// array of animations, each animation having its name and id
|
||||
// Animation is an array of controllers. Animation id is an index in the array
|
||||
|
||||
typedef GlobalAnimation Animation;
|
||||
|
||||
struct AnimationIdPred
|
||||
{
|
||||
const std::vector<Animation>& m_arrAnims;
|
||||
AnimationIdPred(const std::vector<Animation>& arrAnims):
|
||||
m_arrAnims(arrAnims)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator () (int left, int right)const
|
||||
{
|
||||
return stricmp(m_arrAnims[left].strFileName.c_str(), m_arrAnims[right].strFileName.c_str()) < 0;
|
||||
}
|
||||
bool operator () (int left, const char* right)const
|
||||
{
|
||||
return stricmp(m_arrAnims[left].strFileName.c_str(), right)<0;
|
||||
}
|
||||
bool operator () (const char* left, int right)const
|
||||
{
|
||||
return stricmp(left, m_arrAnims[right].strFileName.c_str())<0;
|
||||
}
|
||||
};
|
||||
|
||||
// returns the structure describing the animation data, given the global anim id
|
||||
Animation& GetAnimation (int nAnimID);
|
||||
|
||||
CControllerManager();
|
||||
|
||||
// loads the animation with the specified name; if the animation is already loaded,
|
||||
// then just returns its id
|
||||
// The caller MUST TAKE CARE to bind the animation if it's already loaded before it has registered itself within this manager
|
||||
int StartLoadAnimation (const string& strFileName, float fScale, unsigned nFlags = Animation::FLAGS_DEFAULT_FLAGS);
|
||||
|
||||
// unreferences the controllers and makes the animation unloaded
|
||||
// before this operation, all bones must be unbound
|
||||
bool UnloadAnimation (int nGlobAnimId);
|
||||
|
||||
// loads existing animation record, returns false on error
|
||||
bool LoadAnimation(int nGlobalAnimId);
|
||||
|
||||
// loads the animation info, if not loaded yet
|
||||
bool LoadAnimationInfo(int nGlobalAnimId);
|
||||
|
||||
// updates the animation from the chunk of AnimInfo
|
||||
bool UpdateAnimation (int nGlobalAnimId, const struct CCFAnimInfo* pAnimInfo);
|
||||
|
||||
// notifies the controller manager that another client uses the given animation.
|
||||
// these calls must be balanced with AnimationRelease() calls
|
||||
void AnimationAddRef (int nGlobalAnimId, CryModelAnimationContainer* pClient);
|
||||
|
||||
|
||||
// notifies the controller manager that this client doesn't use the given animation any more.
|
||||
// these calls must be balanced with AnimationAddRef() calls
|
||||
void AnimationRelease (int nGlobalAnimId, CryModelAnimationContainer* pClient);
|
||||
|
||||
void OnStartAnimation (int nGlobalAnimId);
|
||||
void OnTickAnimation(int nGlobalAnimId);
|
||||
void OnApplyAnimation(int nGlobalAnimId);
|
||||
|
||||
// returns the total number of animations hold in memory (for statistics)
|
||||
unsigned NumAnimations();
|
||||
|
||||
// finds controller with the given nControllerID among controller in the animation
|
||||
// identified by nGlobalAnimID
|
||||
IController* GetController (int nGlobalAnimID, unsigned nControllerID);
|
||||
|
||||
~CControllerManager();
|
||||
|
||||
// logs controller usage statistics
|
||||
void LogUsageStats();
|
||||
|
||||
// puts the size of the whole subsystem into this sizer object, classified,
|
||||
// according to the flags set in the sizer
|
||||
void GetSize(class ICrySizer* pSizer);
|
||||
|
||||
// dumps the used animations
|
||||
void DumpAnims();
|
||||
|
||||
void Update();
|
||||
|
||||
void Register (CryModelAnimationContainer* pClient)
|
||||
{
|
||||
m_arrClients.insert (std::lower_bound(m_arrClients.begin(), m_arrClients.end(), pClient), pClient);
|
||||
}
|
||||
void Unregister (CryModelAnimationContainer* pClient)
|
||||
{
|
||||
std::vector<CryModelAnimationContainer*>::iterator it = std::lower_bound(m_arrClients.begin(), m_arrClients.end(), pClient);
|
||||
if(it != m_arrClients.end() && *it == pClient)
|
||||
m_arrClients.erase (it);
|
||||
else
|
||||
assert (0); // the unregistered client tries to unregister
|
||||
}
|
||||
|
||||
// finds the animation by name. Returns -1 if no animation was found
|
||||
// Returns the animation ID if it was found
|
||||
int FindAnimationByFile(const string& sAnimFileName);
|
||||
|
||||
protected:
|
||||
// notifies all clients that the animation or its info has been loaded
|
||||
void FireAnimationGlobalLoad (int nAnimId);
|
||||
|
||||
// immediately load the given animation from the already opened reader
|
||||
bool LoadAnimation(int nAnimId, class CChunkFileReader* pReader);
|
||||
|
||||
// these two are called back when an asynchronous IO operation has finished
|
||||
void StreamOnComplete (IReadStream* pStream, unsigned nError);
|
||||
|
||||
// this structure describes the pending animation load request: it exists as long as the animation
|
||||
// is being loaded (asynchronously)
|
||||
struct PendingAnimLoad:public _reference_target_t
|
||||
{
|
||||
public:
|
||||
PendingAnimLoad (int animId){nAnimId = animId;}
|
||||
PendingAnimLoad (){}
|
||||
// the data that's being loaded
|
||||
CFileMapping_AutoPtr pFile;
|
||||
// the animation for which the data is loaded
|
||||
int nAnimId;
|
||||
// the frame at which the animation load was started
|
||||
int nFrameId;
|
||||
// the stream that loads the data
|
||||
IReadStreamPtr pStream;
|
||||
};
|
||||
TYPEDEF_AUTOPTR(PendingAnimLoad);
|
||||
|
||||
// the set of pending animation load requests; they get deleted as soon as the IO operation is completed
|
||||
std::set<PendingAnimLoad_AutoPtr> m_setPendingAnimLoads;
|
||||
|
||||
// Loads the controller from the chunk, returns the result in the autopointer
|
||||
// It is important that the return type is autoptr: it lets the procedure gracefully destruct
|
||||
// half-constructed animation in case of an error.
|
||||
IController_AutoPtr LoadController(float fScale, const CONTROLLER_CHUNK_DESC_0826*pChunk, int nSize);
|
||||
|
||||
// array of animations
|
||||
// since the number of animations dynamically changes and STL vector has good balanced
|
||||
// reallocation properties, we use it here
|
||||
typedef std::vector<Animation> AnimationArray;
|
||||
AnimationArray m_arrAnims;
|
||||
|
||||
// index array for the animation indices sorted by file name
|
||||
std::vector<int>m_arrAnimByFile;
|
||||
|
||||
void selfValidate();
|
||||
|
||||
size_t m_nCachedSizeofThis;
|
||||
|
||||
// the sorted list of pointers to the clients that use the services of this manager
|
||||
std::vector<CryModelAnimationContainer*> m_arrClients;
|
||||
|
||||
// this scans through all animations cyclicly each frame and checks which ones should be unloaded
|
||||
// due to not being used
|
||||
unsigned m_nLastCheckedUnloadCandidate;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user