/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2009/X/X - 2015/11/14
/// 
/// @brief  メッシュ基本情報。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_CDI_Base.h"


namespace CPL {
namespace CDI {


using TypeGID        = U32;
using TypeAnimeIndex = U32;


#define CPL_MFI_CHUNK_HEAD      "CPLMHEAD" // ヘッダー */
#define CPL_MFI_CHUNK_OBJECT    "OBJECT  " // オブジェクト */
#define CPL_MFI_CHUNK_VTXDECL   "VTXDECL " // 頂点レイアウト */
#define CPL_MFI_CHUNK_VTXSTMLO  "VTXSTMLO" // 頂点ストリームレイアウト */
#define CPL_MFI_CHUNK_VTXSTM    "VTXSTM  " // 頂点ストリームデータ */
#define CPL_MFI_CHUNK_VTXGROUP  "VTXGROUP" // 頂点グループ */
#define CPL_MFI_CHUNK_POLYGON   "POLYGON " // ポリゴン */
#define CPL_MFI_CHUNK_BONEDATA  "BONEDATA" // ボーン */
#define CPL_MFI_CHUNK_TEXCDSET  "TEXCDSET" // テクスチャ座標セット */
#define CPL_MFI_CHUNK_VSINFO    "VSINFO  " // 頂点シェーダー */
#define CPL_MFI_CHUNK_PSINFO    "PSINFO  " // ピクセルシェーダー */
#define CPL_MFI_CHUNK_SHADER    "SHADER  " // シェーダー */
#define CPL_MFI_CHUNK_SDRDATA   "SDRDATA " // シェーダデータ
#define CPL_MFI_CHUNK_TEXINFO   "TEXINFO " // テクスチャ */
#define CPL_MFI_CHUNK_CLRMTRL   "CLRMTRL " // カラーマテリアル */
#define CPL_MFI_CHUNK_TEXMTRL   "TEXMTRL " // テクスチャマテリアル */
#define CPL_MFI_CHUNK_LITMTRL   "LITMTRL " // ライトマテリアル */
#define CPL_MFI_CHUNK_ANMDATA   "ANMDATA " // アニメーションデータ */
#define CPL_MFI_CHUNK_KEYLIST   "KEYLIST " // キーリスト */

// アニメーションキータイプ
#define CPL_MFI_KEY_EVT_TYPE_WAIT "KET_WAIT" // ウエイト */
#define CPL_MFI_KEY_EVT_TYPE_LPST "KET_LPST" // ループスタート */
#define CPL_MFI_KEY_EVT_TYPE_LPED "KET_LPED" // ループエンド */


// _____________________________________________________________________________
/// @brief Core4D 情報
///
// *****************************************************************************
struct MeshFileInfo {
  static const int kCOLOR_MTRL_PARAM_NUM = 4;
  static const int kTEX_MTRL_PARAM_NUM = 4;

  /*
  // 頂点ストリーム識別インデックス
  enum _VTXSTM_IDX {
    VSI_VECTOR,
    VSI_BLEND,
    VSI_NORMAL,
    VSI_COLOR,
    VSI_TEXCOORD,
    VSI_PSIZE,
    VSI_DEPTH,
    VSI_TANGENT,
    VSI_BINORMAL,
    VSI_TESSFACTOR,
    VSI_FOG,

    VSI_NUM,
  };
  */
  
  enum class eKeyFormat : U32
  { BaseKey  = 0
  , IntP0_   = BIT0
  , IntP1_   = IntP0_ << 8
  , IntP2_   = IntP1_ << 8
  , IntP3_   = IntP2_ << 8
  , FloatP0_ = BIT1
  , FloatP1_ = FloatP0_ << 8
  , FloatP2_ = FloatP1_ << 8
  , FloatP3_ = FloatP2_ << 8
  , UV_P0_   = BIT2
  , UV_P1_   = UV_P0_ << 8
  , UV_P2_   = UV_P1_ << 8
  , UV_P3_   = UV_P2_ << 8

  , Int1 = IntP0_
  , Int2 = Int1 | IntP1_
  , Int3 = Int2 | IntP2_
  , Int4 = Int3 | IntP3_

  , Float1 = FloatP0_
  , Float2 = Float1 | FloatP1_
  , Float3 = Float2 | FloatP2_
  , Float4 = Float3 | FloatP3_

  , UV1 = UV_P0_
  , UV2 = UV1 | UV_P0_
  , UV3 = UV2 | UV_P1_
  , UV4 = UV3 | UV_P2_

  , Mask0 = 0xff
  , Mask1 = Mask0 << 8
  , Mask2 = Mask1 << 8
  , Mask3 = Mask2 << 8

  , DefaultEvent  = Int2
  , DefaultVector = Float3
  , DefaultColor  = Float4
  , DefaultUV1    = UV1
  , DefaultUV2    = UV2
  , DefaultUV3    = UV3
  , DefaultUV4    = UV4
  , DefaultMaterial1 = Float1
  , DefaultMaterial2 = Float2
  , DefaultMaterial3 = Float3
  , DefaultMaterial4 = Float4
  };

  enum class eKeyType : U32
  { None      = 0xffffffff
  , BaseKey   = 0
  , Event     = 0x00000010
  , VectorPos = 0x00000100
  , VectorRot
  , VectorScl
  , Color0    = 0x00000200
  , Color1
  , Color2
  , Color3
  , ColorDiffuse  = Color0
  , ColorSpecular = Color1
  , ColorEmissive = Color2
  , ColorAmbient  = Color3
  , Param0 = 0x00000500
  , Param1
  , Param2
  , Param3
  , MaterialPower = 0x00000300
  , LightPower
  , TexCoord      = 0x00000400
  };

  
  /*
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // フォーマットコードからそのフォーマットが使用するストリームNoを返す
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static int GetStreamIndex_by_Format( VTX_FORMAT in_format )
  {
    static const int to_stream[ VF_NUM ] = {
      VSI_VECTOR,     // xyz
      VSI_VECTOR,     // xyzw
      VSI_BLEND,      // blend weight
      VSI_BLEND,      // blend index
      VSI_NORMAL,     // normal
      VSI_PSIZE,      // point size
      VSI_TANGENT,    // 接線
      VSI_BINORMAL,   // 従法線
      VSI_TESSFACTOR, // テセレーション係数
      VSI_FOG,        // fog
      VSI_DEPTH,      // depth
      VSI_TEXCOORD,   // tex0
      VSI_TEXCOORD,   // tex1
      VSI_TEXCOORD,   // tex2
      VSI_TEXCOORD,   // tex3
      VSI_TEXCOORD,   // tex4
      VSI_TEXCOORD,   // tex5
      VSI_TEXCOORD,   // tex6
      VSI_TEXCOORD,   // tex7
      VSI_COLOR,      // color0
      VSI_COLOR,      // color1
      VSI_COLOR,      // color2
      VSI_COLOR,      // color3
      VSI_COLOR,      // color4
      VSI_COLOR,      // color5
      VSI_COLOR,      // color6
      VSI_COLOR,      // color7
    };
    return to_stream[ in_format ];
  }
  */
  enum class eShaderBufferUsage : U32
  { MatrixViewProj
  , MatrixProj
  , MatrixView
  , MatrixWorld
  , MaterialParam0
  , MaterialParam1
  , MaterialParam2
  , MaterialParam3
  , LightPos
  , LightNormal
  , LightAmbient
  , LightDiffuse
  , LightPower
  , LightTheta
  , LightPhi
  , EyePos
  , LookPos
  };


  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 基本チャンククラス
  struct Chunk
  {
    union {
      U64  m_type;
      char m_type_c[8];
    };
    size_t m_size; // チャンクサイズ（チャンク自身も含む）

  protected:
    Chunk( U64 in_type, long in_size );
    Chunk( char const* in_type, long in_size );

  public:
    bool IsType( char_cptr in_type ) const;
    size_t GetSize() const { return m_size; }
  };
  
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // ファイルヘッダ
  struct Header : Chunk
  {
    Header();
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // オブジェクト
  struct Object : Chunk
  {
    Object()
      : Chunk( CPL_MFI_CHUNK_OBJECT, sizeof(*this) )
    {}

    // ローカルデータ
    TypeGID  m_GID;
    TypeGID  m_GID_next;
    TypeGID  m_GID_child;
    TypeGID  m_GID_material;
    TypeGID  m_GID_tex_material;
    TypeGID  m_GID_mirror;    // ミラーの元となるオブジェクトＩＤ
    TypeGID  m_GID_shader;
    TypeGID  m_GID_declaration; // 参照する頂点宣言データのＩＤ
    U8       m_flag_culling;
    U8       m_flag_billboard;
    U8       m_flag_z_sort;
    U8       m_flag_lighting;
    CVector3 m_vec_pos;
    CVector3 m_vec_rot;
    CVector3 m_vec_scl;
    U32      m_vtx_num;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // 頂点リスト（データ）
    // ※ Objectチャンクのローカルデータに続き、m_buf_sizeのデータ列が格納されている
    struct VertexStreamData : Chunk
    {
      VertexStreamData()
        : Chunk( CPL_MFI_CHUNK_VTXSTM, sizeof(*this) )
        , m_GID(0)
        , m_vtx_size(0)
        , m_buf_size(0)
      {}

      TypeGID m_GID;
      U32     m_vtx_size; // １頂点のサイズ
      U32     m_buf_size; // バッファサイズ（チャンク自身はサイズに含まない）

      size_t    InfoSize_() const { return sizeof(*this); }
      size_t    ThisSize_() const { return InfoSize_() + m_buf_size; }
      void_cptr DataAddr_() const { return reinterpret_cast<char_cptr>(this) + InfoSize_(); }
      void_cptr NextAddr_() const { return reinterpret_cast<char_cptr>(this) + ThisSize_(); }
    };

/*    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // 頂点グループ
    struct VertexGroup : Chunk {
      VertexGroup() : Chunk( CPL_MFI_CHUNK_VTXGROUP, sizeof(*this) ) {}

      U32 m_vtx_num  : 30;
      U32 m_idx_type : 2;  // 32 or 16 or 8
      U16 m_idx_table[ 2 ];
      
      size_t    InfoSize_() const { return sizeof(*this) - sizeof(m_idx_table); }
      size_t    ThisSize_() const { return InfoSize_() + (m_vtx_num * m_idx_type / 8); }
      void_cptr DataAddr_() const { return reinterpret_cast<char_cptr>(this) + InfoSize_(); }
      void_cptr NextAddr_() const { return reinterpret_cast<char_cptr>(this) + ThisSize_(); }
    };*/

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // ポリゴン
    struct Polygon : Chunk
    {
      Polygon() : Chunk( CPL_MFI_CHUNK_POLYGON, sizeof(*this) ) {}

      U32 m_poly_num;
      U32 m_idx_type; // 32 or 16 or 8

      union {
        U32 m_index32[1][3];
        U16 m_index16[2][3];
        U8  m_index8 [4][3];
      };

      size_t    InfoSize_() const { return sizeof(*this) - sizeof(m_index32); }
      size_t    ThisSize_() const { return InfoSize_() + (m_poly_num * 3 * m_idx_type / 8); }
      void_cptr DataAddr_() const { return reinterpret_cast<char_cptr>(this) + InfoSize_(); }
      void_cptr NextAddr_() const { return reinterpret_cast<char_cptr>(this) + ThisSize_(); }
    };

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // ボーン
    struct Bone : Chunk
    {
      Bone() : Chunk( CPL_MFI_CHUNK_BONEDATA, sizeof(*this) ) {}

      TypeGID  m_GID;
      TypeGID  m_GID_next;
      TypeGID  m_GID_child;
      U32      m_blend_parent;
      CVector3 m_vec_pos;
      CVector3 m_vec_rot;
      CVector3 m_vec_scl;

      void_cptr NextAddr_() const { return reinterpret_cast<void_cptr>(this + 1); }
    };

    struct TexCoordSet : Chunk
    {
      TexCoordSet() : Chunk( CPL_MFI_CHUNK_TEXCDSET, sizeof(*this) ) {}

      TypeGID m_GID;
      U16     m_stage_num; // ステージ数
      U16     m_dim_num;   // 座標数
      float   m_coord[1];

      char_cptr DataAddr_() const {
        return reinterpret_cast<char_cptr>(m_coord);
      }
    };
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // シェーダー
  struct Shader : Chunk
  {
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // シェーダ用データチャンク
    struct ShaderData : Chunk
    {
      union {
        U64  m_shader_data_type;
        char m_shader_data_type_c[ 8 ];
      };
      ShaderData( char_cptr data_type )
        : Chunk( data_type, 0 )
        , m_shader_data_type(0)
      {}
      ShaderData()
        : Chunk( (U64)0, 0 )
        , m_shader_data_type(0)
      {}
    };

    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // シェーダ用共通チャンク
    struct ShaderInfo : Chunk
    {
      char       m_target[ 12 ]; // 頂点シェーダバージョン
      U32        m_data_num;
      ShaderData m_data[1];

      ShaderInfo( U64 in_type, long in_size )
        : Chunk( in_type, in_size )
      {}
      ShaderInfo( char const* in_type, long in_size )
        : Chunk( in_type, in_size )
      {}

    private:
      template<class T> bool operator == ( T const& ){ return false; }
    };

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // 頂点シェーダー
    struct VSInfo : ShaderInfo
    {
      //VSInfo( VSInfo const& in_vsi );
      VSInfo() : ShaderInfo(CPL_MFI_CHUNK_VSINFO,0){}
      ~VSInfo(){}
      U32 blend_mtx_max : 16;
      U32 blend_idx_num : 13;
      U32 f_ps_light    : 1;
      U32 f_billboard   : 1;
      U32 f_color_type  : 1; // 0:vertex color 1:material color
    };
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // ピクセルシェーダー
    struct PSInfo : ShaderInfo
    {
      PSInfo() : ShaderInfo( CPL_MFI_CHUNK_PSINFO, 0 ) {}
      ~PSInfo(){}
    };

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    TypeGID m_GID;
    TypeGID m_GID_declaration;
    VSInfo  m_vs_info;
    PSInfo  m_ps_info;
//    U32    m_format_num;
//    U8     m_format[ 64 ]; // 4byte アライメントすること（64個ではない）

    int       InfoSize_() const { return sizeof(*this); }
    void_cptr NextAddr_() const { return reinterpret_cast<char_cptr>(this) + InfoSize_(); }

    Shader( VSInfo const& in_vsi, PSInfo const& in_psi )
      : Chunk( CPL_MFI_CHUNK_TEXINFO, sizeof(*this) )
      , m_vs_info(in_vsi)
      , m_ps_info(in_psi)
    {}
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // テクスチャ基本情報
  struct baseTexture : Chunk {
    baseTexture() : Chunk( CPL_MFI_CHUNK_TEXINFO, sizeof(*this) ) {}

    TypeGID m_GID;
    U32     m_tex_type; // 0:Common  1:BuiltIn
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 共通テクスチャ情報
  struct CommonTexture : public baseTexture {
    int  m_path_length; // バッファサイズは m_path_length + 1 となる（ただし４バイトアライメントされる）
    char m_path[ _MAX_PATH ];

    size_t    ThisSize_() const { return sizeof(*this) - sizeof(m_path) + (m_path_length + 1 + 3) / 4 * 4; }
    void_cptr NextAddr_() const { return reinterpret_cast<char_cptr>(this) + ThisSize_(); }
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 組み込みテクスチャ情報
  struct BuiltInTexture : public baseTexture {
    U32  m_tex_size;
    char m_buffer[ sizeof(long) ];

    void_cptr NextAddr_() const
    {
      return reinterpret_cast<char_cptr>(this + 1) - sizeof(long) + m_size;
    }
    long      InfoSize_() const
    {
      return sizeof(*this) - sizeof(m_buffer);
    }
  };

//  // 内包テクスチャテーブル
//  struct PrivateTextureTable {
//    U32 m_texture_num;
//
//    // 内包テクスチャ情報
//    struct PrivateTexture {
//      int  m_GID;
//      U32  m_size;
//      char m_buffer[ sizeof(long) ];
//
//    };
//  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // カラーマテリアル
  struct ColorMaterial : Chunk {
    ColorMaterial() : Chunk( CPL_MFI_CHUNK_CLRMTRL, sizeof(*this) ) {}

    TypeGID m_GID;
    U32     m_format; // bit0～bit3にparam0～param3の使用フラグを割り当て
    struct param {
      TypeGID GID;
      U32     color;
    } m_param[ kCOLOR_MTRL_PARAM_NUM ];

    void_cptr NextAddr_() const
    {
      return reinterpret_cast<char_cptr>(this + 1) + sizeof(param) * (kCOLOR_MTRL_PARAM_NUM-1);
    }
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // テクスチャマテリアル
  struct TextureMaterial : Chunk {
    TextureMaterial() : Chunk( CPL_MFI_CHUNK_TEXMTRL, sizeof(*this) ) {}

    TypeGID m_GID;
    int     m_stage_num;
    struct zzc_param {
      int  tex_index;  // 使用テクスチャのインデックス
      int  use_type;   // 使用タイプ
    } m_param[ kTEX_MTRL_PARAM_NUM ];
    
    void_cptr NextAddr_() const
    {
      return reinterpret_cast<char_cptr>(this + 1) + sizeof(m_param) * (kTEX_MTRL_PARAM_NUM-1);
    }
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // ライトマテリアル
  struct Light : Chunk {
    Light() : Chunk( CPL_MFI_CHUNK_LITMTRL, sizeof(*this) ) {}

    U32                   m_GID;
    U32                   m_GID_keylist_pos;
    U32                   m_GID_keylist_rot;
    U32                   m_GID_keylist_color;
    U32                   m_GID_keylist_power;
    U32                   m_GID_relation_matrix;
    CVector3              m_vec_pos;
    CVector3              m_vec_rot;
    Core::Color::A8R8G8B8 m_color;
    float                 m_power; // ライトパワー（距離？）
    float                 m_theta; // スポットライト内部コーン角度
    float                 m_phi;   // スポットライト外部コーン角度
    int                   m_light_type;

    void_cptr NextAddr_() const { return static_cast<void_cptr>(this + 1); }
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // アニメーションデータ
  struct AnmData : Chunk {
    AnmData() : Chunk( CPL_MFI_CHUNK_ANMDATA, sizeof(*this) ) {}

    // ローカルデータ
    U32  m_GID;
    U32  m_UID; // ユーザーID
    U32  m_keylist_num;
    char m_name[ 16 ];

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // キーリスト
    struct KeyList : Chunk {
      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // キーフレーム
      struct baseKey {
        U32 m_index       : 31; // インデックス
        U32 m_interpolate :  1; // 補間
        baseKey( U32 in_index, U32 in_flag_interpolate )
          : m_index( in_index )
          , m_interpolate( in_flag_interpolate )
        {}
        baseKey() : m_index(0), m_interpolate(false) {}
      };
      struct KeyEvent : baseKey {
        U32 m_ev_type;  // 0: wait  1: loop start  2:loop end
        U32 m_ev_value;
        KeyEvent(
          U32 in_index,
          U32 in_flag_interpolate,
          U32 in_event_type,
          U32 in_event_value )
          : baseKey( in_index, in_flag_interpolate )
          , m_ev_type( in_event_type )
          , m_ev_value( in_event_value )
        {}
      };
      struct KeyVec : baseKey {
        CVector3 m_vec;
        KeyVec( U32 in_index, U32 in_flag_interpolate, CVector3 const& in_vec )
          : baseKey( in_index, in_flag_interpolate )
          , m_vec(in_vec)
        {}
      };
      struct KeyColor : baseKey {
        Core::Color::A8R8G8B8 m_color;
        KeyColor( U32 in_index, U32 in_flag_interpolate, Core::Color::A8R8G8B8 in_color )
          : baseKey( in_index, in_flag_interpolate )
          , m_color(in_color)
        {}
      };
      struct KeyValue : baseKey {
        float m_value;
        KeyValue( U32 in_index, U32 in_flag_interpolate, float in_value )
          : baseKey( in_index, in_flag_interpolate )
          , m_value(in_value)
        {}
      };
      struct KeyTexCoord : baseKey {
        U32 m_GID_texture;
        KeyTexCoord( U32 in_index, U32 in_flag_interpolate, U32 in_GID_tex )
          : baseKey( in_index, in_flag_interpolate )
          , m_GID_texture( in_GID_tex )
        {}
      };
      
      // キーリストデータ
      TypeGID  m_GID;
      TypeGID  m_GID_next;
      TypeGID  m_GID_parent;
      TypeGID  m_GID_relation;
      U32      m_key_num;
      eKeyType m_key_type;
      baseKey  m_Key[1];

      KeyList()
        : Chunk( CPL_MFI_CHUNK_KEYLIST, 0 )
      {}
    };
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // バッファレイアウトデータ
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  struct BufferLayout : Chunk {
    TypeGID             m_GID;
    U32                 m_element_num;
    DX::Layout::Element m_element[ 1 ];

    BufferLayout() : Chunk( CPL_MFI_CHUNK_VTXDECL, 0 ) {}
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 識別子用
  struct Identifier {
    TypeGID m_GID;     // 対応するグローバルＩＤ（このＩＤと比較して識別文字列を割り当てる）
    int     m_length;  // m_nameの予約サイズ(null文字を含み４の倍数となる)
    char    m_name[1]; // 識別文字列（nullを含み、4byteアライメントされている）
  };

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 識別文字列テーブル
  // ※ 識別子は必ずデータの最後尾に配置されること
  struct IdentifierTable {
    int m_item_num;
    int m_offset[ 1 ];

    Identifier const* GetIdentifier( int in_index ) const
    {
      if( FAILED_INDEX(in_index, m_item_num-1) )
      {
        return nullptr;
      }

      Identifier const* ptr_identifier =
        reinterpret_cast<Identifier const*>(m_offset + m_item_num);
      while( in_index-- )
      {
        ptr_identifier =
          reinterpret_cast<Identifier const*>(
            reinterpret_cast<char const*>(ptr_identifier)
              + sizeof(ptr_identifier->m_length)
              + ptr_identifier->m_length);
      }
      return ptr_identifier;
    }
  };
};


typedef MeshFileInfo::Header                        MFI_Header;
typedef MeshFileInfo::Object                        MFI_Object;
typedef MeshFileInfo::Object::VertexStreamData      MFI_VertexStreamData;
typedef MeshFileInfo::Object::Polygon               MFI_Polygon;
typedef MeshFileInfo::Object::Bone                  MFI_Bone;
typedef MeshFileInfo::Object::TexCoordSet           MFI_TexCoordSet;
typedef MeshFileInfo::Shader                        MFI_Shader;
typedef MeshFileInfo::Shader::VSInfo                MFI_ShaderInfoVS;
typedef MeshFileInfo::Shader::PSInfo                MFI_ShaderInfoPS;
typedef MeshFileInfo::baseTexture                   MFI_baseTexture;
typedef MeshFileInfo::CommonTexture                 MFI_CommonTexture;
typedef MeshFileInfo::BuiltInTexture                MFI_BuiltInTexture;
typedef MeshFileInfo::ColorMaterial                 MFI_ColorMaterial;
typedef MeshFileInfo::TextureMaterial               MFI_TextureMaterial;
typedef MeshFileInfo::Light                         MFI_LightMaterial;
typedef MeshFileInfo::AnmData                       MFI_AnimeData;
typedef MeshFileInfo::AnmData::KeyList              MFI_AnimeKeyList;
typedef MeshFileInfo::AnmData::KeyList::baseKey     MFI_baseKeyFrame;
typedef MeshFileInfo::AnmData::KeyList::KeyEvent    MFI_KeyEvent;
typedef MeshFileInfo::AnmData::KeyList::KeyVec      MFI_KeyVector;
typedef MeshFileInfo::AnmData::KeyList::KeyColor    MFI_KeyColor;
typedef MeshFileInfo::AnmData::KeyList::KeyTexCoord MFI_KeyTexCoord;
typedef MeshFileInfo::AnmData::KeyList::KeyValue    MFI_KeyValue;
typedef MeshFileInfo::BufferLayout                  MFI_BufferLayout;
typedef MeshFileInfo::Identifier                    MFI_Identifier;
typedef MeshFileInfo::IdentifierTable               MFI_IdentifierTable;




} // namespace CDI
} // namespace CPL
