/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2015/11/11
/// 
/// @brief  DirectX  頂点定義。
/// 
/// ****************************************************************************

#pragma once

#include "CPL_DX_Kernel.h"


namespace CPL {
namespace DX {


namespace Vtx {

// 型識別用簡易化マクロ？
#define CPL_DEF_DXVTX_GET_COMMON_TYPE_( type, newtype_, func_name )\
typedef type newtype_;\
CPL_DEF_TYPE_PTR_REF2_( type, newtype_ );\
newtype_##_cref func_name() const { return *static_cast<newtype_##_cptr>( this ); }\
newtype_##_ref  func_name()       { return *static_cast<newtype_##_ptr>( this ); }


typedef DXGI_FORMAT VtxFormat_;
typedef float4      TypeColor;
 
// _____________________________________________________________________________
/// @brief CorePLiで扱う一意に扱うための頂点フォーマットコード。
/// 
/// ※ ビット割り当てではなく、IDの配列格納
///    （配列インデックスとしても使うので、VTID_NUMまでは連番でなければならない）
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enum eTypeID
{ kType_XYZ
, kType_XYZW
, kType_BLEND_WEIGHT1
, kType_BLEND_WEIGHT2
, kType_BLEND_WEIGHT3
, kType_BLEND_INDEX
, kType_NORMAL
, kType_PSIZE
, kType_TANGENT   // 接線
, kType_BINORMAL  // 従法線
, kType_TESSFACTOR// テセレーション係数
, kType_FOG
, kType_DEPTH
, kType_TEXCOORD0
, kType_TEXCOORD1
, kType_TEXCOORD2
, kType_TEXCOORD3
, kType_TEXCOORD4
, kType_TEXCOORD5
, kType_TEXCOORD6
, kType_TEXCOORD7
, kType_COLOR0
, kType_COLOR1
, kType_COLOR2
, kType_COLOR3
, kType_COLOR4
, kType_COLOR5
, kType_COLOR6
, kType_COLOR7

, kType_NUM

, kType_NULL  = -1
, kType_ERROR = -2

, kType_BLEND_WEIGHT_BEGIN = kType_BLEND_WEIGHT1
, kType_BLEND_WEIGHT_END   = kType_BLEND_WEIGHT3
, kType_TEXCOORD_BEGEN     = kType_TEXCOORD0
, kType_TEXCOORD_END       = kType_TEXCOORD7
, kType_COLOR_BEGIN        = kType_COLOR0
, kType_COLOR_END          = kType_COLOR7
};
 
// _____________________________________________________________________________
/// @brief ｘｙｚ
///
// *****************************************************************************
struct XYZ {
  float x, y, z;

  XYZ(){}
  XYZ( const XYZ& xyz )
    : x( xyz.x ), y( xyz.y ), z( xyz.z )
  {}
  XYZ( float X, float Y, float Z )
    : x( X ), y( Y ), z( Z )
  {}

  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "POSITION" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_XYZ;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ｘｙｚｗ
///
// *****************************************************************************
struct XYZRHW : XYZ {
  float w; // 同次ｗの逆数

  XYZRHW(){}
  XYZRHW( const XYZRHW& xyzw )
    : XYZ( xyzw.x, xyzw.y, xyzw.z ), w( xyzw.w )
  {}
  XYZRHW( float X, float Y, float Z, float W )
    : XYZ( X, Y, Z ), w( W )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "POSITIONT" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32A32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_XYZW;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZRHW, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ブレンディングウエイト×１
///
// *****************************************************************************
struct BWeight1 {
  float bw0;

  BWeight1(){}
  BWeight1( const BWeight1& bw )
    : bw0( bw.bw0 )
  {}
  BWeight1( float BW0 )
    : bw0( BW0 )
  {}

  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "BLENDWEIGHT0" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_BLEND_WEIGHT1;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight1, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ブレンディングウエイト×２
///
// *****************************************************************************
struct BWeight2 : BWeight1 {
  float bw1;

  BWeight2(){}
  BWeight2( const BWeight2& bw )
    : BWeight1( bw.bw0 )
    , bw1( bw.bw1 )
  {}
  BWeight2( float BW0, float BW1 )
    : BWeight1( BW0 )
    , bw1( BW1 )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "BLENDWEIGHT1" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_BLEND_WEIGHT2;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight2, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ブレンディングウエイト×３
///
// *****************************************************************************
struct BWeight3 : BWeight2 {
  float bw2;

  BWeight3(){}
  BWeight3( const BWeight3& bw )
    : BWeight2( bw.bw0, bw.bw1 )
    , bw2( bw.bw2 )
  {}
  BWeight3( float BW0, float BW1, float BW2 )
    : BWeight2( BW0, BW1 )
    , bw2( BW2 )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "BLENDWEIGHT2" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_BLEND_WEIGHT3;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight3, type0, get0 )
};


// _____________________________________________________________________________
/// @brief 頂点ブレンディングインデックス
///
// *****************************************************************************
struct BIndex {
  union {
    struct {
      U8  bi0, bi1, bi2, bi3;
    };
    U32 bIndex;
  };

  BIndex(){}
  BIndex( const BIndex& bi )
    : bIndex( bi.bIndex )
  {}
  BIndex( U32 index )
    : bIndex( index )
  {}
  BIndex( U8 i0, U8 i1, U8 i2 = 0, U8 i3 = 0 )
    : bi0( i0 ), bi1( i1 ), bi2( i2 ), bi3( i3 )
  {}
  void SetBlendIndex( U8 i0, U8 i1, U8 i2, U8 i3 )
  {
    bi0 = i0;
    bi1 = i1;
    bi2 = i2;
    bi3 = i3;
  }

  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "BLENDINDICES" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R8G8B8A8_UINT;
  static const eTypeID     kTYPE_ID    = kType_BLEND_INDEX;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex, type0, get0 )
};

// _____________________________________________________________________________
/// @brief 頂点ブレンディング　ウエイト×１＆インデックス
///
// *****************************************************************************
struct Blend1 : BWeight1, BIndex {
  Blend1(){}
  Blend1( const Blend1& b )
    : BWeight1( b.bw0 )
    , BIndex( b.bIndex )
  {}
  Blend1( float bw, DWORD index )
    : BWeight1( bw )
    , BIndex( index )
  {}

  static const int kFORMAT_NUM = BWeight1::kFORMAT_NUM + BIndex::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight1, type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type1, get1 )
};

// _____________________________________________________________________________
/// @brief 頂点ブレンディング　ウエイト×２＆インデックス
///
// *****************************************************************************
struct Blend2 : BWeight2, BIndex {
  Blend2(){}
  Blend2( const Blend2& b )
    : BWeight2( b.bw0, b.bw1 )
    , BIndex( b.bIndex )
  {}
  Blend2( float bw0, float bw1, DWORD index )
    : BWeight2( bw0, bw1 )
    , BIndex( index )
  {}
  Blend2( float bw0, float bw1, U8 index0, U8 index1 )
    : BWeight2( bw0, bw1 )
    , BIndex( index0, index1 )
  {}
  
  static const int kFORMAT_NUM = BWeight2::kFORMAT_NUM + BIndex::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight2, type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type1, get1 )
};

// _____________________________________________________________________________
/// @brief 頂点ブレンディング　ウエイト×３＆インデックス
///
// *****************************************************************************
struct Blend3 : BWeight3, BIndex {
  Blend3(){}
  Blend3( const Blend3& b )
    : BWeight3( b.bw0, b.bw1, b.bw2 )
    , BIndex( b.bIndex )
  {}
  Blend3( float bw0, float bw1, float bw2, DWORD index )
    : BWeight3( bw0, bw1, bw2 )
    , BIndex( index )
  {}
  Blend3( float bw0, float bw1, float bw2, U8 index0, U8 index1, U8 index2 )
    : BWeight3( bw0, bw1, bw2 )
    , BIndex( index0, index1, index2 ) {}
  
  static const int kFORMAT_NUM = BWeight3::kFORMAT_NUM + BIndex::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight3, type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type1, get1 )
};


// _____________________________________________________________________________
/// @brief 頂点法線
///
// *****************************************************************************
struct Normal {
  float nx, ny, nz;

  Normal(){}
  Normal( const Normal& nr )
    : nx( nr.nx ), ny( nr.ny ), nz( nr.nz )
  {}
  Normal( float x, float y, float z )
    : nx( x ), ny( y ), nz( z )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "NORMAL" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_NORMAL;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Normal, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ポイントサイズ
///
// *****************************************************************************
struct PSize {
  float psize;

  PSize(){}
  PSize( const PSize& ps )
    : psize( ps.psize )
  {}
  PSize( float size )
    : psize( size )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "PSIZE" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_PSIZE;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( PSize, type0, get0 )
};

// _____________________________________________________________________________
/// @brief ディフューズ色
///
// *****************************************************************************
struct Diffuse {
  TypeColor diffuse; // カラー

  Diffuse(){}
  Diffuse( const Diffuse& d )
    : diffuse( d.diffuse )
  {}
  Diffuse( TypeColor const& C )
    : diffuse( C )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "COLOR" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32A32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_COLOR0;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type0, get0 )
};

// _____________________________________________________________________________
/// @brief スペキュラー色
///
// *****************************************************************************
struct Specular {
  TypeColor specular;

  Specular(){}
  Specular( Specular const& sp )
    : specular( sp.specular )
  {}
  Specular( TypeColor const& C )
    : specular( C )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "COLOR" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32A32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_COLOR0;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Specular, type0, get0 )
};

// _____________________________________________________________________________
/// @brief 汎用カラー
///
// *****************************************************************************
template<int COLOR_NUM>
struct Color {
  TypeColor color[ COLOR_NUM ];

  Color(){}
  Color( TypeColor const* in_ptr_color_table )
  {
    ::memcpy( color, in_ptr_color_table, sizeof( color ) );
  }
  Color( Color const& in_color )
  {
    ::memcpy( color, in_color.color, sizeof( color ) );
  }
  
  static char_cptr SEMANTIC()
  {
    static char sem[] = { 'C', 'O', 'L', 'O', 'R', 0};
    return sem;
  }
  
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32A32_FLOAT;
  static const eTypeID     kTYPE_ID    = (eTypeID)(kType_COLOR0 + COLOR_NUM - 1);
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Color<COLOR_NUM>, type0, get0 )
};


// _____________________________________________________________________________
/// @brief テクスチャ座標×１
///
// *****************************************************************************
struct UV0 {
private:
  class zzc_texcoord_u_ {
    float zzv_u;
    float zzv_dummy;
  public:
    operator float() const { return zzv_u; }
    float& operator = ( float u ){ zzv_u = u; return zzv_u; }
  };
  class zzc_texcoord_v_ {
    float zzv_dummy;
    float zzv_v;
  public:
    operator float() const { return zzv_v; }
    float& operator = ( float v ){ zzv_v = v; return zzv_v; }
  };
public:
  union {
    struct {
      float u0, v0;
    };
    zzc_texcoord_u_ u[1];
    zzc_texcoord_v_ v[1];
  };

  UV0(){}
  UV0( const UV0& uv ) : u0( uv.u0 ), v0( uv.v0 ) {}
  UV0( float u, float v ) : u0( u ), v0( v ) {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TEXCOORD" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_TEXCOORD0;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0, type0, get0 )
};

// _____________________________________________________________________________
/// @brief テクスチャ座標×２
///
// *****************************************************************************
struct UV1 : UV0 {
  float u1, v1;

  UV1(){}
  UV1( const UV1& uv )
    : UV0( uv.u0, uv.v0 )
    , u1( uv.u1 )
    , v1( uv.v1 )
  {}
  UV1( float U0, float V0, float U1, float V1 )
    : UV0( U0, V0 )
    , u1( U1 )
    , v1( V1 )
  {}
  
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TEXCOORD" )
  static const eTypeID     kTYPE_ID    = kType_TEXCOORD1;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV1, type0, get0 )
};

// _____________________________________________________________________________
/// @brief テクスチャ座標×３
///
// *****************************************************************************
struct UV2 : UV1 {
  float u2, v2;

  UV2(){}
  UV2( const UV2& uv )
    : UV1( uv.u0, uv.v0, uv.u1, uv.v1 )
    , u2( uv.u2 )
    , v2( uv.v2 )
  {}
  UV2( float U0, float V0, float U1, float V1, float U2, float V2 )
    : UV1( U0, V0, U1, V1 )
    , u2( U2 )
    , v2( V2 )
  {}
    
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TEXCOORD" )
  static const eTypeID     kTYPE_ID    = kType_TEXCOORD2;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV2, type0, get0 )
};

// _____________________________________________________________________________
/// @brief テクスチャ座標×４
///
// *****************************************************************************
struct UV3 : UV2 {
  float u3, v3;

  UV3(){}
  UV3( const UV3& uv )
    : UV2( uv.u0, uv.v0, uv.u1, uv.v1, uv.u2, uv.v2 )
    , u3( uv.u3 )
    , v3( uv.v3 )
  {}
  UV3( float U0, float V0, float U1, float V1, float U2, float V2, float U3, float V3 )
    : UV2( U0, V0, U1, V1, U2, V2 )
    , u3( U3 )
    , v3( V3 )
  {}
    
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TEXCOORD" )
  static const eTypeID     kTYPE_ID    = kType_TEXCOORD3;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV3, type0, get0 )
};

//// =============================================================================
//// 深度
//struct Depth {
//  float depth;
//
//  Depth(){}
//  Depth( const Depth& in_depth ) : depth( in_depth.depth ) {}
//  Depth( float in_depth ) : depth( in_depth ) {}
//  
//  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "DEPTH" )
//  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32_FLOAT;
//  static const eTypeID     kTYPE_ID    = kType_DEPTH;
//  static const int         kFORMAT_NUM = 1;
//
//  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Depth, type0, get0 )
//};

// _____________________________________________________________________________
/// @brief 接線
///
// *****************************************************************************
struct Tangent {
  float tx, ty, tz;

  Tangent(){}
  Tangent( const Tangent& in_tangent )
    : tx( in_tangent.tx )
    , ty( in_tangent.ty )
    , tz( in_tangent.tz )
  {}
  Tangent( float in_tx, float in_ty, float in_tz )
    : tx( in_tx )
    , ty( in_ty )
    , tz( in_tz )
  {}
    
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TANGENT" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_TANGENT;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Tangent, type0, get0 )
};

// _____________________________________________________________________________
/// @brief 従法線
///
// *****************************************************************************
struct BINormal {
  float bnx, bny, bnz;

  BINormal(){}
  BINormal( const BINormal& in_binormal )
    : bnx( in_binormal.bnx )
    , bny( in_binormal.bny )
    , bnz( in_binormal.bnz )
  {}
  BINormal( float in_bnx, float in_bny, float in_bnz )
    : bnx( in_bnx )
    , bny( in_bny )
    , bnz( in_bnz )
  {}
    
  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "BINORMAL" )
  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32G32B32_FLOAT;
  static const eTypeID     kTYPE_ID    = kType_BINORMAL;
  static const int         kFORMAT_NUM = 1;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BINormal, type0, get0 )
};

//// =============================================================================
//// テセレーション
//struct TessFactor {
//  float tess_factor;
//
//  TessFactor(){}
//  TessFactor( const TessFactor& in_tess_factor )
//    : tess_factor( in_tess_factor.tess_factor ) {}
//  TessFactor( float in_tess_factor )
//    : tess_factor( in_tess_factor ) {}
//    
//  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "TESSFACTOR" )
//  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32_FLOAT;
//  static const eTypeID     kTYPE_ID    = kType_TESSFACTOR;
//  static const int         kFORMAT_NUM = 1;
//
//  CPL_DEF_DXVTX_GET_COMMON_TYPE_( TessFactor, type0, get0 )
//};

//// =============================================================================
//// フォグ
//struct Fog {
//  float fog;
//
//  Fog() {}
//  Fog( const Fog& in_fog ) : fog( in_fog.fog ) {}
//  Fog( float in_fog ) : fog( in_fog ) {}
//  
//  CPL_SINGLETON_INIT( char_cptr, SEMANTIC, "
//  static const VtxFormat_  kFORMAT     = DXGI_FORMAT_R32_FLOAT;
//  static const eTypeID     kTYPE_ID    = kType_FOG;
//  static const int         kFORMAT_NUM = 1;
//
//  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Fog, type0, get0 )
//};




// _____________________________________________________________________________
/// @brief トランスフォーム済み・カラー
///
// *****************************************************************************
struct XYZWC : XYZRHW, Diffuse {
  XYZWC(){}
  XYZWC( const XYZWC& v )
    : XYZRHW( v.x, v.y, v.z, v.w )
    , Diffuse( v.diffuse )
  {}
  XYZWC( float X, float Y, float Z, float W, TypeColor const& C )
    : XYZRHW( X, Y, Z, W )
    , Diffuse( C )
  {}
  ~XYZWC(){}

  static const int kFORMAT_NUM = XYZRHW::kFORMAT_NUM + Diffuse::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZRHW,  type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type1, get1 )
};


// _____________________________________________________________________________
/// @brief トランスフォーム済み・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZWCT1 : XYZWC, UV0 {
  XYZWCT1(){}
  XYZWCT1( const XYZWCT1& v )
    : XYZWC( v.x, v.y, v.z, v.w, v.diffuse )
    , UV0( v.u0, v.v0 )
  {}
  XYZWCT1( float X, float Y, float Z, float W, TypeColor const& C, float U, float V )
    : XYZWC( X, Y, Z, W, C )
    , UV0( U, V )
  {}
  ~XYZWCT1(){}
  
  static const int kFORMAT_NUM = XYZWC::kFORMAT_NUM + UV0::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZRHW,  type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,     type2, get2 )
};



// _____________________________________________________________________________
/// @brief 未トランスフォーム・カラー
///
// *****************************************************************************
struct XYZC : XYZ, Diffuse {
  XYZC(){}
  XYZC( const XYZC& v )
    : XYZ( v.x, v.y, v.z )
    , Diffuse( v.diffuse )
  {}
  XYZC( float X, float Y, float Z, TypeColor C )
    : XYZ( X, Y, Z )
    , Diffuse( C )
  {}
  ~XYZC(){}
  
  static const int kFORMAT_NUM = XYZ::kFORMAT_NUM + Diffuse::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,     type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type1, get1 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZCT1 : XYZC, UV0 {
  XYZCT1(){}
  XYZCT1( const XYZCT1& v )
    : XYZC( v.x, v.y, v.z, v.diffuse )
    , UV0( v.u0, v.v0 )
  {}
  XYZCT1( float X, float Y, float Z, TypeColor C, float U, float V )
    : XYZC( X, Y, Z, C )
    , UV0( U, V )
  {}
  ~XYZCT1(){}
  
  static const int kFORMAT_NUM = XYZWC::kFORMAT_NUM + UV0::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,     type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,     type2, get2 )
};


//// =============================================================================
//// 未トランスフォーム・ブレンドウエイト・カラー
//// =============================================================================
//struct XYZB1C : XYZ, BWeight1, Diffuse {
//  XYZB1C(){}
//  XYZB1C( const XYZB1C& v )
//    : XYZ( v.x, v.y, v.z ), 
//      BWeight1( v.bw0 ), 
//      Diffuse( v.diffuse ) {}
//  XYZB1C( float X, float Y, float Z, float BW, TypeColor C )
//    : XYZ( X, Y, Z ), BWeight1( BW ), Diffuse( C ) {}
//  ~XYZB1C(){}
//};


//// =============================================================================
//// 未トランスフォーム・ブレンディングウエイト・カラー・ＵＶ×１
//// =============================================================================
//struct XYZB1CT1 : XYZB1C, UV0 {
//  XYZB1CT1(){}
//  XYZB1CT1( const XYZB1CT1& v )
//    : XYZB1C( v.x, v.y, v.z, v.bw0, v.diffuse ), 
//      UV0( v.u0, v.v0 ) {}
//  XYZB1CT1( float X, float Y, float Z, float BW, TypeColor C, float U, float V )
//    : XYZB1C( X, Y, Z, BW, C ), 
//      UV0( U, V ) {}
//  ~XYZB1CT1(){}
//};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・インデックス付きブレンド・カラー
///
// *****************************************************************************
struct XYZBi1C : XYZ, Blend1, Diffuse {
  XYZBi1C(){}
  XYZBi1C( const XYZBi1C& v )
    : XYZ( v.x, v.y, v.z )
    , Blend1( v.bw0, v.bIndex )
    , Diffuse( v.diffuse )
  {}
  XYZBi1C( float X, float Y, float Z, float BW, U32 index, TypeColor C )
    : XYZ( X, Y, Z )
    , Blend1( BW, index )
    , Diffuse( C )
  {}
  ~XYZBi1C(){}
  
  static const int kFORMAT_NUM =
    XYZ::kFORMAT_NUM + Blend1::kFORMAT_NUM + Diffuse::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,      type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight1, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type2, get2 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse,  type3, get3 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・インデックス付きブレンド・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZBi1CT1 : XYZBi1C, UV0 {
  XYZBi1CT1(){}
  XYZBi1CT1( const XYZBi1CT1& v )
    : XYZBi1C( v.x, v.y, v.z, v.bw0, v.bIndex, v.diffuse )
    , UV0( v.u0, v.v0 )
  {}
  XYZBi1CT1( float X, float Y, float Z, float BW, U32 index, TypeColor C, float U, float V )
    : XYZBi1C( X, Y, Z, BW, index, C )
    , UV0( U, V )
  {}
  ~XYZBi1CT1(){}
  
  static const int kFORMAT_NUM = XYZBi1C::kFORMAT_NUM + UV0::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,      type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight1, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type2, get2 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse,  type3, get3 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,      type4, get4 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・法線・カラー
///
// *****************************************************************************
struct XYZNrC : XYZ, Normal, Diffuse {
  XYZNrC(){}
  XYZNrC( const XYZNrC& v )
    : XYZ( v.x, v.y, v.z )
    , Normal( v.nx, v.ny, v.nz )
    , Diffuse( v.diffuse )
  {}
  XYZNrC( float X, float Y, float Z, float Nx, float Ny, float Nz, TypeColor C )
    : XYZ( X, Y, Z )
    , Normal( X, Y, Z )
    , Diffuse( C )
  {}
  ~XYZNrC(){}
  
  static const int kFORMAT_NUM =
    XYZ::kFORMAT_NUM + Normal::kFORMAT_NUM + Diffuse::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,     type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Normal,  type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type2, get2 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・法線・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZNrCT1 : XYZNrC, UV0 {
  XYZNrCT1(){}
  XYZNrCT1( const XYZNrCT1& v )
    : XYZNrC( v.x, v.y, v.z, v.nx, v.ny, v.nz, v.diffuse )
    , UV0( v.u0, v.v0 )
  {}
  XYZNrCT1( float X, float Y, float Z, float Nx, float Ny, float Nz, TypeColor C, float U, float V )
    : XYZNrC( X, Y, Z, Nx, Ny, Nz, C )
    , UV0( U, V )
  {}
  ~XYZNrCT1(){}
  
  static const int kFORMAT_NUM = XYZNrC::kFORMAT_NUM + UV0::kFORMAT_NUM;
  
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,     type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Normal,  type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse, type2, get2 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,     type3, get3 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・インデックス付きブレンド・法線・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZBi1NrCT1 : XYZ, Blend1, Normal, Diffuse, UV0 {
  XYZBi1NrCT1(){}
  XYZBi1NrCT1( const XYZBi1NrCT1& v )
    : XYZ    ( v.x, v.y, v.z )
    , Blend1 ( v.bw0, v.bIndex )
    , Diffuse( v.diffuse )
    , UV0    ( v.u0, v.v0 )
  {}
  XYZBi1NrCT1( float X, float Y, float Z, float BW, U32 index, float Nx, float Ny, float Nz, TypeColor C, float U, float V )
    : XYZ    ( X, Y, Z )
    , Blend1 ( BW, index )
    , Normal ( Nx, Ny, Nz )
    , Diffuse( C )
    , UV0    ( U, V )
  {}
  ~XYZBi1NrCT1(){}
  
  static const int kFORMAT_NUM =
    XYZ::kFORMAT_NUM + Blend1::kFORMAT_NUM + Normal::kFORMAT_NUM + Diffuse::kFORMAT_NUM + UV0::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,      type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight1, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type2, get2 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Normal,   type3, get3 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse,  type4, get4 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,      type5, get5 )
};


// _____________________________________________________________________________
/// @brief 未トランスフォーム・インデックス付きブレンド・法線・カラー・ＵＶ×１
///
// *****************************************************************************
struct XYZBi2NrCT1 : XYZ, Blend2, Normal, Diffuse, UV0 {
  XYZBi2NrCT1()
  {}
  XYZBi2NrCT1( const XYZBi2NrCT1& v )
    : XYZ    ( v.x, v.y, v.z )
    , Blend2 ( v.bw0, v.bw1, v.bIndex )
    , Normal ( v.nx, v.ny, v.nz )
    , Diffuse( v.diffuse )
    , UV0    ( v.u0, v.v0 )
  {}
  XYZBi2NrCT1
  ( float X, float Y, float Z,
    float BW0, float BW1,
    U32 index,
    float Nx, float Ny, float Nz,
    TypeColor C, float U, float V )
    : XYZ    ( X, Y, Z )
    , Blend2 ( BW0, BW1, index )
    , Normal ( Nx, Ny, Nz )
    , Diffuse( C )
    , UV0    ( U, V )
  {}
  ~XYZBi2NrCT1(){}
  
  static const int
    kFORMAT_NUM =
      XYZ::kFORMAT_NUM     +
      Blend2::kFORMAT_NUM  +
      Normal::kFORMAT_NUM  +
      Diffuse::kFORMAT_NUM +
      UV0::kFORMAT_NUM;

  CPL_DEF_DXVTX_GET_COMMON_TYPE_( XYZ,      type0, get0 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BWeight2, type1, get1 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( BIndex,   type2, get2 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Normal,   type3, get3 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( Diffuse,  type4, get4 )
  CPL_DEF_DXVTX_GET_COMMON_TYPE_( UV0,      type5, get5 )
};



/// @cond
namespace zzz_ {

// _____________________________________________________________________________
/// @brief 頂点データ共通化用基底クラス
///
// *****************************************************************************
struct baseDataType {
  const S16 type_format;
  const S16 size;
  baseDataType( S16 type_format, S16 size_ )
    : type_format( type_format ), size( size_ ) {}

  // フォーマットの取得用テンプレート
  template<class T> struct zzt_Type_to_Format{ static const int format = kType_NULL; };
};
template<> struct baseDataType::zzt_Type_to_Format<XYZ       > { static const int format = kType_XYZ          ; };
template<> struct baseDataType::zzt_Type_to_Format<XYZRHW    > { static const int format = kType_XYZW         ; };
template<> struct baseDataType::zzt_Type_to_Format<Blend1    > { static const int format = kType_BLEND_WEIGHT1; };
template<> struct baseDataType::zzt_Type_to_Format<Blend2    > { static const int format = kType_BLEND_WEIGHT2; };
template<> struct baseDataType::zzt_Type_to_Format<Blend3    > { static const int format = kType_BLEND_WEIGHT3; };
template<> struct baseDataType::zzt_Type_to_Format<Normal    > { static const int format = kType_NORMAL       ; };
template<> struct baseDataType::zzt_Type_to_Format<PSize     > { static const int format = kType_PSIZE        ; };
template<> struct baseDataType::zzt_Type_to_Format<Tangent   > { static const int format = kType_TANGENT      ; };
template<> struct baseDataType::zzt_Type_to_Format<BINormal  > { static const int format = kType_BINORMAL     ; };
//template<> struct zzt_Type_to_Format<TessFactor> { static const int format = kType_TESSFACTOR   ; };
//template<> struct zzt_Type_to_Format<Depth     > { static const int format = kType_DEPTH        ; };
//template<> struct zzt_Type_to_Format<Fog       > { static const int format = kType_FOG          ; };
template<> struct baseDataType::zzt_Type_to_Format<UV0       > { static const int format = kType_TEXCOORD0    ; };
template<> struct baseDataType::zzt_Type_to_Format<UV1       > { static const int format = kType_TEXCOORD1    ; };
template<> struct baseDataType::zzt_Type_to_Format<UV2       > { static const int format = kType_TEXCOORD2    ; };
template<> struct baseDataType::zzt_Type_to_Format<UV3       > { static const int format = kType_TEXCOORD3    ; };
template<> struct baseDataType::zzt_Type_to_Format<Diffuse   > { static const int format = kType_COLOR0       ; };
template<> struct baseDataType::zzt_Type_to_Format<Specular  > { static const int format = kType_COLOR0       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<1>  > { static const int format = kType_COLOR0       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<2>  > { static const int format = kType_COLOR1       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<3>  > { static const int format = kType_COLOR2       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<4>  > { static const int format = kType_COLOR3       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<5>  > { static const int format = kType_COLOR4       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<6>  > { static const int format = kType_COLOR5       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<7>  > { static const int format = kType_COLOR6       ; };
template<> struct baseDataType::zzt_Type_to_Format<Color<8>  > { static const int format = kType_COLOR7       ; };


// _____________________________________________________________________________
/// @brief 頂点データ設定用構造体
///
// *****************************************************************************
class baseSetDataTypes
  : public baseDataType
{
public:
  void const* m_ptr_data;

protected:
  template<class T>
  baseSetDataTypes( S16 type_, T const& data )
    : baseDataType( type_, sizeof( data ) )
    , m_ptr_data( &data )
  {}

  baseSetDataTypes( S16 type_, S16 size_ )
    : baseDataType( type_, size_ )
    , m_ptr_data( nullptr )
  {}

} typedef bsdt;

} // namespace zzz_
/// @endcond


// *****************************************************************************
class SetDataTypes
  : public zzz_::bsdt
  , public Core::List::DoublyElement< SetDataTypes >
{
  friend class SetDataTypes;
public:
//  typedef Pack<SetDataTypes const> SetVtxDataPack;
private:
  typedef Core::Memory::BlockPool< SetDataTypes > BlockPool_SetDataTypes;
  CPL_SINGLETON_INIT( BlockPool_SetDataTypes, zzo_ListPool_, 32 )

  // 自前のプールから取得するため、newをオーバーライドする
  static void* operator new( size_t size )
  {
    return zzo_ListPool_().New();
  }
  // placement new オーバーライド
  static void* operator new( size_t size, void* ptr ){ return ptr; }

  // 自前のプールに解放するため、deleteをオーバーライドする
  static void  operator delete( void* p )
  {
    zzo_ListPool_().Delete( reinterpret_cast<SetDataTypes*>( p ) );
  }

  //
  template<int N> struct zzt_DataBuild {};

  template<> struct zzt_DataBuild<1>{
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){}
  };
  template<> struct zzt_DataBuild<2>{
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){
      io_SDTs.AddNodeEnd( new SetDataTypes( data.get1() ) );
    }
  };
  template<> struct zzt_DataBuild<3> : zzt_DataBuild<2> {
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){
      zzt_DataBuild<2>::on( data, io_SDTs );
      io_SDTs.AddNodeEnd( new SetDataTypes( data.get2() ) );
    }
  };
  template<> struct zzt_DataBuild<4> : zzt_DataBuild<3> {
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){
      zzt_DataBuild<3>::on( data, io_SDTs );
      io_SDTs.AddNodeEnd( new SetDataTypes( data.get3() ) );
    }
  };
  template<> struct zzt_DataBuild<5> : zzt_DataBuild<4> {
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){
      zzt_DataBuild<4>::on( data, io_SDTs );
      io_SDTs.AddNodeEnd( new SetDataTypes( data.get4() ) );
    }
  };
  template<> struct zzt_DataBuild<6> : zzt_DataBuild<5> {
    template<class T>
    static void on( T const& data, SetDataTypes& io_SDTs ){
      zzt_DataBuild<5>::on( data, io_SDTs );
      io_SDTs.AddNodeEnd( new SetDataTypes( data.get5() ) );
    }
  };
public:
  SetDataTypes() : zzz_::bsdt( kType_NULL, Nothing_() ) {}

  // _____________________________________________________________________________
  /// @brief コピーコンストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  SetDataTypes( SetDataTypes const& in_SDTs )
    : zzz_::bsdt( in_SDTs.type_format, in_SDTs.size )
  {
    m_ptr_data = in_SDTs.m_ptr_data;
    if( in_SDTs.GetNodeNext() )
    {
      SetDataTypes const* new_node =
        new SetDataTypes( *in_SDTs.GetNodeNext() );
    }
  }

  // _____________________________________________________________________________
  /// @brief データ設定用コンストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  SetDataTypes( T const& data )
    : zzz_::bsdt( zzt_Type_to_Format<typename T::type0>::format, data.get0() )
  {
    zzt_DataBuild<T::kFORMAT_NUM>::on( data, *this );
  }

  // _____________________________________________________________________________
  /// データ設定用コンストラクタ
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  SetDataTypes( T const* data )
    : zzz_::bsdt( zzt_Type_to_Format<typename T::type0>::format, data->get0() )
  {
    zzt_DataBuild<T::kFORMAT_NUM>::on( *data, *this );
  }

  // _____________________________________________________________________________
  /// デストラクタ
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ~SetDataTypes()
  {
    SetDataTypes* ptr_next = this->GetNodeNext();
    delete ptr_next;
  }

  // _____________________________________________________________________________
  /// 一致比較オーバーロード
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  bool operator == ( SetDataTypes const& dt ) const
  {
    return dt.type_format == type_format;
  }

  // _____________________________________________________________________________
  /// データ追加用
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  SetDataTypes& operator << ( SetDataTypes const& in_add_data )
  {
    return *this->AddNodeEnd( new SetDataTypes( in_add_data ) );
  }

  //// _____________________________________________________________________________
  //// データ追加用
  //// _____________________________________________________________________________
  //SetDataTypes& operator + ( SetDataTypes const& in_add_data )
  //{
  //  return *this->AddNodeEnd( new SetDataTypes( in_add_data ) );
  //}
};


/// @cond
namespace zzz_ {

// _____________________________________________________________________________
/// @brief 頂点データ設定用の基底クラス
///
// *****************************************************************************
class baseGetDataTypes
  : public baseDataType
{
public:
  void* m_ptr_data;

protected:
  template<class T>
  baseGetDataTypes( S16 type_, T& data )
    : baseDataType( type_, sizeof( data ) )
    , m_ptr_data( &data )
  {}
  baseGetDataTypes( S16 type_, S16 size_ )
    : baseDataType( type_, size_ )
    , m_ptr_data( nullptr )
  {}
  baseGetDataTypes( S16 type_, Nothing_ )
    : baseDataType( type_, 0 )
    , m_ptr_data( nullptr )
  {}

} typedef bgdt;

} // namespace zzz_
/// @endcond


// _____________________________________________________________________________
/// @brief 頂点データ設定用クラス
///
// *****************************************************************************
class GetDataTypes
  : public zzz_::bgdt
  , public Core::List::DoublyElement< GetDataTypes >
{
private:
  CPL_SINGLETON_INIT( Core::Memory::BlockPool< GetDataTypes >, zzo_ListPool_, 32 )
  
  // 自前のプールから取得するため、newをオーバーライドする
  static void* operator new( size_t size )
  {
    return zzo_ListPool_().New();
  }
  // placement new オーバーライド
  static void* operator new( size_t size, void* ptr ){ return ptr; }
  
  // 自前のプールに解放するため、deleteをオーバーライドする
  static void  operator delete( void* p )
  {
    zzo_ListPool_().Delete( reinterpret_cast<GetDataTypes*>( p ) );
  }

  //
  template<int N> struct zzt_DataBuild {};

  template<> struct zzt_DataBuild<1>{
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){}
  };
  template<> struct zzt_DataBuild<2>{
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){
      io_GDTs.AddNodeEnd( new GetDataTypes( data.get1() ) );
    }
  };
  template<> struct zzt_DataBuild<3> : zzt_DataBuild<2> {
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){
      zzt_DataBuild<2>::on( data, io_GDTs );
      io_GDTs.AddNodeEnd( new GetDataTypes( data.get2() ) );
    }
  };
  template<> struct zzt_DataBuild<4> : zzt_DataBuild<3> {
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){
      zzt_DataBuild<3>::on( data, io_GDTs );
      io_GDTs.AddNodeEnd( new GetDataTypes( data.get3() ) );
    }
  };
  template<> struct zzt_DataBuild<5> : zzt_DataBuild<4> {
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){
      zzt_DataBuild<4>::on( data, io_GDTs );
      io_GDTs.AddNodeEnd( new GetDataTypes( data.get4() ) );
    }
  };
  template<> struct zzt_DataBuild<6> : zzt_DataBuild<5> {
    template<class T>
    static void on( T& data, GetDataTypes& io_GDTs ){
      zzt_DataBuild<5>::on( data, io_GDTs );
      io_GDTs.AddNodeEnd( new GetDataTypes( data.get5() ) );
    }
  };
public:
  // _____________________________________________________________________________
  /// @brief デフォルトコンストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  GetDataTypes()
    : zzz_::bgdt( kType_NULL, kNOTHING )
  {}

  // _____________________________________________________________________________
  /// @brief コピーコンストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  GetDataTypes( GetDataTypes const& in_GDTs )
    : zzz_::bgdt( in_GDTs.type_format, in_GDTs.size )
  {
    m_ptr_data = in_GDTs.m_ptr_data;
    if( in_GDTs.GetNodeNext() )
    {
      GetDataTypes* new_node =
        new GetDataTypes( *in_GDTs.GetNodeNext() );
      AddNodeNext( new_node );
    }
  }

  // _____________________________________________________________________________
  /// @brief データ取得オブジェクト設定用コンストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  GetDataTypes( T& data )
    : zzz_::bgdt( zzt_Type_to_Format<typename T::type0>::format, data.get0() )
  {
    zzt_DataBuild<T::kFORMAT_NUM>::on( data, *this );
  }

  // _____________________________________________________________________________
  /// @brief データ取得オブジェクト設定用コンストラクタ（ポインタ用）
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  template<class T>
  GetDataTypes( T* data )
    : zzz_::bgdt( zzt_Type_to_Format<typename T::type0>::format, data->get0() )
  {
    zzt_DataBuild<T::kFORMAT_NUM>::on( *data, *this );
  }

  // _____________________________________________________________________________
  /// @brief デストラクタ。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ~GetDataTypes()
  {
    GetDataTypes* ptr_next = this->GetNodeNext();
    delete ptr_next;
  }

  // _____________________________________________________________________________
  /// @brief 一致比較。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  bool operator == ( GetDataTypes const& dt ) const
  {
    return dt.type_format == type_format;
  }

  // _____________________________________________________________________________
  /// データ追加用。
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  GetDataTypes& operator << ( GetDataTypes const& in_add_data )
  {
    return *this->AddNodeEnd( new GetDataTypes( in_add_data ) );
  }

  //// _____________________________________________________________________________
  //// 
  //// _____________________________________________________________________________
  //GetDataTypes& operator + ( GetDataTypes const& in_add_data )
  //{
  //  return *this->AddNodeEnd( new GetDataTypes( in_add_data ) );
  //}
};


// _____________________________________________________________________________
/// @brief フォーマットコードからそのフォーマットに必要なサイズを返す。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
inline int GetSize_for_TypeID( eTypeID     in_format )
{
  static const int tosize_[ kType_NUM ] = {
    sizeof( float3 ),   // xyz
    sizeof( float4 ),   // xyzw
    sizeof( float ),    // blend 1 weight
    sizeof( float ),    // blend 2 weight
    sizeof( float ),    // blend 3 weight
    sizeof( DWORD ),    // blend index
    sizeof( float3 ),   // normal
    sizeof( float ),    // point size
    sizeof( float3 ),   // 接線
    sizeof( float3 ),   // 従法線
    sizeof( float ),    // テセレーション係数
    sizeof( float ),    // fog
    sizeof( float ),    // depth
    sizeof( float2 ),   // tex0
    sizeof( float2 )*2, // tex1
    sizeof( float2 )*3, // tex2
    sizeof( float2 )*4, // tex3
    sizeof( float4 ),   // tex4
    sizeof( float4 ),   // tex5
    sizeof( float4 ),   // tex6
    sizeof( float4 ),   // tex7
    sizeof( DWORD ),    // color0
    sizeof( DWORD )*2,  // color1
    sizeof( DWORD )*3,  // color2
    sizeof( DWORD )*4,  // color3
    sizeof( DWORD )*5,  // color4
    sizeof( DWORD )*6,  // color5
    sizeof( DWORD )*7,  // color6
    sizeof( DWORD )*8,  // color7
  };
  return tosize_[ in_format ];
}


} // namespace Vtx
} // namespace DX
} // namespace CPL
