1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: anim_ResAnimCurve.h 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 #ifndef NW_ANIM_RESANIMATIONCURVE_H_ 17 #define NW_ANIM_RESANIMATIONCURVE_H_ 18 19 #include <nw/types.h> 20 21 namespace nw { 22 namespace anim { 23 namespace res { 24 25 namespace internal { 26 NW_INLINE f32 Round(f32 value)27 Round( f32 value ) 28 { 29 return nn::math::FFloor(value + 0.5f); 30 } 31 32 NW_INLINE f32 CastS9_10ToF32(s32 value)33 CastS9_10ToF32( s32 value ) 34 { 35 return f32(value) * (1.f / 1024.f); 36 } 37 38 NW_INLINE s32 CastF32ToS9_10(f32 value)39 CastF32ToS9_10( f32 value ) 40 { 41 return s32(Round(value * 1024.f)); 42 } 43 44 NW_INLINE f32 CastS7_8ToF32(s32 value)45 CastS7_8ToF32( s32 value ) 46 { 47 return f32(value) * (1.f / 256.f); 48 } 49 50 NW_INLINE s32 CastF32ToS7_8(f32 value)51 CastF32ToS7_8( f32 value ) 52 { 53 return s32(Round(value * 256.f)); 54 } 55 56 NW_INLINE f32 CastS10_5ToF32(s32 value)57 CastS10_5ToF32( s32 value ) 58 { 59 return f32(value) * (1.f / 32.f); 60 } 61 62 NW_INLINE s32 CastF32ToS10_5(f32 value)63 CastF32ToS10_5( f32 value ) 64 { 65 return s32(Round(value * 32.f)); 66 } 67 68 NW_INLINE f32 CastS6_5ToF32(s32 value)69 CastS6_5ToF32( s32 value ) 70 { 71 return f32(value) * (1.f / 32.f); 72 } 73 74 NW_INLINE s32 CastF32ToS6_5(f32 value)75 CastF32ToS6_5( f32 value ) 76 { 77 return s32(Round(value * 32.f)); 78 } 79 } /* namespace internal */ 80 81 // TODO: 量子化のビット数は仮のものです。 82 83 //! @details :private 84 struct ResFloatKeyFV64Data 85 { 86 ut::ResF32 m_Frame; 87 ut::ResF32 m_Value; 88 GetFrameResFloatKeyFV64Data89 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFV64Data90 f32 GetFrameF32() const { return m_Frame; } GetValueResFloatKeyFV64Data91 f32 GetValue() const { return m_Value; } 92 }; 93 94 //! @details :private 95 struct ResFloatKeyFV32Data 96 { 97 ut::ResU32 m_FrameValue; // u12 m_Frame; u20 m_Value * scale + offset; 98 GetFrameResFloatKeyFV32Data99 u32 GetFrame() const { return m_FrameValue & 0x00000FFF; } GetFrameF32ResFloatKeyFV32Data100 f32 GetFrameF32() const { return static_cast<f32>(this->GetFrame()); } GetValueResFloatKeyFV32Data101 f32 GetValue() const { return static_cast<f32>(m_FrameValue >> 12); } 102 }; 103 104 //! @details :private 105 struct ResFloatKeyFVSS128Data 106 { 107 ut::ResF32 m_Frame; 108 ut::ResF32 m_Value; 109 ut::ResF32 m_InSlope; 110 ut::ResF32 m_OutSlope; 111 GetFrameResFloatKeyFVSS128Data112 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVSS128Data113 f32 GetFrameF32() const { return m_Frame; } GetValueResFloatKeyFVSS128Data114 f32 GetValue() const { return m_Value; } GetInSlopeResFloatKeyFVSS128Data115 f32 GetInSlope() const { return m_InSlope; } GetOutSlopeResFloatKeyFVSS128Data116 f32 GetOutSlope() const { return m_OutSlope; } 117 }; 118 119 //! @details :private 120 struct ResFloatKeyFVSS64Data 121 { 122 ut::ResU32 m_FrameValue; // u12 m_Frame; u20 m_Value * scale + offset; 123 ut::ResS16 m_InSlope; // fx7.8 124 ut::ResS16 m_OutSlope; // fx7.8 125 GetFrameResFloatKeyFVSS64Data126 u32 GetFrame() const { return m_FrameValue & 0x00000FFF; } GetFrameF32ResFloatKeyFVSS64Data127 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVSS64Data128 f32 GetValue() const { return static_cast<f32>( m_FrameValue >> 12 ); } GetInSlopeResFloatKeyFVSS64Data129 f32 GetInSlope() const { return internal::CastS7_8ToF32(m_InSlope); } GetOutSlopeResFloatKeyFVSS64Data130 f32 GetOutSlope() const { return internal::CastS7_8ToF32(m_OutSlope); } 131 }; 132 133 //! @details :private 134 struct ResFloatKeyFVSS48Data 135 { 136 ut::ResU8 m_FrameValue[3]; // u8 m_Frame; u16 m_Value * scale + offset; 137 ut::ResU8 m_InOutSlope[3]; // fx6.5 m_InSlope; fx6.5 m_OutSlope; 138 GetFrameResFloatKeyFVSS48Data139 u32 GetFrame() const { return m_FrameValue[0]; } GetFrameF32ResFloatKeyFVSS48Data140 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVSS48Data141 f32 GetValue() const { return static_cast<f32>( u16(m_FrameValue[1]) + (u16(m_FrameValue[2]) << 8) ); } GetInSlopeResFloatKeyFVSS48Data142 f32 GetInSlope() const { return internal::CastS6_5ToF32( s16(m_InOutSlope[0] + (s8(m_InOutSlope[1] << 4) << 4)) ); } GetOutSlopeResFloatKeyFVSS48Data143 f32 GetOutSlope() const { return internal::CastS6_5ToF32( s16((s8(m_InOutSlope[2]) << 4) + (m_InOutSlope[1] >> 4)) ); } 144 }; 145 146 //! @details :private 147 struct ResFloatKeyFVS96Data 148 { 149 ut::ResF32 m_Frame; 150 ut::ResF32 m_Value; 151 ut::ResF32 m_Slope; 152 GetFrameResFloatKeyFVS96Data153 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS96Data154 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVS96Data155 f32 GetValue() const { return m_Value; } GetSlopeResFloatKeyFVS96Data156 f32 GetSlope() const { return m_Slope; } 157 }; 158 159 //! @details :private 160 struct ResFloatKeyFVS48Data 161 { 162 ut::ResU16 m_Frame; // fx10.5 163 ut::ResU16 m_Value; // m_Value * scale + offset 164 ut::ResS16 m_Slope; // fx7.8 165 GetFrameResFloatKeyFVS48Data166 u32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS48Data167 f32 GetFrameF32() const { return internal::CastS10_5ToF32( m_Frame ); } GetValueResFloatKeyFVS48Data168 f32 GetValue() const { return static_cast<f32>( m_Value ); } GetSlopeResFloatKeyFVS48Data169 f32 GetSlope() const { return internal::CastS7_8ToF32(m_Slope); } 170 }; 171 172 //! @details :private 173 struct ResFloatKeyFVS32Data 174 { 175 ut::ResU8 m_Frame; // u8 176 ut::ResU8 m_ValueSlope[3]; // u12 m_Value * scale + offset; fx6.5 m_Slope; 177 GetFrameResFloatKeyFVS32Data178 u32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS32Data179 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVS32Data180 f32 GetValue() const { return static_cast<f32>( u16(m_ValueSlope[0]) + (u16(m_ValueSlope[1] << 4) << 4) ); } GetSlopeResFloatKeyFVS32Data181 f32 GetSlope() const { return internal::CastS6_5ToF32((s8(m_ValueSlope[2]) << 4) + (m_ValueSlope[1] >> 4)); } 182 }; 183 184 //! @details :private 185 template <typename TKey> 186 struct ResKeysData 187 { 188 TKey m_KeyValue[1]; // 可変長配列にするとコンパイラが落ちるので、サイズ1にしておく。 189 }; 190 191 //! @details :private 192 template <typename TKey> 193 struct ResQuantizedKeysData 194 { 195 ut::ResF32 m_Scale; // Valueに適用する 196 ut::ResF32 m_Offset; 197 ut::ResF32 m_FrameScale; // Frameに適用する 198 ut::ResF32 m_FrameOffset; 199 200 TKey m_KeyValue[1]; 201 }; 202 203 //! @details :private 204 struct ResFloatSegmentCVData 205 { 206 union 207 { 208 ResKeysData<f32> cv32; 209 ResQuantizedKeysData<u16> cv16; 210 ResQuantizedKeysData<u8> cv8; 211 }; 212 }; 213 214 //! @details :private 215 struct ResFloatSegmentFVData 216 { 217 ut::ResU16 m_NumFrameValues; 218 u8 m_Padding_[2]; 219 220 ut::ResF32 m_InvDuration; 221 222 union 223 { 224 ResKeysData<ResFloatKeyFVSS128Data> fvss128; 225 ResQuantizedKeysData<ResFloatKeyFVSS64Data> fvss64; 226 ResQuantizedKeysData<ResFloatKeyFVSS48Data> fvss48; 227 ResKeysData<ResFloatKeyFVS96Data> fvs96; 228 ResQuantizedKeysData<ResFloatKeyFVS48Data> fvs48; 229 ResQuantizedKeysData<ResFloatKeyFVS32Data> fvs32; 230 ResKeysData<ResFloatKeyFV64Data> fv64; 231 ResQuantizedKeysData<ResFloatKeyFV32Data> fv32; 232 }; 233 }; 234 235 //! @details :private 236 struct ResFloatSegmentData 237 { 238 // セグメントカーブの特徴をフラグとして格納しています。 239 // FLAG_CONSTANT : このビットが1である場合には、このセグメントの 240 // アニメーション結果を定数として扱います。 241 // この時、FLAG_BAKED, FLAG_QUANTIZED, FLAG_INTERPORATE_MODE_MASK, 242 // FLAG_QUANTIZED_TYPE_MASK の設定は無効となります。 243 // 244 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 245 // コマ形式の場合には、FLAG_INTERPORATE_MODE_MASK の値は無視されます。 246 // 247 // FLAG_INTERPORATE_MODE_MASK : キーフレーム間の補間方式を設定します。 248 // 249 // FLAG_QUANTIZATION_TYPE_MASK : 量子化の方式を設定します。 250 // 251 enum Flag 252 { 253 FLAG_CONSTANT = (0x1 << 0), 254 FLAG_BAKED = (0x1 << 1), 255 256 FLAG_INTERPORATE_MODE_SHIFT = 2, 257 FLAG_QUANTIZATION_TYPE_SHIFT = 5, 258 259 FLAG_INTERPORATE_MODE_MASK = (0x7 << FLAG_INTERPORATE_MODE_SHIFT), 260 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 261 }; 262 263 enum InterporateMode 264 { 265 INTERPORATE_MODE_STEP = 0, 266 INTERPORATE_MODE_LINEAR = 1, 267 INTERPORATE_MODE_UNIFIED_HERMITE = 2, 268 INTERPORATE_MODE_HERMITE = 3 269 }; 270 271 enum QuantizeType 272 { 273 QUANTIZATION_TYPE_FVSS128 = 0, 274 QUANTIZATION_TYPE_FVSS64 = 1, 275 QUANTIZATION_TYPE_FVSS48 = 2, 276 277 QUANTIZATION_TYPE_FVS96 = 3, 278 QUANTIZATION_TYPE_FVS48 = 4, 279 QUANTIZATION_TYPE_FVS32 = 5, 280 281 QUANTIZATION_TYPE_FV64 = 6, 282 QUANTIZATION_TYPE_FV32 = 7, 283 284 QUANTIZATION_TYPE_CV32 = 0, 285 QUANTIZATION_TYPE_CV16 = 1, 286 QUANTIZATION_TYPE_CV8 = 2 287 }; 288 289 ut::ResF32 m_StartFrame; 290 ut::ResF32 m_EndFrame; 291 ut::ResU32 m_Flags; 292 293 union 294 { 295 ut::ResF32 constantValue; 296 ResFloatSegmentFVData fv; 297 ResFloatSegmentCVData cv; 298 }; 299 }; 300 301 //! @details :private 302 struct ResAnimCurveData 303 { 304 enum RepeatMethod 305 { 306 METHOD_NONE, 307 METHOD_REPEAT, 308 METHOD_MIRROR, 309 METHOD_NUM 310 }; 311 312 ut::ResF32 m_StartFrame; 313 ut::ResF32 m_EndFrame; 314 ut::ResU8 m_InRepeatMethod; 315 ut::ResU8 m_OutRepeatMethod; 316 u8 m_Padding[2]; 317 }; 318 319 //! @details :private 320 struct ResFloatCurveData : public ResAnimCurveData 321 { 322 // セグメントフロートカーブの特徴をフラグとして格納しています。 323 // FLAG_COMPOSITE_CURVE : このカーブが複合カーブであることを示します。 324 // 325 enum Flag 326 { 327 FLAG_COMPOSITE_CURVE = (0x1 << 0), 328 FLAG_SHIFT_MAX = 1 329 }; 330 331 ut::ResU32 m_Flags; 332 }; 333 334 //! @details :private 335 struct ResSegmentFloatCurveData : public ResFloatCurveData 336 { 337 // セグメントフロートカーブの特徴をフラグとして格納しています。 338 // FLAG_CONSTANT : このビットが1である場合には、このカーブの 339 // アニメーション結果を定数として扱います。 340 // FLAG_MONO_SEGMENT : このビットが1である場合には、単一セグメントで 341 // 構成されるカーブとして扱います。 342 // 343 enum Flag 344 { 345 FLAG_CONSTANT = (0x1 << (ResFloatCurveData::FLAG_SHIFT_MAX + 0)), 346 FLAG_MONO_SEGMENT = (0x1 << (ResFloatCurveData::FLAG_SHIFT_MAX + 1)) 347 }; 348 349 union 350 { 351 ut::ResF32 m_ConstantValue; 352 struct 353 { 354 ut::ResS32 m_NumSegments; 355 ut::Offset toSegments[1]; 356 } segmentsTable; 357 }; 358 }; 359 360 361 //! @details :private 362 struct ResCompositeFloatCurveData : public ResFloatCurveData 363 { 364 ut::Offset toLeftCurve; 365 ut::Offset toRightCurve; 366 ut::Offset toLeftBoolCurve; 367 ut::Offset toRightBoolCurve; 368 ut::ResU8 m_CompositeMode; 369 u8 padding[3]; 370 }; 371 372 373 374 //! @details :private 375 struct ResIntKeyFV64Data 376 { 377 ut::ResF32 m_Frame; 378 ut::ResS32 m_Value; 379 GetFrameResIntKeyFV64Data380 f32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV64Data381 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV64Data382 s32 GetValue() const { return m_Value; } 383 }; 384 385 //! @details :private 386 struct ResIntKeyFV32Data 387 { 388 ut::ResU16 m_Frame; 389 ut::ResS16 m_Value; 390 GetFrameResIntKeyFV32Data391 u32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV32Data392 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV32Data393 s16 GetValue() const { return m_Value; } 394 }; 395 396 //! @details :private 397 struct ResIntKeyFV16Data 398 { 399 ut::ResU8 m_Frame; 400 ut::ResS8 m_Value; 401 GetFrameResIntKeyFV16Data402 u32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV16Data403 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV16Data404 s8 GetValue() const { return m_Value; } 405 }; 406 407 //! @details :private 408 struct ResIntCurveFVData 409 { 410 ut::ResU16 m_NumFrameValues; 411 u8 m_Padding_[2]; 412 413 ut::ResF32 m_InvDuration; 414 415 union 416 { 417 ResKeysData<ResIntKeyFV64Data> fv64; 418 ResKeysData<ResIntKeyFV32Data> fv32; 419 ResKeysData<ResIntKeyFV16Data> fv16; 420 }; 421 }; 422 423 //! @details :private 424 struct ResIntCurveCVData 425 { 426 union 427 { 428 ResKeysData<ut::ResS32> cv32; 429 ResKeysData<ut::ResS16> cv16; 430 ResKeysData<ut::ResS8> cv8; 431 }; 432 }; 433 434 435 //! @details :private 436 struct ResIntCurveData : public ResAnimCurveData 437 { 438 // Int カーブの特徴をフラグとして格納しています。 439 // FLAG_CONSTANT : このビットが1である場合には、アニメーション結果を定数値として扱います。 440 // この時、FLAG_BAKED は無視されます。 441 // 442 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 443 // 444 enum Flag 445 { 446 FLAG_CONSTANT = (0x1 << 0), 447 FLAG_BAKED = (0x1 << 2), 448 449 FLAG_QUANTIZATION_TYPE_SHIFT = 3, 450 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 451 }; 452 453 enum QuantizeType 454 { 455 FLAG_QUANTIZATION_TYPE_FV64 = 0, 456 FLAG_QUANTIZATION_TYPE_FV32 = 1, 457 FLAG_QUANTIZATION_TYPE_FV16 = 2, 458 459 FLAG_QUANTIZATION_TYPE_CV32 = 0, 460 FLAG_QUANTIZATION_TYPE_CV16 = 1, 461 FLAG_QUANTIZATION_TYPE_CV8 = 2 462 }; 463 464 ut::ResU32 m_Flags; 465 466 union 467 { 468 ut::ResS32 constantValue; 469 ResIntCurveFVData fv; 470 ResIntCurveCVData cv; 471 }; 472 }; 473 474 475 //! @details :private 476 struct ResBoolCurveData : public ResAnimCurveData 477 { 478 // Bool カーブの特徴をフラグとして格納しています。 479 // FLAG_CONSTANT : このビットが1である場合には、FLAG_CONSTANT_VALUE を 480 // 定数値の結果として扱います。 481 // この時、FLAG_BAKED は無視されます。 482 // 483 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 484 // コマ形式の場合は、1byte に 8フレーム分の bool 値が 485 // 格納されています。 486 // 487 enum Flag 488 { 489 FLAG_CONSTANT = (0x1 << 0), 490 FLAG_CONSTANT_VALUE = (0x1 << 1), 491 FLAG_BAKED = (0x1 << 2), 492 493 FLAG_QUANTIZATION_TYPE_SHIFT = 3, 494 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 495 }; 496 497 enum QuantizeType 498 { 499 FLAG_QUANTIZATION_TYPE_FV64 = 0, 500 FLAG_QUANTIZATION_TYPE_FV32 = 1, 501 FLAG_QUANTIZATION_TYPE_FV16 = 2 502 }; 503 504 ut::ResU32 m_Flags; 505 506 union 507 { 508 ResKeysData<ut::ResU8> cv; 509 ResIntCurveFVData fv; 510 }; 511 }; 512 513 //! @details :private 514 //! ベイクされたアニメーション専用のクラスです。 515 template <typename Type> 516 struct ResBakedCurveData : public ResAnimCurveData 517 { 518 // カーブの特徴をフラグとして格納しています。 519 // FLAG_CONSTANT : このビットが 1 である場合には、アニメーション結果を定数値として扱います。 520 enum Flag 521 { 522 FLAG_CONSTANT = (0x1 << 0) 523 }; 524 525 // TODO: 量子化対応 526 ut::ResU32 m_Flags; 527 528 struct FrameValue 529 { 530 Type cv; 531 ut::ResU32 flag; 532 }; 533 ResKeysData<FrameValue> frames; 534 }; 535 536 //! @details :private 537 //! フルベイクアニメーション専用のクラスです。 538 struct ResFullBakedCurveData : public ResAnimCurveData 539 { 540 ResKeysData<ut::ResMtx34_> frames; 541 }; 542 543 // ベイクされたアニメ用の型名を定義します。 544 typedef ResBakedCurveData<ut::ResVec3_> ResVector3CurveData; //!< @details :private 545 typedef ResBakedCurveData<ut::ResVec4> ResVector4CurveData; //!< @details :private 546 547 f32 CalcFloatCurve( const ResFloatCurveData* pCurve, f32 frame ); //!< @details :private 548 bool CalcBoolCurve( const ResBoolCurveData* pCurve, f32 frame ); //!< @details :private 549 s32 CalcIntCurve( const ResIntCurveData* pCurve, f32 frame ); //!< @details :private 550 551 void CalcVector3Curve( math::VEC3* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame ); //!< @details :private 552 553 void CalcTranslateCurve( math::MTX34* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame ); //!< @details :private 554 void CalcRotateCurve( math::MTX34* result, bit32* flags, const ResVector4CurveData* pCurve, f32 frame ); //!< @details :private 555 556 void CalcTransformCurve( math::MTX34* result, const ResFullBakedCurveData* pCurve, f32 frame ); //!< @details :private 557 558 } /* namespace res */ 559 } /* namespace anim */ 560 } /* namespace nw */ 561 562 #endif /* NW_ANIM_RESANIMATIONCURVE_H_ */ 563