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