1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     anim_AnimFrameController.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_ANIM_ANIMFRAMECONTROLLER_H_
19 #define NW_ANIM_ANIMFRAMECONTROLLER_H_
20 
21 #include <nw/types.h>
22 
23 namespace nw {
24 namespace anim {
25 
26 //---------------------------------------------------------------------------
27 //! @brief アニメーションフレームのクラスです。
28 //---------------------------------------------------------------------------
29 class AnimFrame
30 {
31 public:
32     //----------------------------------------
33     //! @name コンストラクタ/デストラクタ
34     //@{
35 
36     //! コンストラクタです。
AnimFrame()37     AnimFrame() { ResetFrame(0.0f); }
38 
39     //! @brief コンストラクタです。
40     //!
41     //! @param[in] frame フレームです。
42     //!
AnimFrame(f32 frame)43     AnimFrame(f32 frame) { ResetFrame(frame); }
44 
45     //! @brief コンストラクタです。
46     //!
47     //! @param[in] frame フレームです。
48     //! @param[in] lastFrame 前回のフレームです。
49     //!
AnimFrame(f32 frame,f32 lastFrame)50     AnimFrame(f32 frame, f32 lastFrame) { Set(frame, lastFrame); }
51 
52     //! @brief コンストラクタです。
53     //!
54     //! @param[in] animFrame アニメーションフレームです。
55     //!
AnimFrame(const AnimFrame & animFrame)56     AnimFrame(const AnimFrame& animFrame) { Set(animFrame); }
57 
58     //! デストラクタです。
~AnimFrame()59     virtual ~AnimFrame() {}
60 
61     //@}
62 
63     //----------------------------------------
64     //! @name 取得/設定
65     //@{
66 
67     //! フレームを取得します。
GetFrame()68     f32 GetFrame() const { return m_Frame; }
69 
70     //! @brief フレームを設定します。
71     //!
72     //! @param[in] frame 設定するフレームです。
73     //!
SetFrame(f32 frame)74     void SetFrame(f32 frame)
75     {
76         m_LastFrame = m_Frame;
77         m_Frame = frame;
78     }
79 
80     //! 前回のフレームを取得します。
GetLastFrame()81     f32 GetLastFrame() const { return m_LastFrame; }
82 
83     //! @brief 前回のフレームを設定します。
84     //!
85     //! @param[in] lastFrame 設定する前回のフレームです。
86     //!
SetLastFrame(f32 lastFrame)87     void SetLastFrame(f32 lastFrame) { m_LastFrame = lastFrame; }
88 
89     //! @brief アニメーションフレームを設定します。
90     //!
91     //! @param[in] animFrame 設定するアニメーションフレームです。
92     //!
Set(const AnimFrame & animFrame)93     void Set(const AnimFrame& animFrame)
94     {
95         m_Frame = animFrame.GetFrame();
96         m_LastFrame = animFrame.GetLastFrame();
97     }
98 
99     //! @brief アニメーションフレームを設定します。
100     //!
101     //! @param[in] frame 設定するフレームです。
102     //! @param[in] lastFrame 設定する前回のフレームです。
103     //!
Set(f32 frame,f32 lastFrame)104     void Set(f32 frame, f32 lastFrame)
105     {
106         m_Frame = frame;
107         m_LastFrame = lastFrame;
108     }
109 
110     //! @brief アニメーションフレームをリセットします。
111     //!
112     //! @param[in] frame 設定するフレームです。
113     //!
ResetFrame(f32 frame)114     void ResetFrame(f32 frame)
115     {
116         m_Frame = m_LastFrame = frame;
117     }
118 
119     //! フレーム間隔を取得します。
GetDelta()120     f32 GetDelta() const { return m_Frame - m_LastFrame; }
121 
122     //! 順再生かどうかを取得します。
IsOrder()123     bool IsOrder() const { return m_Frame >= m_LastFrame; }
124 
125     //@}
126 
127     //----------------------------------------
128     //! @name 比較
129     //@{
130 
131     bool operator==(const AnimFrame& rhs) const
132     {
133         return m_Frame == rhs.m_Frame && m_LastFrame == rhs.m_LastFrame;
134     }
135     bool operator!=(const AnimFrame& rhs) const
136     {
137         return m_Frame != rhs.m_Frame || m_LastFrame != rhs.m_LastFrame;
138     }
139 
140     //@}
141 
142 private:
143     f32 m_Frame;
144     f32 m_LastFrame;
145 };
146 
147 //---------------------------------------------------------------------------
148 //! @brief 一回再生用のアニメーション再生方法です。
149 //!
150 //! @param[in] startFrame 開始フレームです。
151 //! @param[in] endFrame 終了フレームです。
152 //! @param[in] inputFrame 元のフレームです。
153 //! @param[in] pUserData ユーザーデータです。
154 //!
155 //! @return 修正したフレームを返します。
156 //---------------------------------------------------------------------------
157 f32 PlayPolicy_Onetime(f32 startFrame, f32 endFrame, f32 inputFrame, void* pUserData);
158 
159 //---------------------------------------------------------------------------
160 //! @brief ループ再生用のアニメーション再生方法です。
161 //!
162 //! @param[in] startFrame 開始フレームです。
163 //! @param[in] endFrame 終了フレームです。
164 //! @param[in] inputFrame 元のフレームです。
165 //! @param[in] pUserData ユーザーデータです。
166 //!
167 //! @return 修正したフレームを返します。
168 //---------------------------------------------------------------------------
169 f32 PlayPolicy_Loop(f32 startFrame, f32 endFrame, f32 inputFrame, void* pUserData);
170 
171 //---------------------------------------------------------------------------
172 //! @brief アニメーションフレームを制御するクラスです。
173 //---------------------------------------------------------------------------
174 class AnimFrameController
175 {
176 public:
177     //! アニメーション再生方法の型です。
178     typedef f32 (*PlayPolicy)(f32 startFrame, f32 endFrame, f32 inputFrame, void* pUserData);
179 
180     //----------------------------------------
181     //! @name コンストラクタ/デストラクタ
182     //@{
183 
184     //! @brief コンストラクタです。
185     //!
186     //! @param[in] startFrame 開始フレームです。
187     //! @param[in] endFrame 終了フレームです。
188     //! @param[in] playPolicy アニメーション再生方法です。
189     //! @param[in] userData ユーザーデータです。
190     //!
191     AnimFrameController(
192         f32 startFrame = 0.0f,
193         f32 endFrame = 1.0f,
194         PlayPolicy playPolicy = PlayPolicy_Onetime,
195         void* userData = NULL)
m_AnimFrame(startFrame)196     : m_AnimFrame(startFrame),
197       m_StepFrame(1.0f),
198       m_StartFrame(startFrame),
199       m_EndFrame(endFrame),
200       m_PlayPolicy(playPolicy),
201       m_UserData(userData)
202     {}
203 
204     //! デストラクタです。
~AnimFrameController()205     virtual ~AnimFrameController() {}
206 
207     //@}
208 
209     //----------------------------------------
210     //! @name 取得/設定
211     //@{
212 
213     //! アニメーションフレームを取得します。
GetAnimFrame()214     const AnimFrame& GetAnimFrame() const { return m_AnimFrame; }
215 
216     //! アニメーションフレームを取得します。
GetAnimFrame()217     AnimFrame& GetAnimFrame() { return m_AnimFrame; }
218 
219     //! アニメーションフレームを設定します。
SetAnimFrame(const AnimFrame & animFrame)220     void SetAnimFrame(const AnimFrame& animFrame) { m_AnimFrame = animFrame; }
221 
222     //! フレームを取得します。
GetFrame()223     f32 GetFrame() const { return m_AnimFrame.GetFrame(); }
224 
225     //! @brief フレームを設定します。
226     //!
227     //! @param[in] frame 設定するフレームです。
228     //!
SetFrame(f32 frame)229     void SetFrame(f32 frame)
230     {
231         m_AnimFrame.SetFrame(m_PlayPolicy(m_StartFrame, m_EndFrame, frame, m_UserData));
232     }
233 
234     //! フレームの増分を取得します。
GetStepFrame()235     f32 GetStepFrame() const { return m_StepFrame; }
236 
237     //! @brief フレームの増分を設定します。
238     //!
239     //!        1 回の UpdateFrame() で進めるフレーム数です。
240     //!
241     //! @param[in] stepFrame 設定する増分です。
242     //!
SetStepFrame(f32 stepFrame)243     void SetStepFrame(f32 stepFrame) { m_StepFrame = stepFrame; }
244 
245     //! 開始フレームを取得します。
GetStartFrame()246     f32 GetStartFrame() const { return m_StartFrame; }
247 
248     //! @brief 開始フレームを設定します。
249     //!
250     //! @param[in] startFrame 設定する開始フレームです。
251     //!
SetStartFrame(f32 startFrame)252     void SetStartFrame(f32 startFrame) { m_StartFrame = startFrame; }
253 
254     //! 終了フレームを取得します。
GetEndFrame()255     f32 GetEndFrame() const { return m_EndFrame; }
256 
257     //! @brief 終了フレームを設定します。
258     //!
259     //! @param[in] endFrame 設定する終了フレームです。
260     //!
SetEndFrame(f32 endFrame)261     void SetEndFrame(f32 endFrame) { m_EndFrame = endFrame; }
262 
263     //! アニメーション再生方法を取得します。
GetPlayPolicy()264     PlayPolicy GetPlayPolicy() const { return m_PlayPolicy; }
265 
266     //! @brief アニメーション再生方法を設定します。
267     //!
268     //! @param[in] playPolicy 設定するアニメーション再生方法です。
269     //! PlayPolicy_Onetime() と PlayPolicy_Loop() がライブラリで用意されています。
270     //!
SetPlayPolicy(PlayPolicy playPolicy)271     void SetPlayPolicy(PlayPolicy playPolicy) { m_PlayPolicy = playPolicy; }
272 
273     //! ユーザーデータを取得します。
GetUserData()274     const void* GetUserData() const { return m_UserData; }
275 
276     //! ユーザーデータを取得します。
GetUserData()277     void* GetUserData() { return m_UserData; }
278 
279     //! @brief ユーザーデータを設定します。
280     //!
281     //! 設定したユーザーデータは、 SetPlayPolicy() で設定した関数に渡されます。
282     //! ユーザー定義の関数を設定している場合に、関数内からアクセスすることができます。
283     //! 例えば、アニメーションの再生が終了したらフラグを立てるといった応用があります。
284     //!
285     //! @param[in] userData 設定するユーザーデータです。
286     //!
SetUserData(void * userData)287     void SetUserData(void* userData) { m_UserData = userData; }
288 
289     //@}
290 
291     //----------------------------------------
292     //! @name 更新
293     //@{
294 
295     //! アニメーションフレームを進めます。
UpdateFrame()296     void UpdateFrame()
297     {
298         SetFrame(GetFrame() + m_StepFrame);
299     }
300 
301     //@}
302 
303 private:
304     AnimFrame m_AnimFrame;
305     f32 m_StepFrame;
306     f32 m_StartFrame;
307     f32 m_EndFrame;
308     PlayPolicy m_PlayPolicy;
309     void* m_UserData;
310 };
311 
312 } /* namespace anim */
313 } /* namespace nw */
314 
315 #endif /* NW_ANIM_ANIMFRAMECONTROLLER_H_ */
316