1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_TransformAnimBlendOp.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: 32420 $
16  *---------------------------------------------------------------------------*/
17 
18 #ifndef NW_GFX_TRANSFORMANIMBLENDOP_H_
19 #define NW_GFX_TRANSFORMANIMBLENDOP_H_
20 
21 #include <nw/anim/anim_AnimBlend.h>
22 
23 namespace nw {
24 namespace gfx {
25 
26 //---------------------------------------------------------------------------
27 //! @brief トランスフォームアニメーションのブレンドオペレーションの基底クラスです。
28 //---------------------------------------------------------------------------
29 class TransformAnimBlendOp : public anim::AnimBlendOp
30 {
31 public:
32     //! 無効な重み値です。
33     //!
34     //! :private
35     static const float WeightDiscard;
36 
37     //----------------------------------------
38     //! @name コンストラクタ/デストラクタ
39     //@{
40 
41     //! @brief コンストラクタです。
42     //!
43     //! @param[in] hasBlend ブレンド処理があるかどうかです。
44     //! @param[in] hasPostBlend ブレンド後の処理があるかどうかです。
45     //!
TransformAnimBlendOp(bool hasBlend,bool hasPostBlend)46     TransformAnimBlendOp(bool hasBlend, bool hasPostBlend)
47     : AnimBlendOp(hasBlend, hasPostBlend) {}
48 
49     //! デストラクタです。
~TransformAnimBlendOp()50     virtual ~TransformAnimBlendOp() {}
51 
52     //@}
53 
54 
55     //----------------------------------------
56     //! @name 適用
57     //@{
58 
59     //! @brief ブレンド処理結果を対象に適用します。
60     //!
61     //! @param[out] target ブレンド処理結果を適用する対象です。
62     //! @param[in] result ブレンド処理結果です。
63     //!
64     virtual void Apply(void* target, const anim::AnimResult* result) const;
65 
66     //! @brief 対象を AnimResult に変換します。
67     //!
68     //! @param[out] result 出力の AnimResult です。
69     //! @param[in] source 変換元へのポインタです。
70     //!
71     //! :private
72     virtual void ConvertToAnimResult(anim::AnimResult* result, const void* source) const;
73 
74     //@}
75 
76 protected:
77     //----------------------------------------
78     //! @name 基本ブレンド処理
79     //@{
80 
81     //! @details :private
82     enum BasicBlendFlags
83     {
84         FLAG_ACCURATE_SCALE_SHIFT = 0,
85         FLAG_QUATERNION_ROTATE_SHIFT = 1,
86 
87         // 正確なスケールブレンドをするかどうかです。
88         FLAG_ACCURATE_SCALE = 0x1 << FLAG_ACCURATE_SCALE_SHIFT,
89 
90         // クォータニオンで回転をブレンドするかどうかです。オフなら行列の回転成分をブレンドします。
91         FLAG_QUATERNION_ROTATE = 0x1 << FLAG_QUATERNION_ROTATE_SHIFT
92     };
93 
94     //! @brief 標準的なスケールのブレンド処理を行います。
95     //!
96     //! @param[in,out] dst ブレンド処理結果です。
97     //! @param[in] src ブレンド処理の入力です。
98     //! @param[in] weight ブレンド処理の入力の重みです。
99     //!
100     //! :private
101     void BlendScaleStandard(
102         CalculatedTransform* dst,
103         const CalculatedTransform* src,
104         const float weight) const;
105 
106     //! @brief 正確なスケールのブレンド処理を行います。
107     //!
108     //! @param[in,out] dst ブレンド処理結果です。
109     //! @param[in] src ブレンド処理の入力です。
110     //! @param[in] weight ブレンド処理の入力の重みです。
111     //!
112     //! :private
113     void BlendScaleAccurate(
114         CalculatedTransform* dst,
115         const CalculatedTransform* src,
116         const float weight) const;
117 
118     //! @brief 正確なスケールブレンドのブレンド後の処理を行います。
119     //!
120     //! :private
121     //!
122     //! @param[in,out] transform トランスフォームです。
123     //!
124     //! @return 正しく処理できれば true を返します。
125     bool PostBlendAccurateScale(CalculatedTransform* transform) const;
126 
127     //! @brief 行列の回転のブレンド処理を行います。
128     //!
129     //! @param[in,out] dst ブレンド処理結果です。
130     //! @param[in] src ブレンド処理の入力です。
131     //! @param[in] weight ブレンド処理の入力の重みです。
132     //!
133     //! :private
134     void BlendRotateMatrix(
135         CalculatedTransform* dst,
136         const CalculatedTransform* src,
137         const float weight) const;
138 
139     //! @brief クォータニオンの回転のブレンド処理を行います。
140     //!
141     //! @param[in,out] dst ブレンド処理結果です。
142     //! @param[in] src ブレンド処理の入力です。
143     //! @param[in] weight ブレンド処理の入力の重みです。
144     //!
145     //! :private
146     void BlendRotateQuaternion(
147         CalculatedTransform* dst,
148         const CalculatedTransform* src,
149         const float weight) const;
150 
151     //! @brief 移動のブレンド処理を行います。
152     //!
153     //! @param[in,out] dst ブレンド処理結果です。
154     //! @param[in] src ブレンド処理の入力です。
155     //! @param[in] weight ブレンド処理の入力の重みです。
156     //!
157     //! :private
158     void BlendTranslate(
159         CalculatedTransform* dst,
160         const CalculatedTransform* src,
161         const float weight) const;
162 
163     //! @brief トランスフォームの上書き処理を行います。
164     //!
165     //! :private
166     //!
167     //! @param[in,out] dst ブレンド処理結果です。
168     //! @param[in] src ブレンド処理の入力です。
169     //! @param[in] blendFlags ブレンド処理のフラグです。
170     //!
171     //! @return すべての成分が上書きされたら true を返します。
172     bool OverrideTransform(
173         CalculatedTransform* dst,
174         const CalculatedTransform* src,
175         const bit32 blendFlags
176     ) const;
177 
178     //@}
179 };
180 
181 //---------------------------------------------------------------------------
182 //! @brief トランスフォームアニメーションの標準的なブレンドオペレーションのクラスです。
183 //! 回転行列の各成分をブレンドした後に、正規直交化します。
184 //---------------------------------------------------------------------------
185 class TransformAnimBlendOpStandard : public TransformAnimBlendOp
186 {
187 public:
188     //----------------------------------------
189     //! @name コンストラクタ/デストラクタ
190     //@{
191 
192     //! コンストラクタです。
TransformAnimBlendOpStandard()193     TransformAnimBlendOpStandard()
194     : TransformAnimBlendOp(true, true)
195     {}
196 
197     //! デストラクタです。
~TransformAnimBlendOpStandard()198     virtual ~TransformAnimBlendOpStandard() {}
199 
200     //@}
201 
202     //----------------------------------------
203     //! @name ブレンド
204     //@{
205 
206     //! @brief ブレンド処理を行います。
207     //!
208     //! @param[in,out] dst ブレンド処理結果です。
209     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
210     //! このブレンドオペレーションでは使用しません。
211     //! @param[in] src ブレンド処理の入力です。
212     //! @param[in] srcWeights ブレンド処理の入力の重みです。
213     //!
214     //! @return ブレンド処理のループを継続するなら true を返します。
215     //!
Blend(anim::AnimResult * dst,float * dstWeights,const anim::AnimResult * src,const float * srcWeights)216     virtual bool Blend(
217         anim::AnimResult* dst,
218         float* dstWeights,
219         const anim::AnimResult* src,
220         const float* srcWeights) const
221     {
222         (void)dstWeights;
223         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
224         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
225         BlendScaleStandard(dstX, srcX, srcWeights[0]);
226         BlendRotateMatrix (dstX, srcX, srcWeights[1]);
227         BlendTranslate    (dstX, srcX, srcWeights[2]);
228         return true;
229     }
230 
231     //! @brief ブレンド後の処理を行います。
232     //!
233     //! @param[in,out] result ブレンド処理結果です。
234     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
235     //! このブレンドオペレーションでは使用しません。
236     //!
237     //! @return 成功すれば true を返します。
238     //!
PostBlend(anim::AnimResult * result,const float * weights)239     virtual bool PostBlend(anim::AnimResult* result, const float* weights) const
240     {
241         (void)weights;
242         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(result);
243         return dstX->NormalizeRotateMatrix();
244     }
245 
246     //! @brief 上書き処理を行います。
247     //!
248     //! @param[in,out] dst ブレンド処理結果です。
249     //! @param[in] src ブレンド処理の入力です。
250     //!
251     //! @return すべての成分が上書きされたら true を返します。
252     //!
Override(anim::AnimResult * dst,const anim::AnimResult * src)253     virtual bool Override(anim::AnimResult* dst, const anim::AnimResult* src) const
254     {
255         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
256         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
257         return OverrideTransform(dstX, srcX, 0);
258     }
259 
260     //@}
261 };
262 
263 //---------------------------------------------------------------------------
264 //! @brief トランスフォームアニメーションの正確なスケールブレンドに対応したブレンドオペレーションのクラスです。
265 //---------------------------------------------------------------------------
266 class TransformAnimBlendOpAccScale : public TransformAnimBlendOp
267 {
268 public:
269     //----------------------------------------
270     //! @name コンストラクタ/デストラクタ
271     //@{
272 
273     //! コンストラクタです。
TransformAnimBlendOpAccScale()274     TransformAnimBlendOpAccScale()
275     : TransformAnimBlendOp(true, true)
276     {}
277 
278     //! デストラクタです。
~TransformAnimBlendOpAccScale()279     virtual ~TransformAnimBlendOpAccScale() {}
280 
281     //@}
282 
283     //----------------------------------------
284     //! @name ブレンド
285     //@{
286 
287     //! @brief ブレンド処理を行います。
288     //!
289     //! @param[in,out] dst ブレンド処理結果です。
290     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
291     //! このブレンドオペレーションでは使用しません。
292     //! @param[in] src ブレンド処理の入力です。
293     //! @param[in] srcWeights ブレンド処理の入力の重みです。
294     //!
295     //! @return ブレンド処理のループを継続するなら true を返します。
296     //!
Blend(anim::AnimResult * dst,float * dstWeights,const anim::AnimResult * src,const float * srcWeights)297     virtual bool Blend(
298         anim::AnimResult* dst,
299         float* dstWeights,
300         const anim::AnimResult* src,
301         const float* srcWeights) const
302     {
303         (void)dstWeights;
304         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
305         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
306         BlendScaleAccurate(dstX, srcX, srcWeights[0]);
307         BlendRotateMatrix (dstX, srcX, srcWeights[1]);
308         BlendTranslate    (dstX, srcX, srcWeights[2]);
309         return true;
310     }
311 
312     //! @brief ブレンド後の処理を行います。
313     //!
314     //! @param[in,out] result ブレンド処理結果です。
315     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
316     //! このブレンドオペレーションでは使用しません。
317     //!
318     //! @return 成功すれば true を返します。
319     //!
PostBlend(anim::AnimResult * result,const float * weights)320     virtual bool PostBlend(anim::AnimResult* result, const float* weights) const
321     {
322         (void)weights;
323         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(result);
324         const bool scaleRet = PostBlendAccurateScale(dstX);
325         return dstX->NormalizeRotateMatrix() && scaleRet;
326     }
327 
328     //! @brief 上書き処理を行います。
329     //!
330     //! @param[in,out] dst ブレンド処理結果です。
331     //! @param[in] src ブレンド処理の入力です。
332     //!
333     //! @return すべての成分が上書きされたら true を返します。
334     //!
Override(anim::AnimResult * dst,const anim::AnimResult * src)335     virtual bool Override(anim::AnimResult* dst, const anim::AnimResult* src) const
336     {
337         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
338         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
339         return OverrideTransform(dstX, srcX, FLAG_ACCURATE_SCALE);
340     }
341 
342     //@}
343 };
344 
345 //---------------------------------------------------------------------------
346 //! @brief トランスフォームアニメーションのクォータニオンによる回転ブレンドに対応したブレンドオペレーションのクラスです。
347 //---------------------------------------------------------------------------
348 class TransformAnimBlendOpQuat : public TransformAnimBlendOp
349 {
350 public:
351     //----------------------------------------
352     //! @name コンストラクタ/デストラクタ
353     //@{
354 
355     //! コンストラクタです。
TransformAnimBlendOpQuat()356     TransformAnimBlendOpQuat()
357     : TransformAnimBlendOp(true, true)
358     {}
359 
360     //! デストラクタです。
~TransformAnimBlendOpQuat()361     virtual ~TransformAnimBlendOpQuat() {}
362 
363     //@}
364 
365     //----------------------------------------
366     //! @name ブレンド
367     //@{
368 
369     //! @brief ブレンド処理を行います。
370     //!
371     //! @param[in,out] dst ブレンド処理結果です。
372     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
373     //! このブレンドオペレーションでは使用しません。
374     //! @param[in] src ブレンド処理の入力です。
375     //! @param[in] srcWeights ブレンド処理の入力の重みです。
376     //!
377     //! @return ブレンド処理のループを継続するなら true を返します。
378     //!
Blend(anim::AnimResult * dst,float * dstWeights,const anim::AnimResult * src,const float * srcWeights)379     virtual bool Blend(
380         anim::AnimResult* dst,
381         float* dstWeights,
382         const anim::AnimResult* src,
383         const float* srcWeights) const
384     {
385         (void)dstWeights;
386         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
387         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
388         BlendScaleStandard   (dstX, srcX, srcWeights[0]);
389         BlendRotateQuaternion(dstX, srcX, srcWeights[1]);
390         BlendTranslate       (dstX, srcX, srcWeights[2]);
391         return true;
392     }
393 
394     //! @brief ブレンド後の処理を行います。
395     //!
396     //! @param[in,out] result ブレンド処理結果です。
397     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
398     //! このブレンドオペレーションでは使用しません。
399     //!
400     //! @return 成功すれば true を返します。
401     //!
PostBlend(anim::AnimResult * result,const float * weights)402     virtual bool PostBlend(anim::AnimResult* result, const float* weights) const
403     {
404         (void)weights;
405         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(result);
406         return dstX->QuaternionToRotateMatrix();
407     }
408 
409     //! @brief 上書き処理を行います。
410     //!
411     //! @param[in,out] dst ブレンド処理結果です。
412     //! @param[in] src ブレンド処理の入力です。
413     //!
414     //! @return すべての成分が上書きされたら true を返します。
415     //!
Override(anim::AnimResult * dst,const anim::AnimResult * src)416     virtual bool Override(anim::AnimResult* dst, const anim::AnimResult* src) const
417     {
418         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
419         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
420         return OverrideTransform(dstX, srcX, FLAG_QUATERNION_ROTATE);
421     }
422 
423     //@}
424 };
425 
426 //---------------------------------------------------------------------------
427 //! @brief トランスフォームアニメーションの正確なスケールブレンドとクォータニオンによる回転ブレンドに対応したブレンドオペレーションのクラスです。
428 //---------------------------------------------------------------------------
429 class TransformAnimBlendOpAccScaleQuat : public TransformAnimBlendOp
430 {
431 public:
432     //----------------------------------------
433     //! @name コンストラクタ/デストラクタ
434     //@{
435 
436     //! コンストラクタです。
TransformAnimBlendOpAccScaleQuat()437     TransformAnimBlendOpAccScaleQuat()
438     : TransformAnimBlendOp(true, true)
439     {}
440 
441     //! デストラクタです。
~TransformAnimBlendOpAccScaleQuat()442     virtual ~TransformAnimBlendOpAccScaleQuat() {}
443 
444     //@}
445 
446     //----------------------------------------
447     //! @name ブレンド
448     //@{
449 
450     //! @brief ブレンド処理を行います。
451     //!
452     //! @param[in,out] dst ブレンド処理結果です。
453     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
454     //! このブレンドオペレーションでは使用しません。
455     //! @param[in] src ブレンド処理の入力です。
456     //! @param[in] srcWeights ブレンド処理の入力の重みです。
457     //!
458     //! @return ブレンド処理のループを継続するなら true を返します。
459     //!
Blend(anim::AnimResult * dst,float * dstWeights,const anim::AnimResult * src,const float * srcWeights)460     virtual bool Blend(
461         anim::AnimResult* dst,
462         float* dstWeights,
463         const anim::AnimResult* src,
464         const float* srcWeights) const
465     {
466         (void)dstWeights;
467         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
468         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
469         BlendScaleAccurate   (dstX, srcX, srcWeights[0]);
470         BlendRotateQuaternion(dstX, srcX, srcWeights[1]);
471         BlendTranslate       (dstX, srcX, srcWeights[2]);
472         return true;
473     }
474 
475     //! @brief ブレンド後の処理を行います。
476     //!
477     //! @param[in,out] result ブレンド処理結果です。
478     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
479     //! このブレンドオペレーションでは使用しません。
480     //!
481     //! @return 成功すれば true を返します。
482     //!
PostBlend(anim::AnimResult * result,const float * weights)483     virtual bool PostBlend(anim::AnimResult* result, const float* weights) const
484     {
485         (void)weights;
486         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(result);
487         const bool scaleRet = PostBlendAccurateScale(dstX);
488         return dstX->QuaternionToRotateMatrix() && scaleRet;
489     }
490 
491     //! @brief 上書き処理を行います。
492     //!
493     //! @param[in,out] dst ブレンド処理結果です。
494     //! @param[in] src ブレンド処理の入力です。
495     //!
496     //! @return すべての成分が上書きされたら true を返します。
497     //!
Override(anim::AnimResult * dst,const anim::AnimResult * src)498     virtual bool Override(anim::AnimResult* dst, const anim::AnimResult* src) const
499     {
500         CalculatedTransform* dstX = reinterpret_cast<CalculatedTransform*>(dst);
501         const CalculatedTransform* srcX = reinterpret_cast<const CalculatedTransform*>(src);
502         return OverrideTransform(dstX, srcX, FLAG_ACCURATE_SCALE | FLAG_QUATERNION_ROTATE);
503     }
504 
505     //@}
506 };
507 
508 //---------------------------------------------------------------------------
509 //! @brief スケルタルアニメーションではない、トランスフォームノードのアニメーションのためのブレンドオペレーションです。
510 //---------------------------------------------------------------------------
511 class AnimBlendOpTransform : public TransformAnimBlendOp
512 {
513 public:
514     //----------------------------------------
515     //! @name コンストラクタ/デストラクタ
516     //@{
517 
518     //! コンストラクタです。
AnimBlendOpTransform()519     AnimBlendOpTransform()
520         : TransformAnimBlendOp(true, true)
521     {}
522 
523     //! デストラクタです。
~AnimBlendOpTransform()524     virtual ~AnimBlendOpTransform() {}
525 
526     //@}
527 
528     //----------------------------------------
529     //! @name ブレンド
530     //@{
531 
532     //! @brief ブレンド処理を行います。
533     //!        必要なフラグ設定などを行い、処理を TransformAnimBlendOpStandard にゆだねます。
534     //!
535     //! @param[in,out] dst ブレンド処理結果です。
536     //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。
537     //! このブレンドオペレーションでは使用しません。
538     //! @param[in] src ブレンド処理の入力です。
539     //! @param[in] srcWeight ブレンド処理の入力の重みです。
540     //!
541     //! @return ブレンド処理のループを継続するなら true を返します。
542     //!
Blend(anim::AnimResult * dst,float * dstWeights,const anim::AnimResult * src,const float * srcWeight)543     virtual bool Blend(
544         anim::AnimResult* dst,
545         float* dstWeights,
546         const anim::AnimResult* src,
547         const float* srcWeight) const
548     {
549         NW_NULL_ASSERT(dst);
550         NW_NULL_ASSERT(src);
551         NW_NULL_ASSERT(srcWeight);
552 
553         // TransformAnimIntepolator が FLAG_IS_IGNORE_ALL を立てるのと同じことを
554         // 初回ブレンドのみここで行なう。
555         if (!dst->IsEnabledFlags(VALID_SINGLE))
556         {
557             CalculatedTransform* transform =
558                 reinterpret_cast<CalculatedTransform*>(dst->GetValueBuffer());
559             transform->EnableFlags(CalculatedTransform::FLAG_IS_IGNORE_ALL);
560 
561             // VALID_SINGLE を使うのは AnimBlendOpFloat::Blend() などにあわせている。
562             dst->EnableFlags(VALID_SINGLE);
563         }
564 
565         // 重みを配列にする。
566         float srcWeights[3] = { *srcWeight, *srcWeight, *srcWeight };
567 
568         return blendOp.Blend(
569             reinterpret_cast<anim::AnimResult*>(dst->GetValueBuffer()),
570             dstWeights,
571             reinterpret_cast<const anim::AnimResult*>(src->GetValueBuffer()),
572             srcWeights);
573     }
574 
575     //! @brief ブレンド後の処理を行います。
576     //!
577     //! @param[in,out] result ブレンド処理結果です。
578     //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。
579     //! このブレンドオペレーションでは使用しません。
580     //!
581     //! @return 成功すれば true を返します。
582     //!
PostBlend(anim::AnimResult * result,const float * weight)583     virtual bool PostBlend(anim::AnimResult* result, const float* weight) const
584     {
585         NW_NULL_ASSERT(result);
586 
587         CalculatedTransform* transform =
588             reinterpret_cast<CalculatedTransform*>(result->GetValueBuffer());
589 
590         bool resultBlend;
591         // TransformAnimBlendOpStandard::PostBlend() では weights を使用しないので、
592         // weight が指定されているかどうかにかかわらず NULL を渡す。
593 #if 0
594         if (weight)
595         {
596             float weights[3] = { *weight, *weight, *weight };
597             resultBlend= blendOp.PostBlend(
598                 reinterpret_cast<anim::AnimResult*>(transform),
599                 weights);
600         }
601         else
602 #endif
603         {
604             NW_UNUSED_VARIABLE(weight);
605             resultBlend= blendOp.PostBlend(
606                 reinterpret_cast<anim::AnimResult*>(transform),
607                 NULL);
608         }
609 
610         // フラグ更新を行なう。
611         // TODO: TransformAnimInterpolator と同じようなフラグ更新の方法に変更する。
612         transform->UpdateScaleFlags();
613         transform->UpdateRotateFlags();
614         transform->UpdateTranslateFlags();
615         transform->UpdateCompositeFlags();
616 
617         transform->EnableFlags(CalculatedTransform::FLAG_IS_DIRTY);
618 
619         // このフラグを立てないと TransformNode::UpdateTransform() で計算が行なわれない。
620         transform->EnableFlags(CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
621 
622         return resultBlend;
623     }
624 
625     //! @brief 上書き処理を行います。
626     //!
627     //! @param[in,out] dst ブレンド処理結果です。
628     //! @param[in] src ブレンド処理の入力です。
629     //!
630     //! @return すべての成分が上書きされたら true を返します。
631     //!
Override(anim::AnimResult * dst,const anim::AnimResult * src)632     virtual bool Override(anim::AnimResult* dst, const anim::AnimResult* src) const
633     {
634         // transformを取得
635         CalculatedTransform* transform =
636             reinterpret_cast<CalculatedTransform*>(dst->GetValueBuffer());
637 
638         // TransformAnimIntepolator が FLAG_IS_IGNORE_ALL を立てるのと同じことを
639         // 初回ブレンドのみここで行なう。
640         if (!dst->IsEnabledFlags(VALID_SINGLE))
641         {
642             transform->EnableFlags(CalculatedTransform::FLAG_IS_IGNORE_ALL);
643 
644             // VALID_SINGLE を使うのは AnimBlendOpFloat::Blend() などにあわせている。
645             dst->EnableFlags(VALID_SINGLE);
646         }
647 
648         bool result = blendOp.Override(
649             reinterpret_cast<anim::AnimResult*>(dst->GetValueBuffer()),
650             reinterpret_cast<const anim::AnimResult*>(src->GetValueBuffer()));
651 
652         // 全ての成分が上書きされない時のことを考慮し、
653         // BlendOpの中からは、すべてのブレンドが終わったタイミングは分からないので毎回フラグをたてる。
654         transform->UpdateScaleFlags();
655         transform->UpdateRotateFlags();
656         transform->UpdateTranslateFlags();
657         transform->UpdateCompositeFlags();
658 
659         // blendと同様にTransformMatrixが変更されたフラグを立てる
660         transform->EnableFlags(CalculatedTransform::FLAG_IS_DIRTY);
661         // このフラグを立てないと TransformNode::UpdateTransform() で計算が行なわれない。
662         transform->EnableFlags(CalculatedTransform::FLAG_IS_WORLDMATRIX_CALCULATION_ENABLED);
663 
664         return result;
665     }
666 
667 private:
668 
669     // 処理を委ねる BlendOperation の実体
670     TransformAnimBlendOpStandard blendOp;
671 };
672 
673 } // namespace gfx
674 } // namespace nw
675 
676 #endif // NW_GFX_TRANSFORMANIMBLENDOP_H_
677