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 CastS9_10ToF32(s32 value)27 CastS9_10ToF32( s32 value ) 28 { 29 return f32(value) * (1.f / 1024.f); 30 } 31 32 NW_INLINE s32 CastF32ToS9_10(f32 value)33 CastF32ToS9_10( f32 value ) 34 { 35 return s32(value * 1024.f); 36 } 37 38 NW_INLINE f32 CastS7_8ToF32(s32 value)39 CastS7_8ToF32( s32 value ) 40 { 41 return f32(value) * (1.f / 256.f); 42 } 43 44 NW_INLINE s32 CastF32ToS7_8(f32 value)45 CastF32ToS7_8( f32 value ) 46 { 47 return s32(value * 256.f); 48 } 49 50 NW_INLINE f32 CastS10_5ToF32(s32 value)51 CastS10_5ToF32( s32 value ) 52 { 53 return f32(value) * (1.f / 32.f); 54 } 55 56 NW_INLINE s32 CastF32ToS10_5(f32 value)57 CastF32ToS10_5( f32 value ) 58 { 59 return s32(value * 32.f); 60 } 61 62 NW_INLINE f32 CastS6_5ToF32(s32 value)63 CastS6_5ToF32( s32 value ) 64 { 65 return f32(value) * (1.f / 32.f); 66 } 67 68 NW_INLINE s32 CastF32ToS6_5(f32 value)69 CastF32ToS6_5( f32 value ) 70 { 71 return s32(value * 32.f); 72 } 73 } /* namespace internal */ 74 75 // TODO: 量子化のビット数は仮のものです。 76 77 //! @details :private 78 struct ResFloatKeyFV64Data 79 { 80 ut::ResF32 m_Frame; 81 ut::ResF32 m_Value; 82 GetFrameResFloatKeyFV64Data83 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFV64Data84 f32 GetFrameF32() const { return m_Frame; } GetValueResFloatKeyFV64Data85 f32 GetValue() const { return m_Value; } 86 }; 87 88 //! @details :private 89 struct ResFloatKeyFV32Data 90 { 91 ut::ResU32 m_FrameValue; // u12 m_Frame; u20 m_Value * scale + offset; 92 GetFrameResFloatKeyFV32Data93 u32 GetFrame() const { return m_FrameValue & 0x00000FFF; } GetFrameF32ResFloatKeyFV32Data94 f32 GetFrameF32() const { return static_cast<f32>(this->GetFrame()); } GetValueResFloatKeyFV32Data95 f32 GetValue() const { return static_cast<f32>(m_FrameValue >> 12); } 96 }; 97 98 //! @details :private 99 struct ResFloatKeyFVSS128Data 100 { 101 ut::ResF32 m_Frame; 102 ut::ResF32 m_Value; 103 ut::ResF32 m_InSlope; 104 ut::ResF32 m_OutSlope; 105 GetFrameResFloatKeyFVSS128Data106 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVSS128Data107 f32 GetFrameF32() const { return m_Frame; } GetValueResFloatKeyFVSS128Data108 f32 GetValue() const { return m_Value; } GetInSlopeResFloatKeyFVSS128Data109 f32 GetInSlope() const { return m_InSlope; } GetOutSlopeResFloatKeyFVSS128Data110 f32 GetOutSlope() const { return m_OutSlope; } 111 }; 112 113 //! @details :private 114 struct ResFloatKeyFVSS64Data 115 { 116 ut::ResU32 m_FrameValue; // u12 m_Frame; u20 m_Value * scale + offset; 117 ut::ResS16 m_InSlope; // fx7.8 118 ut::ResS16 m_OutSlope; // fx7.8 119 GetFrameResFloatKeyFVSS64Data120 u32 GetFrame() const { return m_FrameValue & 0x00000FFF; } GetFrameF32ResFloatKeyFVSS64Data121 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVSS64Data122 f32 GetValue() const { return static_cast<f32>( m_FrameValue >> 12 ); } GetInSlopeResFloatKeyFVSS64Data123 f32 GetInSlope() const { return internal::CastS7_8ToF32(m_InSlope); } GetOutSlopeResFloatKeyFVSS64Data124 f32 GetOutSlope() const { return internal::CastS7_8ToF32(m_OutSlope); } 125 }; 126 127 //! @details :private 128 struct ResFloatKeyFVSS48Data 129 { 130 ut::ResU8 m_FrameValue[3]; // u8 m_Frame; u16 m_Value * scale + offset; 131 ut::ResU8 m_InOutSlope[3]; // fx6.5 m_InSlope; fx6.5 m_OutSlope; 132 GetFrameResFloatKeyFVSS48Data133 u32 GetFrame() const { return m_FrameValue[0]; } GetFrameF32ResFloatKeyFVSS48Data134 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVSS48Data135 f32 GetValue() const { return static_cast<f32>( u16(m_FrameValue[1]) + (u16(m_FrameValue[2]) << 8) ); } GetInSlopeResFloatKeyFVSS48Data136 f32 GetInSlope() const { return internal::CastS6_5ToF32( s16(m_InOutSlope[0] + (s8(m_InOutSlope[1] << 4) << 4)) ); } GetOutSlopeResFloatKeyFVSS48Data137 f32 GetOutSlope() const { return internal::CastS6_5ToF32( s16((s8(m_InOutSlope[2]) << 4) + (m_InOutSlope[1] >> 4)) ); } 138 }; 139 140 //! @details :private 141 struct ResFloatKeyFVS96Data 142 { 143 ut::ResF32 m_Frame; 144 ut::ResF32 m_Value; 145 ut::ResF32 m_Slope; 146 GetFrameResFloatKeyFVS96Data147 f32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS96Data148 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVS96Data149 f32 GetValue() const { return m_Value; } GetSlopeResFloatKeyFVS96Data150 f32 GetSlope() const { return m_Slope; } 151 }; 152 153 //! @details :private 154 struct ResFloatKeyFVS48Data 155 { 156 ut::ResU16 m_Frame; // fx10.5 157 ut::ResU16 m_Value; // m_Value * scale + offset 158 ut::ResS16 m_Slope; // fx7.8 159 GetFrameResFloatKeyFVS48Data160 u32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS48Data161 f32 GetFrameF32() const { return internal::CastS10_5ToF32( m_Frame ); } GetValueResFloatKeyFVS48Data162 f32 GetValue() const { return static_cast<f32>( m_Value ); } GetSlopeResFloatKeyFVS48Data163 f32 GetSlope() const { return internal::CastS7_8ToF32(m_Slope); } 164 }; 165 166 //! @details :private 167 struct ResFloatKeyFVS32Data 168 { 169 ut::ResU8 m_Frame; // u8 170 ut::ResU8 m_ValueSlope[3]; // u12 m_Value * scale + offset; fx6.5 m_Slope; 171 GetFrameResFloatKeyFVS32Data172 u32 GetFrame() const { return m_Frame; } GetFrameF32ResFloatKeyFVS32Data173 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResFloatKeyFVS32Data174 f32 GetValue() const { return static_cast<f32>( u16(m_ValueSlope[0]) + (u16(m_ValueSlope[1] << 4) << 4) ); } GetSlopeResFloatKeyFVS32Data175 f32 GetSlope() const { return internal::CastS6_5ToF32((s8(m_ValueSlope[2]) << 4) + (m_ValueSlope[1] >> 4)); } 176 }; 177 178 //! @details :private 179 template <typename TKey> 180 struct ResKeysData 181 { 182 TKey m_KeyValue[1]; // 可変長配列にするとコンパイラが落ちるので、サイズ1にしておく。 183 }; 184 185 //! @details :private 186 template <typename TKey> 187 struct ResQuantizedKeysData 188 { 189 ut::ResF32 m_Scale; 190 ut::ResF32 m_Offset; 191 192 TKey m_KeyValue[1]; 193 }; 194 195 //! @details :private 196 struct ResFloatSegmentCVData 197 { 198 union 199 { 200 ResKeysData<f32> cv32; 201 ResQuantizedKeysData<u16> cv16; 202 ResQuantizedKeysData<u8> cv8; 203 }; 204 }; 205 206 //! @details :private 207 struct ResFloatSegmentFVData 208 { 209 ut::ResU16 m_NumFrameValues; 210 u8 m_Padding_[2]; 211 212 ut::ResF32 m_InvDuration; 213 214 union 215 { 216 ResKeysData<ResFloatKeyFVSS128Data> fvss128; 217 ResQuantizedKeysData<ResFloatKeyFVSS64Data> fvss64; 218 ResQuantizedKeysData<ResFloatKeyFVSS48Data> fvss48; 219 ResKeysData<ResFloatKeyFVS96Data> fvs96; 220 ResQuantizedKeysData<ResFloatKeyFVS48Data> fvs48; 221 ResQuantizedKeysData<ResFloatKeyFVS32Data> fvs32; 222 ResKeysData<ResFloatKeyFV64Data> fv64; 223 ResQuantizedKeysData<ResFloatKeyFV32Data> fv32; 224 }; 225 }; 226 227 //! @details :private 228 struct ResFloatSegmentData 229 { 230 // セグメントカーブの特徴をフラグとして格納しています。 231 // FLAG_CONSTANT : このビットが1である場合には、このセグメントの 232 // アニメーション結果を定数として扱います。 233 // この時、FLAG_BAKED, FLAG_QUANTIZED, FLAG_INTERPORATE_MODE_MASK, 234 // FLAG_QUANTIZED_TYPE_MASK の設定は無効となります。 235 // 236 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 237 // コマ形式の場合には、FLAG_INTERPORATE_MODE_MASK の値は無視されます。 238 // 239 // FLAG_INTERPORATE_MODE_MASK : キーフレーム間の補間方式を設定します。 240 // 241 // FLAG_QUANTIZATION_TYPE_MASK : 量子化の方式を設定します。 242 // 243 enum Flag 244 { 245 FLAG_CONSTANT = (0x1 << 0), 246 FLAG_BAKED = (0x1 << 1), 247 248 FLAG_INTERPORATE_MODE_SHIFT = 2, 249 FLAG_QUANTIZATION_TYPE_SHIFT = 5, 250 251 FLAG_INTERPORATE_MODE_MASK = (0x7 << FLAG_INTERPORATE_MODE_SHIFT), 252 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 253 }; 254 255 enum InterporateMode 256 { 257 INTERPORATE_MODE_STEP = 0, 258 INTERPORATE_MODE_LINEAR = 1, 259 INTERPORATE_MODE_UNIFIED_HERMITE = 2, 260 INTERPORATE_MODE_HERMITE = 3 261 }; 262 263 enum QuantizeType 264 { 265 QUANTIZATION_TYPE_FVSS128 = 0, 266 QUANTIZATION_TYPE_FVSS64 = 1, 267 QUANTIZATION_TYPE_FVSS48 = 2, 268 269 QUANTIZATION_TYPE_FVS96 = 3, 270 QUANTIZATION_TYPE_FVS48 = 4, 271 QUANTIZATION_TYPE_FVS32 = 5, 272 273 QUANTIZATION_TYPE_FV64 = 6, 274 QUANTIZATION_TYPE_FV32 = 7, 275 276 QUANTIZATION_TYPE_CV32 = 0, 277 QUANTIZATION_TYPE_CV16 = 1, 278 QUANTIZATION_TYPE_CV8 = 2 279 }; 280 281 ut::ResF32 m_StartFrame; 282 ut::ResF32 m_EndFrame; 283 ut::ResU32 m_Flags; 284 285 union 286 { 287 ut::ResF32 constantValue; 288 ResFloatSegmentFVData fv; 289 ResFloatSegmentCVData cv; 290 }; 291 }; 292 293 //! @details :private 294 struct ResAnimCurveData 295 { 296 enum RepeatMethod 297 { 298 METHOD_NONE, 299 METHOD_REPEAT, 300 METHOD_MIRROR, 301 METHOD_RELATIVE, 302 METHOD_NUM 303 }; 304 305 ut::ResF32 m_StartFrame; 306 ut::ResF32 m_EndFrame; 307 ut::ResU8 m_InRepeatMethod; 308 ut::ResU8 m_OutRepeatMethod; 309 u8 m_Padding[2]; 310 }; 311 312 //! @details :private 313 struct ResFloatCurveData : public ResAnimCurveData 314 { 315 // セグメントフロートカーブの特徴をフラグとして格納しています。 316 // FLAG_COMPOSITE_CURVE : このカーブが複合カーブであることを示します。 317 // 318 enum Flag 319 { 320 FLAG_COMPOSITE_CURVE = (0x1 << 0), 321 FLAG_SHIFT_MAX = 1 322 }; 323 324 ut::ResU32 m_Flags; 325 }; 326 327 //! @details :private 328 struct ResSegmentFloatCurveData : public ResFloatCurveData 329 { 330 // セグメントフロートカーブの特徴をフラグとして格納しています。 331 // FLAG_CONSTANT : このビットが1である場合には、このカーブの 332 // アニメーション結果を定数として扱います。 333 // FLAG_MONO_SEGMENT : このビットが1である場合には、単一セグメントで 334 // 構成されるカーブとして扱います。 335 // 336 enum Flag 337 { 338 FLAG_CONSTANT = (0x1 << (ResFloatCurveData::FLAG_SHIFT_MAX + 0)), 339 FLAG_MONO_SEGMENT = (0x1 << (ResFloatCurveData::FLAG_SHIFT_MAX + 1)) 340 }; 341 342 union 343 { 344 ut::ResF32 m_ConstantValue; 345 struct 346 { 347 ut::ResS32 m_NumSegments; 348 ut::Offset toSegments[1]; 349 } segmentsTable; 350 }; 351 }; 352 353 354 //! @details :private 355 struct ResCompositeFloatCurveData : public ResFloatCurveData 356 { 357 ut::Offset toLeftCurve; 358 ut::Offset toRightCurve; 359 ut::Offset toLeftBoolCurve; 360 ut::Offset toRightBoolCurve; 361 ut::ResU8 m_CompositeMode; 362 u8 padding[3]; 363 }; 364 365 366 367 //! @details :private 368 struct ResIntKeyFV64Data 369 { 370 ut::ResF32 m_Frame; 371 ut::ResS32 m_Value; 372 GetFrameResIntKeyFV64Data373 f32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV64Data374 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV64Data375 s32 GetValue() const { return m_Value; } 376 }; 377 378 //! @details :private 379 struct ResIntKeyFV32Data 380 { 381 ut::ResU16 m_Frame; 382 ut::ResS16 m_Value; 383 GetFrameResIntKeyFV32Data384 u32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV32Data385 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV32Data386 s16 GetValue() const { return m_Value; } 387 }; 388 389 //! @details :private 390 struct ResIntKeyFV16Data 391 { 392 ut::ResU8 m_Frame; 393 ut::ResS8 m_Value; 394 GetFrameResIntKeyFV16Data395 u32 GetFrame() const { return m_Frame; } GetFrameF32ResIntKeyFV16Data396 f32 GetFrameF32() const { return static_cast<f32>( this->GetFrame() ); } GetValueResIntKeyFV16Data397 s8 GetValue() const { return m_Value; } 398 }; 399 400 //! @details :private 401 struct ResIntCurveFVData 402 { 403 ut::ResU16 m_NumFrameValues; 404 u8 m_Padding_[2]; 405 406 ut::ResF32 m_InvDuration; 407 408 union 409 { 410 ResKeysData<ResIntKeyFV64Data> fv64; 411 ResKeysData<ResIntKeyFV32Data> fv32; 412 ResKeysData<ResIntKeyFV16Data> fv16; 413 }; 414 }; 415 416 //! @details :private 417 struct ResIntCurveCVData 418 { 419 union 420 { 421 ResKeysData<ut::ResS32> cv32; 422 ResKeysData<ut::ResS16> cv16; 423 ResKeysData<ut::ResS8> cv8; 424 }; 425 }; 426 427 428 //! @details :private 429 struct ResIntCurveData : public ResAnimCurveData 430 { 431 // Int カーブの特徴をフラグとして格納しています。 432 // FLAG_CONSTANT : このビットが1である場合には、アニメーション結果を定数値として扱います。 433 // この時、FLAG_BAKED は無視されます。 434 // 435 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 436 // 437 enum Flag 438 { 439 FLAG_CONSTANT = (0x1 << 0), 440 FLAG_BAKED = (0x1 << 2), 441 442 FLAG_QUANTIZATION_TYPE_SHIFT = 3, 443 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 444 }; 445 446 enum QuantizeType 447 { 448 FLAG_QUANTIZATION_TYPE_FV64 = 0, 449 FLAG_QUANTIZATION_TYPE_FV32 = 1, 450 FLAG_QUANTIZATION_TYPE_FV16 = 2, 451 452 FLAG_QUANTIZATION_TYPE_CV32 = 0, 453 FLAG_QUANTIZATION_TYPE_CV16 = 1, 454 FLAG_QUANTIZATION_TYPE_CV8 = 2 455 }; 456 457 ut::ResU32 m_Flags; 458 459 union 460 { 461 ut::ResS32 constantValue; 462 ResIntCurveFVData fv; 463 ResIntCurveCVData cv; 464 }; 465 }; 466 467 468 //! @details :private 469 struct ResBoolCurveData : public ResAnimCurveData 470 { 471 // Bool カーブの特徴をフラグとして格納しています。 472 // FLAG_CONSTANT : このビットが1である場合には、FLAG_CONSTANT_VALUE を 473 // 定数値の結果として扱います。 474 // この時、FLAG_BAKED は無視されます。 475 // 476 // FLAG_BAKED : アニメーションデータをコマ形式として扱います。 477 // コマ形式の場合は、1byte に 8フレーム分の bool 値が 478 // 格納されています。 479 // 480 enum Flag 481 { 482 FLAG_CONSTANT = (0x1 << 0), 483 FLAG_CONSTANT_VALUE = (0x1 << 1), 484 FLAG_BAKED = (0x1 << 2), 485 486 FLAG_QUANTIZATION_TYPE_SHIFT = 3, 487 FLAG_QUANTIZATION_TYPE_MASK = (0x7 << FLAG_QUANTIZATION_TYPE_SHIFT) 488 }; 489 490 enum QuantizeType 491 { 492 FLAG_QUANTIZATION_TYPE_FV64 = 0, 493 FLAG_QUANTIZATION_TYPE_FV32 = 1, 494 FLAG_QUANTIZATION_TYPE_FV16 = 2 495 }; 496 497 ut::ResU32 m_Flags; 498 499 union 500 { 501 ResKeysData<ut::ResU8> cv; 502 ResIntCurveFVData fv; 503 }; 504 }; 505 506 //! @details :private 507 //! ベイクされたアニメーション専用のクラスです。 508 template <typename Type> 509 struct ResBakedCurveData : public ResAnimCurveData 510 { 511 // カーブの特徴をフラグとして格納しています。 512 // FLAG_CONSTANT : このビットが 1 である場合には、アニメーション結果を定数値として扱います。 513 enum Flag 514 { 515 FLAG_CONSTANT = (0x1 << 0) 516 }; 517 518 // TODO: 量子化対応 519 ut::ResU32 m_Flags; 520 521 struct FrameValue 522 { 523 Type cv; 524 ut::ResU32 flag; 525 }; 526 ResKeysData<FrameValue> frames; 527 }; 528 529 // ベイクされたアニメ用の型名を定義します。 530 typedef ResBakedCurveData<ut::ResVec3_> ResVector3CurveData; //!< @details :private 531 typedef ResBakedCurveData<ut::ResVec4> ResVector4CurveData; //!< @details :private 532 533 f32 CalcFloatCurve( const ResFloatCurveData* pCurve, f32 frame ); //!< @details :private 534 bool CalcBoolCurve( const ResBoolCurveData* pCurve, f32 frame ); //!< @details :private 535 s32 CalcIntCurve( const ResIntCurveData* pCurve, f32 frame ); //!< @details :private 536 537 void CalcVector3Curve( math::VEC3* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame ); //!< @details :private 538 539 void CalcTranslateCurve( math::MTX34* result, bit32* flags, const ResVector3CurveData* pCurve, f32 frame ); //!< @details :private 540 void CalcRotateCurve( math::MTX34* result, bit32* flags, const ResVector4CurveData* pCurve, f32 frame ); //!< @details :private 541 542 } /* namespace res */ 543 } /* namespace anim */ 544 } /* namespace nw */ 545 546 #endif /* NW_ANIM_RESANIMATIONCURVE_H_ */ 547