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