1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_ResShape.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: 18106 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_GFX_RESSHAPE_H_ 17 #define NW_GFX_RESSHAPE_H_ 18 19 #include <nw/ut/ut_ResUtil.h> 20 #include <nw/ut/ut_ResDictionary.h> 21 #include <nw/gfx/res/gfx_ResSceneObject.h> 22 #include <nw/gfx/res/gfx_ResVertex.h> 23 #include <nw/math/math_ResTypes.h> 24 #include <nw/gfx/res/gfx_ResTypeInfo.h> 25 #include <nw/ut/ut_ResPrimitive.h> 26 27 namespace nw { 28 namespace gfx { 29 namespace res { 30 31 //=================================== 32 // モーフィング用クラス 33 //=================================== 34 //! @details :private 35 struct ResKeyShapeWeightData 36 { 37 nw::ut::ResS32 m_Index; 38 nw::ut::ResF32 m_Weight; 39 }; 40 41 //-------------------------------------------------------------------------- 42 //! @brief 頂点モーフィングに割り当てるキーシェイプのインデックス番号とウェイト値を表すバイナリリソースクラスです。 43 //! @details :private 44 //--------------------------------------------------------------------------- 45 class ResKeyShapeWeight : public nw::ut::ResCommon< ResKeyShapeWeightData > 46 { 47 public: 48 NW_RES_CTOR( ResKeyShapeWeight ) 49 50 NW_RES_FIELD_PRIMITIVE_DECL( s32, Index ) // GetIndex(), SetIndex() 51 NW_RES_FIELD_PRIMITIVE_DECL( f32, Weight ) // GetWeight(), SetWeight() 52 }; 53 54 //! @details :private 55 struct ResMorphShapeData 56 { 57 nw::ut::ResTypeInfo typeInfo; 58 nw::ut::ResS32 m_KeyShapeWeightsTableCount; 59 nw::ut::Offset toKeyShapeWeightsTable; 60 }; 61 62 //-------------------------------------------------------------------------- 63 //! @brief キーシェイプを合成して頂点モーフィングをするための情報を表すバイナリリソースクラスです。 64 //! @details :private 65 //--------------------------------------------------------------------------- 66 class ResMorphShape : public nw::ut::ResCommon< ResMorphShapeData > 67 { 68 public: 69 NW_RES_CTOR( ResMorphShape ) 70 71 NW_RES_FIELD_STRUCT_LIST_DECL( ResKeyShapeWeight, KeyShapeWeights ) 72 }; 73 74 //! @details :private 75 struct ResSeparateDataMorphShapeData : public ResMorphShapeData 76 { 77 nw::ut::ResS32 m_DeltaVertexAttributesTableCount; 78 nw::ut::Offset toDeltaVertexAttributesTable; 79 }; 80 81 //-------------------------------------------------------------------------- 82 //! @brief 複数の属性を組み合わせてモーフィング差分を管理する為バイナリリソースクラスです。 83 //! @details :private 84 //--------------------------------------------------------------------------- 85 class ResSeparateDataMorphShape : public ResMorphShape 86 { 87 public: 88 NW_RES_CTOR_INHERIT( ResSeparateDataMorphShape, ResMorphShape ) 89 90 NW_RES_FIELD_CLASS_LIST_DECL( ResVertexAttribute, DeltaVertexAttributes ) // GetDeltaVertexAttributes(int idx), GetDeltaVertexAttributesCount() 91 }; 92 93 //=================================== 94 // プリミティブクラス 95 //=================================== 96 //! @details :private 97 struct ResPrimitiveData 98 { 99 nw::ut::ResS32 m_IndexStreamsTableCount; 100 nw::ut::Offset toIndexStreamsTable; 101 nw::ut::ResS32 m_BufferObjectsTableCount; 102 nw::ut::Offset toBufferObjectsTable; 103 }; 104 105 //-------------------------------------------------------------------------- 106 //! @brief シェイプを構成する一つのプリミティブを表すバイナリリソースクラスです。 107 //--------------------------------------------------------------------------- 108 class ResPrimitive : public nw::ut::ResCommon< ResPrimitiveData > 109 { 110 public: 111 NW_RES_CTOR( ResPrimitive ) 112 113 //--------------------------------------------------------------------------- 114 //! @fn void SetBufferObjects(int idx, u32 value) 115 //! @brief バッファオブジェクトのリストに要素を設定します。 116 //--------------------------------------------------------------------------- 117 //--------------------------------------------------------------------------- 118 //! @fn s32 GetIndexStreamsCount() const 119 //! @brief 頂点インデックスのストリームの要素数を取得します。 120 //--------------------------------------------------------------------------- 121 //--------------------------------------------------------------------------- 122 //! @fn ResIndexStream GetIndexStreams(int idx) 123 //! @brief 頂点インデックスのストリームを取得します。 124 //--------------------------------------------------------------------------- 125 //--------------------------------------------------------------------------- 126 //! @fn s32 GetBufferObjectsCount() const 127 //! @brief バッファオブジェクトの要素数を取得します。 128 //--------------------------------------------------------------------------- 129 //--------------------------------------------------------------------------- 130 //! @fn u32 GetBufferObjects(int idx) const 131 //! @brief バッファオブジェクトを取得します。 132 //--------------------------------------------------------------------------- 133 NW_RES_FIELD_CLASS_LIST_DECL( ResIndexStream, IndexStreams ) // GetIndexStreams(int idx), GetIndexStreamsCount() 134 NW_RES_FIELD_PRIMITIVE_LIST_DECL( u32, BufferObjects ) // GetBufferObjects(), GetBufferObjects(int idx), GetBufferObjectsCount() 135 136 //--------------------------------------------------------------------------- 137 //! @brief リソースの初期化処理をおこないます。 138 //--------------------------------------------------------------------------- 139 void Setup(); 140 141 //--------------------------------------------------------------------------- 142 //! @brief リソースの解放準備をおこないます。 143 //--------------------------------------------------------------------------- 144 void Cleanup(); 145 }; 146 typedef nw::ut::ResArrayClass<ResPrimitive>::type ResPrimitiveArray; 147 148 149 //! @details :private 150 struct ResPrimitiveSetData 151 { 152 nw::ut::ResS32 m_BoneIndexTableTableCount; 153 nw::ut::Offset toBoneIndexTableTable; 154 nw::ut::ResS32 m_SkinningMode; 155 nw::ut::ResS32 m_PrimitivesTableCount; 156 nw::ut::Offset toPrimitivesTable; 157 }; 158 159 //-------------------------------------------------------------------------- 160 //! @brief 同一のマトリクス群に影響する複数のプリミティブを表すバイナリリソースクラスです。 161 //--------------------------------------------------------------------------- 162 class ResPrimitiveSet : public nw::ut::ResCommon< ResPrimitiveSetData > 163 { 164 public: 165 //! @brief スキニングモードを表します。 166 enum SkinningModeType 167 { 168 SKINNING_MODE_NONE, //!< スキニング無しの設定です。 169 SKINNING_MODE_RIGID, //!< リジッドスキニングの設定です。 170 SKINNING_MODE_SMOOTH //!< スムーススキニングの設定です。 171 }; 172 173 NW_RES_CTOR( ResPrimitiveSet ) 174 175 //--------------------------------------------------------------------------- 176 //! @fn void SetSkinningMode(s32 value) 177 //! @brief スキニングのモードを設定します。 178 //--------------------------------------------------------------------------- 179 //--------------------------------------------------------------------------- 180 //! @fn void SetBoneIndexTable(int idx, s32 value) 181 //! @brief ボーンインデックスのテーブルのリストに要素を設定します。 182 //--------------------------------------------------------------------------- 183 //--------------------------------------------------------------------------- 184 //! @fn s32 GetSkinningMode() const 185 //! @brief スキニングのモードを取得します。 186 //--------------------------------------------------------------------------- 187 //--------------------------------------------------------------------------- 188 //! @fn s32 GetPrimitivesCount() const 189 //! @brief プリミティブの要素数を取得します。 190 //--------------------------------------------------------------------------- 191 //--------------------------------------------------------------------------- 192 //! @fn ResPrimitive GetPrimitives(int idx) 193 //! @brief プリミティブを取得します。 194 //--------------------------------------------------------------------------- 195 //--------------------------------------------------------------------------- 196 //! @fn s32 GetBoneIndexTableCount() const 197 //! @brief ボーンインデックスのテーブルの要素数を取得します。 198 //--------------------------------------------------------------------------- 199 //--------------------------------------------------------------------------- 200 //! @fn s32 GetBoneIndexTable(int idx) const 201 //! @brief ボーンインデックスのテーブルを取得します。 202 //--------------------------------------------------------------------------- 203 NW_RES_FIELD_PRIMITIVE_LIST_DECL( s32, BoneIndexTable ) // GetBoneIndexTable(), GetBoneIndexTable(int idx), GetBoneIndexTableCount() 204 NW_RES_FIELD_PRIMITIVE_DECL( s32, SkinningMode ) // GetSkinningMode(), SetSkinningMode() 205 NW_RES_FIELD_CLASS_LIST_DECL( ResPrimitive, Primitives ) // GetPrimitives(int idx), GetPrimitivesCount() 206 207 //--------------------------------------------------------------------------- 208 //! @brief リソースの初期化処理をおこないます。 209 //--------------------------------------------------------------------------- 210 void Setup(); 211 212 //--------------------------------------------------------------------------- 213 //! @brief リソースの解放準備をおこないます。 214 //--------------------------------------------------------------------------- 215 void Cleanup(); 216 }; 217 typedef nw::ut::ResArrayClass<ResPrimitiveSet>::type ResPrimitiveSetArray; 218 219 220 //=================================== 221 // シェイプクラス 222 //=================================== 223 //! @details :private 224 struct ResShapeData : public ResSceneObjectData 225 { 226 nw::ut::ResU32 m_Flags; 227 nw::ut::Offset toBoundingVolume; 228 nw::ut::ResVec3 m_PositionOffset; 229 nw::ut::ResS32 m_PrimitiveSetsTableCount; 230 nw::ut::Offset toPrimitiveSetsTable; 231 u32 m_BaseAddress; 232 }; 233 234 //-------------------------------------------------------------------------- 235 //! @brief 頂点によって構成される形状を表すバイナリリソースクラスです。 236 //--------------------------------------------------------------------------- 237 class ResShape : public ResSceneObject 238 { 239 public: 240 enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResShape) }; 241 enum { SIGNATURE = NW_RES_SIGNATURE32('SHOB') }; 242 243 enum Flag 244 { 245 FLAG_HAS_BEEN_SETUP = 0x1 << 0 //!< 既にセットアップ済みであることを示すフラグ 246 }; 247 NW_RES_CTOR_INHERIT(ResShape,ResSceneObject)248 NW_RES_CTOR_INHERIT( ResShape, ResSceneObject ) 249 250 //--------------------------------------------------------------------------- 251 //! @fn u32 GetFlags() const 252 //! @brief フラグの値を取得します。 253 //--------------------------------------------------------------------------- 254 //--------------------------------------------------------------------------- 255 //! @fn void SetFlags(u32 value) 256 //! @brief フラグの値を設定します。 257 //--------------------------------------------------------------------------- 258 NW_RES_FIELD_PRIMITIVE_DECL( u32, Flags ) // GetFlags(), SetFlags() 259 260 //--------------------------------------------------------------------------- 261 //! @fn nw::ut::ResBoundingVolume GetBoundingVolume() 262 //! @brief 指向性境界ボックスを取得します。 263 //--------------------------------------------------------------------------- 264 NW_RES_FIELD_CLASS_DECL( nw::ut::ResBoundingVolume, BoundingVolume) // GetBoundingVolume() 265 266 //--------------------------------------------------------------------------- 267 //! @fn nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() 268 //! @brief 指向性境界ボックスを取得します。 269 //--------------------------------------------------------------------------- 270 nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() 271 { 272 nw::ut::ResOrientedBoundingBox resOBB( ref().toBoundingVolume.to_ptr() ); 273 274 NW_ASSERT( resOBB.IsValid() || (resOBB.GetTypeInfo() == nw::ut::ResOrientedBoundingBox::TYPE_INFO) ); 275 return resOBB; 276 } 277 GetOrientedBoundingBox()278 const nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() const 279 { 280 const nw::ut::ResOrientedBoundingBox resOBB( ref().toBoundingVolume.to_ptr() ); 281 282 NW_ASSERT( resOBB.IsValid() || (resOBB.GetTypeInfo() == nw::ut::ResOrientedBoundingBox::TYPE_INFO) ); 283 return resOBB; 284 } 285 286 //--------------------------------------------------------------------------- 287 //! @fn nw::ut::ResOrientedBoundingBoxData & GetOrientedBoundingBoxData() 288 //! @brief 指向性境界ボックスを取得します。 289 //--------------------------------------------------------------------------- GetOrientedBoundingBoxData()290 nw::ut::ResOrientedBoundingBoxData& GetOrientedBoundingBoxData() 291 { 292 return this->GetOrientedBoundingBox().ref(); 293 } 294 GetOrientedBoundingBoxData()295 const nw::ut::ResOrientedBoundingBoxData& GetOrientedBoundingBoxData() const 296 { 297 return this->GetOrientedBoundingBox().ref(); 298 } 299 300 //--------------------------------------------------------------------------- 301 //! @fn const nw::math::VEC3 & GetPositionOffset() const 302 //! @brief 座標情報に加算するオフセット値を取得します。 303 //--------------------------------------------------------------------------- 304 //--------------------------------------------------------------------------- 305 //! @fn void SetPositionOffset(f32 x, f32 y, f32 z) 306 //! @brief 座標情報に加算するオフセット値を設定します。 307 //--------------------------------------------------------------------------- NW_RES_FIELD_VECTOR3_DECL(nw::math::VEC3,PositionOffset)308 NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, PositionOffset ) // GetPositionOffset() 309 310 //--------------------------------------------------------------------------- 311 //! @fn s32 GetPrimitiveSetsCount() const 312 //! @brief プリミティブの集合の要素数を取得します。 313 //--------------------------------------------------------------------------- 314 //--------------------------------------------------------------------------- 315 //! @fn ResPrimitiveSet GetPrimitiveSets(int idx) 316 //! @brief プリミティブの集合を取得します。 317 //--------------------------------------------------------------------------- 318 NW_RES_FIELD_CLASS_LIST_DECL( ResPrimitiveSet, PrimitiveSets ) // GetPrimitiveSets(int idx), GetPrimitiveSetsCount() 319 320 //-------------------------------------------------------------------------- 321 //! @brief ローカルな中心位置を取得します。 322 //! 323 //! @return ローカルな中心位置の座標です。 324 //--------------------------------------------------------------------------- 325 const nw::math::VEC3& GetCenterPosition() const { return this->GetOrientedBoundingBox().GetCenterPosition(); } 326 327 //-------------------------------------------------------------------------- 328 //! @brief ローカルな中心位置を設定します。 329 //! 330 //! @param[in] x 中心位置の x 座標です。 331 //! @param[in] y 中心位置の y 座標です。 332 //! @param[in] z 中心位置の z 座標です。 333 //--------------------------------------------------------------------------- SetCenterPosition(f32 x,f32 y,f32 z)334 void SetCenterPosition( f32 x, f32 y, f32 z ) { return this->GetOrientedBoundingBox().SetCenterPosition(x, y, z); } 335 336 //-------------------------------------------------------------------------- 337 //! @brief ローカルな中心位置を設定します。 338 //! 339 //! @param[in] value 中心位置の座標です。 340 //--------------------------------------------------------------------------- SetCenterPosition(const nw::math::VEC3 & value)341 void SetCenterPosition(const nw::math::VEC3& value) { return this->GetOrientedBoundingBox().SetCenterPosition(value); } 342 343 //! @brief リソースの初期化をおこないます。 344 Result Setup(); 345 346 //! @brief リソースの後始末をおこないます。 347 void Cleanup(); 348 }; 349 typedef nw::ut::ResArrayClass<ResShape>::type ResShapeArray; 350 351 352 //! @details :private 353 struct ResSeparateDataShapeData : public ResShapeData 354 { 355 nw::ut::ResS32 m_VertexAttributesTableCount; 356 nw::ut::Offset toVertexAttributesTable; 357 nw::ut::Offset toMorphShape; 358 }; 359 360 361 //-------------------------------------------------------------------------- 362 //! @brief 複数の属性を組み合わせて形状を現すバイナリリソースクラスです。 363 //--------------------------------------------------------------------------- 364 class ResSeparateDataShape : public ResShape 365 { 366 public: 367 enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResSeparateDataShape) }; 368 enum { SIGNATURE = NW_RES_SIGNATURE32('SPSH') }; 369 370 NW_RES_CTOR_INHERIT( ResSeparateDataShape, ResShape ) 371 372 //--------------------------------------------------------------------------- 373 //! @fn s32 GetVertexAttributesCount() const 374 //! @brief 頂点属性の要素数を取得します。 375 //--------------------------------------------------------------------------- 376 //--------------------------------------------------------------------------- 377 //! @fn ResVertexAttribute GetVertexAttributes(int idx) 378 //! @brief 頂点属性を取得します。 379 //--------------------------------------------------------------------------- 380 //--------------------------------------------------------------------------- 381 //! @fn ResSeparateDataMorphShape GetMorphShape() 382 //! @brief 頂点モーフィングの設定を取得します。 383 //--------------------------------------------------------------------------- 384 NW_RES_FIELD_CLASS_LIST_DECL( ResVertexAttribute, VertexAttributes ) // GetVertexAttributes(int idx), GetVertexAttributesCount() 385 NW_RES_FIELD_CLASS_DECL( ResSeparateDataMorphShape, MorphShape ) // GetMorphShape() 386 }; 387 388 } // namespace res 389 390 namespace internal { 391 392 //-------------------------------------------------------------------------- 393 //! @brief ResInterleavedVertexStream に含まれる実データを持たない内部頂点属性も含めて列挙するイテレータです。 394 //! 395 //! @detail nw::gfx::GatherVertexAttributes 関数で取得します。 396 //--------------------------------------------------------------------------- 397 class ResVertexAttributeIterator 398 { 399 public: 400 //--------------------------------------------------------------------------- 401 //! @brief シェイプから、ResVertexAttributeIterator を生成します。 402 //! 403 //! @param[in] shape シェイプリソースです。 404 //! 405 //! @return 先頭の頂点属性を指すイテレータです。 406 //--------------------------------------------------------------------------- Begin(ResSeparateDataShape shape)407 static ResVertexAttributeIterator Begin(ResSeparateDataShape shape) 408 { 409 return ResVertexAttributeIterator(shape); 410 } 411 412 //--------------------------------------------------------------------------- 413 //! @brief コピーコンストラクタです。 414 //! 415 //! @param[in] value コピー元の値です。 416 //--------------------------------------------------------------------------- ResVertexAttributeIterator(const ResVertexAttributeIterator & value)417 /* implicit */ ResVertexAttributeIterator(const ResVertexAttributeIterator& value) 418 : m_Shape( value.m_Shape ), 419 m_Interleave( value.m_Interleave ), 420 m_IndexOnShape( value.m_IndexOnShape ), 421 m_IndexOnInterleave( value.m_IndexOnInterleave ) 422 { 423 } 424 425 //--------------------------------------------------------------------------- 426 //! @brief イテレータが有効な値を指しているかどうかを取得します。 427 //! 428 //! @return 有効な値であれば true、そうでなければ false を返します。 429 //--------------------------------------------------------------------------- IsValid()430 bool IsValid() const 431 { 432 return (m_IndexOnShape >= 0); 433 } 434 435 //--------------------------------------------------------------------------- 436 //! @brief ポインタ参照演算子です。 437 //! 438 //! @return イテレータの指している頂点属性を返します。 439 //--------------------------------------------------------------------------- 440 ResVertexAttribute operator*() 441 { 442 if (m_Interleave.IsValid()) 443 { 444 return m_Interleave.GetVertexStreams( m_IndexOnInterleave ); 445 } 446 else 447 { 448 return m_Shape.GetVertexAttributes( m_IndexOnShape ); 449 } 450 } 451 452 //--------------------------------------------------------------------------- 453 //! @brief ポインタ参照演算子です。 454 //! 455 //! @return イテレータの指している頂点属性を返します。 456 //--------------------------------------------------------------------------- 457 const ResVertexAttribute operator*() const 458 { 459 if (m_Interleave.IsValid()) 460 { 461 return m_Interleave.GetVertexStreams( m_IndexOnInterleave ); 462 } 463 else 464 { 465 return m_Shape.GetVertexAttributes( m_IndexOnShape ); 466 } 467 } 468 469 470 //--------------------------------------------------------------------------- 471 //! @brief 前置のインクリメント演算子です。 472 //! 473 //! @return インクリメント後のイテレータを返します。 474 //--------------------------------------------------------------------------- 475 ResVertexAttributeIterator& operator++() 476 { 477 if (m_Interleave.IsValid()) 478 { 479 ++m_IndexOnInterleave; 480 if (m_Interleave.GetVertexStreamsCount() > m_IndexOnInterleave) 481 { 482 return *this; 483 } 484 485 m_Interleave = ResInterleavedVertexStream(NULL); 486 m_IndexOnInterleave = -1; 487 } 488 489 ++m_IndexOnShape; 490 if (m_Shape.GetVertexAttributesCount() > m_IndexOnShape) 491 { 492 ResVertexAttribute attribute = m_Shape.GetVertexAttributes(m_IndexOnShape); 493 494 if (attribute.GetFlags() & ResVertexAttribute::FLAG_INTERLEAVE) 495 { 496 m_Interleave = ResStaticCast<ResInterleavedVertexStream>( attribute ); 497 m_IndexOnInterleave = 0; 498 } 499 } 500 else 501 { 502 m_IndexOnShape = -1; 503 } 504 505 return *this; 506 } 507 508 //--------------------------------------------------------------------------- 509 //! @brief 後置のインクリメント演算子です。 510 //! 511 //! @return インクリメント前のイテレータを返します。 512 //--------------------------------------------------------------------------- 513 ResVertexAttributeIterator operator++(int) 514 { 515 ResVertexAttributeIterator copy = *this; 516 517 this->operator++(); 518 519 return copy; 520 } 521 522 private: 523 ResSeparateDataShape m_Shape; 524 ResInterleavedVertexStream m_Interleave; 525 s32 m_IndexOnShape; 526 s32 m_IndexOnInterleave; 527 528 //--------------------------------------------------------------------------- 529 //! @brief コンストラクタです。 530 //! 531 //! @param[in] shape 532 //--------------------------------------------------------------------------- 533 ResVertexAttributeIterator(ResSeparateDataShape shape)534 explicit ResVertexAttributeIterator(ResSeparateDataShape shape) 535 : m_Shape( shape ), 536 m_Interleave( ResInterleavedVertexStream(NULL) ), 537 m_IndexOnShape( 0 ), 538 m_IndexOnInterleave( -1 ) 539 { 540 NW_ASSERT( shape.IsValid() ); 541 542 ResVertexAttribute attribute = shape.GetVertexAttributes(0); 543 544 if (attribute.GetFlags() & ResVertexAttribute::FLAG_INTERLEAVE) 545 { 546 m_Interleave = ResStaticCast<ResInterleavedVertexStream>( attribute ); 547 m_IndexOnInterleave = 0; 548 } 549 } 550 }; 551 552 } // namespace internal 553 554 } // namespace gfx 555 } // namespace nw 556 557 #endif // NW_GFX_RESSHAPE_H_ 558