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