1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     lyt_Animation.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 26791 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_LYT_ANIMATION_H_
17 #define NW_LYT_ANIMATION_H_
18 
19 #include <nw/ut/ut_LinkList.h>
20 
21 #include <nw/lyt/lyt_Types.h>
22 
23 namespace nw
24 {
25 namespace lyt
26 {
27 namespace res
28 {
29 
30 struct BinaryFileHeader;
31 struct AnimationBlock;
32 struct AnimationTagBlock;
33 struct AnimationShareBlock;
34 
35 } // namespace res
36 
37 namespace internal
38 {
39 
40 class AnimPaneTreeLink;
41 
42 } // namespace internal
43 
44 class Pane;
45 class Layout;
46 class Group;
47 class Material;
48 class ResourceAccessor;
49 class TextureInfo;
50 class AnimationLink;
51 
52 //---------------------------------------------------------------------------
53 //! :category アニメーション
54 //!
55 //! @brief アニメーションの基底クラスです。
56 //!
57 //! @since 2009/09/18 初版。
58 //---------------------------------------------------------------------------
59 class AnimTransform
60 {
61 public:
62     //----------------------------------------
63     //! @name コンストラクタ/デストラクタ
64     //@{
65 
66     //! @brief コンストラクタです。
67     //!
68     //! @since 2009/09/18 初版。
69     //!
70     AnimTransform();
71 
72     //! @brief デストラクタです。
73     //!
74     //! @since 2009/09/18 初版。
75     //!
76     virtual ~AnimTransform();
77 
78     //@}
79 
80     //----------------------------------------
81     //! @name 設定/取得
82     //@{
83 
84     //! @brief 現在のフレーム位置を取得します。
85     //!
86     //! @return 現在のフレーム位置を返します。
87     //!
88     //! @sa SetFrame
89     //!
90     //! @since 2009/09/18 初版。
91     //!
GetFrame()92     f32 GetFrame() const
93     {
94         return m_Frame;
95     }
96 
97     //! @brief フレーム位置を設定します。
98     //!
99     //! @param frame  フレーム位置です。
100     //!
101     //! @sa GetFrame
102     //!
103     //! @since 2009/09/18 初版。
104     //!
SetFrame(f32 frame)105     void SetFrame(f32 frame)
106     {
107         m_Frame = frame;
108     }
109 
110     //! @brief フレームの長さを取得します。
111     //!
112     //! @return フレームの長さを返します。
113     //!
114     //! @since 2009/09/18 初版。
115     //!
116     u16 GetFrameSize() const;
117 
118     //! @brief フレーム位置の最大値を取得します。
119     //!
120     //! @return フレーム位置の最大値を返します。
121     //!
122     //! @since 2009/09/18 初版。
123     //!
GetFrameMax()124     f32 GetFrameMax() const
125     {
126         return GetFrameSize();
127     }
128 
129     //! @brief アニメーションブロックを取得します。
130     //!
131     //! @return アニメーションブロックへのポインタを返します。
132     //!
133     //! @sa SetResource
134     //!
135     //! @since 2009/09/18 初版。
136     //!
GetAnimResource()137     const res::AnimationBlock* GetAnimResource() const
138     {
139         return m_pRes;
140     }
141 
142     //@}
143 
144     //----------------------------------------
145     //! @name アニメーション
146     //@{
147 
148     //! @brief ループ用のアニメーションデータか判定します。
149     //!
150     //! @details
151     //! アニメーションデータがループ用としてマークされているかどうかを
152     //! 判定します。
153     //!
154     //! @return
155     //! アニメーションデータがループ用としてマークされている場合は true を
156     //! 返します。
157     //!
158     //! @since 2009/09/18 初版。
159     //!
160     bool IsLoopData() const;
161 
162     //! @brief アニメーションを再生します。
163     //!
164     //! @details
165     //! idx で指定されたアニメーションを pPane で指定したペインで再生します。
166     //!
167     //! @param idx  アニメーションのインデックスです。
168     //! @param pPane  ペインです。
169     //!
170     //! @sa Bind
171     //!
172     //! @since 2009/09/18 初版。
173     //!
174     virtual void Animate(u32 idx, Pane* pPane) = 0;
175 
176     //! @brief アニメーションを再生します。
177     //!
178     //! @details
179     //! idx で指定されたアニメーションを pMaterial で指定したマテリアルで
180     //! 再生します。
181     //!
182     //! @param idx  アニメーションのインデックスです。
183     //! @param pMaterial  マテリアルです。
184     //!
185     //! @sa Bind
186     //!
187     //! @since 2009/09/18 初版。
188     //!
189     virtual void Animate(u32 idx, Material* pMaterial) = 0;
190 
191     //@}
192 
193     //----------------------------------------
194     //! @name リソース
195     //@{
196 
197     //! @brief アニメーションが使用するリソースを設定します。
198     //!
199     //! @param pRes  リソースのアニメーションブロックへのポインタです。
200     //! @param pResAccessor  リソースアクセサです。
201     //!
202     //! @details
203     //! Bind() でアニメーションに関連付けるアニメーションブロックデータと
204     //! アニメーションデータに必要なリソースを設定します。
205     //!
206     //! また、 Bind() で必要になる AnimationLink を
207     //! アニメーションブロックに含まれるアニメーション対象の個数分確保します。
208     //!
209     //! AnimationLink は、バインドされるアニメーションの対象(ペインや
210     //! マテリアル)毎に必要です。
211     //!
212     //! この関数の実装では SetAnimResource() を使用して、アニメーション
213     //! ブロックデータを登録しなければなりません。
214     //!
215     //! @sa Bind
216     //! @sa SetAnimResource
217     //! @sa lyt::AnimationLink
218     //!
219     //! @since 2009/09/18
220     //!
221     virtual void SetResource(
222         const res::AnimationBlock* pRes,
223         ResourceAccessor* pResAccessor) = 0;
224 
225     //! @brief アニメーションが使用するリソースを設定します。
226     //!
227     //! @param pRes  リソースのアニメーションブロックへのポインタです。
228     //! @param pResAccessor  リソースアクセサです。
229     //! @param animNum  確保する AnimationLink 数です。
230     //!
231     //! @details
232     //! Bind() でアニメーションに関連付けるアニメーションブロックデータと
233     //! アニメーションデータに必要なリソースを設定します。
234     //!
235     //! また、 Bind() で必要になる AnimationLink を
236     //! animNum で指定された個数、確保します。
237     //!
238     //! AnimationLink は、バインドされるアニメーションの対象(ペインや
239     //! マテリアル)毎に必要です。
240     //!
241     //! 本関数の実装では SetAnimResource() を使用して、アニメーション
242     //! ブロックデータを登録しなければなりません。
243     //!
244     //! @sa Bind
245     //! @sa SetAnimResource
246     //! @sa lyt::AnimationLink
247     //!
248     //! @since 2009/09/18
249     //!
250     virtual void SetResource(
251         const res::AnimationBlock* pRes,
252         ResourceAccessor* pResAccessor,
253         u16 animNum) = 0;
254 
255     //! @brief アニメーションの関連付けを行います。
256     //!
257     //! @details
258     //! pPane で指定したペインにアニメーションを関連付けます。
259     //!
260     //! bRecursive に true を渡して呼び出した場合は、ペインを pPane の子からも
261     //! 検索します。
262     //!
263     //! bDisable に true を渡して呼び出した場合は、アニメーションを無効状態で
264     //! 関連付けます。
265     //!
266     //! @param pPane  ペインへのポインタです。
267     //! @param bRecursive  再帰的に検索する場合は true を指定します。
268     //! @param bDisable  アニメーションを無効状態で関連付ける場合は true を
269     //!                  指定します。
270     //!
271     //! @since 2009/09/18 初版。
272     //!
273     virtual void  Bind(
274         Pane* pPane,
275         bool bRecursive,
276         bool bDisable = false) = 0;
277 
278     //! @brief アニメーションの関連付けを行います。
279     //!
280     //! @details
281     //! pMaterial で指定したマテリアルにアニメーションを関連付けます。
282     //!
283     //! bDisable に true を渡して呼び出した場合は、アニメーションを無効状態で
284     //! 関連付けます。
285     //!
286     //! @param pMaterial  マテリアルへのポインタです。
287     //! @param bDisable  アニメーションを無効状態で関連付ける場合は true を
288     //!                  指定します。
289     //!
290     //! @since 2009/09/18 初版。
291     //!
292     virtual void Bind(Material* pMaterial, bool bDisable = false) = 0;
293 
294     //@}
295 
296     //! :private
297     //! @brief リンク情報です。
298     ut::LinkListNode m_Link;
299 
300 protected:
301     //----------------------------------------
302     //! @name 設定/取得
303     //@{
304 
305     //! @brief アニメーションリソースへのポインタを設定します。
306     //!
307     //! @details
308     //! SetResource() の実装内で使用され、 GetAnimResource() の戻り値を設定します。
309     //!
310     //! @param pRes  アニメーションブロックへのポインタです。
311     //!
312     //! @sa SetResource
313     //! @sa GetAnimResource
314     //!
315     //! @since 2009/09/18 初版。
316     //!
SetAnimResource(const res::AnimationBlock * pRes)317     void SetAnimResource(const res::AnimationBlock* pRes)
318     {
319         m_pRes = pRes;
320     }
321 
322     //@}
323 
324 protected:
325     //! @details :private
326     //! アニメーションリソースです。
327     const res::AnimationBlock* m_pRes;
328 
329     //! @details :private
330     //! カレントフレーム値です。
331     f32 m_Frame;
332 };
333 
334 //---------------------------------------------------------------------------
335 //! :category アニメーション
336 //!
337 //! @brief アニメーションの基礎クラスです。
338 //!
339 //! @since 2009/09/18 初版。
340 //---------------------------------------------------------------------------
341 class AnimTransformBasic : public AnimTransform
342 {
343 private:
344     typedef AnimTransform Base;
345 
346 public:
347     //----------------------------------------
348     //! @name コンストラクタ/デストラクタ
349     //@{
350 
351     //! @brief コンストラクタです。
352     //!
353     //! @since 2009/09/18 初版。
354     //!
355     AnimTransformBasic();
356 
357     //! @brief デストラクタです。
358     //!
359     //! @since 2009/09/18 初版。
360     //!
361     virtual ~AnimTransformBasic();
362 
363     //@}
364 
365     //----------------------------------------
366     //! @name アニメーション
367     //@{
368 
369     virtual void Animate(
370         u32 idx,
371         Pane* pPane);
372 
373     virtual void Animate(
374         u32 idx,
375         Material* pMaterial);
376 
377     //@}
378 
379     //----------------------------------------
380     //! @name リソース
381     //@{
382 
383     virtual void SetResource(
384         const res::AnimationBlock* pRes,
385         ResourceAccessor* pResAccessor);
386 
387     virtual void SetResource(
388         const res::AnimationBlock* pRes,
389         ResourceAccessor* pResAccessor,
390         u16 animNum);
391 
392     virtual void Bind(
393         Pane* pPane,
394         bool bRecursive,
395         bool bDisable = false);
396 
397     virtual void Bind(
398         Material* pMaterial,
399         bool bDisable = false);
400 
401     //@}
402 
403     //! :private
404     //! @brief アニメーションの関連付けを行います。
405     template<typename T>
Bind(T * pTarget,AnimationLink * pAnimLink,u16 idx,bool bDisable)406     AnimationLink* Bind(
407         T* pTarget,
408         AnimationLink* pAnimLink,
409         u16 idx,
410         bool bDisable)
411     {
412         NW_NULL_ASSERT(pTarget);
413 
414         pAnimLink = this->FindUnbindLink(pAnimLink);
415         if (! pAnimLink)
416         {
417             NW_WARNING(false, "all AnimationLink used.");
418             return 0;
419         }
420 
421         pAnimLink->Set(this, idx, bDisable);
422         pTarget->AddAnimationLink(pAnimLink);
423 
424         return ++pAnimLink;
425     }
426 
427 protected:
428     //! @details :private
429     AnimationLink* FindUnbindLink(AnimationLink* pLink) const;
430 
431     //! @details :private
432     //! テクスチャの情報です。
433     TextureInfo* m_pTexAry;
434 
435     //! @details :private
436     //! アニメーションリンクです。
437     AnimationLink* m_pAnimLinkAry;
438 
439     //! @details :private
440     //! アニメーションリンクの数です。
441     u16 m_AnimLinkNum;
442 };
443 
444 //---------------------------------------------------------------------------
445 //! :category アニメーション
446 //!
447 //! @brief アニメーションリソースクラスです。
448 //!
449 //! @since 2009/09/18 初版。
450 //---------------------------------------------------------------------------
451 class AnimResource
452 {
453 public:
454     //----------------------------------------
455     //! @name コンストラクタ/デストラクタ
456     //@{
457 
458     //! @brief コンストラクタです。
459     //!
460     //! @details
461     //! リソースの関連付けは行われません。
462     //! 別途 Set() を使用して関連付けを行います。
463     //!
464     //! @sa Set
465     //!
466     //! @since 2009/09/18 初版。
467     //!
468     AnimResource();
469 
470     //! @brief コンストラクタです。
471     //!
472     //! @details
473     //! anmResBuf で指定したアニメーションリソースが関連付けられます。
474     //!
475     //! @param anmResBuf  アニメーションリソースへのポインタです。
476     //!
477     //! @since 2009/09/18 初版。
478     //!
AnimResource(const void * anmResBuf)479     explicit AnimResource(const void* anmResBuf)
480     {
481         Set(anmResBuf);
482     }
483 
484     //@}
485 
486     //----------------------------------------
487     //! @name 設定/取得
488     //@{
489 
490     //! @brief アニメーションリソースを関連付けます。
491     //!
492     //! @param anmResBuf アニメーションリソースへのポインタです。
493     //!
494     //! @since 2009/09/18 初版。
495     //!
496     void Set(const void* anmResBuf);
497 
498     //! @brief アニメーションリソースを取得します。
499     //!
500     //! @return ファイルヘッダへのポインタを返します。
501     //!
502     //! @since 2009/09/18 初版。
503     //!
GetFileHeader()504     const ut::BinaryFileHeader* GetFileHeader() const
505     {
506         return m_pFileHeader;
507     }
508 
509     //! @brief アニメーションブロックを取得します。
510     //!
511     //! @return アニメーションブロックへのポインタを返します。
512     //!
513     //! @since 2009/09/18 初版。
514     //!
GetResourceBlock()515     const res::AnimationBlock* GetResourceBlock() const
516     {
517         return m_pResBlock;
518     }
519 
520     //! @brief アニメーション区間タグブロックを取得します。
521     //!
522     //! @return アニメーション区間タグブロックへのポインタを返します。
523     //!
524     //! @since 2009/09/18 初版。
525     //!
GetTagBlock()526     const res::AnimationTagBlock* GetTagBlock() const
527     {
528         return m_pTagBlock;
529     }
530 
531     //! @brief アニメーション区間タグの通し番号を取得します。
532     //!
533     //! @return アニメーション区間タグの0から始まる通し番号を返します。
534     //!
535     //! @since 2009/09/18 初版。
536     //!
537     u16 GetTagOrder() const;
538 
539     //! @brief アニメーション区間タグの名前を取得します。
540     //!
541     //! @return アニメーション区間タグの名前を返します。
542     //!
543     //! @since 2009/09/18 初版。
544     //!
545     const char* GetTagName() const;
546 
547     //! @brief アニメーション区間タグのグループ数を取得します。
548     //!
549     //! @return アニメーション区間タグに設定されているグループ数を返します。
550     //!
551     //! @since 2009/09/18 初版。
552     //!
553     u16 GetGroupNum() const;
554 
555     //! @brief アニメーション区間タグのグループ配列を取得します。
556     //!
557     //! @return
558     //! アニメーション区間タグに設定されているグループ配列の
559     //! 先頭ポインタを返します。
560     //!
561     //! @since 2009/09/18 初版。
562     //!
563     const AnimationGroupRef* GetGroupArray() const;
564 
565     //! @brief
566     //! アニメーションをバインドするとき、ペインの子孫となるペインも対象に
567     //! するかどうかを判定します。
568     //!
569     //! @return
570     //! アニメーションをバインドするとき、子孫のペインも対象にするときは
571     //! true を返します。
572     //!
573     //! @since 2009/09/18 初版。
574     //!
575     bool IsDescendingBind() const;
576 
577     //! @brief アニメーション共有情報の個数を取得します。
578     //!
579     //! @return アニメーション共有情報の個数を返します。
580     //!
581     //! @since 2009/09/18 初版。
582     //!
583     u16 GetAnimationShareInfoNum() const;
584 
585     //! @brief アニメーション共有情報の配列を取得します。
586     //!
587     //! @return AnimationShareInfo オブジェクト配列の先頭ポインタを返します。
588     //!
589     //! @since 2009/09/18 初版。
590     //!
591     const AnimationShareInfo* GetAnimationShareInfoArray() const;
592 
593     //! @brief バインドされるアニメーションの個数を計算します。
594     //!
595     //! @details
596     //! pPane で指定したペインにバインドされるアニメーションの個数を計算します。
597     //!
598     //! bRecursive に true を指定した場合は、関連付けるペインを子ペインからも
599     //! 検索します。
600     //!
601     //! @param pPane ペインへのポインタです。
602     //! @param bRecursive 子ペインも検索するか指定します。
603     //!
604     //! @return バインドされるアニメーションの個数を返します。
605     //!
606     //! @since 2009/09/18 初版。
607     //!
608     u16 CalcAnimationNum(Pane* pPane, bool bRecursive) const;
609 
610     //! @brief バインドされるアニメーションの個数を計算します。
611     //!
612     //! @details
613     //! pMaterial で指定されたマテリアルにバインドされるアニメーションの
614     //! 個数を計算します。
615     //!
616     //! @param pMaterial マテリアルへのポインタです。
617     //!
618     //! @return バインドされるアニメーションの個数を返します。
619     //!
620     //! @since 2009/09/18 初版。
621     //!
622     u16 CalcAnimationNum(Material* pMaterial) const;
623 
624     //! @brief バインドされるアニメーションの個数を計算します。
625     //!
626     //! @details
627     //! pGroup で指定されたグループに含まれるペインにバインドされる
628     //! アニメーションの個数を計算します。
629     //!
630     //! bRecursive に true を指定した場合は、関連付けるペインを子ペインからも
631     //! 検索します。
632     //!
633     //! @param pGroup グループへのポインタです。
634     //! @param bRecursive 子ペインも検索するか指定します。
635     //!
636     //! @return バインドされるアニメーションの個数を返します。
637     //!
638     //! @since 2009/09/18 初版。
639     //!
640     u16 CalcAnimationNum(Group* pGroup, bool bRecursive) const;
641 
642     //@}
643 
644 protected:
645     //! @details :private
646     void Init();
647 
648     //! :private
649     //!
650     //! @brief アニメーションリソースが設定されているか確認します。
651     //!
652     //! @return 設定されていれば true を返します。
653     //!
654     //! @since 2009/09/18 初版。
655     //!
656     bool CheckResource() const;
657 
658     //! @details :private
659     const ut::BinaryFileHeader* m_pFileHeader;
660 
661     //! @details :private
662     const res::AnimationBlock* m_pResBlock;
663 
664     //! @details :private
665     const res::AnimationTagBlock* m_pTagBlock;
666 
667     //! @details :private
668     const res::AnimationShareBlock* m_pShareBlock;
669 };
670 
671 namespace internal
672 {
673 
674 class AnimPaneTree
675 {
676 public:
677     AnimPaneTree();
678 
679     AnimPaneTree(
680         Pane* pTargetPane,
681         const AnimResource& animRes);
682 
683     void Set(
684         Pane* pTargetPane,
685         const AnimResource& animRes);
686 
687     AnimTransform* Bind(
688         Layout* pLayout,
689         Pane* pTargetPane,
690         ResourceAccessor* pResAccessor) const;
691 
IsEnabled()692     bool IsEnabled() const
693     {
694         return m_LinkNum > 0;
695     }
696 
GetAnimResource()697     const AnimResource& GetAnimResource() const
698     {
699         return m_AnimRes;
700     }
701 
702 protected:
703     //! @details :private
704     static u16 FindAnimContent(
705         const res::AnimationBlock* pAnimBlock,
706         const char* animContName,
707         u8 animContType);
708 
709     //! @details :private
710     void Init();
711 
712     //! @details :private
713     static const u16 NOBIND = u16(-1);
714 
715     //! @details :private
716     static const int MATERIAL_NUM_MAX = 1 + 4 + 4;
717 
718     //! @details :private
719     AnimResource m_AnimRes;
720 
721     //! @details :private
722     u16 m_AnimPaneIdx;
723 
724     //! @details :private
725     u16 m_LinkNum;
726 
727     //! @details :private
728     u16 m_AnimMatIdxs[MATERIAL_NUM_MAX];
729 
730     //! @details :private
731     u8 m_AnimMatCnt;
732 };
733 
734 AnimationLink* FindAnimationLink(
735     AnimationList* pAnimList,
736     AnimTransform* pAnimTrans);
737 
738 AnimationLink* FindAnimationLink(
739     AnimationList* pAnimList,
740     const AnimResource& animRes);
741 
742 void UnbindAnimationLink(
743     AnimationList* pAnimList,
744     AnimTransform* pAnimTrans);
745 
746 } // namespace nw::lyt::internal
747 } // namespace nw::lyt
748 } // namespace nw
749 
750 #endif // NW_LYT_ANIMATION_H_
751