/**************************************************************************** Copyright (c) 2011-2013,WebJet Business Division,CYOU http://www.genesis-3d.com.cn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ****************************************************************************/ #pragma once #include "math/matrix44.h" #include "math/float3.h" #include "math/quaternion.h" //#include "AnimationState.h" #include "resource/skeletonres.h" #include "animation/AnimationLayer.h" #include "animation/ClipControl.h" //#include "animation/AnimationState.h" namespace Animations { struct CheckedNode { Util::String nodeName; ushort parentIndex; Math::float3 defPosition; Math::quaternion defRotation; Math::float3 defScale; }; struct DefaultToRootXInfo { Util::String skelName; Math::matrix44 toRootX; }; class Animation : public Core::RefCounted { __DeclareClass(Animation); public: typedef Util::Array< GPtr > AnimClips; typedef Util::Array< ClipControl*> ClipControls; typedef Util::Array< AnimationLayer* > AnimationLayers; enum QueueMode { CompleteOthers = 0, PlayNow = 2 }; Animation(); ~Animation(); void AddAnimClip(const GPtr& animClip); void RemoveAnimClip(const Resources::ResourceId& clipName); AnimClips& GetAnimClips(); int GetAnimClipCount() const; void PlayAnim(const Resources::ResourceId& name, int playMode = ClipControl::StopSameAnimLayer); void Stop(); void Stop(const Resources::ResourceId& name, float time); bool Contain(const Resources::ResourceId& name); bool IsPlaying(); bool IsPaused(); bool IsPlaying(const Resources::ResourceId& name); bool IsPaused(const Resources::ResourceId& name); void CrossFading(const Resources::ResourceId& name, int playMode, float fadingTime = 0.3); void Blending(const Resources::ResourceId& name, float targetWeight, float time); void SetWrapMode(const Resources::ResourceId& name, int wrapMode); int GetWrapMode(const Resources::ResourceId& name); void SetLayer(const Resources::ResourceId& name, int layer); int GetLayer(const Resources::ResourceId& name); void SetPlayRate(const Resources::ResourceId& name, float rate); void SetNormalizedTime(const Resources::ResourceId& name, float time); void SetWeight(const Resources::ResourceId& name, float weight); float GetWeight(const Resources::ResourceId& name); void SetEnable(const Resources::ResourceId& name, bool enable); bool IsEnable(const Resources::ResourceId& name); void SetTime(const Resources::ResourceId& name, float time); float GetWrapTime(const Resources::ResourceId& name); ClipControl* GetClipControl(const Resources::ResourceId& name) const; Util::Array& GetToParentTrans(); const Util::Array& GetNodeParentIndexVec() const; const Util::Array& GetNodeNameVec() const; bool UpdateAnimation(float time); void AddAffectedNodes(const Resources::ResourceId& stateName, const Util::String& nodeName, bool recursive); void RemoveAffectedNodes(const Resources::ResourceId& stateName, const Util::String& nodeName, bool recursive); const bool IsUpdate() const; void Pause(const Resources::ResourceId& name); void Resume(const Resources::ResourceId& name); bool IsAnimNodeAffected(const Resources::ResourceId& stateName, const Util::String& nodeName); void ClientAdd(); void ClientSub(); int GetClientCount() const; bool BuildDefaultToRootTrans(); const Util::Array& GetDefaultToRootX() const; //Set skelnode tree, build CheckedNodeˇ˘NodeName and NodeParentIndex array void SetSkelTree(const Util::Array< GPtr >& skelTree); void SetUpdateTime(float updateTime); float m_LocalTimer; float m_UpdateTime; private: enum NoName { DefaultLayer = 0, }; void sample(); void buildControl(AnimationClip* clip, AnimationLayer* layer); AnimationLayer* buildLayer(int index); AnimationLayer* findLayer(int index) const; AnimationClip* findClip(const Resources::ResourceId& name) const; ClipControl* findControl(const Resources::ResourceId& name) const; int findClipIndex(const Resources::ResourceId& name) const; void buildLayerWeight(const ClipControls& activeControls, int nodeCount); template void blendControl(const ClipControl* cc, int nodeCount); void blendFrameDataFromFree(int bone_index, float take_from_free, const Math::float3& pos, const Math::quaternion& rotate, const Math::float3& scale); void blendFrameData(int bone_index, float take_force, const Math::float3& pos, const Math::quaternion& rotate, const Math::float3& scale); void clearClipControls(); void clearAnimClips(); void clearLayers(); AnimClips m_AnimClips; ClipControls m_ClipControls; AnimationLayers m_AnimationLayers; Util::Array m_NodeParentIndexVec; Util::Array m_NodeNameVec; Util::Array< CheckedNode > m_CheckedNodeList; Util::Array m_DefaultToRootX; //--------------------------------- temp data. --------------------------------- Util::Array m_ToParentTrans; Util::Array m_SampledTrans; Util::Array m_SampledScale; Util::Array m_SampledRotation; Util::Array m_FreeWeights; Util::Array m_LayerWeights; //------------------------------------------------------------------------------- GPtr m_CurrentAnimClip; int m_ClientCount;//Use for record this animation's user count bool m_bUpdateResult; bool m_bDirty; }; inline Animation::AnimClips& Animation::GetAnimClips() { return m_AnimClips; } inline Util::Array& Animation::GetToParentTrans() { return m_ToParentTrans; } inline ClipControl* Animation::GetClipControl(const Resources::ResourceId& name) const { return findControl(name); } inline const Util::Array& Animation::GetNodeParentIndexVec() const { return m_NodeParentIndexVec; } inline const Util::Array& Animation::GetNodeNameVec() const { return m_NodeNameVec; } inline const bool Animation::IsUpdate() const { return m_bUpdateResult; } inline void Animation::ClientAdd() { ++m_ClientCount; } inline void Animation::ClientSub() { --m_ClientCount; n_assert(-1 < m_ClientCount); } inline int Animation::GetClientCount() const { return m_ClientCount; } inline const Util::Array& Animation::GetDefaultToRootX() const { return m_DefaultToRootX; } }