#pragma once #include "GameObject.h" #include "ShadowGeometry.h" #include "Utils/ClientUtils.h" #include "Map/TaskManager.h" #include "AnimModel.h" #define INVALID_ANIMID NiActorManager::INVALID_SEQUENCE_ID typedef NiActorManager::SequenceID AnimationID; // //enum AnimID //{ // Idle = 0, // Stand, // Walk, // Run, // AttackId_Begin, // Attack01, // Attack02, // Attack03, // Attack04, // Attack05, // Attack06, // AttackId_End, // Death, // // AnimMax //}; extern NiFixedString ANIMSEQ_IDLE; extern NiFixedString ANIMSEQ_WALK; extern NiFixedString ANIMSEQ_RUN; extern NiFixedString ANIMSEQ_DEATH; enum { ANIM_BLEND_LAYER_MAX = 4, ANIM_EVENT_MAX = 8, }; enum EAnimEventID { ANIM_EVENT_UNKNOWN = 0, ANIM_EVENT_ATTACK_BEGIN, ANIM_EVENT_ATTACK_HIT, ANIM_EVENT_ATTACK_END, }; struct AnimEvent { EAnimEventID EventID; DWORD Time; }; // 动画事件 struct AnimationEventSet { //INT ActivedSeq[ANIM_BLEND_LAYER_MAX]; //INT DeactivedSeq[ANIM_BLEND_LAYER_MAX]; AnimationEventSet() { NumEvnets = 0; Mask = 0; CurSeqEnded = FALSE; } INT Mask; INT NumEvnets; BOOL CurSeqEnded; AnimEvent Events[ANIM_EVENT_MAX]; }; struct AnimationParam { NiFixedString kName; float fFreq; bool bLoop; bool bForceStart; int iPriority; }; // 封装动作 class CAnimObject : public CGameObject, public NiActorManager::CallbackObject { public: enum { ANIM_LAYER_0 = 0, ANIM_LAYER_1, ANIM_LAYER_2, ANIM_LAYER_3, MAX_ANIM_LAYER = 4, }; CAnimObject(void); virtual ~CAnimObject(void); static void StaticInitAnimNames(); static void StaticDeInitAnimNames(); // 动作 AnimationID GetAnimationIDByName(const NiFixedString& AnimName) const; // TextKey virtual void RegistTextKey(); // void RemapSequenceID(); // For activating secondary (layered) animations NiControllerSequence* CAnimObject::ActivateAnimation(const char* AnimName, int iPriority = 1, int ip2 = 0, float fEaseInTime = 0.25f , AnimationID eSync = NiKFMTool::SYNC_SEQUENCE_ID_NONE, bool bLoop = false, bool bEndSeq = true, bool bDeactivateAll = false); NiControllerSequence* ActivateAnimation(AnimationID eCode, int iPriority = 1, int ip2 = 0, float fEaseInTime = 0.25f, AnimationID eSync = NiKFMTool::SYNC_SEQUENCE_ID_NONE, bool bLoop = false, bool bEndSeq = true, bool bDeactivateAll = false); void DeactivateAllLayerAnims(); bool DeactivateAnimation(AnimationID eCode, float fEaseOutTime = 0.0f, bool bForce = false); void DeactivateSecAnimation(float fEaseOutTime = 0.0f); virtual BOOL CreateActor(const char* KfmName, bool bAsync); virtual void OnActorLoaded(NiActorManager* pkActorManager); virtual BOOL IsAnimObject() { return TRUE; } bool IsActorLoaded() const { return m_spActorManager != NULL; } bool IsActorLoading() const { return m_bActorLoading; } virtual void ProcessAnimation(DWORD dwDeltaTime); virtual void Update(float dt); virtual bool Draw(CCullingProcess* pkCuller); void ReflashShadowCaster(); CShadowGeometry* GetShadow() { return m_spShadowGeometry; } void ChangeShadowType(CShadowGeometry::ShadowType eShadowType); void CreateShadow(); // new animation method float UpdateCurAnimation(); virtual NiControllerSequence* SetCurAnimation(AnimationID Anim, float Frequence = 1.0f, BOOL bLoop = FALSE, BOOL bForceStart = FALSE, int iPriority = -1); virtual NiControllerSequence* SetCurAnimation(const char* AnimName, float Frequence = 1.0f, BOOL bLoop = FALSE, BOOL bForceStart = FALSE, int iPriority = -1); void RecursiveSetBones(NiNode* pkNode, int i); NiActorManager* GetActorManager() { return m_spActorManager; } void ResetCurAnimation() { m_CurAnimation = NULL; } NiBoneLODController* FindBoneLODController(NiAVObject* pkObject); NiBoneLODController* GetLODController() { return m_pkLODCtrl; } float GetNextEndTime() const { return m_fNextEndTime; } float GetNextEndTime2() const { return m_fNextEndTime2; } bool IsCurAnimEndInTime( float fTime ) { if (!m_bNotUpdateTime && m_spActorManager && m_spActorManager->GetTargetAnimation() != NiActorManager::INVALID_SEQUENCE_ID) { m_fNextEndTime = m_spActorManager->GetNextEventTime(NiActorManager::TEXT_KEY_EVENT, m_spActorManager->GetTargetAnimation(), "end"); return bool(fTime >= m_fNextEndTime); } m_bNotUpdateTime = false; return false; } bool IsCurSecAnimEndInTime( float fTimeNow ) { return bool(fTimeNow >= m_fNextEndTime2); } const NiTObjectArray& GetTextKeys() { return m_textKeys; } float GetInitBoundRadius() const { return m_fInitBoundRadius; } unsigned int GetWaitSeqNum() const { return m_uiWaitSeqNum; } void OnEquipmentChanged(); void SetClientObject(bool bClientObject) { m_bClientObject = bClientObject; } bool IsClientObject() const { return m_bClientObject; } unsigned int GetAvatarReversion() const { return m_uiAvatarReversion; } void AddAvatarModel(CAvatarModel* pkAvatarModel) { m_kAvatarModels.Add(pkAvatarModel); } virtual bool HasAnimBound(); virtual bool GetPickBound(NiBound& kBound); virtual bool IsPick(NiPick& kPicker,const NiPoint3& kOrig,const NiPoint3& kDir); protected: // CallbackObject virtual void AnimActivated(NiActorManager* pkManager, NiActorManager::SequenceID eSequenceID, float fCurrentTime, float fEventTime); virtual void AnimDeactivated(NiActorManager* pkManager, NiActorManager::SequenceID eSequenceID, float fCurrentTime, float fEventTime); virtual void TextKeyEvent(NiActorManager* pkManager, NiActorManager::SequenceID eSequenceID, const NiFixedString& kTextKey, const NiTextKeyMatch* pkMatchObject, float fCurrentTime, float fEventTime); virtual void EndOfSequence(NiActorManager* pkManager, NiActorManager::SequenceID eSequenceID, float fCurrentTime, float fEventTime); void CollectBoundBox(NiAVObject* pNode); void CaculateBoundBox(); NiActorManagerPtr m_spActorManager; NiControllerSequence* m_CurAnimation; // 当前独占动画(No Blend layer). AnimationParam m_kCurAnimationParam; NiTPrimitiveArray m_kBoundBoxList; NiTPrimitiveArray m_kAvatarModels; //因为Actor 没有装载完,推迟的Avatar bool m_bClientObject; //是否是纯客户端自己创建的对象 unsigned int m_uiAvatarReversion; //每次Avatar有变化就加1 bool m_bActorLoading; //为True时表示 ActorManager已经开始装载, 但是没有装载完 AnimationID m_uiCurrAnimID; AnimationID m_uiSecAnim; float m_fNextEndTime; float m_fNextEndTime2; bool m_bNotUpdateTime; typedef std::map SequenceMap; SequenceMap m_SequenceMap; NiTPrimitiveSet m_kLayerAnimations; CShadowGeometryPtr m_spShadowGeometry; CShadowGeometry::ShadowType m_eShadowType; NiTObjectArray m_textKeys; NiBoneLODController* m_pkLODCtrl; float m_fInitBoundRadius; unsigned int m_uiWaitSeqNum; static float ms_fLODDist[3]; };