/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_AnimGroup.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_ANIMGROUP_H_ #define NW_GFX_ANIMGROUP_H_ #include #include #include #include namespace nw { namespace anim { class AnimBlendOp; } namespace gfx { class SceneNode; //--------------------------------------------------------------------------- //! @brief アニメーション対象を抽象化するクラスです。 //! //! アニメーション対象メンバへのポインタを保持します。 //! 対象メンバとはボーンのトランスフォーム、マテリアルのディフューズカラーといった単位です。 //! //! また、対象メンバのオリジナル値(インスタンス生成時の値)を保存しています。 //--------------------------------------------------------------------------- class AnimGroup : public GfxObject { public: //! @brief 評価前コールバック関数の定義です。 //! 対象オブジェクトの評価が必要なら true を返します。 typedef bool (*PreEvaluateCallback)(AnimGroup* animGroup, int targetObjIdx); //---------------------------------------- //! @name 作成 //@{ //! アニメーショングループを構築するクラスです。 class Builder { public: //! コンストラクタです。 Builder() : m_SceneNode(NULL), m_UseOriginalValue(false) {} //! アニメーショングループリソースを設定します。 Builder& ResAnimGroup(anim::ResAnimGroup resAnimGroup) { m_ResAnimGroup = resAnimGroup; return *this; } //! 対象となるシーンノードを設定します。 Builder& SetSceneNode(SceneNode* sceneNode) { m_SceneNode = sceneNode; return *this; } //! オリジナル値を使用するかどうかを設定します。 Builder& UseOriginalValue(bool use) { m_UseOriginalValue = use; return *this; } //! @brief 生成時に必要なメモリサイズを取得します。 //! //! メモリサイズは Builder の設定によって変化します。 //! すべての設定が終わった後にこの関数を呼び出してください。 //! //! @param[in] alignment 計算に用いるアライメントです。2 のべき乗である必要があります。 size_t GetMemorySize(size_t alignment = os::IAllocator::DEFAULT_ALIGNMENT) const { os::MemorySizeCalculator size(alignment); GetMemorySizeInternal(&size); return size.GetSizeWithPadding(alignment); } //! @details :private void GetMemorySizeInternal(os::MemorySizeCalculator* pSize) const { os::MemorySizeCalculator& size = *pSize; size += sizeof(AnimGroup); AnimGroup::GetMemorySizeForInitialize(pSize, m_ResAnimGroup, m_UseOriginalValue); } //! @brief アニメーショングループを生成します。 //! //! @param[in] allocator アロケータです。 //! //! @return 生成されたアニメーショングループです。 //! AnimGroup* Create(os::IAllocator* allocator) { void* buf = allocator->Alloc(sizeof(AnimGroup)); if (buf == NULL) { return NULL; } AnimGroup* animGroup = new(buf) AnimGroup(m_ResAnimGroup, m_SceneNode, allocator); Result result = animGroup->Initialize(m_UseOriginalValue); if (result.IsSuccess()) { return animGroup; } else { SafeDestroy(animGroup); return NULL; } } private: SceneNode* m_SceneNode; anim::ResAnimGroup m_ResAnimGroup; bool m_UseOriginalValue; }; //@} //---------------------------------------- //! @name 取得/設定 //@{ //! アニメーショングループリソースを取得します。 anim::ResAnimGroup GetResAnimGroup() const { return m_ResAnimGroup; } //! グラフィックスアニメーショングループリソースを取得します。 anim::ResGraphicsAnimGroup GetResGraphicsAnimGroup() const { return *reinterpret_cast(&m_ResAnimGroup); } //! アニメーショングループメンバリソースを取得します。 anim::ResAnimGroupMember GetResAnimGroupMember(int memberIdx) const { return m_ResAnimGroup.GetMemberInfoSet(memberIdx); } //! アニメーショングループメンバリソースを取得します。 anim::ResAnimGroupMember GetResAnimGroupMember(const char* key) const { return m_ResAnimGroup.GetMemberInfoSet(key); } //! アニメーショングループメンバリソースのインデックスを取得します。 int GetResAnimGroupMemberIndex(const char* key) const { return m_ResAnimGroup.GetMemberInfoSetIndex(key); } //! 名前を取得します。 const char* GetName() const { return m_ResAnimGroup.GetName(); } //! アニメーショングループメンバ数を取得します。 s32 GetMemberCount() const { return m_ResAnimGroup.GetMemberInfoSetCount(); } //! アニメーショングループ内のブレンドオペレーションを取得します。 const anim::AnimBlendOp* GetBlendOperationInGroup(int blendOpIdx) const { NW_MINMAXLT_ASSERT(blendOpIdx, 0, m_BlendOperations.Size()); return m_BlendOperations[blendOpIdx]; } //! アニメーショングループ内のブレンドオペレーションを設定します。 void SetBlendOperationInGroup(int blendOpIdx, anim::AnimBlendOp* blendOp) { NW_MINMAXLT_ASSERT(blendOpIdx, 0, m_BlendOperations.Size()); m_BlendOperations[blendOpIdx] = blendOp; } //! メンバに対するブレンドオペレーションを取得します。 const anim::AnimBlendOp* GetBlendOperation(int memberIdx) const { return GetBlendOperationInGroup( GetResAnimGroupMember(memberIdx).GetBlendOperationIndex()); } //! 対象オブジェクトが属するシーンノードを取得します。 SceneNode* GetSceneNode() const { return m_SceneNode; } //! 対象オブジェクトのインデックスを取得します。 int GetTargetObjectIndex(int memberIdx) const { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetObjectIndicies.Size()); return m_TargetObjectIndicies[memberIdx]; } //! 対象オブジェクトのインデックスを設定します。 void SetTargetObjectIndex(int memberIdx, const int targetObjIdx) { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetObjectIndicies.Size()); m_TargetObjectIndicies[memberIdx] = targetObjIdx; } //! 対象オブジェクトのポインタを取得します。 void* GetTargetObject(int memberIdx) const { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetObjects.Size()); return m_TargetObjects[memberIdx]; } //! 対象オブジェクトのポインタを設定します。 void SetTargetObject(int memberIdx, void* object) { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetObjects.Size()); m_TargetObjects[memberIdx] = object; } //! 対象メンバのポインタを取得します。 void* GetTargetPtr(int memberIdx) const { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetPtrs.Size()); return m_TargetPtrs[memberIdx]; } //! 対象メンバのポインタを設定します。 void SetTargetPtr(int memberIdx, void* target) { NW_MINMAXLT_ASSERT(memberIdx, 0, m_TargetPtrs.Size()); m_TargetPtrs[memberIdx] = target; } //! メンバのオリジナル値を持っているかどうかを取得します。 bool HasOriginalValue() const { return m_OriginalValues.Size() != 0; } //! メンバのオリジナル値を取得します。 const void* GetOriginalValue(int memberIdx) const { NW_MINMAXLT_ASSERT(memberIdx, 0, m_OriginalValues.Size()); return m_OriginalValues[memberIdx]; } //! メンバのオリジナル値を設定します。 void SetOriginalValue(int memberIdx, const void* value) { NW_MINMAXLT_ASSERT(memberIdx, 0, m_OriginalValues.Size()); m_OriginalValues[memberIdx] = value; } //! 評価前コールバック関数を取得します。 PreEvaluateCallback GetPreEvaluateCallback() const { return m_PreEvaluateCallback; } //! 評価前コールバック関数を設定します。 void SetPreEvaluateCallback(PreEvaluateCallback function) { m_PreEvaluateCallback = function; } //! フルベイクアニメーションを使用するかを取得します。 //! //! :private bool GetFullBakedAnimEnabled() const { return m_FullBakedAnimEnabled; } //! フルベイクアニメーションを使用するかを設定します。 //! //! :private void SetFullBakedAnimEnabled(bool enable) { m_FullBakedAnimEnabled = enable; } //! @brief すべてのメンバをオリジナル値にリセットします。 void Reset(); //@} protected: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 //! //! :private AnimGroup( anim::ResAnimGroup resAnimGroup, SceneNode* sceneNode, os::IAllocator* allocator); //! デストラクタです。 //! //! :private virtual ~AnimGroup() {} //@} //! Initialize() の実行に必要なメモリサイズを取得します。 //! //! :private static void GetMemorySizeForInitialize(os::MemorySizeCalculator* pSize, const anim::ResAnimGroup resAnimGroup, bool useOriginalValue); //! メンバを初期化します。 //! //! :private Result Initialize(bool useOriginalValue); private: anim::ResAnimGroup m_ResAnimGroup; //!< アニメーショングループのリソースです。 ut::MoveArray m_BlendOperations; //!< ブレンドオペレーションです。 SceneNode* m_SceneNode; //!< 対象オブジェクトが属するシーンノードです。 ut::MoveArray m_TargetObjectIndicies; //!< メンバごとの対象オブジェクトのインデックスです。 ut::MoveArray m_TargetObjects; //!< メンバごとの対象オブジェクトのポインタです。 ut::MoveArray m_TargetPtrs; //!< メンバごとの対象のポインタです。 ut::MoveArray m_OriginalValues; //!< メンバごとのオリジナル値です。 PreEvaluateCallback m_PreEvaluateCallback; //!< 評価前コールバック関数です。 bool m_FullBakedAnimEnabled; //!< フルベイクアニメを使用するかを指定します。 }; } // namespace gfx } // namespace nw #endif // NW_GFX_ANIMGROUP_H_