1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_AnimObject.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_ANIMOBJECT_H_
19 #define NW_GFX_ANIMOBJECT_H_
20 
21 #include <nw/math.h>
22 #include <nw/anim/anim_AnimResult.h>
23 #include <nw/gfx/gfx_GfxObject.h>
24 #include <nw/ut/ut_RuntimeTypeInfo.h>
25 
26 namespace nw {
27 namespace gfx {
28 
29 class AnimGroup;
30 
31 //---------------------------------------------------------------------------
32 //! @brief アニメーションの重みを比較します。
33 //!
34 //! @param[in] weight 重み
35 //! @param[in] value 比較する値
36 //!
37 //! @return 重みと比較する値の誤差が許容値以下なら true を返します。
38 //---------------------------------------------------------------------------
39 NW_INLINE bool
AnimWeightNearlyEqual(const float weight,const float value)40 AnimWeightNearlyEqual(const float weight, const float value)
41 {
42     // 0.1%未満は無視することとします。
43     const float Epsilon = 0.001f;
44     return math::FAbs(weight - value) <= Epsilon;
45 }
46 
47 //---------------------------------------------------------------------------
48 //! @brief アニメーションの重みが 0 にほぼ等しいか比較します。
49 //!
50 //! @param[in] weight 重み
51 //!
52 //! @return 重みと 0 との誤差が許容値以下なら true を返します。
53 //---------------------------------------------------------------------------
54 NW_INLINE bool
AnimWeightNearlyEqualZero(const float weight)55 AnimWeightNearlyEqualZero(const float weight)
56 {
57     return AnimWeightNearlyEqual(weight, 0.0f);
58 }
59 
60 //---------------------------------------------------------------------------
61 //! @brief アニメーションの重みが 1 にほぼ等しいか比較します。
62 //!
63 //! @param[in] weight 重み
64 //!
65 //! @return 重みと 1 との誤差が許容値以下なら true を返します。
66 //---------------------------------------------------------------------------
67 NW_INLINE bool
AnimWeightNearlyEqualOne(const float weight)68 AnimWeightNearlyEqualOne(const float weight)
69 {
70     return AnimWeightNearlyEqual(weight, 1.0f);
71 }
72 
73 //---------------------------------------------------------------------------
74 //! @brief アニメーションブレンドの重みを正規化するスケールを取得します。
75 //!
76 //! @param[in] weightSum 重みの合計です。
77 //!
78 //! @return 重みを正規化するスケールです。
79 //---------------------------------------------------------------------------
80 NW_INLINE float
GetAnimWeightNormalizeScale(float weightSum)81 GetAnimWeightNormalizeScale(float weightSum)
82 {
83     return
84         AnimWeightNearlyEqualOne(weightSum) ||
85         AnimWeightNearlyEqualZero(weightSum) ?
86         1.0f : 1.0f / weightSum;
87 }
88 
89 //---------------------------------------------------------------------------
90 //! @brief アニメーション評価を抽象化するクラスです。
91 //! 抽象クラスですのでインスタンス化して使用することはできません。
92 //!
93 //! フレームを進める、各フレームの値を取得する、などの動作を抽象化しています。
94 //! 単一のアニメーションを評価する AnimEvaluator, 複数のアニメーションをブレンドする AnimBlender などの派生クラスがあります。
95 //---------------------------------------------------------------------------
96 class AnimObject : public GfxObject
97 {
98 public:
99     //! @details :private
100     NW_UT_RUNTIME_TYPEINFO;
101 
102     //----------------------------------------
103     //! @name コンストラクタ/デストラクタ
104     //@{
105 
106     //! コンストラクタです。
AnimObject(os::IAllocator * allocator,u32 animType)107     AnimObject(os::IAllocator* allocator, u32 animType)
108     : GfxObject(allocator),
109       m_AnimGroup(NULL),
110       m_AnimType(animType) {}
111 
112     //! デストラクタです。
~AnimObject()113     virtual ~AnimObject() {}
114 
115     //@}
116 
117     //----------------------------------------
118     //! @name 基本操作
119     //@{
120 
121     //! @brief アニメーションを関連付けます。
122     //!
123     //! @param[in] animGroup アニメーショングループです。
124     //!
125     //! @return バインドに成功したら true を返します。
126     //!
127     //! @sa TryBind
Bind(AnimGroup * animGroup)128     bool Bind(AnimGroup* animGroup)
129     {
130         return TryBind(animGroup).IsSuccess();
131     }
132 
133     //! @brief アニメーションを関連付けます。
134     //!
135     //! Bind() よりも詳細なバインド結果を得ることができます。
136     //!
137     //! @param[in] animGroup アニメーショングループです。
138     //!
139     //! @return バインドの結果を返します。
140     //!
141     //! @sa Bind
142     //! @sa BindResult
143     virtual Result TryBind(AnimGroup* animGroup) = 0;
144 
145     //! アニメーションの関連付けを解除します。
146     virtual void Release() = 0;
147 
148     //! フレームを更新します。
149     virtual void UpdateFrame() = 0;
150 
151     //@}
152 
153     //----------------------------------------
154     //! @name 評価
155     //@{
156 
157     //! @brief メンバ単位でアニメーション結果を取得します。
158     //!
159     //! @param[out] target アニメーション結果を書き込む対象です。
160     //! @param[in] memberIdx メンバインデックスです。
161     //!
162     //! @return アニメーション結果を返します。
163     //! ブレンドオペレーションを使用する場合は、返り値のアニメーション結果を使用してください。
164     //!
165     virtual const anim::AnimResult* GetResult(
166         void* target,
167         int memberIdx) const = 0;
168 
169     //@}
170 
171     //----------------------------------------
172     //! @name 取得/設定
173     //@{
174 
175     //! アニメーショングループを取得します。
GetAnimGroup()176     const AnimGroup* GetAnimGroup() const { return m_AnimGroup; }
177 
178     //! アニメーショングループを取得します。
GetAnimGroup()179     AnimGroup* GetAnimGroup() { return m_AnimGroup; }
180 
181     //! アニメーショングループを設定します。
SetAnimGroup(AnimGroup * group)182     void SetAnimGroup(AnimGroup* group) { m_AnimGroup = group; }
183 
184     //! @brief メンバに関連付けられたアニメーションが存在するかどうかを取得します。
185     //!
186     //! @param[in] memberIdx メンバインデックスです。
187     //!
188     //! @return アニメーションが存在すれば true を返します。
189     //!
190     virtual bool HasMemberAnim(int memberIdx) const = 0;
191 
192     //@}
193 
194     //----------------------------------------
195     //! @name キャッシュ
196     //@{
197 
198     //! アニメーション評価結果の内部キャッシュが古ければ更新します。
199     virtual void UpdateCache() = 0;
200 
201     //! @details :private
202     enum
203     {
204         ANIMTYPE_SIMPLE,
205         ANIMTYPE_TRANSFORM_SIMPLE,
206         ANIMTYPE_BLENDER
207     };
208 
209     //! @details :private
GetAnimType()210     u32 GetAnimType() const { return m_AnimType; }
211 
212     //@}
213 
214 protected:
215     //! @details :private
216     AnimGroup* m_AnimGroup;
217     //! @details :private
218     u32        m_AnimType;
219 };
220 
221 } // namespace gfx
222 } // namespace nw
223 
224 #endif // NW_GFX_ANIMOBJECT_H_
225