/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ResShape.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 18106 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_RESSHAPE_H_ #define NW_GFX_RESSHAPE_H_ #include #include #include #include #include #include #include namespace nw { namespace gfx { namespace res { //=================================== // モーフィング用クラス //=================================== //! @details :private struct ResKeyShapeWeightData { nw::ut::ResS32 m_Index; nw::ut::ResF32 m_Weight; }; //-------------------------------------------------------------------------- //! @brief 頂点モーフィングに割り当てるキーシェイプのインデックス番号とウェイト値を表すバイナリリソースクラスです。 //! @details :private //--------------------------------------------------------------------------- class ResKeyShapeWeight : public nw::ut::ResCommon< ResKeyShapeWeightData > { public: NW_RES_CTOR( ResKeyShapeWeight ) NW_RES_FIELD_PRIMITIVE_DECL( s32, Index ) // GetIndex(), SetIndex() NW_RES_FIELD_PRIMITIVE_DECL( f32, Weight ) // GetWeight(), SetWeight() }; //! @details :private struct ResMorphShapeData { nw::ut::ResTypeInfo typeInfo; nw::ut::ResS32 m_KeyShapeWeightsTableCount; nw::ut::Offset toKeyShapeWeightsTable; }; //-------------------------------------------------------------------------- //! @brief キーシェイプを合成して頂点モーフィングをするための情報を表すバイナリリソースクラスです。 //! @details :private //--------------------------------------------------------------------------- class ResMorphShape : public nw::ut::ResCommon< ResMorphShapeData > { public: NW_RES_CTOR( ResMorphShape ) NW_RES_FIELD_STRUCT_LIST_DECL( ResKeyShapeWeight, KeyShapeWeights ) }; //! @details :private struct ResSeparateDataMorphShapeData : public ResMorphShapeData { nw::ut::ResS32 m_DeltaVertexAttributesTableCount; nw::ut::Offset toDeltaVertexAttributesTable; }; //-------------------------------------------------------------------------- //! @brief 複数の属性を組み合わせてモーフィング差分を管理する為バイナリリソースクラスです。 //! @details :private //--------------------------------------------------------------------------- class ResSeparateDataMorphShape : public ResMorphShape { public: NW_RES_CTOR_INHERIT( ResSeparateDataMorphShape, ResMorphShape ) NW_RES_FIELD_CLASS_LIST_DECL( ResVertexAttribute, DeltaVertexAttributes ) // GetDeltaVertexAttributes(int idx), GetDeltaVertexAttributesCount() }; //=================================== // プリミティブクラス //=================================== //! @details :private struct ResPrimitiveData { nw::ut::ResS32 m_IndexStreamsTableCount; nw::ut::Offset toIndexStreamsTable; nw::ut::ResS32 m_BufferObjectsTableCount; nw::ut::Offset toBufferObjectsTable; }; //-------------------------------------------------------------------------- //! @brief シェイプを構成する一つのプリミティブを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResPrimitive : public nw::ut::ResCommon< ResPrimitiveData > { public: NW_RES_CTOR( ResPrimitive ) //--------------------------------------------------------------------------- //! @fn void SetBufferObjects(int idx, u32 value) //! @brief バッファオブジェクトのリストに要素を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetIndexStreamsCount() const //! @brief 頂点インデックスのストリームの要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResIndexStream GetIndexStreams(int idx) //! @brief 頂点インデックスのストリームを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetBufferObjectsCount() const //! @brief バッファオブジェクトの要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetBufferObjects(int idx) const //! @brief バッファオブジェクトを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_CLASS_LIST_DECL( ResIndexStream, IndexStreams ) // GetIndexStreams(int idx), GetIndexStreamsCount() NW_RES_FIELD_PRIMITIVE_LIST_DECL( u32, BufferObjects ) // GetBufferObjects(), GetBufferObjects(int idx), GetBufferObjectsCount() //--------------------------------------------------------------------------- //! @brief リソースの初期化処理をおこないます。 //--------------------------------------------------------------------------- void Setup(); //--------------------------------------------------------------------------- //! @brief リソースの解放準備をおこないます。 //--------------------------------------------------------------------------- void Cleanup(); }; typedef nw::ut::ResArrayClass::type ResPrimitiveArray; //! @details :private struct ResPrimitiveSetData { nw::ut::ResS32 m_BoneIndexTableTableCount; nw::ut::Offset toBoneIndexTableTable; nw::ut::ResS32 m_SkinningMode; nw::ut::ResS32 m_PrimitivesTableCount; nw::ut::Offset toPrimitivesTable; }; //-------------------------------------------------------------------------- //! @brief 同一のマトリクス群に影響する複数のプリミティブを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResPrimitiveSet : public nw::ut::ResCommon< ResPrimitiveSetData > { public: //! @brief スキニングモードを表します。 enum SkinningModeType { SKINNING_MODE_NONE, //!< スキニング無しの設定です。 SKINNING_MODE_RIGID, //!< リジッドスキニングの設定です。 SKINNING_MODE_SMOOTH //!< スムーススキニングの設定です。 }; NW_RES_CTOR( ResPrimitiveSet ) //--------------------------------------------------------------------------- //! @fn void SetSkinningMode(s32 value) //! @brief スキニングのモードを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetBoneIndexTable(int idx, s32 value) //! @brief ボーンインデックスのテーブルのリストに要素を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetSkinningMode() const //! @brief スキニングのモードを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetPrimitivesCount() const //! @brief プリミティブの要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResPrimitive GetPrimitives(int idx) //! @brief プリミティブを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetBoneIndexTableCount() const //! @brief ボーンインデックスのテーブルの要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetBoneIndexTable(int idx) const //! @brief ボーンインデックスのテーブルを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_PRIMITIVE_LIST_DECL( s32, BoneIndexTable ) // GetBoneIndexTable(), GetBoneIndexTable(int idx), GetBoneIndexTableCount() NW_RES_FIELD_PRIMITIVE_DECL( s32, SkinningMode ) // GetSkinningMode(), SetSkinningMode() NW_RES_FIELD_CLASS_LIST_DECL( ResPrimitive, Primitives ) // GetPrimitives(int idx), GetPrimitivesCount() //--------------------------------------------------------------------------- //! @brief リソースの初期化処理をおこないます。 //--------------------------------------------------------------------------- void Setup(); //--------------------------------------------------------------------------- //! @brief リソースの解放準備をおこないます。 //--------------------------------------------------------------------------- void Cleanup(); }; typedef nw::ut::ResArrayClass::type ResPrimitiveSetArray; //=================================== // シェイプクラス //=================================== //! @details :private struct ResShapeData : public ResSceneObjectData { nw::ut::ResU32 m_Flags; nw::ut::Offset toBoundingVolume; nw::ut::ResVec3 m_PositionOffset; nw::ut::ResS32 m_PrimitiveSetsTableCount; nw::ut::Offset toPrimitiveSetsTable; u32 m_BaseAddress; }; //-------------------------------------------------------------------------- //! @brief 頂点によって構成される形状を表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResShape : public ResSceneObject { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResShape) }; enum { SIGNATURE = NW_RES_SIGNATURE32('SHOB') }; enum Flag { FLAG_HAS_BEEN_SETUP = 0x1 << 0 //!< 既にセットアップ済みであることを示すフラグ }; NW_RES_CTOR_INHERIT( ResShape, ResSceneObject ) //--------------------------------------------------------------------------- //! @fn u32 GetFlags() const //! @brief フラグの値を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetFlags(u32 value) //! @brief フラグの値を設定します。 //--------------------------------------------------------------------------- NW_RES_FIELD_PRIMITIVE_DECL( u32, Flags ) // GetFlags(), SetFlags() //--------------------------------------------------------------------------- //! @fn nw::ut::ResBoundingVolume GetBoundingVolume() //! @brief 指向性境界ボックスを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_CLASS_DECL( nw::ut::ResBoundingVolume, BoundingVolume) // GetBoundingVolume() //--------------------------------------------------------------------------- //! @fn nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() //! @brief 指向性境界ボックスを取得します。 //--------------------------------------------------------------------------- nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() { nw::ut::ResOrientedBoundingBox resOBB( ref().toBoundingVolume.to_ptr() ); NW_ASSERT( resOBB.IsValid() || (resOBB.GetTypeInfo() == nw::ut::ResOrientedBoundingBox::TYPE_INFO) ); return resOBB; } const nw::ut::ResOrientedBoundingBox GetOrientedBoundingBox() const { const nw::ut::ResOrientedBoundingBox resOBB( ref().toBoundingVolume.to_ptr() ); NW_ASSERT( resOBB.IsValid() || (resOBB.GetTypeInfo() == nw::ut::ResOrientedBoundingBox::TYPE_INFO) ); return resOBB; } //--------------------------------------------------------------------------- //! @fn nw::ut::ResOrientedBoundingBoxData & GetOrientedBoundingBoxData() //! @brief 指向性境界ボックスを取得します。 //--------------------------------------------------------------------------- nw::ut::ResOrientedBoundingBoxData& GetOrientedBoundingBoxData() { return this->GetOrientedBoundingBox().ref(); } const nw::ut::ResOrientedBoundingBoxData& GetOrientedBoundingBoxData() const { return this->GetOrientedBoundingBox().ref(); } //--------------------------------------------------------------------------- //! @fn const nw::math::VEC3 & GetPositionOffset() const //! @brief 座標情報に加算するオフセット値を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetPositionOffset(f32 x, f32 y, f32 z) //! @brief 座標情報に加算するオフセット値を設定します。 //--------------------------------------------------------------------------- NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, PositionOffset ) // GetPositionOffset() //--------------------------------------------------------------------------- //! @fn s32 GetPrimitiveSetsCount() const //! @brief プリミティブの集合の要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResPrimitiveSet GetPrimitiveSets(int idx) //! @brief プリミティブの集合を取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_CLASS_LIST_DECL( ResPrimitiveSet, PrimitiveSets ) // GetPrimitiveSets(int idx), GetPrimitiveSetsCount() //-------------------------------------------------------------------------- //! @brief ローカルな中心位置を取得します。 //! //! @return ローカルな中心位置の座標です。 //--------------------------------------------------------------------------- const nw::math::VEC3& GetCenterPosition() const { return this->GetOrientedBoundingBox().GetCenterPosition(); } //-------------------------------------------------------------------------- //! @brief ローカルな中心位置を設定します。 //! //! @param[in] x 中心位置の x 座標です。 //! @param[in] y 中心位置の y 座標です。 //! @param[in] z 中心位置の z 座標です。 //--------------------------------------------------------------------------- void SetCenterPosition( f32 x, f32 y, f32 z ) { return this->GetOrientedBoundingBox().SetCenterPosition(x, y, z); } //-------------------------------------------------------------------------- //! @brief ローカルな中心位置を設定します。 //! //! @param[in] value 中心位置の座標です。 //--------------------------------------------------------------------------- void SetCenterPosition(const nw::math::VEC3& value) { return this->GetOrientedBoundingBox().SetCenterPosition(value); } //! @brief リソースの初期化をおこないます。 Result Setup(); //! @brief リソースの後始末をおこないます。 void Cleanup(); }; typedef nw::ut::ResArrayClass::type ResShapeArray; //! @details :private struct ResSeparateDataShapeData : public ResShapeData { nw::ut::ResS32 m_VertexAttributesTableCount; nw::ut::Offset toVertexAttributesTable; nw::ut::Offset toMorphShape; }; //-------------------------------------------------------------------------- //! @brief 複数の属性を組み合わせて形状を現すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResSeparateDataShape : public ResShape { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResSeparateDataShape) }; enum { SIGNATURE = NW_RES_SIGNATURE32('SPSH') }; NW_RES_CTOR_INHERIT( ResSeparateDataShape, ResShape ) //--------------------------------------------------------------------------- //! @fn s32 GetVertexAttributesCount() const //! @brief 頂点属性の要素数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResVertexAttribute GetVertexAttributes(int idx) //! @brief 頂点属性を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResSeparateDataMorphShape GetMorphShape() //! @brief 頂点モーフィングの設定を取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_CLASS_LIST_DECL( ResVertexAttribute, VertexAttributes ) // GetVertexAttributes(int idx), GetVertexAttributesCount() NW_RES_FIELD_CLASS_DECL( ResSeparateDataMorphShape, MorphShape ) // GetMorphShape() }; } // namespace res namespace internal { //-------------------------------------------------------------------------- //! @brief ResInterleavedVertexStream に含まれる実データを持たない内部頂点属性も含めて列挙するイテレータです。 //! //! @detail nw::gfx::GatherVertexAttributes 関数で取得します。 //--------------------------------------------------------------------------- class ResVertexAttributeIterator { public: //--------------------------------------------------------------------------- //! @brief シェイプから、ResVertexAttributeIterator を生成します。 //! //! @param[in] shape シェイプリソースです。 //! //! @return 先頭の頂点属性を指すイテレータです。 //--------------------------------------------------------------------------- static ResVertexAttributeIterator Begin(ResSeparateDataShape shape) { return ResVertexAttributeIterator(shape); } //--------------------------------------------------------------------------- //! @brief コピーコンストラクタです。 //! //! @param[in] value コピー元の値です。 //--------------------------------------------------------------------------- /* implicit */ ResVertexAttributeIterator(const ResVertexAttributeIterator& value) : m_Shape( value.m_Shape ), m_Interleave( value.m_Interleave ), m_IndexOnShape( value.m_IndexOnShape ), m_IndexOnInterleave( value.m_IndexOnInterleave ) { } //--------------------------------------------------------------------------- //! @brief イテレータが有効な値を指しているかどうかを取得します。 //! //! @return 有効な値であれば true、そうでなければ false を返します。 //--------------------------------------------------------------------------- bool IsValid() const { return (m_IndexOnShape >= 0); } //--------------------------------------------------------------------------- //! @brief ポインタ参照演算子です。 //! //! @return イテレータの指している頂点属性を返します。 //--------------------------------------------------------------------------- ResVertexAttribute operator*() { if (m_Interleave.IsValid()) { return m_Interleave.GetVertexStreams( m_IndexOnInterleave ); } else { return m_Shape.GetVertexAttributes( m_IndexOnShape ); } } //--------------------------------------------------------------------------- //! @brief ポインタ参照演算子です。 //! //! @return イテレータの指している頂点属性を返します。 //--------------------------------------------------------------------------- const ResVertexAttribute operator*() const { if (m_Interleave.IsValid()) { return m_Interleave.GetVertexStreams( m_IndexOnInterleave ); } else { return m_Shape.GetVertexAttributes( m_IndexOnShape ); } } //--------------------------------------------------------------------------- //! @brief 前置のインクリメント演算子です。 //! //! @return インクリメント後のイテレータを返します。 //--------------------------------------------------------------------------- ResVertexAttributeIterator& operator++() { if (m_Interleave.IsValid()) { ++m_IndexOnInterleave; if (m_Interleave.GetVertexStreamsCount() > m_IndexOnInterleave) { return *this; } m_Interleave = ResInterleavedVertexStream(NULL); m_IndexOnInterleave = -1; } ++m_IndexOnShape; if (m_Shape.GetVertexAttributesCount() > m_IndexOnShape) { ResVertexAttribute attribute = m_Shape.GetVertexAttributes(m_IndexOnShape); if (attribute.GetFlags() & ResVertexAttribute::FLAG_INTERLEAVE) { m_Interleave = ResStaticCast( attribute ); m_IndexOnInterleave = 0; } } else { m_IndexOnShape = -1; } return *this; } //--------------------------------------------------------------------------- //! @brief 後置のインクリメント演算子です。 //! //! @return インクリメント前のイテレータを返します。 //--------------------------------------------------------------------------- ResVertexAttributeIterator operator++(int) { ResVertexAttributeIterator copy = *this; this->operator++(); return copy; } private: ResSeparateDataShape m_Shape; ResInterleavedVertexStream m_Interleave; s32 m_IndexOnShape; s32 m_IndexOnInterleave; //--------------------------------------------------------------------------- //! @brief コンストラクタです。 //! //! @param[in] shape //--------------------------------------------------------------------------- explicit ResVertexAttributeIterator(ResSeparateDataShape shape) : m_Shape( shape ), m_Interleave( ResInterleavedVertexStream(NULL) ), m_IndexOnShape( 0 ), m_IndexOnInterleave( -1 ) { NW_ASSERT( shape.IsValid() ); ResVertexAttribute attribute = shape.GetVertexAttributes(0); if (attribute.GetFlags() & ResVertexAttribute::FLAG_INTERLEAVE) { m_Interleave = ResStaticCast( attribute ); m_IndexOnInterleave = 0; } } }; } // namespace internal } // namespace gfx } // namespace nw #endif // NW_GFX_RESSHAPE_H_