1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     anim_AnimBlend.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_ANIMBLEND_H_
19 #define NW_ANIM_ANIMBLEND_H_
20 
21 #include <nw/types.h>
22 #include <nw/anim/anim_AnimResult.h>
23 #include <nw/ut/ut_Flag.h>
24 
25 namespace nw {
26 namespace anim {
27 
28 //---------------------------------------------------------------------------
29 //! @brief アニメーションのブレンドオペレーションの基底クラスです。
30 //---------------------------------------------------------------------------
31 class AnimBlendOp
32 {
33 public:
34     //! 基本ブレンド処理用のフラグの定義です。
35     //!
36     //! :private
37     enum Flags
38     {
39         VALID_SINGLE = AnimResult::FLAG_VALID_COMPONENT0,
40 
41         VALID_X = AnimResult::FLAG_VALID_COMPONENT0,
42         VALID_Y = AnimResult::FLAG_VALID_COMPONENT1,
43         VALID_Z = AnimResult::FLAG_VALID_COMPONENT2,
44         VALID_W = AnimResult::FLAG_VALID_COMPONENT3,
45         VALID_XY   = VALID_X | VALID_Y,
46         VALID_XYZ  = VALID_X | VALID_Y | VALID_Z,
47         VALID_XYZW = VALID_X | VALID_Y | VALID_Z | VALID_W,
48 
49         VALID_R = AnimResult::FLAG_VALID_COMPONENT0,
50         VALID_G = AnimResult::FLAG_VALID_COMPONENT1,
51         VALID_B = AnimResult::FLAG_VALID_COMPONENT2,
52         VALID_A = AnimResult::FLAG_VALID_COMPONENT3,
53         VALID_RGBA = VALID_R | VALID_G | VALID_B | VALID_A,
54 
55         CONVERTED = AnimResult::FLAG_CONVERTED
56     };
57 
58     //----------------------------------------
59     //! @name コンストラクタ/デストラクタ
60     //@{
61 
62     //! @brief コンストラクタです。
63     //!
64     //! @param[in] hasBlend ブレンド処理があるかどうかです。
65     //! @param[in] hasPostBlend ブレンド後の処理があるかどうかです。
66     //!
AnimBlendOp(bool hasBlend,bool hasPostBlend)67     AnimBlendOp(bool hasBlend, bool hasPostBlend)
68     : m_HasBlend(hasBlend),
69       m_HasPostBlend(hasPostBlend) {}
70 
71     //! デストラクタです。
~AnimBlendOp()72     virtual ~AnimBlendOp() {}
73 
74     //@}
75 
76     //----------------------------------------
77     //! @name 取得/設定
78     //@{
79 
80     //! @brief ブレンド処理があるかどうかを取得します。
81     //!
82     //! @return ブレンド処理があるなら true を返します。
83     //!
HasBlend()84     bool HasBlend() const { return m_HasBlend; }
85 
86     //! @brief ブレンド後の処理があるかどうかを取得します。
87     //!
88     //! @return ブレンド後の処理があるなら true を返します。
89     //!
HasPostBlend()90     bool HasPostBlend() const { return m_HasPostBlend; }
91 
92     //@}
93 
94     //----------------------------------------
95     //! @name ブレンド
96     //@{
97 
98     //! @brief ブレンド処理を行います。
99     //!
100     //! @param[in,out] dst ブレンド処理結果です。
101     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
102     //! 成分ごとの重みの累積値で再正規化を行う必要がなければ NULL を指定します。
103     //! @param[in] src ブレンド処理の入力です。
104     //! @param[in] srcWeights ブレンド処理の入力の重みです。
105     //! ブレンドオペレーションによって、全成分で共通の場合と、成分ごとに異なる場合があります。
106     //!
107     //! @return ブレンド処理のループを継続するなら true を返します。
108     //!
Blend(AnimResult * dst,float * dstWeights,const AnimResult * src,const float * srcWeights)109     virtual bool Blend(
110         AnimResult* dst,
111         float* dstWeights,
112         const AnimResult* src,
113         const float* srcWeights) const
114     {
115         (void)dst;
116         (void)dstWeights;
117         (void)src;
118         (void)srcWeights;
119         return true;
120     }
121 
122     //! @brief ブレンド後の処理を行います。
123     //!
124     //! @param[in,out] result ブレンド処理結果です。
125     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
126     //! 成分ごとの重みの累積値で再正規化を行う必要がなければ NULL を指定します。
127     //!
128     //! @return 成功すれば true を返します。
129     //!
PostBlend(AnimResult * result,const float * weights)130     virtual bool PostBlend(AnimResult* result, const float* weights) const
131     {
132         (void)result;
133         (void)weights;
134         return true;
135     };
136 
137     //! @brief 上書き処理を行います。
138     //!
139     //! @param[in,out] dst ブレンド処理結果です。
140     //! @param[in] src ブレンド処理の入力です。
141     //!
142     //! @return すべての成分が上書きされたら true を返します。
143     //!
144     virtual bool Override(AnimResult* dst, const AnimResult* src) const = 0;
145 
146     //@}
147 
148     //----------------------------------------
149     //! @name 適用
150     //@{
151 
152     //! @brief ブレンド処理結果を対象に適用します。
153     //!
154     //! @param[out] target ブレンド処理結果を適用する対象です。
155     //! @param[in] result ブレンド処理結果です。
156     //!
157     virtual void Apply(void* target, const AnimResult* result) const = 0;
158 
159     //! @brief 対象を AnimResult に変換します。
160     //!
161     //! @param[out] result 出力の AnimResult です。
162     //! @param[in] source 変換元へのポインタです。
163     //!
164     //! :private
165     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const = 0;
166 
167     //@}
168 
169 protected:
170     //----------------------------------------
171     //! @name 基本ブレンド処理
172     //@{
173 
174     //! FloatVector のブレンド処理を行います。
175     //!
176     //! :private
177     bool BlendFloatVector(
178         AnimResult* dst,
179         const AnimResult* src,
180         float srcWeight,
181         int compCount
182     ) const;
183 
184     //! FloatVector の上書き処理を行います。
185     //!
186     //! :private
187     bool OverrideFloatVector(
188         AnimResult* dst,
189         const AnimResult* src,
190         int compCount,
191         bit32 allCompValidFlag
192     ) const;
193 
194     //@}
195 
196     //----------------------------------------
197     //! @name 基本適用処理
198     //@{
199 
200     //! FloatVector のブレンド処理結果を対象に適用します。
201     //!
202     //! :private
203     void ApplyFloatVector(void* target, const AnimResult* result, int compCount) const;
204 
205     //! @brief FloatVector を AnimResult に変換します。
206     //!
207     //! @param[out] result 出力の AnimResult です。
208     //! @param[in] source 変換元へのポインタです。
209     //!
210     //! :private
211     void ConvertFloatVectorToAnimResult(AnimResult* result, const void* source, int compCount) const;
212 
213 
214     //@}
215 
216 private:
217     bool m_HasBlend;
218     bool m_HasPostBlend;
219 };
220 
221 //---------------------------------------------------------------------------
222 //! @brief bool アニメーションのブレンドオペレーションのクラスです。
223 //---------------------------------------------------------------------------
224 class AnimBlendOpBool : public AnimBlendOp
225 {
226 public:
227     //----------------------------------------
228     //! @name コンストラクタ/デストラクタ
229     //@{
230 
231     //! コンストラクタです。
AnimBlendOpBool()232     AnimBlendOpBool()
233     : AnimBlendOp(true, false) {}
234 
235     //! デストラクタです。
~AnimBlendOpBool()236     virtual ~AnimBlendOpBool() {}
237 
238     //@}
239 
240     //----------------------------------------
241     //! @name ブレンド
242     //@{
243 
244     virtual bool Blend(
245         AnimResult* dst,
246         float* dstWeights,
247         const AnimResult* src,
248         const float* srcWeights) const;
249 
Override(AnimResult * dst,const AnimResult * src)250     virtual bool Override(AnimResult* dst, const AnimResult* src) const
251     {
252         *reinterpret_cast<bool*>(dst->GetValueBuffer()) =
253             *reinterpret_cast<const bool*>(src->GetValueBuffer());
254         dst->SetFlags(VALID_SINGLE);
255         return true;
256     }
257 
258     //@}
259 
260     //----------------------------------------
261     //! @name 適用
262     //@{
263 
Apply(void * target,const AnimResult * result)264     virtual void Apply(void* target, const AnimResult* result) const
265     {
266         *reinterpret_cast<bool*>(target) =
267             *reinterpret_cast<const bool*>(result->GetValueBuffer());
268     }
269 
ConvertToAnimResult(AnimResult * result,const void * source)270     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
271     {
272         *reinterpret_cast<bool*>(result->GetValueBuffer()) =
273             *reinterpret_cast<const bool*>(source);
274         result->SetFlags(VALID_SINGLE);
275     }
276 
277 
278     //@}
279 };
280 
281 //---------------------------------------------------------------------------
282 //! @brief int アニメーションのブレンドオペレーションのクラスです。
283 //---------------------------------------------------------------------------
284 class AnimBlendOpInt : public AnimBlendOp
285 {
286 public:
287     //----------------------------------------
288     //! @name コンストラクタ/デストラクタ
289     //@{
290 
291     //! コンストラクタです。
AnimBlendOpInt()292     AnimBlendOpInt()
293     : AnimBlendOp(false, false) {} // ブレンド処理なし(常に上書き)
294 
295     //! デストラクタです。
~AnimBlendOpInt()296     virtual ~AnimBlendOpInt() {}
297 
298     //@}
299 
300     //----------------------------------------
301     //! @name ブレンド
302     //@{
303 
Override(AnimResult * dst,const AnimResult * src)304     virtual bool Override(AnimResult* dst, const AnimResult* src) const
305     {
306         *reinterpret_cast<int*>(dst->GetValueBuffer()) =
307             *reinterpret_cast<const int*>(src->GetValueBuffer());
308         dst->SetFlags(VALID_SINGLE);
309         return true;
310     }
311 
312     //@}
313 
314     //----------------------------------------
315     //! @name 適用
316     //@{
317 
Apply(void * target,const AnimResult * result)318     virtual void Apply(void* target, const AnimResult* result) const
319     {
320         *reinterpret_cast<int*>(target) =
321             *reinterpret_cast<const int*>(result->GetValueBuffer());
322     }
323 
ConvertToAnimResult(AnimResult * result,const void * source)324     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
325     {
326         *reinterpret_cast<int*>(result->GetValueBuffer()) =
327             *reinterpret_cast<const int*>(source);
328         result->SetFlags(VALID_SINGLE);
329     }
330     //@}
331 };
332 
333 //---------------------------------------------------------------------------
334 //! @brief float アニメーションのブレンドオペレーションのクラスです。
335 //---------------------------------------------------------------------------
336 class AnimBlendOpFloat : public AnimBlendOp
337 {
338 public:
339     //----------------------------------------
340     //! @name コンストラクタ/デストラクタ
341     //@{
342 
343     //! コンストラクタです。
AnimBlendOpFloat()344     AnimBlendOpFloat()
345     : AnimBlendOp(true, false) {}
346 
347     //! デストラクタです。
~AnimBlendOpFloat()348     virtual ~AnimBlendOpFloat() {}
349 
350     //@}
351 
352     //----------------------------------------
353     //! @name ブレンド
354     //@{
355 
356     virtual bool Blend(
357         AnimResult* dst,
358         float* dstWeights,
359         const AnimResult* src,
360         const float* srcWeights) const;
361 
Override(AnimResult * dst,const AnimResult * src)362     virtual bool Override(AnimResult* dst, const AnimResult* src) const
363     {
364         *reinterpret_cast<float*>(dst->GetValueBuffer()) =
365             *reinterpret_cast<const float*>(src->GetValueBuffer());
366         dst->SetFlags(VALID_SINGLE);
367         return true;
368     }
369 
370     //@}
371 
372     //----------------------------------------
373     //! @name 適用
374     //@{
375 
Apply(void * target,const AnimResult * result)376     virtual void Apply(void* target, const AnimResult* result) const
377     {
378         *reinterpret_cast<float*>(target) =
379             *reinterpret_cast<const float*>(result->GetValueBuffer());
380     }
381 
ConvertToAnimResult(AnimResult * result,const void * source)382     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
383     {
384         *reinterpret_cast<float*>(result->GetValueBuffer()) =
385             *reinterpret_cast<const float*>(source);
386         result->SetFlags(VALID_SINGLE);
387     }
388     //@}
389 };
390 
391 //---------------------------------------------------------------------------
392 //! @brief Vector2 アニメーションのブレンドオペレーションのクラスです。
393 //---------------------------------------------------------------------------
394 class AnimBlendOpVector2 : public AnimBlendOp
395 {
396 public:
397     //! 成分数の定義です。
398     enum { COMP_COUNT = 2 };
399 
400     //! フラグの定義です。
401     enum { VALID_ALL = VALID_XY };
402 
403     //----------------------------------------
404     //! @name コンストラクタ/デストラクタ
405     //@{
406 
407     //! コンストラクタです。
AnimBlendOpVector2()408     AnimBlendOpVector2()
409     : AnimBlendOp(true, false) {}
410 
411     //! デストラクタです。
~AnimBlendOpVector2()412     virtual ~AnimBlendOpVector2() {}
413 
414     //@}
415 
416     //----------------------------------------
417     //! @name ブレンド
418     //@{
419 
Blend(AnimResult * dst,float * dstWeights,const AnimResult * src,const float * srcWeights)420     virtual bool Blend(
421         AnimResult* dst,
422         float* dstWeights,
423         const AnimResult* src,
424         const float* srcWeights) const
425     {
426         NW_ASSERT(src->GetFlags() & VALID_ALL);
427         (void)dstWeights;
428         return BlendFloatVector(dst, src, srcWeights[0], COMP_COUNT);
429     }
430 
Override(AnimResult * dst,const AnimResult * src)431     virtual bool Override(AnimResult* dst, const AnimResult* src) const
432     {
433         return OverrideFloatVector(dst, src, COMP_COUNT, VALID_ALL);
434     }
435 
436     //@}
437 
438     //----------------------------------------
439     //! @name 適用
440     //@{
441 
Apply(void * target,const AnimResult * result)442     virtual void Apply(void* target, const AnimResult* result) const
443     {
444         ApplyFloatVector(target, result, COMP_COUNT);
445     }
446 
ConvertToAnimResult(AnimResult * result,const void * source)447     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
448     {
449         ConvertFloatVectorToAnimResult(result, source, COMP_COUNT);
450     }
451     //@}
452 };
453 
454 //---------------------------------------------------------------------------
455 //! @brief Vector3 アニメーションのブレンドオペレーションのクラスです。
456 //---------------------------------------------------------------------------
457 class AnimBlendOpVector3 : public AnimBlendOp
458 {
459 public:
460     //! 成分数の定義です。
461     enum { COMP_COUNT = 3 };
462 
463     //! フラグの定義です。
464     enum { VALID_ALL = VALID_XYZ };
465 
466     //----------------------------------------
467     //! @name コンストラクタ/デストラクタ
468     //@{
469 
470     //! コンストラクタです。
AnimBlendOpVector3()471     AnimBlendOpVector3()
472     : AnimBlendOp(true, false) {}
473 
474     //! デストラクタです。
~AnimBlendOpVector3()475     virtual ~AnimBlendOpVector3() {}
476 
477     //@}
478 
479     //----------------------------------------
480     //! @name ブレンド
481     //@{
482 
Blend(AnimResult * dst,float * dstWeights,const AnimResult * src,const float * srcWeights)483     virtual bool Blend(
484         AnimResult* dst,
485         float* dstWeights,
486         const AnimResult* src,
487         const float* srcWeights) const
488     {
489         NW_ASSERT(src->GetFlags() & VALID_ALL);
490         (void)dstWeights;
491         return BlendFloatVector(dst, src, srcWeights[0], COMP_COUNT);
492     }
493 
Override(AnimResult * dst,const AnimResult * src)494     virtual bool Override(AnimResult* dst, const AnimResult* src) const
495     {
496         return OverrideFloatVector(dst, src, COMP_COUNT, VALID_ALL);
497     }
498 
499     //@}
500 
501     //----------------------------------------
502     //! @name 適用
503     //@{
504 
Apply(void * target,const AnimResult * result)505     virtual void Apply(void* target, const AnimResult* result) const
506     {
507         ApplyFloatVector(target, result, COMP_COUNT);
508     }
509 
ConvertToAnimResult(AnimResult * result,const void * source)510     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
511     {
512         ConvertFloatVectorToAnimResult(result, source, COMP_COUNT);
513     }
514     //@}
515 };
516 
517 //---------------------------------------------------------------------------
518 //! @brief RGBA カラーアニメーションのブレンドオペレーションのクラスです。
519 //---------------------------------------------------------------------------
520 class AnimBlendOpRgbaColor : public AnimBlendOp
521 {
522 public:
523     //! 成分数です。
524     enum { COMPONENT_COUNT = 4 };
525 
526     //----------------------------------------
527     //! @name コンストラクタ/デストラクタ
528     //@{
529 
530     //! コンストラクタです。
AnimBlendOpRgbaColor()531     AnimBlendOpRgbaColor()
532     : AnimBlendOp(true, false) {}
533 
534     //! デストラクタです。
~AnimBlendOpRgbaColor()535     virtual ~AnimBlendOpRgbaColor() {}
536 
537     //@}
538 
539     //----------------------------------------
540     //! @name ブレンド
541     //@{
542 
543     virtual bool Blend(
544         AnimResult* dst,
545         float* dstWeights,
546         const AnimResult* src,
547         const float* srcWeights) const;
548 
549     virtual bool Override(AnimResult* dst, const AnimResult* src) const;
550 
551     //@}
552 
553     //----------------------------------------
554     //! @name 適用
555     //@{
556 
557     virtual void Apply(void* target, const AnimResult* result) const;
558 
559     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const;
560     //@}
561 };
562 
563 //---------------------------------------------------------------------------
564 //! @brief テクスチャパターンアニメーションのブレンドオペレーションのクラスです。
565 //---------------------------------------------------------------------------
566 class AnimBlendOpTexture : public AnimBlendOp
567 {
568 public:
569     //----------------------------------------
570     //! @name コンストラクタ/デストラクタ
571     //@{
572 
573     //! コンストラクタです。
AnimBlendOpTexture()574     AnimBlendOpTexture()
575     : AnimBlendOp(false, false) {} // ブレンド処理なし(常に上書き)
576 
577     //! デストラクタです。
~AnimBlendOpTexture()578     virtual ~AnimBlendOpTexture() {}
579 
580     //@}
581 
582     //----------------------------------------
583     //! @name ブレンド
584     //@{
585 
Override(AnimResult * dst,const AnimResult * src)586     virtual bool Override(AnimResult* dst, const AnimResult* src) const
587     {
588         ut::Offset* dstOffset = reinterpret_cast<ut::Offset*>(dst->GetValueBuffer());
589         const ut::Offset* srcOffset = reinterpret_cast<const ut::Offset*>(src->GetValueBuffer());
590 
591         dstOffset->set_ptr(srcOffset->to_ptr());
592         dst->SetFlags(VALID_SINGLE);
593         return true;
594     }
595 
596     //@}
597 
598     //----------------------------------------
599     //! @name 適用
600     //@{
601 
Apply(void * target,const AnimResult * result)602     virtual void Apply(void* target, const AnimResult* result) const
603     {
604         ut::Offset* dstOffset = reinterpret_cast<ut::Offset*>(target);
605         const ut::Offset* srcOffset = reinterpret_cast<const ut::Offset*>(result->GetValueBuffer());
606 
607         dstOffset->set_ptr(srcOffset->to_ptr());
608     }
609 
ConvertToAnimResult(AnimResult * result,const void * source)610     virtual void ConvertToAnimResult(AnimResult* result, const void* source) const
611     {
612         ut::Offset* dstOffset = reinterpret_cast<ut::Offset*>(result->GetValueBuffer());
613         const ut::Offset* srcOffset = reinterpret_cast<const ut::Offset*>(source);
614 
615         dstOffset->set_ptr(srcOffset->to_ptr());
616         result->SetFlags(VALID_SINGLE);
617     }
618     //@}
619 };
620 
621 } /* namespace anim */
622 } /* namespace nw */
623 
624 #endif /* NW_ANIM_ANIMBLEND_H_ */
625