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