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