1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_AnimBlender.h
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: 31311 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_GFX_ANIMBLENDER_H_
19 #define NW_GFX_ANIMBLENDER_H_
20 
21 #include <nw/gfx/gfx_AnimObject.h>
22 #include <nw/ut/ut_RuntimeTypeInfo.h>
23 #include <nw/ut/ut_MoveArray.h>
24 
25 namespace nw {
26 namespace gfx {
27 
28 //---------------------------------------------------------------------------
29 //! @brief 汎用アニメーションブレンドの基底クラスです。
30 //! 抽象クラスですのでインスタンス化して使用することはできません。
31 //!
32 //! AnimBlender は複数の AnimEvaluator のアニメーション評価結果をブレンドします。
33 //! AnimBlender で他の AnimBlender のアニメーション評価結果をブレンドすることも可能です。
34 //---------------------------------------------------------------------------
35 class AnimBlender : public AnimObject
36 {
37 public:
38     NW_UT_RUNTIME_TYPEINFO;
39 
40     //! アニメーションオブジェクトの MoveArray の定義です。
41     //!
42     //! :private
43     typedef ut::MoveArray<AnimObject*> AnimObjectArray;
44 
45     //----------------------------------------
46     //! @name コンストラクタ/デストラクタ
47     //@{
48 
49     //! コンストラクタです。
AnimBlender(os::IAllocator * allocator)50     AnimBlender(
51         os::IAllocator* allocator)
52     : AnimObject(allocator, ANIMTYPE_BLENDER)
53     {
54     }
55 
56     //! デストラクタです。
~AnimBlender()57     virtual ~AnimBlender() {}
58 
59     //@}
60 
61     //----------------------------------------
62     //! @name 基本操作
63     //@{
64 
65     //! @brief アニメーションを関連付けます。
66     //!
67     //! Bind よりも詳細なバインド結果を得ることができます。
68     //!
69     //! @param[in] animGroup アニメーショングループです。
70     //!
71     //! @return バインドの結果を返します。
72     //!
73     //! @sa Bind
74     //! @sa TryBindResult
TryBind(AnimGroup * animGroup)75     virtual Result TryBind(AnimGroup* animGroup)
76     {
77         NW_NULL_ASSERT(animGroup);
78         NW_ASSERT(m_AnimGroup == NULL);
79         m_AnimGroup = animGroup;
80         return Result(BIND_RESULT_OK);
81     }
82 
83     //! アニメーションの関連付けを解除します。
Release()84     virtual void Release()
85     {
86         m_AnimGroup = NULL;
87     }
88 
89     //! フレームを更新します。
UpdateFrame()90     virtual void UpdateFrame()
91     {
92         for (int animObjIdx = 0; animObjIdx < m_AnimObjects.Size(); ++animObjIdx)
93         {
94             if (m_AnimObjects[animObjIdx] != NULL)
95             {
96                 m_AnimObjects[animObjIdx]->UpdateFrame();
97             }
98         }
99     }
100 
101     //@}
102 
103     //----------------------------------------
104     //! @name 取得/設定
105     //@{
106 
107     //! @brief メンバに関連付けられたアニメーションが存在するかどうかを取得します。
108     //!
109     //! @param[in] memberIdx メンバインデックスです。
110     //!
111     //! @return アニメーションが存在すれば true を返します。
112     //!
HasMemberAnim(int memberIdx)113     virtual bool HasMemberAnim(int memberIdx) const
114     {
115         for (int animObjIdx = 0; animObjIdx < m_AnimObjects.Size(); ++animObjIdx)
116         {
117             if (m_AnimObjects[animObjIdx] != NULL &&
118                 m_AnimObjects[animObjIdx]->HasMemberAnim(memberIdx))
119             {
120                 return true;
121             }
122         }
123         return false;
124     }
125 
126     //@}
127 
128     //----------------------------------------
129     //! @name アニメーションオブジェクト
130     //@{
131 
132     //! @brief アニメーションオブジェクトを追加します。
133     //!
134     //! @param[in] animObj 追加するアニメーションオブジェクトです。
135     //! NULL を指定しておいて、後で ReplaceAnimObject() で置き換えることも可能です。
136     //!
AddAnimObject(AnimObject * animObj)137     void AddAnimObject(AnimObject* animObj)
138     {
139         NW_ASSERT(m_AnimObjects.Size() < m_AnimObjects.Capacity());
140         m_AnimObjects.PushBack(animObj);
141     }
142 
143     //! @brief アニメーションオブジェクトを取得します。
144     //!
145     //! @param[in] animObjIdx アニメーションオブジェクトのインデックスです。
146     //!
147     //! @return アニメーションオブジェクトです。
148     //!
GetAnimObject(int animObjIdx)149     const AnimObject* GetAnimObject(int animObjIdx) const
150     {
151         NW_MINMAXLT_ASSERT(animObjIdx, 0, m_AnimObjects.Size());
152         return m_AnimObjects[animObjIdx];
153     }
154 
155     //! @brief アニメーションオブジェクトを取得します。
156     //!
157     //! @param[in] animObjIdx アニメーションオブジェクトのインデックスです。
158     //!
159     //! @return アニメーションオブジェクトです。
160     //!
GetAnimObject(int animObjIdx)161     AnimObject* GetAnimObject(int animObjIdx)
162     {
163         NW_MINMAXLT_ASSERT(animObjIdx, 0, m_AnimObjects.Size());
164         return m_AnimObjects[animObjIdx];
165     }
166 
167     //! @brief アニメーションオブジェクトを置き替えます。
168     //!
169     //! @param[in] animObjIdx 置き替えるアニメーションオブジェクトのインデックスです。
170     //! @param[in] animObj アニメーションオブジェクトです。
171     //! NULL を指定した場合、アニメーションオブジェクトがない状態になります。
172     //!
173     //! @return 置き替える前のアニメーションオブジェクトです。
174     //!
ReplaceAnimObject(int animObjIdx,AnimObject * animObj)175     AnimObject* ReplaceAnimObject(int animObjIdx, AnimObject* animObj)
176     {
177         NW_MINMAXLT_ASSERT(animObjIdx, 0, m_AnimObjects.Size());
178         AnimObject* oldObj = m_AnimObjects[animObjIdx];
179         m_AnimObjects[animObjIdx] = animObj;
180         return oldObj;
181     }
182 
183     //! アニメーションオブジェクトをクリアします。
ClearAnimObjects()184     void ClearAnimObjects()
185     {
186         m_AnimObjects.Clear();
187     }
188 
189     //! 追加されているアニメーションオブジェクト数を取得します。
GetAnimObjectCount()190     int GetAnimObjectCount() const
191     {
192         return m_AnimObjects.Size();
193     }
194 
195     //! アニメーションオブジェクトの最大数を取得します。
GetMaxAnimObjects()196     int GetMaxAnimObjects() const
197     {
198         return m_AnimObjects.Capacity();
199     }
200 
201     //@}
202 
203     //----------------------------------------
204     //! @name キャッシュ
205     //@{
206 
207     //! アニメーション評価結果の内部キャッシュが古ければ更新します。
UpdateCache()208     virtual void UpdateCache()
209     {
210         for (int animObjIdx = 0; animObjIdx < m_AnimObjects.Size(); ++animObjIdx)
211         {
212             if (m_AnimObjects[animObjIdx] != NULL)
213             {
214                 m_AnimObjects[animObjIdx]->UpdateCache();
215             }
216         }
217     }
218 
219     //@}
220 
221 protected:
222     //! Initialize() の実行に必要なメモリサイズを取得します。
223     //!
224     //! :private
GetMemorySizeForInitialize(os::MemorySizeCalculator * pSize,int maxAnimObjects)225     static void GetMemorySizeForInitialize(os::MemorySizeCalculator* pSize, int maxAnimObjects)
226     {
227         os::MemorySizeCalculator& size = *pSize;
228 
229         size += sizeof(AnimObject*) * maxAnimObjects;
230     }
231 
232     //! @details :private
Initialize(int maxAnimObjects)233     Result Initialize(int maxAnimObjects)
234     {
235         Result result = INITIALIZE_RESULT_OK;
236 
237         void* memory = GetAllocator().Alloc(sizeof(AnimObject*) * maxAnimObjects);
238 
239         if (memory == NULL)
240         {
241             result |= Result::MASK_FAIL_BIT;
242         }
243         NW_ENSURE_AND_RETURN(result);
244 
245         m_AnimObjects = AnimObjectArray(memory, maxAnimObjects, &GetAllocator());
246 
247         return result;
248     }
249 
250     AnimObjectArray m_AnimObjects; //!< @details :private
251 };
252 
253 } // namespace gfx
254 } // namespace nw
255 
256 #endif // NW_GFX_ANIMBLENDER_H_
257