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