1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     anim_ResAnimCurve.cpp
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: $
16  *---------------------------------------------------------------------------*/
17 
18 #include "../precompiled.h"
19 
20 #include <nw/anim/res/anim_ResAnimCurve.h>
21 #include <nw/anim/res/anim_ResAnim.h>
22 #include <nw/anim/res/anim_ResAnimGroup.h>
23 
24 #include <cmath>
25 #include <nw/math/math_Arithmetic.h>
26 
27 namespace nw {
28 namespace anim {
29 namespace res {
30 
31 namespace {
32 
33     /*!--------------------------------------------------------------------------*
34       @brief        キー形式毎の特性の定義です。
35      *---------------------------------------------------------------------------*/
36     template <typename T>
37     class ResAnimTraits;
38 
39     // ResAnimTraits の扱うフレーム数は、すべてセグメントの先頭を 0 としたものです。
40     //---------------------------------------------------------------------------
41     // QuantizedFrame
42     // 対象セグメントの量子化パラメータでフレーム数を量子化します。
43     //---------------------------------------------------------------------------
44     //---------------------------------------------------------------------------
45     // GetFrame
46     // キーのフレーム数を量子化されたまま返します。
47     //---------------------------------------------------------------------------
48     //---------------------------------------------------------------------------
49     // GetFrameF32
50     // キーのフレーム数をデコードして返します。
51     //---------------------------------------------------------------------------
52 
53     template <>
54     class ResAnimTraits<ResFloatKeyFV64Data>
55     {
56     public:
57         typedef ResFloatKeyFV64Data KeyType;
58         typedef f32                 FrameType;
59 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)60         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
61             { return &(pSegment->fv64.m_KeyValue[ keyIdx ]); }
62 
QuantizedFrame(const ResFloatSegmentFVData *,f32 frame)63         static FrameType QuantizedFrame( const ResFloatSegmentFVData*, f32 frame ) { return frame; }
GetFrame(const KeyType * pKey)64         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData *,const KeyType * pKey)65         static f32       GetFrameF32( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->GetFrameF32(); }
GetValue(const ResFloatSegmentFVData *,const KeyType * pKey)66         static f32       GetValue( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->GetValue(); }
67     };
68 
69     template <>
70     class ResAnimTraits<ResFloatKeyFV32Data>
71     {
72     public:
73         typedef ResFloatKeyFV32Data KeyType;
74         typedef u32                 FrameType;
75 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)76         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
77             { return &(pSegment->fv32.m_KeyValue[ keyIdx ]); }
78 
QuantizedFrame(const ResFloatSegmentFVData * pSegment,f32 frame)79         static FrameType QuantizedFrame( const ResFloatSegmentFVData* pSegment, f32 frame )
80             {
81                 f32 decoded = frame / pSegment->fv32.m_FrameScale;
82                 return FrameType(internal::Round(decoded));
83             }
GetFrame(const KeyType * pKey)84         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)85         static f32       GetFrameF32( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
86             {
87                 f32 frame = pKey->GetFrameF32();
88                 return frame * pSegment->fv32.m_FrameScale;
89             }
GetValue(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)90         static f32       GetValue( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
91             {
92                 f32 value = pKey->GetValue();
93                 return value * pSegment->fv32.m_Scale + pSegment->fv32.m_Offset;
94             }
95     };
96 
97     template <>
98     class ResAnimTraits<ResFloatKeyFVSS128Data>
99     {
100     public:
101         typedef ResFloatKeyFVSS128Data KeyType;
102         typedef f32                    FrameType;
103 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)104         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
105             { return &(pSegment->fvss128.m_KeyValue[ keyIdx ]); }
106 
QuantizedFrame(const ResFloatSegmentFVData *,f32 frame)107         static FrameType QuantizedFrame( const ResFloatSegmentFVData*, f32 frame ) { return frame; }
GetFrame(const KeyType * pKey)108         static FrameType GetFrame( const KeyType* pKey ) { return pKey->m_Frame; }
GetFrameF32(const ResFloatSegmentFVData *,const KeyType * pKey)109         static f32       GetFrameF32( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->m_Frame; }
GetValue(const ResFloatSegmentFVData *,const KeyType * pKey)110         static f32       GetValue( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->m_Value; }
GetInSlope(const KeyType * pKey)111         static f32       GetInSlope( const KeyType* pKey ) { return pKey->m_InSlope; }
GetOutSlope(const KeyType * pKey)112         static f32       GetOutSlope( const KeyType* pKey ) { return pKey->m_OutSlope; }
113     };
114 
115     template <>
116     class ResAnimTraits<ResFloatKeyFVSS64Data>
117     {
118     public:
119         typedef ResFloatKeyFVSS64Data KeyType;
120         typedef u32                   FrameType;
121 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)122         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
123             { return &(pSegment->fvss64.m_KeyValue[ keyIdx ]); }
124 
QuantizedFrame(const ResFloatSegmentFVData * pSegment,f32 frame)125         static FrameType QuantizedFrame( const ResFloatSegmentFVData* pSegment, f32 frame )
126             {
127                 f32 decoded = frame / pSegment->fvss64.m_FrameScale;
128                 return FrameType(internal::Round(decoded));
129             }
GetFrame(const KeyType * pKey)130         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)131         static f32       GetFrameF32( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
132             {
133                 f32 frame = pKey->GetFrameF32();
134                 return frame * pSegment->fvss64.m_FrameScale;
135             }
GetValue(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)136         static f32       GetValue( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
137             {
138                 f32 value = pKey->GetValue();
139                 return value * pSegment->fvss64.m_Scale + pSegment->fvss64.m_Offset;
140             }
GetInSlope(const KeyType * pKey)141         static f32       GetInSlope( const KeyType* pKey ) { return pKey->GetInSlope(); }
GetOutSlope(const KeyType * pKey)142         static f32       GetOutSlope( const KeyType* pKey ) { return pKey->GetOutSlope(); }
143     };
144 
145     template <>
146     class ResAnimTraits<ResFloatKeyFVSS48Data>
147     {
148     public:
149         typedef ResFloatKeyFVSS48Data KeyType;
150         typedef u32                  FrameType;
151 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)152         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
153             { return &(pSegment->fvss48.m_KeyValue[ keyIdx ]); }
154 
QuantizedFrame(const ResFloatSegmentFVData * pSegment,f32 frame)155         static FrameType QuantizedFrame( const ResFloatSegmentFVData* pSegment, f32 frame )
156             {
157                 f32 decoded = frame / pSegment->fvss48.m_FrameScale;
158                 return FrameType(internal::Round(decoded));
159             }
GetFrame(const KeyType * pKey)160         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)161         static f32       GetFrameF32( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
162             {
163                 f32 frame = pKey->GetFrameF32();
164                 return frame * pSegment->fvss48.m_FrameScale;
165             }
GetValue(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)166         static f32       GetValue( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
167             {
168                 f32 value = pKey->GetValue();
169                 return value * pSegment->fvss48.m_Scale + pSegment->fvss48.m_Offset;
170             }
GetInSlope(const KeyType * pKey)171         static f32       GetInSlope( const KeyType* pKey ) { return pKey->GetInSlope(); }
GetOutSlope(const KeyType * pKey)172         static f32       GetOutSlope( const KeyType* pKey ) { return pKey->GetOutSlope(); }
173     };
174 
175 
176     template <>
177     class ResAnimTraits<ResFloatKeyFVS96Data>
178     {
179     public:
180         typedef ResFloatKeyFVS96Data KeyType;
181         typedef f32                  FrameType;
182 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)183         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
184             { return &(pSegment->fvs96.m_KeyValue[ keyIdx ]); }
185 
QuantizedFrame(const ResFloatSegmentFVData *,f32 frame)186         static FrameType QuantizedFrame( const ResFloatSegmentFVData*, f32 frame ) { return frame; }
GetFrame(const KeyType * pKey)187         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData *,const KeyType * pKey)188         static f32       GetFrameF32( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->GetFrameF32(); }
GetValue(const ResFloatSegmentFVData *,const KeyType * pKey)189         static f32       GetValue( const ResFloatSegmentFVData*, const KeyType* pKey ) { return pKey->GetValue(); }
GetSlope(const KeyType * pKey)190         static f32       GetSlope( const KeyType* pKey ) { return pKey->GetSlope(); }
191     };
192 
193     template <>
194     class ResAnimTraits<ResFloatKeyFVS48Data>
195     {
196     public:
197         typedef ResFloatKeyFVS48Data  KeyType;
198         typedef u32                   FrameType;
199 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)200         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
201             { return &(pSegment->fvs48.m_KeyValue[ keyIdx ]); }
202 
QuantizedFrame(const ResFloatSegmentFVData * pSegment,f32 frame)203         static FrameType QuantizedFrame( const ResFloatSegmentFVData* pSegment, f32 frame )
204             {
205                 f32 decoded = frame / pSegment->fvs48.m_FrameScale;
206                 return internal::CastF32ToS10_5(decoded);
207             }
GetFrame(const KeyType * pKey)208         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)209         static f32       GetFrameF32( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
210             {
211                 f32 frame = pKey->GetFrameF32();
212                 return frame * pSegment->fvs48.m_FrameScale;
213             }
GetValue(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)214         static f32       GetValue( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
215             {
216                 f32 value = pKey->GetValue();
217                 return value * pSegment->fvs48.m_Scale + pSegment->fvs48.m_Offset;
218             }
GetSlope(const KeyType * pKey)219         static f32       GetSlope( const KeyType* pKey ) { return pKey->GetSlope(); }
220     };
221 
222     template <>
223     class ResAnimTraits<ResFloatKeyFVS32Data>
224     {
225     public:
226         typedef ResFloatKeyFVS32Data KeyType;
227         typedef u32                  FrameType;
228 
GetKey(const ResFloatSegmentFVData * pSegment,uint keyIdx)229         static const KeyType*   GetKey( const ResFloatSegmentFVData* pSegment, uint keyIdx )
230             { return &(pSegment->fvs32.m_KeyValue[ keyIdx ]); }
231 
QuantizedFrame(const ResFloatSegmentFVData * pSegment,f32 frame)232         static FrameType QuantizedFrame( const ResFloatSegmentFVData* pSegment, f32 frame )
233             {
234                 f32 decoded = frame / pSegment->fvs32.m_FrameScale;
235                 return FrameType(internal::Round(decoded));
236             }
GetFrame(const KeyType * pKey)237         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)238         static f32       GetFrameF32( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
239             {
240                 f32 frame = pKey->GetFrameF32();
241                 return frame * pSegment->fvs32.m_FrameScale;
242             }
GetValue(const ResFloatSegmentFVData * pSegment,const KeyType * pKey)243         static f32       GetValue( const ResFloatSegmentFVData* pSegment, const KeyType* pKey )
244             {
245                 f32 value = f32(pKey->m_ValueSlope[0] + ((pKey->m_ValueSlope[1] & 0x0F) << 8) );
246                 return value * pSegment->fvs32.m_Scale + pSegment->fvs32.m_Offset;
247             }
GetSlope(const KeyType * pKey)248         static f32       GetSlope( const KeyType* pKey ) { return pKey->GetSlope(); }
249     };
250 
251 
252     template <>
253     class ResAnimTraits<ResIntKeyFV64Data>
254     {
255     public:
256         typedef ResIntKeyFV64Data KeyType;
257         typedef f32               FrameType;
258 
GetKey(const ResIntCurveFVData * pCurve,uint keyIdx)259         static const KeyType*   GetKey( const ResIntCurveFVData* pCurve, uint keyIdx )
260             { return &(pCurve->fv64.m_KeyValue[ keyIdx ]); }
261 
QuantizedFrame(const ResIntCurveFVData *,f32 frame)262         static FrameType QuantizedFrame( const ResIntCurveFVData*, f32 frame ) { return frame; }
GetFrame(const KeyType * pKey)263         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResIntCurveFVData *,const KeyType * pKey)264         static f32       GetFrameF32( const ResIntCurveFVData*, const KeyType* pKey ) { return pKey->GetFrameF32(); }
GetValue(const ResIntCurveFVData *,const KeyType * pKey)265         static s32       GetValue( const ResIntCurveFVData*, const KeyType* pKey ) { return pKey->GetValue(); }
266     };
267 
268     template <>
269     class ResAnimTraits<ResIntKeyFV32Data>
270     {
271     public:
272         typedef ResIntKeyFV32Data KeyType;
273         typedef u32               FrameType;
274 
GetKey(const ResIntCurveFVData * pCurve,uint keyIdx)275         static const KeyType*   GetKey( const ResIntCurveFVData* pCurve, uint keyIdx )
276             { return &(pCurve->fv32.m_KeyValue[ keyIdx ]); }
277 
QuantizedFrame(const ResIntCurveFVData *,f32 frame)278         static FrameType QuantizedFrame( const ResIntCurveFVData*, f32 frame ) { return u32(frame); }
GetFrame(const KeyType * pKey)279         static FrameType GetFrame( const KeyType* pKey ) { return pKey->GetFrame(); }
GetFrameF32(const ResIntCurveFVData *,const KeyType * pKey)280         static f32       GetFrameF32( const ResIntCurveFVData*, const KeyType* pKey ) { return pKey->GetFrameF32(); }
GetValue(const ResIntCurveFVData *,const KeyType * pKey)281         static s32       GetValue( const ResIntCurveFVData* /*pCurve*/, const KeyType* pKey )
282             {
283                 return pKey->GetValue();
284             }
285     };
286 
287 
288     template <>
289     class ResAnimTraits<ResIntKeyFV16Data>
290     {
291     public:
292         typedef ResIntKeyFV16Data KeyType;
293         typedef u32               FrameType;
294 
GetKey(const ResIntCurveFVData * pCurve,uint keyIdx)295         static const KeyType*   GetKey( const ResIntCurveFVData* pCurve, uint keyIdx )
296             { return &(pCurve->fv16.m_KeyValue[ keyIdx ]); }
297 
QuantizedFrame(const ResIntCurveFVData *,f32 frame)298         static FrameType QuantizedFrame( const ResIntCurveFVData*, f32 frame ) { return u32(frame); }
GetFrame(const KeyType * pKey)299         static FrameType GetFrame( const KeyType* pKey ) { return u32(pKey->m_Frame); }
GetFrameF32(const ResIntCurveFVData *,const KeyType * pKey)300         static f32       GetFrameF32( const ResIntCurveFVData*, const KeyType* pKey ) { return f32( GetFrame( pKey ) ); }
GetValue(const ResIntCurveFVData *,const KeyType * pKey)301         static s32       GetValue( const ResIntCurveFVData* /*pCurve*/, const KeyType* pKey )
302             {
303                 return s32(pKey->m_Value);
304             }
305     };
306 
307     typedef f32 (*NormalizeFrameFunc)( f32 frame, f32 startFrame, f32 endFrame );
308 
309     f32
NormalizeFrameNonePre_(f32 frame,f32 startFrame,f32)310     NormalizeFrameNonePre_( f32 frame, f32 startFrame, f32 /* endFrame */ )
311     {
312         return (frame < startFrame) ? startFrame : frame;
313     }
314 
315     f32
NormalizeFrameNonePost_(f32 frame,f32,f32 endFrame)316     NormalizeFrameNonePost_( f32 frame, f32 /*startFrame*/, f32 endFrame )
317     {
318         return (frame > endFrame) ? endFrame : frame;
319     }
320 
321     f32
NormalizeFrameRepeatPre_(f32 frame,f32 startFrame,f32 endFrame)322     NormalizeFrameRepeatPre_( f32 frame, f32 startFrame, f32 endFrame )
323     {
324         f32 duration = endFrame - startFrame;
325 
326         s32 cnt = static_cast<s32>(std::floor( (frame - startFrame) / duration ));
327         frame -= cnt * duration;
328 
329         return frame;
330     }
331 
332     f32
NormalizeFrameRepeatPost_(f32 frame,f32 startFrame,f32 endFrame)333     NormalizeFrameRepeatPost_( f32 frame, f32 startFrame, f32 endFrame )
334     {
335         f32 duration = endFrame - startFrame;
336 
337         s32 cnt = static_cast<s32>(std::floor( (frame - startFrame) / duration ));
338         frame -= cnt * duration;
339 
340         return frame;
341     }
342 
343     f32
NormalizeFrameMirrorPre_(f32 frame,f32 startFrame,f32 endFrame)344     NormalizeFrameMirrorPre_( f32 frame, f32 startFrame, f32 endFrame )
345     {
346         bool needsReverse = false;
347         f32 duration = endFrame - startFrame;
348 
349         s32 cnt = static_cast<s32>(std::floor( (frame - startFrame) / duration ));
350         frame -= cnt * duration;
351         needsReverse = (cnt & 1)? true : false;
352 
353         return needsReverse ? startFrame + endFrame - frame : frame;
354     }
355 
356     f32
NormalizeFrameMirrorPost_(f32 frame,f32 startFrame,f32 endFrame)357     NormalizeFrameMirrorPost_( f32 frame, f32 startFrame, f32 endFrame )
358     {
359         bool needsReverse = false;
360         f32 duration = endFrame - startFrame;
361 
362         s32 cnt = static_cast<s32>(std::floor( (frame - startFrame) / duration ));
363         frame -= cnt * duration;
364         needsReverse = (cnt & 1)? true : false;
365 
366         return needsReverse ? startFrame + endFrame - frame : frame;
367     }
368 
369     /*!--------------------------------------------------------------------------*
370       @brief        フレームを正規化します。
371 
372       @param[in]    frame   正規化するフレームです。
373       @param[in]    pCurve  アニメーションデータへのポインタです。
374 
375       @return
376      *---------------------------------------------------------------------------*/
NormalizeFrame_(f32 frame,const ResAnimCurveData * pCurve)377     f32 NormalizeFrame_( f32 frame, const ResAnimCurveData* pCurve )
378     {
379         static const NormalizeFrameFunc preRepeatMethod[] =
380         {
381             NormalizeFrameNonePre_,
382             NormalizeFrameRepeatPre_,
383             NormalizeFrameMirrorPre_,
384         };
385 
386         static const NormalizeFrameFunc postRepeatMethod[] =
387         {
388             NormalizeFrameNonePost_,
389             NormalizeFrameRepeatPost_,
390             NormalizeFrameMirrorPost_,
391         };
392 
393         NW_ASSERT( pCurve->m_InRepeatMethod < ResAnimCurveData::METHOD_NUM );
394         NW_ASSERT( pCurve->m_OutRepeatMethod < ResAnimCurveData::METHOD_NUM );
395 
396         if ( frame < pCurve->m_StartFrame )
397         {
398             return preRepeatMethod[ pCurve->m_InRepeatMethod ]( frame, pCurve->m_StartFrame, pCurve->m_EndFrame );
399         }
400 
401         // リピート時に、EndFrame と等しいフレームは、StartFrame と同じものとして扱うので、
402         // 終端の判定のみ if の判定条件にイコールを入れている。
403         if ( frame >= pCurve->m_EndFrame )
404         {
405             return postRepeatMethod[ pCurve->m_OutRepeatMethod ]( frame, pCurve->m_StartFrame, pCurve->m_EndFrame );
406         }
407 
408         return frame;
409     }
410 
411     /*!--------------------------------------------------------------------------*
412       @brief        指定されたフレーム以下の最大のキーフレームを検索して返します。
413 
414       @param[in]    pSegment キーを検索するセグメントです。
415       @param[in]    frame    キーを検索するフレーム数です。セグメントの先頭を 0 とします。
416 
417       @return       キーフレームです。
418      *---------------------------------------------------------------------------*/
419     template <typename Traits, typename Segment>
420     const typename Traits::KeyType*
GetKeyFV_(const Segment * pSegment,f32 frame)421     GetKeyFV_( const Segment* pSegment, f32 frame )
422     {
423         // この関数内での“フレーム”はセグメントの先頭を 0 としたフレーム数
424 
425         typename Traits::FrameType quantizedFrame = Traits::QuantizedFrame( pSegment, frame );
426 
427         // 先頭のキーより前の場合は特別扱い
428         // 先頭のフレームに複数のキーがある場合、それより前のフレームでは最初のキーを選択する
429         const typename Traits::KeyType* pFirstKey = Traits::GetKey(pSegment, 0);
430         if ( quantizedFrame < Traits::GetFrame( pFirstKey ) )
431         {
432             return pFirstKey;
433         }
434 
435         // 末尾のキーを超える場合は特別扱い
436         const typename Traits::KeyType* pLastKey = Traits::GetKey(pSegment, pSegment->m_NumFrameValues - 1);
437         if ( Traits::GetFrame( pLastKey ) <= quantizedFrame )
438         {
439             return pLastKey;
440         }
441 
442         // キーが等幅で打たれていると仮定して、キーの位置を推測する。
443         uint keyIdx = static_cast<uint>( frame * pSegment->m_InvDuration * (pSegment->m_NumFrameValues - 1) );
444         NW_ASSERT( keyIdx <= pSegment->m_NumFrameValues - 1U );
445 
446         const typename Traits::KeyType* pKey = Traits::GetKey(pSegment, keyIdx);
447 
448         // 推測位置から線形探索
449         if ( quantizedFrame < Traits::GetFrame( pKey ) )
450         {
451             do
452             {
453                 NW_ASSERT( Traits::GetKey(pSegment, 0) < pKey );
454                 --pKey;
455             } while ( quantizedFrame < Traits::GetFrame( pKey ) );
456         }
457         else
458         {
459             do
460             {
461                 NW_ASSERT( pKey < Traits::GetKey(pSegment, pSegment->m_NumFrameValues - 1) );
462                 ++pKey;
463             } while ( Traits::GetFrame( pKey ) <= quantizedFrame );
464 
465             // ここにきた時点で1つ通り過ぎている
466             NW_ASSERT( Traits::GetKey(pSegment, 0) < pKey );
467             --pKey;
468         }
469 
470         return pKey;
471     }
472 
473     /*!--------------------------------------------------------------------------*
474       @brief        指定されたフレームに相当するセグメントを返します。
475 
476       @param[in]    pCurve  セグメントを検索するセグメントカーブです。
477       @param[in]    frame   セグメントを検索するフレーム数です。
478 
479       @return       カーブの中から対象となるセグメントを検索します。
480      *---------------------------------------------------------------------------*/
481     NW_INLINE const ResFloatSegmentData*
GetFloatSegment_(const ResSegmentFloatCurveData * pCurve,f32 frame)482     GetFloatSegment_( const ResSegmentFloatCurveData* pCurve, f32 frame )
483     {
484         NW_NULL_ASSERT( pCurve );
485         NW_ASSERT( pCurve->m_StartFrame <= frame && frame <= pCurve->m_EndFrame );
486 
487         // 単一セグメントである場合は唯一のセグメントを返します。
488         if ( pCurve->m_Flags & ResSegmentFloatCurveData::FLAG_MONO_SEGMENT )
489         {
490             return reinterpret_cast<const ResFloatSegmentData*>( pCurve->segmentsTable.toSegments[0].to_ptr() );
491         }
492 
493         s32 segmentCount = pCurve->segmentsTable.m_NumSegments;
494 
495         NW_ASSERT( segmentCount > 0 );
496 
497         const ut::Offset* pOffsetTable = &(pCurve->segmentsTable.toSegments[0]);
498 
499         for ( const ut::Offset* pOffset = pOffsetTable; pOffset < pOffsetTable + segmentCount; ++pOffset )
500         {
501             const ResFloatSegmentData* pSegment = reinterpret_cast<const ResFloatSegmentData*>( pOffset->to_ptr() );
502 
503             if ( pSegment->m_EndFrame > frame )
504             {
505                 return pSegment;
506             }
507         }
508 
509         return reinterpret_cast<const ResFloatSegmentData*>( pOffsetTable[ segmentCount - 1 ].to_ptr() );
510     }
511 
512     template <typename Traits>
513     const typename Traits::KeyType*
GetFloatKeyFV_(const ResFloatSegmentFVData * pSegment,f32 frame)514     GetFloatKeyFV_( const ResFloatSegmentFVData* pSegment, f32 frame )
515     {
516         // frame はセグメント先頭を 0 としたフレーム数
517         return GetKeyFV_<Traits, ResFloatSegmentFVData>( pSegment, frame );
518     }
519 
520 
521     template <typename Traits>
522     f32
CalcStepFloatSegmentFV_(const ResFloatSegmentFVData * pSegment,f32 frame)523     CalcStepFloatSegmentFV_( const ResFloatSegmentFVData* pSegment, f32 frame )
524     {
525         // frame はセグメント先頭を 0 としたフレーム数
526         const typename Traits::KeyType* pKey = GetFloatKeyFV_<Traits>( pSegment, frame );
527 
528         return Traits::GetValue( pSegment, pKey );
529     }
530 
531 
532     template <typename Traits>
533     f32
CalcLinearFloatSegmentFV_(const ResFloatSegmentFVData * pSegment,f32 frame)534     CalcLinearFloatSegmentFV_( const ResFloatSegmentFVData* pSegment, f32 frame )
535     {
536         // frame はセグメント先頭を 0 としたフレーム数
537         const typename Traits::KeyType* pKey = GetFloatKeyFV_<Traits>( pSegment, frame );
538         const typename Traits::KeyType* pLastKey = Traits::GetKey(pSegment, pSegment->m_NumFrameValues - 1);
539 
540         f32 keyFrame = Traits::GetFrameF32( pSegment, pKey );
541 
542         if ( keyFrame == frame || pKey == pLastKey )
543         {
544             return Traits::GetValue( pSegment, pKey );
545         }
546 
547         const typename Traits::KeyType* pNextKey = pKey + 1;
548 
549         f32 nextKeyFrame = Traits::GetFrameF32( pSegment, pNextKey );
550         f32 rate = (frame - keyFrame) / (nextKeyFrame - keyFrame);
551 
552         return Traits::GetValue( pSegment, pKey ) * (1.0f - rate)
553                + Traits::GetValue( pSegment, pNextKey ) * rate;
554     }
555 
556     template <typename Traits>
557     f32
CalcHermiteFloatSegmentFVSS_(const ResFloatSegmentFVData * pSegment,f32 frame)558     CalcHermiteFloatSegmentFVSS_( const ResFloatSegmentFVData* pSegment, f32 frame )
559     {
560         // frame はセグメント先頭を 0 としたフレーム数
561         const typename Traits::KeyType* pKey = GetFloatKeyFV_<Traits>( pSegment, frame );
562         const typename Traits::KeyType* pLastKey = Traits::GetKey(pSegment, pSegment->m_NumFrameValues - 1);
563 
564         f32 keyFrame = Traits::GetFrameF32( pSegment, pKey );
565 
566         if ( keyFrame == frame || pKey == pLastKey )
567         {
568             return Traits::GetValue( pSegment, pKey );
569         }
570 
571         const typename Traits::KeyType* pNextKey = pKey + 1;
572 
573         f32 p  = frame - keyFrame;
574         f32 d  = Traits::GetFrameF32( pSegment, pNextKey ) - keyFrame;
575         f32 v0 = Traits::GetValue( pSegment, pKey );
576         f32 v1 = Traits::GetValue( pSegment, pNextKey );
577         f32 t0 = Traits::GetOutSlope( pKey );
578         f32 t1 = Traits::GetInSlope( pNextKey );
579 
580         return nw::math::Hermite( v0, t0, v1, t1, p, d );
581     }
582 
583     template <typename Traits>
584     f32
CalcHermiteFloatSegmentFVS_(const ResFloatSegmentFVData * pSegment,f32 frame)585     CalcHermiteFloatSegmentFVS_( const ResFloatSegmentFVData* pSegment, f32 frame )
586     {
587         // frame はセグメント先頭を 0 としたフレーム数
588         const typename Traits::KeyType* pKey = GetFloatKeyFV_<Traits>( pSegment, frame );
589         const typename Traits::KeyType* pLastKey = Traits::GetKey(pSegment, pSegment->m_NumFrameValues - 1);
590 
591         // UNDONE: 同じフレームにキーが複数存在する場合の対処が必要。
592 
593         f32 keyFrame = Traits::GetFrameF32( pSegment, pKey );
594 
595         if ( keyFrame == frame || pKey == pLastKey )
596         {
597             return Traits::GetValue( pSegment, pKey );
598         }
599 
600         const typename Traits::KeyType* pNextKey = pKey + 1;
601 
602         f32 p  = frame - keyFrame;
603         f32 d  = Traits::GetFrameF32( pSegment, pNextKey ) - keyFrame;
604         f32 v0 = Traits::GetValue( pSegment, pKey );
605         f32 v1 = Traits::GetValue( pSegment, pNextKey );
606         f32 t0 = Traits::GetSlope( pKey );
607         f32 t1 = Traits::GetSlope( pNextKey );
608 
609         return nw::math::Hermite( v0, t0, v1, t1, p, d );
610     }
611 
612     typedef f32 (*CalcFloatSegmentFVFunc)( const ResFloatSegmentFVData* pSegment, f32 frame );
613 
614     static CalcFloatSegmentFVFunc s_CalcFloatSegmentFVTable[][8] =
615     {
616         {
617             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS128Data> >,
618             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS64Data> >,
619             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS48Data> >,
620             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS96Data> >,
621             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS48Data> >,
622             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS32Data> >,
623             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFV64Data> >,
624             CalcStepFloatSegmentFV_< ResAnimTraits<ResFloatKeyFV32Data> >,
625         },
626         {
627             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS128Data> >,
628             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS64Data> >,
629             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVSS48Data> >,
630             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS96Data> >,
631             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS48Data> >,
632             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFVS32Data> >,
633             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFV64Data> >,
634             CalcLinearFloatSegmentFV_< ResAnimTraits<ResFloatKeyFV32Data> >,
635         },
636         {
637             CalcHermiteFloatSegmentFVSS_< ResAnimTraits<ResFloatKeyFVSS128Data> >,
638             CalcHermiteFloatSegmentFVSS_< ResAnimTraits<ResFloatKeyFVSS64Data> >,
639             CalcHermiteFloatSegmentFVSS_< ResAnimTraits<ResFloatKeyFVSS48Data> >,
640             CalcHermiteFloatSegmentFVS_< ResAnimTraits<ResFloatKeyFVS96Data> >,
641             CalcHermiteFloatSegmentFVS_< ResAnimTraits<ResFloatKeyFVS48Data> >,
642             CalcHermiteFloatSegmentFVS_< ResAnimTraits<ResFloatKeyFVS32Data> >,
643             NULL,
644             NULL,
645         }
646     };
647 
648 
649     template <typename Traits>
650     const typename Traits::KeyType*
GetIntKeyFV_(const ResIntCurveFVData * pCurve,f32 frame)651     GetIntKeyFV_( const ResIntCurveFVData* pCurve, f32 frame )
652     {
653         return GetKeyFV_<Traits, ResIntCurveFVData>( pCurve, frame );
654     }
655 
656 
657     template <typename Traits>
658     s32
CalcIntCurveFV_(const ResIntCurveFVData * pCurve,f32 frame)659     CalcIntCurveFV_( const ResIntCurveFVData* pCurve, f32 frame )
660     {
661         const typename Traits::KeyType* pKey = GetIntKeyFV_<Traits>( pCurve, frame );
662 
663         return Traits::GetValue( pCurve, pKey );
664     }
665 
666     typedef s32 (*CalcIntCurveFVFunc)( const ResIntCurveFVData* pCurve, f32 frame );
667 
668     static CalcIntCurveFVFunc s_CalcIntCurveFVTable[] =
669     {
670         CalcIntCurveFV_< ResAnimTraits<ResIntKeyFV64Data> >,
671         CalcIntCurveFV_< ResAnimTraits<ResIntKeyFV32Data> >,
672         CalcIntCurveFV_< ResAnimTraits<ResIntKeyFV16Data> >,
673     };
674 
675 
676     NW_INLINE f32
CalcFloatSegment_(const ResFloatSegmentData * pSegment,f32 frame)677     CalcFloatSegment_( const ResFloatSegmentData* pSegment, f32 frame )
678     {
679         NW_NULL_ASSERT( pSegment );
680         NW_ASSERT( pSegment->m_StartFrame <= frame && frame <= pSegment->m_EndFrame );
681         NW_ASSERT(!(pSegment->m_Flags & ResFloatSegmentData::FLAG_BAKED));
682 
683         if ( pSegment->m_Flags & ResFloatSegmentData::FLAG_CONSTANT )
684         {
685             return pSegment->constantValue;
686         }
687 
688         u32 quantizeType = (pSegment->m_Flags & ResFloatSegmentData::FLAG_QUANTIZATION_TYPE_MASK) >>
689             ResFloatSegmentData::FLAG_QUANTIZATION_TYPE_SHIFT;
690 
691         u32 interporateMode = (pSegment->m_Flags & ResFloatSegmentData::FLAG_INTERPORATE_MODE_MASK) >>
692                                   ResFloatSegmentData::FLAG_INTERPORATE_MODE_SHIFT;
693 
694         return s_CalcFloatSegmentFVTable[ interporateMode ][ quantizeType ]( &(pSegment->fv), frame - pSegment->m_StartFrame );
695     }
696 
697 
698     NW_INLINE f32
CalcSegmentFloatCurve_(const ResSegmentFloatCurveData * pCurve,f32 frame)699     CalcSegmentFloatCurve_( const ResSegmentFloatCurveData* pCurve, f32 frame )
700     {
701         NW_NULL_ASSERT( pCurve );
702         NW_ASSERT( pCurve->m_StartFrame <= frame && frame <= pCurve->m_EndFrame );
703 
704         if ( pCurve->m_Flags & ResSegmentFloatCurveData::FLAG_CONSTANT )
705         {
706             return pCurve->m_ConstantValue;
707         }
708 
709         const ResFloatSegmentData* pSegment = GetFloatSegment_( pCurve, frame );
710 
711         if ( frame < pSegment->m_StartFrame )
712         {
713             // 量子化の影響で、セグメント間に隙間があいてしまうことがあるため
714             frame = pSegment->m_StartFrame;
715         }
716 
717         return CalcFloatSegment_( pSegment, frame );
718     }
719 
720 
721     NW_INLINE f32
CalcCompositeFloatCurve_(const ResCompositeFloatCurveData * pCurve,f32 frame)722     CalcCompositeFloatCurve_( const ResCompositeFloatCurveData* pCurve, f32 frame )
723     {
724         const ResFloatCurveData* pLeftCurve =
725             reinterpret_cast<const ResFloatCurveData*>( pCurve->toLeftCurve.to_ptr() );
726         const ResFloatCurveData* pRightCurve =
727             reinterpret_cast<const ResFloatCurveData*>( pCurve->toRightCurve.to_ptr() );
728 
729         f32 leftValue  = CalcFloatCurve( pLeftCurve, frame );
730         f32 rightValue = CalcFloatCurve( pRightCurve, frame );
731 
732         // UNDONE: CompositeCurve には未対応。 bool curve の乗算をしていない。
733 
734         return leftValue + rightValue;
735     }
736 
737 
738 
739     bool
CalcBoolCurveCV_(const ResBoolCurveData * pCurve,f32 frame)740     CalcBoolCurveCV_( const ResBoolCurveData* pCurve, f32 frame )
741     {
742         NW_ASSERT( pCurve->m_StartFrame <= frame && frame <= pCurve->m_EndFrame );
743 
744         float frameOffset = frame - pCurve->m_StartFrame;
745 
746         // EndFrameが小数の場合に、PostInfinityを正しく計算する
747         if (frame == pCurve->m_EndFrame)
748         {
749             frameOffset = math::FCeil(frameOffset);
750         }
751 
752         u32 index = u32(frameOffset) / 8;
753         u32 shift = u32(frameOffset) % 8;
754 
755         return ( (pCurve->cv.m_KeyValue[ index ] >> shift) & 0x1) != 0;
756     }
757 
758 
759     void
CalcVector3CurveCV_(math::VEC3 * result,bit32 * flags,const ResVector3CurveData * pCurve,f32 frame)760     CalcVector3CurveCV_( math::VEC3* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame )
761     {
762         u32 index = u32(frame);
763         f32 remainder = frame - index;
764         const ResVector3CurveData::FrameValue& frameValue = pCurve->frames.m_KeyValue[index];
765 
766         if ( remainder == 0 )
767         {
768             // 整数フレーム
769             *result = frameValue.cv;
770             *flags |= frameValue.flag;
771         }
772         else if ( frame == pCurve->m_EndFrame )
773         {
774             // 最終フレームが小数のときの特殊処理
775 
776             // 小数フレームの場合は一つ手前の整数フレームのコマを引くが、
777             // 最終フレームに限っては次のコマにその値が保存してある。
778             u32 lastIndex = index + 1;
779 
780             const ResVector3CurveData::FrameValue& lastFrameValue = pCurve->frames.m_KeyValue[lastIndex];
781             *result = lastFrameValue.cv;
782             *flags |= lastFrameValue.flag;
783         }
784         else
785         {
786             // 小数フレーム
787             f32 nextFrame = NormalizeFrame_( frame + 1.0f, pCurve );
788             u32 nextIndex = u32(nextFrame);
789             const ResVector3CurveData::FrameValue& nextFrameValue = pCurve->frames.m_KeyValue[nextIndex];
790 
791             VEC3Lerp(
792                 result,
793                 static_cast<const math::VEC3*>(&frameValue.cv),
794                 static_cast<const math::VEC3*>(&nextFrameValue.cv),
795                 remainder );
796 
797             // 補間の両端でフラグが立っているなら、補間後も立っているはず
798             // 両端で立たず、2点の間のどこかで立つことはありうるが、その1フレームだけ軽くなってもメリットは薄そう
799             // それより、平均的な処理負荷を下げるためシンプルな実装にする
800             *flags |= (frameValue.flag & nextFrameValue.flag);
801         }
802     }
803 
804     void
CalcRotateCurveCV_(math::MTX34 * result,bit32 * flags,const ResVector4CurveData * pCurve,f32 frame)805     CalcRotateCurveCV_( math::MTX34* result, bit32* flags, const ResVector4CurveData* pCurve, f32 frame )
806     {
807         u32 index = u32(frame);
808         f32 remainder = frame - index;
809         const ResVector4CurveData::FrameValue& frameValue = pCurve->frames.m_KeyValue[index];
810 
811         math::MTX34 mtx;
812 
813         if ( remainder == 0 )
814         {
815             // 整数フレーム
816 
817             // クォータニオンを用意
818             math::QUAT quaternion(frameValue.cv);
819             // クォータニオンから回転行列を生成する
820             math::QUATToMTX34(&mtx, &quaternion);
821 
822             *flags |= frameValue.flag;
823         }
824         else if ( frame == pCurve->m_EndFrame )
825         {
826             // 最終フレームが小数のときの特殊処理
827 
828             // 小数フレームの場合は一つ手前の整数フレームのコマを引くが、
829             // 最終フレームに限っては次のコマにその値が保存してある。
830             u32 lastIndex = index + 1;
831 
832             const ResVector4CurveData::FrameValue& lastFrameValue = pCurve->frames.m_KeyValue[lastIndex];
833             math::QUAT quaternion(lastFrameValue.cv);
834             math::QUATToMTX34(&mtx, &quaternion);
835             *flags |= lastFrameValue.flag;
836         }
837         else
838         {
839             // 小数フレーム
840             f32 nextFrame = NormalizeFrame_( frame + 1.0f, pCurve );
841             u32 nextIndex = u32(nextFrame);
842             const ResVector4CurveData::FrameValue& nextFrameValue = pCurve->frames.m_KeyValue[nextIndex];
843 
844             // クォータニオンを用意
845             math::QUAT lerpResult;
846             math::QUAT q1(frameValue.cv);
847             math::QUAT q2(nextFrameValue.cv);
848 
849             // 補間してから回転行列を生成する
850             math::QUATLerp(&lerpResult, &q1, &q2, remainder);
851             math::QUATToMTX34(&mtx, &lerpResult);
852 
853             // 意図はCalcVector3CurveCV_のコメントを参照
854             *flags |= (frameValue.flag & nextFrameValue.flag);
855         }
856 
857         // Mtx34の4列目はTranslateの値が入るので、
858         // Rotateのカーブ評価であるこの関数ではあえて上書きを行わない。
859         result->f._00 = mtx.f._00;
860         result->f._01 = mtx.f._01;
861         result->f._02 = mtx.f._02;
862         //result->f._03 = 0.0f;
863         result->f._10 = mtx.f._10;
864         result->f._11 = mtx.f._11;
865         result->f._12 = mtx.f._12;
866         //result->f._13 = 0.0f;
867         result->f._20 = mtx.f._20;
868         result->f._21 = mtx.f._21;
869         result->f._22 = mtx.f._22;
870         //result->f._23 = 0.0f;
871     }
872 
873 
CalcTranslateCurveCV_(math::MTX34 * result,bit32 * flags,const ResVector3CurveData * pCurve,f32 frame)874     void CalcTranslateCurveCV_( math::MTX34* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame )
875     {
876         u32 index = u32(frame);
877         f32 remainder = frame - index;
878         const ResVector3CurveData::FrameValue& frameValue = pCurve->frames.m_KeyValue[index];
879 
880         if ( remainder == 0 )
881         {
882             // 整数フレーム
883             result->f._03 = frameValue.cv.x;
884             result->f._13 = frameValue.cv.y;
885             result->f._23 = frameValue.cv.z;
886 
887             *flags |= frameValue.flag;
888         }
889         else if ( frame == pCurve->m_EndFrame )
890         {
891             // 最終フレームが小数のときの特殊処理
892 
893             // 小数フレームの場合は一つ手前の整数フレームのコマを引くが、
894             // 最終フレームに限っては次のコマにその値が保存してある。
895             u32 lastIndex = index + 1;
896 
897             const ResVector3CurveData::FrameValue& lastFrameValue = pCurve->frames.m_KeyValue[lastIndex];
898             result->f._03 = lastFrameValue.cv.x;
899             result->f._13 = lastFrameValue.cv.y;
900             result->f._23 = lastFrameValue.cv.z;
901             *flags |= lastFrameValue.flag;
902         }
903         else
904         {
905             // 小数フレーム
906             f32 nextFrame = NormalizeFrame_( frame + 1.0f, pCurve );
907             u32 nextIndex = u32(nextFrame);
908             const ResVector3CurveData::FrameValue& nextFrameValue = pCurve->frames.m_KeyValue[nextIndex];
909 
910             math::VEC3 v;
911             VEC3Lerp(
912                 &v,
913                 static_cast<const math::VEC3*>(&frameValue.cv),
914                 static_cast<const math::VEC3*>(&nextFrameValue.cv),
915                 remainder );
916 
917             result->f._03 = v.x;
918             result->f._13 = v.y;
919             result->f._23 = v.z;
920 
921             // 意図はCalcVector3CurveCV_のコメントを参照
922             *flags |= (frameValue.flag & nextFrameValue.flag);
923         }
924     }
925 } // namespace
926 
927 f32
CalcFloatCurve(const ResFloatCurveData * pCurve,f32 frame)928 CalcFloatCurve( const ResFloatCurveData* pCurve, f32 frame )
929 {
930     NW_NULL_ASSERT( pCurve );
931 
932     frame = NormalizeFrame_( frame, pCurve );
933 
934     if ( pCurve->m_Flags & ResFloatCurveData::FLAG_COMPOSITE_CURVE )
935     {
936         return CalcCompositeFloatCurve_( reinterpret_cast<const ResCompositeFloatCurveData*>( pCurve ), frame );
937     }
938     else
939     {
940         return CalcSegmentFloatCurve_( reinterpret_cast<const ResSegmentFloatCurveData*>( pCurve ), frame );
941     }
942 }
943 
944 
945 s32
CalcIntCurve(const ResIntCurveData * pCurve,f32 frame)946 CalcIntCurve( const ResIntCurveData* pCurve, f32 frame )
947 {
948     NW_NULL_ASSERT( pCurve );
949     NW_ASSERT(!(pCurve->m_Flags & ResIntCurveData::FLAG_BAKED));
950 
951     frame = NormalizeFrame_( frame, pCurve );
952 
953     if ( pCurve->m_Flags & ResIntCurveData::FLAG_CONSTANT )
954     {
955         return pCurve->constantValue;
956     }
957 
958     u32 quantizedType = (pCurve->m_Flags & ResIntCurveData::FLAG_QUANTIZATION_TYPE_MASK) >>
959                         ResIntCurveData::FLAG_QUANTIZATION_TYPE_SHIFT;
960 
961     return s_CalcIntCurveFVTable[ quantizedType ]( &(pCurve->fv), frame );
962 }
963 
964 
965 bool
CalcBoolCurve(const ResBoolCurveData * pCurve,f32 frame)966 CalcBoolCurve( const ResBoolCurveData* pCurve, f32 frame )
967 {
968     NW_NULL_ASSERT( pCurve );
969 
970     frame = NormalizeFrame_( frame, pCurve );
971 
972     if ( pCurve->m_Flags & ResBoolCurveData::FLAG_CONSTANT )
973     {
974         return ((pCurve->m_Flags & ResBoolCurveData::FLAG_CONSTANT_VALUE) != 0);
975     }
976 
977     if ( pCurve->m_Flags & ResBoolCurveData::FLAG_BAKED )
978     {
979         return CalcBoolCurveCV_( pCurve, frame );
980     }
981     else
982     {
983         u32 quantizedType = (pCurve->m_Flags & ResBoolCurveData::FLAG_QUANTIZATION_TYPE_MASK) >>
984                             ResBoolCurveData::FLAG_QUANTIZATION_TYPE_SHIFT;
985 
986         return  (s_CalcIntCurveFVTable[ quantizedType ]( &(pCurve->fv), frame ) != 0);
987     }
988 }
989 
990 
991 void
CalcVector3Curve(math::VEC3 * result,bit32 * flags,const ResVector3CurveData * pCurve,f32 frame)992 CalcVector3Curve( math::VEC3* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame )
993 {
994     NW_NULL_ASSERT( pCurve );
995 
996     if ( pCurve->m_Flags & ResVector3CurveData::FLAG_CONSTANT )
997     {
998         // コンスタントの場合は最初のフレームの値を使用する
999         frame = pCurve->m_StartFrame;
1000     }
1001     else
1002     {
1003         frame = NormalizeFrame_( frame, pCurve );
1004     }
1005 
1006     // TODO: 量子化対応
1007     CalcVector3CurveCV_( result, flags, pCurve, frame );
1008 }
1009 
1010 
1011 /*!--------------------------------------------------------------------------*
1012   @brief ベイクされたRotateのカーブ評価です。カーブはVector4ですが、書き込み先はMtx34です。
1013  *---------------------------------------------------------------------------*/
CalcRotateCurve(math::MTX34 * result,bit32 * flags,const ResVector4CurveData * pCurve,f32 frame)1014 void CalcRotateCurve(math::MTX34* result, bit32* flags, const ResVector4CurveData* pCurve, f32 frame)
1015 {
1016     NW_NULL_ASSERT( pCurve );
1017 
1018     frame = NormalizeFrame_( frame, pCurve );
1019 
1020     if ( pCurve->m_Flags & ResVector4CurveData::FLAG_CONSTANT )
1021     {
1022         // コンスタントの場合は最初のフレームの値を使用する
1023         frame = pCurve->m_StartFrame;
1024     }
1025 
1026     // TODO: 量子化対応
1027     CalcRotateCurveCV_( result, flags, pCurve, frame );
1028 }
1029 
1030 
1031 /*!--------------------------------------------------------------------------*
1032   @brief ベイクされたTranslateのカーブ評価です。カーブはVector3ですが、書き込み先はMtx34です。
1033  *---------------------------------------------------------------------------*/
CalcTranslateCurve(math::MTX34 * result,bit32 * flags,const ResVector3CurveData * pCurve,f32 frame)1034 void CalcTranslateCurve(math::MTX34* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame)
1035 {
1036     NW_NULL_ASSERT( pCurve );
1037 
1038     if ( pCurve->m_Flags & ResVector3CurveData::FLAG_CONSTANT )
1039     {
1040         // コンスタントの場合は最初のフレームの値を使用する
1041         frame = pCurve->m_StartFrame;
1042     }
1043     else
1044     {
1045         frame = NormalizeFrame_( frame, pCurve );
1046     }
1047 
1048     // TODO: 量子化対応
1049     CalcTranslateCurveCV_( result, flags, pCurve, frame );
1050 }
1051 
1052 
1053 void
CalcTransformCurve(math::MTX34 * result,const ResFullBakedCurveData * pCurve,f32 frame)1054 CalcTransformCurve( math::MTX34* result, const ResFullBakedCurveData* pCurve, f32 frame )
1055 {
1056     NW_NULL_ASSERT( pCurve );
1057 
1058     frame = NormalizeFrame_( frame, pCurve );
1059     u32 index = u32(frame);
1060 
1061     // 最終フレームが小数の場合に対応する
1062     if (frame == pCurve->m_EndFrame)
1063     {
1064         // 「最後の整数フレームのコマ」の一つ先に、EndFrameのときの結果がベイクされている
1065         index += 1;
1066     }
1067 
1068     MTX34Copy(
1069         result,
1070         static_cast<const math::MTX34*>(&pCurve->frames.m_KeyValue[index]) );
1071 }
1072 
1073 } /* namespace res */
1074 } /* namespace anim */
1075 } /* namespace nw */
1076 
1077