// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2008 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net /* ==================================================================== * ÆÄ ÀÏ : ActorManagerForPartition.h * ¸ñ Àû : °ÔÀӺ긮¿À ActorManagerÀÇ WrappingÀ̸鼭, ij¸¯ÅÍ ºÐÇÒ °ü¸® * ¸¦ Ãß°¡Çϱâ À§Çؼ­ »ó¼ÓÀ» ÀÌ¿ëÇÏÁö ¾ÊÀº º°µµÀÇ Å¬·¡½ºÀÌ´Ù. * ÀÛ ¼º ÀÚ : À̹ý¼® * ÀÛ ¼º ÀÏ : 2006.01.19 * ÁÖÀÇ»çÇ× : ¿£Áø¿¡ Æ÷ÇԵǾîÁø cActorManagerForPartition°¡ »ó¼ÓÀ» Áö¿øÇÏÁö ¾ÊÀº »óȲ * ÁÁÀº ÀÇ°ß °³½Ã ¹Ù¶ø´Ï´Ù!! * °ÔÀӺ긮¿À ±âº»Äڵ忡¼­ °¡Á®¿Â ºÎºÐÀº ±ÔÄ¢À» Àû¿ëÇÏÁö ¾Ê¾Ò´Ù. * Root NodeÀÇ Update¸¦ ÃÖ¼ÒÈ­ ÇÏ·Á°í ³ë·ÂÇÏÀÚ!! * =================================================================== */ #pragma once class cModelInstance; class NiPoseBinding; class NiSkinningLODController; NiSmartPointer(NiTextKeyMatch); class NIANIMATION_ENTRY cActorManagerForPartition : public NiRefObject, public NiSequenceData::ActivationCallback { public: typedef unsigned int SequenceID; // Deprecated typedef. typedef SequenceID EventCode; class NIANIMATION_ENTRY CallbackObject { public: // Virtual destructor defined in case derived classes need virtual // destruction. virtual ~CallbackObject() {}; virtual void AnimActivated(cActorManagerForPartition* pkManager, SequenceID eSequenceID, float fCurrentTime, float fEventTime) = 0; virtual void AnimDeactivated(cActorManagerForPartition* pkManager, SequenceID eSequenceID, float fCurrentTime, float fEventTime) = 0; virtual void AnimCompleted(cActorManagerForPartition* pkManager, SequenceID eSequenceID, float fCurrentTime, float fEventTime) = 0; virtual void TextKeyEvent(cActorManagerForPartition* pkManager, SequenceID eSequenceID, const NiFixedString& kTextKey, const NiTextKeyMatch* pkMatchObject, float fCurrentTime, float fEventTime) = 0; virtual void EndOfSequence(cActorManagerForPartition* pkManager, SequenceID eSequenceID, float fCurrentTime, float fEventTime) = 0; }; enum EventType { ANIM_ACTIVATED, ANIM_DEACTIVATED, ANIM_COMPLETED, TEXT_KEY_EVENT, END_OF_SEQUENCE }; enum TransitionState { NO_TRANSITION, BLENDING, MORPHING, CROSSFADING }; // Static constants. static const SequenceID ANY_SEQUENCE_ID; static const SequenceID INVALID_SEQUENCE_ID; static const float INVALID_TIME; static const float SEQUENCE_DATA_FREQUENCY; // Deprecated static constants. static const SequenceID ANY_EVENT_CODE; static const SequenceID INVALID_EVENT_CODE; // Static creation functions. //static cActorManagerForPartition* Create(const char* pcKFMFilename, // bool bCumulativeAnimations = false, bool bLoadFilesFromDisk = true, // NiStream* pkStream = NULL, NiPoseBinding* pkPoseBinding = NULL); //static cActorManagerForPartition* Create(NiKFMTool* pkKFMTool, // const char* pcKFMFilePath, bool bCumulativeAnimations = false, // bool bLoadFilesFromDisk = true, NiStream* pkStream = NULL, // NiPoseBinding* pkPoseBinding = NULL); // Destructor. ~cActorManagerForPartition(); // Cloning function. Creates a clone of the cActorManagerForPartition and all of // its contents. // cActorManagerForPartition* Clone(NiCloningProcess* pkCloningProcess = NULL); // Reloads the NIF file using the info in the NiKFMTool class. // If bLoadNIFFile is false, the NIF root will be loaded directly from // pkStream without loading a NIF file. pkStream cannot be NULL if // bLoadNIFFile is false. // bool ReloadNIFFile(NiStream* pkStream = NULL, bool bLoadNIFFile = true, // NiPoseBinding* pkPoseBinding = NULL); // Changes the NIF root and actor root that are being used for the // cActorManagerForPartition. This function does the same thing as ReloadNIFFile but // does not require the root objects to reside in an NiStream object or // to be loaded from disk. // bool ChangeNIFRoot(NiAVObject* pkNIFRoot, // NiPoseBinding* pkPoseBinding = NULL); // Loads the specified sequence data using the info in the // NiKFMTool class. If bLoadKFFile is false, the sequence data // will be loaded directly from pkStream without loading a KF file. // pkStream cannot be NULL if bLoadKFFile is false. // bool LoadSequenceData(SequenceID eSequenceID, bool bLoadKFFile = true, // NiStream* pkStream = NULL); // Loads all the sequence datas in the NiKFMTool class. // If pkStream is NULL this function creates and deletes its own // stream, otherwise it uses the given stream. // bool LoadAllSequenceData(NiStream* pkStream = NULL); // Changes the NiSequenceData object that is used for the specified // SequenceID. This function does the same thing as LoadSequenceData // but does not require the NiSequenceData object to reside in // an NiStream object or to be loaded from disk. bool ChangeSequenceData(SequenceID eSequenceID, NiSequenceData* pkSeqData); // Unloads the specified sequence data from the actor manager, removing // it from the NiControllerManager in the process. If there is no other // smart pointer referencing this sequence data, it will be deleted. void UnloadSequenceData(SequenceID eSequenceID); // Update function. Must be called with the current time periodically to // update the state machine. void Update(float fTime); // Functions for setting/getting the next target animation. SequenceID GetTargetAnimation() const; inline NiSequenceData* SetTargetAnimation(SequenceID eSequenceID); // inline bool SetTargetAnimation(SequenceID eSequenceID); inline void Reset(); /// LBS NiSequenceData* UpdateTargetAnimation(SequenceID eSequenceID); // Functions for getting the current state of the actor manager. SequenceID GetCurAnimation() const; TransitionState GetTransitionState() const; SequenceID GetNextAnimation() const; // Functions for setting/getting the callback object. inline void SetCallbackObject(CallbackObject* pkCallbackObject); CallbackObject* GetCallbackObject() const; // Gets the root of the NIF file that was loaded. // inline NiAVObject* GetNIFRoot() const; // Gets the actor root (the target of the NiControllerManager). // inline NiAVObject* GetActorRoot() const; // Accessor functions. inline NiKFMTool* GetKFMTool() const; inline NiControllerManager* GetControllerManager() const; inline NiSkinningLODController* GetSkinningLODController() const; inline NiSequenceData* GetSequenceData(SequenceID eSequenceID) const; // Returns the first active sequence assigned to eSequenceID. NiControllerSequence* GetActiveSequence(SequenceID eSequenceID, bool bCheckExtraSequences, bool bCheckStateSequences) const; // Returns the ID of the specified sequence. SequenceID GetSequenceID(NiControllerSequence* pkSequence, bool bCheckExtraSequences, bool bCheckStateSequences) const; // Gets the accumulation root of the actor, if there is one. inline NiAVObject* GetAccumRoot() const; // Finds the SequenceID for the first found sequence data with a given // name. Returns INVALID_SEQUENCE_ID if the name is not found. // pcName must be non-NULL. SequenceID FindSequenceID(const char* pcName) const; // Functions for registering and unregistering callback events to occur // within some advance notification time. bool RegisterCallback(EventType eEventType, SequenceID eSequenceID, const NiFixedString& kTextKey); void UnregisterCallback(EventType eEventType, SequenceID eSequenceID, const NiFixedString& kTextKey); bool RegisterCallback(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject = NULL ); void UnregisterCallback(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject = NULL ); inline void ClearAllRegisteredCallbacks(); // Gets the time of the next event. If the next time cannot be predicted, // INVALID_TIME is returned. inline float GetNextEventTime(EventType eEventType, SequenceID eSequenceID, const NiFixedString& kTextKey); inline float GetNextEventTime(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject = NULL); // Activate a sequence separately from the internal state machine. This // is useful for layering animations on top of a base animation that is // controlled by the state machine. The newly activated sequence is // returned. Callbacks are available for these animations. NiControllerSequence* ActivateSequence(SequenceID eSequenceID, int iPriority = 0, float fWeight = 1.0f, float fEaseInTime = 0.0f, SequenceID eTimeSyncSeqID = NiKFMTool::SYNC_SEQUENCE_ID_NONE, float fFrequency = SEQUENCE_DATA_FREQUENCY, float fStartFrame = 0.0f); bool DeactivateSequence(SequenceID eSequenceID, float fEaseOutTime = 0.0f); // Refreshes the cActorManagerForPartition's internal pointer to its // NiControllerManager. This function is useful if you have // programmatically changed the NiControllerManager that the actor // manager is using and need the cActorManagerForPartition to reflect that change. inline void RefreshControllerManager(); // Causes the timeline of callback events to be rebuilt during the next // update. inline void RebuildTimeline(); // *** begin Emergent internal use only *** // Override for NiSequenceData::ActivationCallback virtual void ActivationChanged(NiControllerSequence* pkSequence, NiAnimState eState); NiKFMTool::KFM_RC ChangeSequenceID(SequenceID eOldID, SequenceID eNewID); class ChainCompletionInfo : public NiRefObject { public: ChainCompletionInfo(); ~ChainCompletionInfo(); inline void SetName(const NiFixedString& kName); inline void SetNextName(const NiFixedString& kNextName); float m_fSeqStart; float m_fTransStart; float m_fTransEnd; float m_fInSeqBeginFrame; NiFixedString m_kName; NiFixedString m_kNextName; NiKFMTool::Transition* m_pkTransition; unsigned int m_uiSrcID; unsigned int m_uiDesID; }; typedef NiPointer ChainCompletionInfoPtr; typedef NiTObjectSet ChainCompletionInfoPtrSet; class CompletionInfo : public NiRefObject { public: float m_fFrameInDestWhenTransitionCompletes; float m_fTimeToCompleteTransition; float m_fFrameTransitionOccursInSrc; float m_fTimeForChainToComplete; NiKFMTool::Transition::BlendPair* m_pkBlendPair; ChainCompletionInfoPtrSet m_kChainCompletionInfoSet; }; typedef NiPointer CompletionInfoPtr; bool FindTimeForAnimationToCompleteTransition( unsigned int uiTransSrcID, unsigned int uiTransDesID, NiKFMTool::Transition* pkTransition, float fBeginSQTime, float fDesiredTransitionSQTime, CompletionInfo* pkInfoOut); protected: ChainCompletionInfo* FillChainComplete( unsigned int uiSrcID, unsigned int uiDesID, float fDuration, float& fSrcBeginFrame, float& fTotalTime); // *** end Emergent internal use only *** ////////////////////////////////////////////////////////////////////////// // Ãß°¡ ÄÚµå LBS /// ÃʱâÈ­ bool Initialize( NiNode* pModelRoot, cModelInstance* pModel ); public: /// °´Ã¼ »ý¼º½Ã Ãß°¡ ÇÔ¼ö void AddPartsObject( unsigned int partIdx, const char* partName ); /// Gets the root of the NIF file that was loaded. unsigned int GetPartsCount(); NiAVObject* GetParts( unsigned int partIdx ) const; /// Gets the actor root (the target of the NiControllerManager). NiAVObject* GetActorRoot() const; NiNode* GetNifRoot() const; /// Static creation functions. /// ¾Ö´Ï¸ÞÀÌ¼Ç Á¤º¸, NIFÆÄÀÏ Á¤º¸ »ý¼º static cActorManagerForPartition* Create( cModelInstance* pModel ); /// ÆÄÆ®¸¦ ±³Ã¼ÇÑ´Ù. (±âÁ¸ °´Ã¼µµ DetachµÈ´Ù.) void ChangePartsObject( unsigned int partIdx, NiAVObject* pObj ); /// ¹è¿­À» ºñ¿î´Ù. void RemoveAllPartsArray(); ////////////////////////////////////////////////////////////////////////// protected: class CallbackData : public NiRefObject { public: CallbackData(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch * pkMatchObject = NULL); ~CallbackData(); EventType m_eEventType; SequenceID m_eSequenceID; NiTextKeyMatchPtr GetMatchObject( ) const; inline void SetMatchObject( NiTextKeyMatch * pkMatchObject ); protected: NiTextKeyMatchPtr m_spMatchObject; }; typedef NiPointer CallbackDataPtr; public: class TimelineData : public NiMemObject { public: TimelineData(){}; ~TimelineData(); inline void SetValues(float fEventTime, EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject, const NiFixedString& kTextKeyMatched); float m_fEventTime; EventType m_eEventType; SequenceID m_eSequenceID; NiTextKeyMatchPtr m_spMatchObject; NiFixedString m_kTextKeyMatched; }; protected: cActorManagerForPartition(NiKFMTool* pkKFMTool, bool bCumulativeAnimations); // bool Initialize(NiStream& kStream, NiPoseBinding* pkPoseBinding); // bool LoadNIFFile(NiStream& kStream, bool bLoadNIFFile, // NiPoseBinding* pkPoseBinding); bool AddSequenceData(SequenceID eSequenceID, NiStream& kStream, bool bLoadKFFile); float GetNextAnimActivatedTime(SequenceID eSequenceID); float GetNextAnimDeactivatedTime(SequenceID eSequenceID); float GetNextTextKeyEventTime(SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject); float GetNextTextKeyEventTime(SequenceID eSequenceID, const NiFixedString& kTextKey); inline float GetNextEndOfSequenceTime(SequenceID eSequenceID); void BuildTimeline(); void AddTimelineDataObject(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject); void RemoveTimelineDataObjects(EventType eEventType, SequenceID eSequenceID, NiTextKeyMatch* pkMatchObject); void ProcessCallbacks(); void RaiseAnimActivatedEvents(SequenceID eEventSeqID); void RaiseAnimDeactivatedEvents(SequenceID eEventSeqID); void RaiseAnimCompletedEvents(SequenceID eEventSeqID); NiKFMTool::Transition::BlendPair* GetNextBlendPair( unsigned int uiTransSrcID, unsigned int uiTransDesID, NiKFMTool::Transition* pkTransition, float fFrameTime, float& fActualUnboundedFrame); NiControllerSequence* GetExtraSequence(SequenceID eSequenceID) const; void RemoveInactiveExtraSequences(); ////////////////////////////////////////////////////////////////////////// // Ãß°¡ º¯¼ö LBS (ºÐÇÒ Á¤º¸µé) /// ºÐÇÒ °´Ã¼ ÂüÁ¶ Á¤º¸¸¦ °®´Â´Ù. NiTPrimitiveArray mArrayParts; /// Actor Main Node NiNodePtr m_spModelRoot; ////////////////////////////////////////////////////////////////////////// NiKFMTool* m_spKFMTool; NiControllerManagerPtr m_spManager; CallbackObject* m_pkCallbackObject; SequenceID m_eTargetID; float m_fTime; float m_fTimelineRefreshTime; bool m_bBuildTimeline; bool m_bStartTransition; TransitionState m_eTransitionState; float m_fTransStartTime; float m_fTransEndTime; float m_fTransStartFrameTime; const char* m_pcTargetKey; SequenceID m_eCurID; NiControllerSequencePtr m_spCurSequence; SequenceID m_eNextID; NiSequenceDataPtr m_spNextSeqData; NiControllerSequencePtr m_spNextSequence; float m_fNextChainTime; NiTPointerList m_kChainIDs; NiTPointerList m_kChainDurations; bool m_bChainActive; bool m_bCumulativeAnimationsRequested; NiTPointerMap m_kSeqDataMap; NiTObjectArray m_kCallbacks; NiTObjectList m_kTimeline; // Allow just one active extra sequence per ID. NiTPointerMap m_kExtraSequenceMap; }; NiSmartPointer(cActorManagerForPartition); #include "ActorManagerForPartition.inl"