/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2009/X/X - 2016/12/26
/// 
/// @brief  メッシュ関連データ
/// 
/// ****************************************************************************

#pragma once

#include "CPL_CDI_MeshInfo.h"


namespace CPL {
namespace CDI {



/*
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_VECTOR,     DX::VtxElmXYZ>        VEB_Vector;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_BLEND,      DX::VtxElmBWeight0,
                                        DX::VtxElmBIndex>     VEB_Blend;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_NORMAL,     DX::VtxElmNormal>     VEB_Normal;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_COLOR,      DX::VtxElmColor>      VEB_Color;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TEXCOORD,   DX::VtxElmTex0>       VEB_TexCoord0;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TEXCOORD,   DX::VtxElmTex1>       VEB_TexCoord1;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TEXCOORD,   DX::VtxElmTex2>       VEB_TexCoord2;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TEXCOORD,   DX::VtxElmTex3>       VEB_TexCoord3;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_PSIZE,      DX::VtxElmPSize>      VEB_PSize;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_DEPTH,      DX::VtxElmDepth>      VEB_Depth;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TANGENT,    DX::VtxElmTangent>    VEB_Tangent;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_BINORMAL,   DX::VtxElmBINormal>   VEB_BINormal;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_TESSFACTOR, DX::VtxElmTessFactor> VEB_TessFactor;
typedef DX::Buffer::Interface_<
          MeshFileInfo::VSI_FOG,        DX::VtxElmFog>        VEB_Fog;
*/



// _____________________________________________________________________________
/// @brief メッシュデータクラス
///
// *****************************************************************************
class MeshData {
public:
  // エラーコード？
  enum class eErrorCode : int
  { NotCore4dFile = (int)0xff000000
  , NotCreateTexture
  , NotCreateVertexDeclaration
  , NotCreateVertexBuffer
  , NotCreateIndexBuffer
  };

  // バッファインデックス？
  enum class eBufferIndex : int
  { Error  = -1
  , Vertex
  , Normal
  , BlendWeight
  , BlendIndex
  , Texture
  };

//  typedef U32 TYPE_INDEX; // U32 or U16

  // 頂点フォーマットごとの使用ストリームのインデックステーブル
  // ※ 並びはMeshFileInfo::VTX_FORMAT に依存する
//  static const int STREAM_INDEX_LIST[ MeshFileInfo::VF_NUM ];

//// スマートポインタのタイプをすべて定義用　※ 最後は；が必要だよ♪
//#define CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE(type) \
//  using Sp_##type  = std::shared_ptr<type>;\
//  using CSp_##type = std::shared_ptr<type const>;\
//  using Wp_##type  = std::weak_ptr<type>;\
//  using CWp_##type = std::weak_ptr<type const>;\
//  using Sp_##type##_ref   = Sp_##type&;\
//  using Sp_##type##_cref  = Sp_##type const&;\
//  using Wp_##type##_ref   = Wp_##type&;\
//  using Wp_##type##_cref  = Wp_##type const&;\
//  using CSp_##type##_ref  = CSp_##type&;\
//  using CSp_##type##_cref = CSp_##type const&;\
//  using CWp_##type##_ref  = CWp_##type&;\
//  using CWp_##type##_cref = CWp_##type const&

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 前方宣言
  class   baseData;
  class   Object;
  class   Bone;
  class   LayoutBuffer;
  class   TexCoordSet;
//  class   VertexStreamData;
  class   Texture;
  class   ColorMaterial;
  class   TextureMaterial;
  class   LightMaterial;
  class   AnmData;
  class   AnmKeyList;
  class   baseKeyFrame;
  class   KeyEvent;
  class   KeyVector;
  class   KeyColor;
  class   KeyTexCoord;
  class   KeyParam1;
  class   KeyParam2;
  class   KeyParam3;
  class   KeyParam4;
  class   Shader;
//  class VS_Param;
//  class PS_Param;
//  class VertexGroup;
  //// スマートポイント化
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( baseData        );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( Object          );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( Bone            );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( LayoutBuffer    );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( TexCoordSet     );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( Texture         );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( ColorMaterial   );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( TextureMaterial );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( LightMaterial   );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( AnmData         );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( AnmKeyList      );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( baseKeyFrame    );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyEvent        );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyVector       );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyColor        );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyTexCoord     );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyParam1       );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyParam2       );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyParam3       );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( KeyParam4       );
  //CPL_DEF_MESHDATA_SMPTR_ALL_DEFINE( Shader          );

  //using SpCBufferLayout = CLayoutBuffer::shared_ptr;
  //using SpCVertexShader = CVertexShader::shared_ptr;
  //using SpCPixelShader  = CPixelShader::shared_ptr;
  //using SpCInputLayout  = CInputLayout::shared_ptr;

  using Array_SpVtxLayout     = std::vector< sdptr<LayoutBuffer   > >;
  using Array_SpObject        = std::vector< sdptr<Object         > >;
  using Array_SpShader        = std::vector< sdptr<Shader         > >;
  using Array_SpTexture       = std::vector< sdptr<Texture        > >;
  using Array_SpTexMaterial   = std::vector< sdptr<TextureMaterial> >;
  using Array_SpMaterial      = std::vector< sdptr<ColorMaterial  > >;
  using Array_SpLightMaterial = std::vector< sdptr<LightMaterial  > >;
  using Array_SpAnime         = std::vector< sdptr<AnmData        > >;
 
  using void_sptr = sdptr<void>;
  using Array_DataSPtr = Core::Array::DynamicKey<TypeGID, void_sptr>;
  using Array_ChunkPtr = Core::Array::DynamicKey<void*, MeshFileInfo::Chunk const*>;
 
protected:
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // ＩＤ検索
  template<class T_Ret, class T_Iterator>
  static std::shared_ptr<T_Ret>
    zzf_search_by_ID_
      ( _in<TypeGID> in_ID
      , T_Iterator   in_itr_begin
      , T_Iterator   in_itr_end
      )
  {
    auto itr = in_itr_begin;
    while( itr != in_itr_end )
    {
      if( (*itr)->GetUniqueID() == in_ID )
      {
        return (*itr)->GetLinkMyself();
      }
      ++itr;
    }
    return nullptr;
  }
  // ID検索（ツリーポインタ用）
  template<class T_Ret>
  static std::shared_ptr<T_Ret>
    zzf_search_by_ID_
      ( _in <TypeGID               > in_ID
      , cref<std::shared_ptr<T_Ret>> in_sp_tree_root
      )
  {
    auto sp_node = in_sp_tree_root;
    while( sp_node )
    {
      if( sp_node->GetUniqueID() == in_ID )
      {
        return sp_node;
      }
      if( sp_node->GetLinkChild() )
      {
        auto sp_node_hit = zzf_search_by_ID_( in_ID, sp_node->GetLinkChild() );
        if( sp_node_hit )
        {
          return sp_node_hit;
        }
      }
      sp_node = sp_node->GetLinkNext();
    }
    return nullptr;
  }

  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  // 名前検索
  template<class T_Ret, class T_Iterator>
  static std::shared_ptr<T_Ret>
    zzf_search_by_Name_
      ( char_cptr  in_name
      , T_Iterator in_itr_begin
      , T_Iterator in_itr_end
      )
  {
    auto itr = in_itr_begin;
    while( itr != in_itr_end )
    {
      if( (*itr)->GetName() == in_name )
      {
        return (*itr)->GetLinkMyself();
      }
      ++itr;
    }
    return nullptr;
  }
  // 名前検索（ツリーポインタ用）
  template<class T_Ret>
  static std::shared_ptr<T_Ret>
    zzf_search_by_Name_
      ( pin <char                  > in_name
      , cref<std::shared_ptr<T_Ret>> in_sp_tree_root
      )
  {
    auto sp_node = in_sp_tree_root;
    while( sp_node )
    {
      if( sp_node->GetName() == in_name )
      {
        return sp_node;
      }
      if( sp_node->GetLinkChild() )
      {
        auto sp_node_hit = zzf_search_by_Name_( in_name, sp_node->GetLinkChild() );
        if( sp_node_hit )
        {
          return sp_node_hit;
        }
      }
      sp_node = sp_node->GetLinkNext();
    }
    return nullptr;
  }
  
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  static eBufferIndex zzf_GetBufferIndex_by_VertexTypeID( _in<int> in_type_ID )
  {
    switch( in_type_ID )
    {
    case DX::Vtx::kType_XYZ:           return eBufferIndex::Vertex;
    case DX::Vtx::kType_NORMAL:        return eBufferIndex::Normal;
    case DX::Vtx::kType_BLEND_WEIGHT1: return eBufferIndex::BlendWeight;
    case DX::Vtx::kType_BLEND_INDEX:   return eBufferIndex::BlendIndex;
    default: return eBufferIndex::Error;
    }
  }

public:
  // _____________________________________________________________________________
  /// @brief データ共通の基底クラス
  ///
  // *****************************************************************************
  class baseData
    : public Core::BaseObject
  {
    friend class baseData;

    Core::StringA m_name; // 識別文字列 / identifier

  protected:
    // 補間補助関数
    void zzf_getKeyListVec
      ( _in <sdptr<baseData>> in_sp_keylist
      , _in <bool           > in_flag_interpolate
      , rout<CVector3       > out_vec
      ) const;

  public:
    baseData(){}
    baseData( cref<baseData> in_data )
      : m_name( in_data.m_name )
    {}
    baseData( rvref<baseData> in_data )
      : m_name( std::move(in_data.m_name) )
    {}
    virtual ~baseData(){};

    TypeGID             GetUniqueID() const { return TypeGID(((size_t)this) >> 2); }
    cref<Core::StringA> GetName() const { return m_name; }
    void                SetName( _in<Core::StringA> in_name ){ m_name = in_name; }

    virtual sdptr<baseData> CreateClone() const = 0;
  };

  // _____________________________________________________________________________
  /// @brief 基本データクラス
  ///
  // *****************************************************************************
  template< class T_Class >
  class baseDataT
    : public baseData
    , public Core::IncludeSmartLink< T_Class >
  {
  protected:
    baseDataT(){}
    baseDataT( cref<baseDataT> in_data )
      : baseData( in_data )
    {}
    baseDataT( rvref<baseDataT> in_data )
      : baseData( in_data )
    {}
    ~baseDataT(){}
  };

  // _____________________________________________________________________________
  /// @brief リスト型基本データクラス
  ///
  // *****************************************************************************
  template< class T_Class >
  class baseDataListT
    : public baseData
    , public Core::IncludeSmartLinkList< T_Class >
  {
  protected:
    baseDataListT(){}
    baseDataListT( cref<baseDataListT> in_data_list )
      : baseData( in_data_list )
    {}
    baseDataListT( rvref<baseDataListT> in_data_list )
      : baseData( in_data_list )
    {}
    ~baseDataListT(){}
  };

  // _____________________________________________________________________________
  /// @brief ツリー型基本データクラス
  ///
  // *****************************************************************************
  template< class T_Class >
  class baseDataTreeT
    : public baseData
    , public Core::IncludeSmartLinkTree< T_Class >
  {
  protected:
    baseDataTreeT(){}
    baseDataTreeT( cref<baseDataTreeT> in_data )
      : baseData( in_data )
    {}
    baseDataTreeT( rvref<baseDataTreeT> in_data )
      : baseData( in_data )
    {}
    ~baseDataTreeT(){}
  };
  
  // _____________________________________________________________________________
  /// @brief ライト渡し用構造体
  ///
  // *****************************************************************************
  struct LightDataTable {
    size_t                           m_light_num;
    Core::Array::Constant<float4>*   m_ptr_color_table;
    Core::Array::Constant<CVector3>* m_ptr_pos_table;
    Core::Array::Constant<CVector3>* m_ptr_normal_table;
    Core::Array::Constant<float>*    m_ptr_power_table;

    LightDataTable()
      : m_light_num( 0 )
      , m_ptr_color_table ( nullptr )
      , m_ptr_pos_table   ( nullptr )
      , m_ptr_normal_table( nullptr )
      , m_ptr_power_table ( nullptr )
    {}
  };
  // テクスチャ渡し用
  using Array_TexData = std::vector< DX::DXTexture2D* >;

  // _____________________________________________________________________________
  /// @brief メッシュ描画用情報
  ///
  // *****************************************************************************
  struct DrawDesc {
    ptr<DX::DXDeviceContext> m_ptr_d3d_emd_ctx;
    cptr<CMatrix>            m_ptr_mtx_view_proj;
    cptr<CMatrix>            m_ptr_mtx_proj;
    cptr<CMatrix>            m_ptr_mtx_view;
    cptr<CMatrix>            m_ptr_mtx_world;
    int                      m_world_mtx_num;
    cptr<CVector3>           m_ptr_eye_pos;
    cptr<CVector3>           m_ptr_look_pos;

    DrawDesc()
      : m_ptr_d3d_emd_ctx  ( nullptr )
      , m_ptr_mtx_view_proj( nullptr )
      , m_ptr_mtx_proj     ( nullptr )
      , m_ptr_mtx_view     ( nullptr )
      , m_ptr_mtx_world    ( nullptr )
      , m_world_mtx_num    ( 1 )
      , m_ptr_eye_pos      ( nullptr )
      , m_ptr_look_pos     ( nullptr )
    {}
    ~DrawDesc(){}
  };

  // _____________________________________________________________________________
  /// @brief オブジェクト描画用情報
  ///
  // *****************************************************************************
  struct DrawObjectDesc : public DrawDesc
  {
    cptr<Array_TexData > m_ptr_tex_table;
    cptr<LightDataTable> m_ptr_light_table;

    DrawObjectDesc()
      : m_ptr_tex_table  ( nullptr )
      , m_ptr_light_table( nullptr )
    {}
    ~DrawObjectDesc(){}
  };

//  MFI_Header const* m_ptr_info_header;

  // _____________________________________________________________________________
  /// @brief バッファレイアウト
  ///
  // *****************************************************************************
  class LayoutBuffer
    : public baseDataT< LayoutBuffer >
  {
  private:
    using td_base = baseDataT< LayoutBuffer >;
    friend class MeshData;
    friend class LayoutBuffer;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , _in<DX::DXDevice*      > in_ptr_d3d_dev
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );

    sdptr<CLayoutBuffer> m_sp_layout_buf;
    DX::CpDXInputLayout  m_cp_input_layout;
  public:
    sdptr<CLayoutBuffer>
      GetLayoutBuffer() const { return m_sp_layout_buf; }
    void
      SetLayoutBuffer( _in<sdptr<CLayoutBuffer>> in_sp_layout_buf )
    {
      m_sp_layout_buf = in_sp_layout_buf;
    }

    DX::CpDXInputLayout
      GetInputLayout() const { return m_cp_input_layout; }
    void
      SetInputLayout( _in<DX::CpDXInputLayout> in_DXIL ){
        m_cp_input_layout = in_DXIL; }

    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( LayoutBuffer, *this );
    }


    LayoutBuffer( pio<DX::DXDevice> in_ptr_d3d_dev )
    {}
    LayoutBuffer( cref<LayoutBuffer> in_data )
      : td_base( in_data )
      , m_sp_layout_buf  ( in_data.m_sp_layout_buf )
      , m_cp_input_layout( in_data.m_cp_input_layout )
    {}
    LayoutBuffer( rvref<LayoutBuffer> in_data )
      : td_base( std::move(in_data) )
      , m_sp_layout_buf  ( std::move(in_data.m_sp_layout_buf) )
      , m_cp_input_layout( std::move(in_data.m_cp_input_layout) )
    {}
    ~LayoutBuffer(){}
  };

  // _____________________________________________________________________________
  /// @brief ボーン
  ///
  // *****************************************************************************
  class Bone
    : public baseDataTreeT< Bone >
  {
  private:
    using td_base = baseDataTreeT< Bone >;
    friend class Object;
//      MFI_Bone const* m_ptr_info_bone;
    //CMatrix      m_local_mtx;     // ローカルマトリクス
    //int          m_flag_update;   // マトリクスの更新の必要があるかどうか
    ptr<CMatrix>  m_ptr_world_mtx; // 変換済みワールドマトリクスへのポインタ
    //Array::D_Float m_blend_weight_tbl; // 頂点ブレンドの重み ※ たぶん必要ない
    wkptr<Object> m_wp_belong_object; // 自身が属するオブジェクトへのポインタを保持

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );
    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

  public:
    CVector3     m_vec_pos;
    CVector3     m_vec_rot;
    CVector3     m_vec_scl;
    
    //ScPtr_Bone        m_sp_bone_next;
    //ScPtr_Bone        m_sp_bone_child;
    //ScPtr_Bone        m_sp_bone_parent;
    wkptr<AnmKeyList> m_wp_relation_keylist_pos;
    wkptr<AnmKeyList> m_wp_relation_keylist_rot;
    wkptr<AnmKeyList> m_wp_relation_keylist_scl;

    Core::Array::Dynamic<U32> m_vtx_index; // ブレンドに含める頂点インデックス

    //int           GetNodeNum() const;
    //int           GetNodeChildNum() const {
    //                return m_sp_bone_child ? m_sp_bone_child->GetNodeNum() : 0; }

    void
      SetBelongObject( _in<sdptr<Object>> in_sp_object ){
        m_wp_belong_object = in_sp_object; }

    sdptr<Object>
      GetBelongObject() const {
        return m_wp_belong_object.lock(); }

    void GetLocalPos( _in<bool> in_flag_interpolate, rout<CVector3> out_vec ) const;
    void GetLocalRot( _in<bool> in_flag_interpolate, rout<CVector3> out_vec ) const;
    void GetLocalScl( _in<bool> in_flag_interpolate, rout<CVector3> out_vec ) const;

    cptr<CMatrix>
      GetWorldMatrix() const { return m_ptr_world_mtx; }
    ptr<CMatrix>
      GetWorldMatrix()       { return m_ptr_world_mtx; }
    void
      Release( rio<Array_DataSPtr> io_table_for_data_pointer );
    ptr<CMatrix>
      UpdateMatrix
        ( pout<CMatrix> out_ptr_mtx
        , pin <CMatrix> in_ptr_parent_mtx
        , _in <bool   > in_flag_interpolate
        );

    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( Bone, *this );
    }

    Bone();
    Bone( _in<sdptr<Object>> in_sp_object );
    Bone( cref<Bone> in_bone );
    Bone( rvref<Bone> in_bone );
    ~Bone(){}
  };

  // _____________________________________________________________________________
  /// @brief テクスチャ座標セット
  ///
  // *****************************************************************************
  class TexCoordSet
    : public baseDataT< TexCoordSet >
  {
    using td_base  = baseDataT< TexCoordSet >;
    using SpVtxBuf = sdptr<DX::Buffer::Interface_>;
    friend class Object;

    SpVtxBuf m_sp_vsb_texcoordset;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , _in<DX::DXDevice*      > in_ptr_d3d_dev
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        , _in<U32                > in_vtx_num
        );
    sdptr<DX::Layout::Buffer> zzz_makeLayoutBuffer_();
  public:
    U16 m_stage_num; // ステージ数(1-8)
    U16 m_dim_num;   // 座標数(1-4)
    
    // _____________________________________________________________________________
    /// @brief クローンの作成
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( TexCoordSet, *this );
    }

    TexCoordSet();
    TexCoordSet( cref<TexCoordSet> in_texcoord );
    TexCoordSet( rvref<TexCoordSet> in_texcoord );
    ~TexCoordSet(){ Release(); }

    void
      Release();
    SpVtxBuf
      GetTexCoordBuf() const { return m_sp_vsb_texcoordset; }
    int
      GetVtxElmSize() const { return m_stage_num * m_dim_num; }
  };


  // _____________________________________________________________________________
  /// @brief オブジェクト
  ///
  // *****************************************************************************
  class Object
    : public baseDataTreeT< Object >
  {
  public:
  protected:
    friend class MeshData;

    using td_base          = baseDataTreeT< Object >;
    using Array_Matrix     = Core::Array::Dynamic< CMatrix >;
    using Array_Bone       = Core::Array::Dynamic< sdptr<Bone> >;
    using Array_TexCoord   = Core::Array::Dynamic< sdptr<TexCoordSet> >;
    using Array_Vector3    = Core::Array::Dynamic<CDI::CVector3>;
    using Array_Int        = Core::Array::Dynamic<int>;
    using IndexBuf         = DX::Buffer::DynamicEX_Index;
    using BufCollection    = DX::Buffer::Collection;
    using LayoutBuf        = DX::Layout::Buffer;
    using RenderCollection = DX::RenderCollection;

    Array_Matrix        m_blend_matrix;
    Array_Bone          m_bone_sp_table;  // ボーンのポインタテーブル
    Array_TexCoord      m_tcs_sp_table;   // テクスチャ座標セットテーブル

    sdptr<BufCollection>    m_sp_buf_collection; // バッファセット
    sdptr<LayoutBuf>        m_sp_layout_buf;     // 使用する頂点宣言
    sdptr<IndexBuf>         m_sp_idx_buf;        // インデックスバッファ(TYPE_INDEX[])
    sdptr<RenderCollection> m_sp_render_collection; // オブジェクトのレンダーコレクション

    CVector3 m_vec_pos;
    CVector3 m_vec_rot;
    CVector3 m_vec_scl;
    U32      m_vtx_num;
    U32      m_poly_num;
    //U32      m_flag_culling   : 4; // カリングモード
    U8       m_flag_billboard; // 
    U8       m_flag_z_sort;
    U8       m_flag_lighting;
    U8       m_flag_view;
    U8       m_tex_index[ 4 ]; // 使用テクスチャインデックス
    U8       m_tex_blend[ 4 ]; // テクスチャブレンドフラグ

    mutable wkptr<Bone>             m_wp_bone_root;
    mutable wkcptr<Object>          m_wp_mirror_object;        // ミラー描画対象となるオブジェクト
    mutable sdptr<RenderCollection> m_sp_mirror_context;       // ミラー描画用の描画情報（ミラー元の設定から変更するステータスのみ保持する）
    mutable wkptr<TexCoordSet  >    m_wp_relation_texcoordset; // 関連付けられているテクスチャセットポインタ
    mutable wkptr<ColorMaterial>    m_wp_relation_material;    // 関連付けられているマテリアルポインタ
    mutable wkptr<AnmKeyList   >    m_wp_relation_keylist_pos; // 関連付けられている座標キーリスト
    mutable wkptr<AnmKeyList   >    m_wp_relation_keylist_rot; // 関連付けられている角度キーリスト
    mutable wkptr<AnmKeyList   >    m_wp_relation_keylist_scl; // 関連付けられているスケールキーリスト
    mutable wkptr<Shader       >    m_wp_relation_shader;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , _in<DX::DXDevice*      > in_ptr_d3d_dev
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );

    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

    void
      zzf_clearRelation_();

    void
      zzf_updateShaderData_
        ( _in<DrawObjectDesc> in_draw_obj_desc
        , pin<CMatrix       > in_ptr_mtx_BBR
        ) const;

  public:
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<DX::Buffer::Interface_>
      GetBuffer_by_Index( _in<eBufferIndex> in_index );
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdcptr<DX::Buffer::Interface_>
      GetBuffer_by_Index( _in<eBufferIndex> in_index ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<IndexBuf>
      GetIndexBuffer() const
    {
      return m_sp_idx_buf;
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<LayoutBuf>
      GetBufferLayout() const
    {
      return m_sp_layout_buf;
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<Bone>
      GetBoneRoot() const
    {
      return m_wp_bone_root.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdcptr<Bone>
      GetBone( _in<int> in_tbl_idx ) const
    {
      return m_bone_sp_table[ in_tbl_idx ];
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual ptr<CMatrix>
      GetBlendMatrix( _in<DX::TYPE_INDEX> in_index )
    {
      return &m_blend_matrix[ in_index ];
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual cptr<CMatrix>
      GetBlendMatrix( _in<DX::TYPE_INDEX> in_index ) const
    {
      return &m_blend_matrix[ in_index ];
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<TexCoordSet>
      GetTexCoordSet( _in<DX::TYPE_INDEX> in_index )
    {
      return m_tcs_sp_table[ in_index ];
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdcptr<TexCoordSet>
      GetTexCoordSet( _in<DX::TYPE_INDEX> in_index ) const
    {
      return m_tcs_sp_table[ in_index ];
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual size_t
      GetTexCoordSetNum() const
    {
      return m_tcs_sp_table.GetNum();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdcptr<Object>
      GetRelation_MirrorObject() const
    {
      return m_wp_mirror_object.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<TexCoordSet>
      GetRelation_TexCoordSet() const
    {
      return m_wp_relation_texcoordset.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<ColorMaterial>
      GetRelation_ColorMaterial() const
    {
      return m_wp_relation_material.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<AnmKeyList>
      GetRelation_KeyListPos() const
    {
      return m_wp_relation_keylist_pos.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<AnmKeyList>
      GetRelation_KeyListRot() const
    {
      return m_wp_relation_keylist_rot.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<AnmKeyList>
      GetRelation_KeyListScl() const
    {
      return m_wp_relation_keylist_scl.lock();
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<Shader>
      GetRelation_Shader() const
    {
      return m_wp_relation_shader.lock();
    }

    // _____________________________________________________________________________
    /// @brief 座標の取得
    /// @return 座標を返します。
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual cref<CVector3> GetVecPos() const { return m_vec_pos; }
    /// @copydoc GetVecPos
    virtual ref<CVector3>  GetVecPos()       { return m_vec_pos; }

    // _____________________________________________________________________________
    /// @brief 角度の取得
    /// @return 角度を返します。
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual cref<CVector3> GetVecRot() const { return m_vec_rot; }
    /// @copydoc GetVecRot
    virtual ref<CVector3>  GetVecRot()       { return m_vec_rot; }

    // _____________________________________________________________________________
    /// @brief 倍率の取得
    /// @return 倍率を返します。
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual cref<CVector3> GetVecScl() const { return m_vec_scl; }
    /// @copydoc GetVecScl
    virtual ref<CVector3>  GetVecScl()       { return m_vec_scl; }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      GetLocalPos( rout<CVector3> out_pos, _in<bool> in_flag_interpolate = true ) const;
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      GetLocalRot( rout<CVector3> out_rot, _in<bool> in_flag_interpolate = true ) const;
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      GetLocalScl( rout<CVector3> out_scl, _in<bool> in_flag_interpolate = true ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual U32
      GetVertexNum()     const { return m_vtx_num; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual U32
      GetPolygonNum()    const { return m_poly_num; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual bool
      GetFlag_ZSort()    const { return m_flag_z_sort != 0; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual bool
      GetFlag_Lighting() const { return m_flag_lighting != 0; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual bool
      GetFlag_View()     const { return m_flag_view != 0; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      GetZSortIndex
        ( _in <CVector3     > in_eye_pos
        , _in <bool         > in_flag_order
        , _in <Array_Vector3> in_vec_trans_tbl
        , rout<Array_Int    > out_poly_idx_table
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetDeclaration( _in<sdptr<LayoutBuf>> in_sp_declaration ){
        m_sp_layout_buf = in_sp_declaration; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetRootBone( _in<sdptr<Bone>> in_sp_bone ){
        m_wp_bone_root = in_sp_bone; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetVecPos( _in<CVector3> in_vec_pos ){
        m_vec_pos = in_vec_pos; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetVecRot( _in<CVector3> in_vec_rot ){
        m_vec_rot = in_vec_rot; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetVecScl( _in<CVector3> in_vec_scl ){
        m_vec_scl = in_vec_scl; }
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      SetFlag_ZSort( _in<bool> in_flag_zsort ){
        m_flag_z_sort = in_flag_zsort; }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      Release();
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      UpdateMatrix
        ( pin<CMatrix> in_ptr_matrix_for_parent
        , _in<bool   > in_flag_interpolate
        );
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      UpdateNormalVector();
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      UpdateSortIndex( _in<Core::Array::Dynamic<int>> in_poly_idx_tbl );


    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      Draw( _in<DrawObjectDesc> in_draw_obj_desc ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      DeleteVertex( _in<DX::TYPE_INDEX> in_del_index, _in<int> in_del_num = 1 );
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      ResizeVertexBuffer( _in<int> in_num );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      AddVertex
        ( _in<DX::TYPE_INDEX>   in_insert_key_index
        , _in<CVtxSetDataTypes> in_vtx_data_types
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      GetVertexData
        ( _in <DX::TYPE_INDEX  > in_vtx_idx
        , rout<CVtxGetDataTypes> out_vtx_data_types
        ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      SetVertexData
        ( _in<DX::TYPE_INDEX  > in_vtx_idx
        , _in<CVtxSetDataTypes> in_vtx_data_types
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      GetIndex
        ( _in <DX::TYPE_INDEX> in_poly_idx
        , _in <int           > in_vtx_no
        , rout<DX::TYPE_INDEX> out_index
        ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      SetIndex
        ( _in <DX::TYPE_INDEX> in_poly_idx
        , _in <int           > in_vtx_no
        , _in <DX::TYPE_INDEX> in_vtx_idx
        , pout<DX::TYPE_INDEX> out_ptr_vtx_idx
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      AddPolygon
        ( _in<DX::TYPE_INDEX>  in_insert_poly_idx
        , _in<DX::TYPE_INDEX3> in_index_list
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      DeletePolygon( _in<DX::TYPE_INDEX> in_poly_idx );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      DeletePolygonList( _in<size_t*> in_poly_table, _in<UINT> in_num );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      GetPolyIndex
        ( _in <DX::TYPE_INDEX > in_poly_idx
        , rout<DX::TYPE_INDEX3> out_index_list
        ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual HRESULT
      SetPolyIndex
        ( _in<DX::TYPE_INDEX > in_poly_idx
        , _in<DX::TYPE_INDEX3> in_index_list
        );

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual U32
      GetNearIndex( _in<CVector3> in_pos ) const;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<Bone>
      On_NewBone() const { return CPL_MAKE_SHARED(Bone); }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual sdptr<TexCoordSet>
      On_NewTexCoordSet() const { return CPL_MAKE_SHARED(TexCoordSet); }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( Object, *this );
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Object();
    Object( cref<Object> );
    Object( rvref<Object> );
    ~Object(){ Release(); }
  };

  // _____________________________________________________________________________
  /// @brief テクスチャ
  ///
  // *****************************************************************************
  class Texture
    : public baseDataT< Texture >
  {
    using td_base = baseDataT<Texture>;
    friend class MeshData;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , _in<DX::DXDevice*      > in_ptr_d3d_dev
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        , _in<Core::String       > in_file_path
        );

  public:
    DX::DXTexture2D* m_ptr_texture;

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void Release();

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( Texture, *this );
    }

    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Texture()
      : m_ptr_texture( nullptr )
    {}
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Texture( cref<Texture> in_texture );
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Texture( rvref<Texture> in_texture );
    // _____________________________________________________________________________
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ~Texture(){ Release(); }
  };

  // _____________________________________________________________________________
  /// @brief カラーマテリアル
  ///
  // *****************************************************************************
  class ColorMaterial
    : public baseDataT< ColorMaterial >
  {
  private:
    using td_base = baseDataT< ColorMaterial >;
    friend class MeshData;
//    MFI_ColorMaterial const* m_ptr_info_material;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );
    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

  public:
    wkptr<AnmKeyList> m_wp_relation_keylist_color[ MeshFileInfo::kCOLOR_MTRL_PARAM_NUM ];
    float4            m_color[ MeshFileInfo::kCOLOR_MTRL_PARAM_NUM ];

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( ColorMaterial, *this );
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ColorMaterial();
    ColorMaterial( cref<ColorMaterial> in_data );
    ColorMaterial( rvref<ColorMaterial> in_data );
    ~ColorMaterial(){}
  };

  // _____________________________________________________________________________
  /// @brief テクスチャマテリアル
  ///
  // *****************************************************************************
  class TextureMaterial
    : public baseDataT< TextureMaterial >
  {
  private:
    using td_base = baseDataT< TextureMaterial >;
    using type_this = TextureMaterial;
    friend class MeshData;

    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

  public:
    int stage_num;
    struct zzc_param {
      int  tex_index;  // 使用テクスチャのインデックス
      int  use_type;   // 使用タイプ
    } param[ MeshFileInfo::kTEX_MTRL_PARAM_NUM ];

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( TextureMaterial, *this );
    }

    TextureMaterial(){}
    TextureMaterial( cref<TextureMaterial> in_mtrl )
      : td_base( in_mtrl )
      , stage_num( in_mtrl.stage_num )
    {}
    TextureMaterial( rvref<TextureMaterial> in_mtrl )
      : td_base( std::move(in_mtrl) )
      , stage_num( in_mtrl.stage_num )
    {}
    ~TextureMaterial(){}
  };

  // _____________________________________________________________________________
  /// @brief ライトマテリアル
  ///
  // *****************************************************************************
  class LightMaterial
    : public baseDataT< LightMaterial >
  {
  private:
    using td_base = baseDataT< LightMaterial >;
    friend class MeshData;
//    MFI_LightMaterial const* m_ptr_info_light;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );
    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

  public:
    CVector3          m_vec_pos;
    CVector3          m_vec_rot;
    float4            m_color;
    float             m_power;
    float             m_theta;
    float             m_phi;
    int               m_type;
    wkptr<AnmKeyList> m_wp_relation_keylist_pos;
    wkptr<AnmKeyList> m_wp_relation_keylist_rot;
    wkptr<AnmKeyList> m_wp_relation_keylist_color;
    wkptr<AnmKeyList> m_wp_relation_keylist_power;
    wkptr<baseData>   m_wp_relation_matrix; // Object or Boneになる

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    virtual void
      Release();

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( LightMaterial, *this );
    }

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    LightMaterial();
    LightMaterial( cref<LightMaterial> in_data );
    LightMaterial( rvref<LightMaterial> in_data );
    ~LightMaterial(){ Release(); }
  };

  // _____________________________________________________________________________
  /// @brief 基底キーフレーム
  ///
  // *****************************************************************************
  class baseKeyFrame
    : public baseDataListT< baseKeyFrame >
  {
    using td_base = baseDataListT< baseKeyFrame >;
  public:
    U32 m_index       : 31; // インデックス
    U32 m_interpolate :  1; // 補間

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    baseKeyFrame( pin<char> in_ptr_data_addr )
      : m_index
          ( reinterpret_cast<baseKeyFrame const*>(in_ptr_data_addr)->m_index )
      , m_interpolate
          ( reinterpret_cast<baseKeyFrame const*>(in_ptr_data_addr)->m_interpolate )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    baseKeyFrame( _in<U32> in_index, _in<bool> in_flag_interpolate )
      : m_index      ( in_index )
      , m_interpolate( in_flag_interpolate )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    baseKeyFrame( cref<baseKeyFrame> in_data )
      : td_base( in_data )
      , m_index      ( in_data.m_index )
      , m_interpolate( in_data.m_interpolate )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    baseKeyFrame( rvref<baseKeyFrame> in_data )
      : td_base( std::move(in_data) )
      , m_index      ( in_data.m_index )
      , m_interpolate( in_data.m_interpolate )
    {}
  };
  
  // _____________________________________________________________________________
  /// @brief イベントキー
  ///
  // *****************************************************************************
  class KeyEvent : public baseKeyFrame {
  public:
    U32 m_ev_type;
    int m_ev_value;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyEvent( rio<char_cptr> io_ptr_key_data );
    // _____________________________________________________________________________
    /// @brief KeyEvent コピーコンストラクタ
    /// 
    /// @param[in] in_data : コピー元のKeyEventオブジェクトを指定します。
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyEvent( cref<KeyEvent> in_data )
      : baseKeyFrame( in_data )
      , m_ev_type   ( in_data.m_ev_type )
      , m_ev_value  ( in_data.m_ev_value )
    {}
    // _____________________________________________________________________________
    /// @brief KeyEvent ムーブコンストラクタ
    /// 
    /// @param[in] in_data : ムーブ元のKeyEventオブジェクトを指定します。
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyEvent( rvref<KeyEvent> in_data )
      : baseKeyFrame( std::move(in_data) )
      , m_ev_type   ( in_data.m_ev_type )
      , m_ev_value  ( in_data.m_ev_value )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyEvent
    ( _in<U32 > in_index
    , _in<bool> in_flag_interpolate
    , _in<U32 > in_ev_type
    , _in<int > in_ev_value
    ) : baseKeyFrame( in_index, in_flag_interpolate )
      , m_ev_type   ( in_ev_type )
      , m_ev_value  ( in_ev_value )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyEvent, *this );
    }
  };
  
  // _____________________________________________________________________________
  /// @brief パラメータキー
  ///
  // *****************************************************************************
  class KeyParam1 : public baseKeyFrame {
  public:
    float m_param0;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam1( rio<char_cptr> in_ptr_data_addr )
      : baseKeyFrame( in_ptr_data_addr )
      , m_param0    ( reinterpret_cast<KeyParam1 const*>(in_ptr_data_addr)->m_param0 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam1( cref<KeyParam1> in_data )
      : baseKeyFrame( in_data )
      , m_param0    ( in_data.m_param0 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam1( rvref<KeyParam1> in_data )
      : baseKeyFrame( std::move(in_data) )
      , m_param0    ( in_data.m_param0 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam1
    ( _in<U32  > in_index
    , _in<bool > in_flag_interpolate
    , _in<float> in_param0
    ) : baseKeyFrame( in_index, in_flag_interpolate )
      , m_param0    ( in_param0 )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyParam1, *this );
    }

    // *****************************************************************************
    // 列挙用クラス
    template<int X, class Base>
    struct EX_ : Base
    {
      EX_( rio<char_cptr> io_ptr_key_data )
        : Base( io_ptr_key_data )
      {}
      EX_
      ( _in<U32  > in_index
      , _in<bool > in_flag_interpolate
      , _in<float> in_param0 = 0.0f
      ) : Base( in_index, in_flag_interpolate, in_param0 )
      {}
    };
  };
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  typedef KeyParam1::EX_<0,KeyParam1> KeyMtrlPower;
  typedef KeyParam1::EX_<1,KeyParam1> KeyLightPower;

  // *****************************************************************************
  class KeyParam2 : public KeyParam1 {
  public:
    float m_param1;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam2( rio<char_cptr> io_ptr_key_data )
      : KeyParam1( io_ptr_key_data )
      , m_param1 ( reinterpret_cast<KeyParam2 const*>(io_ptr_key_data)->m_param1 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam2( cref<KeyParam2> in_data )
      : KeyParam1( in_data )
      , m_param1 ( in_data.m_param1 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam2( rvref<KeyParam2> in_data )
      : KeyParam1( std::move(in_data) )
      , m_param1 ( in_data.m_param1 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam2
    ( _in<U32  > in_index
    , _in<bool > in_flag_interpolate
    , _in<float> in_param0
    , _in<float> in_param1
    ) : KeyParam1( in_index, in_flag_interpolate, in_param0 )
      , m_param1 ( in_param1 )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyParam2, *this );
    }
  };

  // *****************************************************************************
  class KeyParam3 : public KeyParam2 {
  public:
    float m_param2;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam3( rio<char_cptr> io_ptr_key_data )
      : KeyParam2( io_ptr_key_data )
      , m_param2 ( reinterpret_cast<KeyParam3 const*>(io_ptr_key_data)->m_param2 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam3( cref<KeyParam3> in_data )
      : KeyParam2( in_data )
      , m_param2 ( in_data.m_param2 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam3( rvref<KeyParam3> in_data )
      : KeyParam2( std::move(in_data) )
      , m_param2 ( in_data.m_param2 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam3
    ( _in<U32  > in_index
    , _in<bool > in_flag_interpolate
    , _in<float> in_param0
    , _in<float> in_param1
    , _in<float> in_param2
    ) : KeyParam2( in_index, in_flag_interpolate, in_param0, in_param1 )
      , m_param2 ( in_param2 )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyParam3, *this );
    }
  };

  // *****************************************************************************
  class KeyParam4 : public KeyParam3 {
  public:
    float m_param3;
    
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam4( rio<char_cptr> in_ptr_data_addr )
      : KeyParam3( in_ptr_data_addr )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam4( cref<KeyParam4> in_data )
      : KeyParam3( in_data )
      , m_param3 ( in_data.m_param3 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam4( rvref<KeyParam4> in_data )
      : KeyParam3( std::move(in_data) )
      , m_param3 ( in_data.m_param3 )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyParam4
    ( _in<U32  > in_index
    , _in<bool > in_flag_interpolate
    , _in<float> in_param0
    , _in<float> in_param1
    , _in<float> in_param2
    , _in<float> in_param3
    ) : KeyParam3
      ( in_index, in_flag_interpolate
      , in_param0, in_param1, in_param2
      )
      , m_param3 ( in_param3 )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyParam4, *this );
    }
  };
  
  // _____________________________________________________________________________
  /// @brief ベクトルキー
  ///
  // *****************************************************************************
  class KeyVector
    : public baseKeyFrame
  {
  public:
    CVector3 m_vec;
  protected:
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyVector( rio<char_cptr> in_ptr_data_addr );
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyVector( cref<KeyVector> in_data )
      : baseKeyFrame( in_data )
      , m_vec( in_data.m_vec )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyVector( rvref<KeyVector> in_data )
      : baseKeyFrame( std::move(in_data) )
      , m_vec( in_data.m_vec )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyVector
    ( _in<U32     > in_index
    , _in<bool    > in_flag_interpolate
    , _in<CVector3> in_vec = CVector3(0,0,0)
    ) : baseKeyFrame( in_index, in_flag_interpolate )
      , m_vec( in_vec )
    {}
  public:
    // *****************************************************************************
    template<int X, class T_Base>
    class EX_ : public T_Base
    {
    public:
      EX_( rio<char_cptr> in_ptr_data_addr )
        : T_Base( in_ptr_data_addr )
      {}
      EX_( cref<EX_> in_data ) : T_Base( in_data )
      {}
      EX_
      ( _in<U32     > in_index
      , _in<bool    > in_flag_interpolate
      , _in<CVector3> in_vec = CVector3(0,0,0)
      ) : T_Base( in_index, in_flag_interpolate, in_vec )
      {}

      // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      // クローンの作成
      sdptr<baseData> CreateClone() const override
      {
        return CPL_MAKE_SHARED( EX_, *this );
      }
    };
  };
  typedef KeyVector::EX_<0, KeyVector> KeyVecPos;
  typedef KeyVector::EX_<1, KeyVector> KeyVecRot;
  typedef KeyVector::EX_<2, KeyVector> KeyVecScl;


  // _____________________________________________________________________________
  /// @brief カラーキー
  ///
  // *****************************************************************************
  class KeyColor
    : public baseKeyFrame
  {
  public:
    float4 m_color;

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyColor( rio<char_cptr> io_ptr_data_addr );
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyColor( cref<KeyColor> in_data )
      : baseKeyFrame( in_data )
      , m_color( in_data.m_color )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyColor( rvref<KeyColor> in_data )
      : baseKeyFrame( std::move(in_data) )
      , m_color( in_data.m_color )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyColor
    ( _in<U32   > in_index
    , _in<bool  > in_flag_interpolate
    , _in<float4> in_color = float4(1,1,1,1)
    ) : baseKeyFrame( in_index, in_flag_interpolate )
      , m_color( in_color )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyColor, *this );
    }
  };
  //// =============================================================================
  //class KeyValue : public baseKeyFrame {
  //public:
  //  float m_value;
  //  KeyValue( char_cptr& in_ptr_data_addr );
  //  KeyValue( U32 in_index, U32 in_flag_interpolate, float in_value = 0.0f )
  //    : baseKeyFrame( in_index, in_flag_interpolate ),
  //      m_value( in_value )
  //  {}
  //};

  // _____________________________________________________________________________
  /// @brief テクスチャキー
  ///
  // *****************************************************************************
  class KeyTexCoord
    : public baseKeyFrame
  {
  public:
    // 関連付けUVセットポインタ。
    wkptr<TexCoordSet> m_wp_relation_texcoordset;
    // ファイル読み込み時一時設定するテクスチャのGID.
    // 以前は関連付けUVセットポインタに一時的に設定していたが、スマポ化したため不可に。
    TypeGID            m_GID_tex{0};

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyTexCoord( rio<char_cptr> io_ptr_data_addr );
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyTexCoord( cref<KeyTexCoord> in_data )
      : baseKeyFrame( in_data )
      , m_wp_relation_texcoordset( in_data.m_wp_relation_texcoordset )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyTexCoord( rvref<KeyTexCoord> in_data )
      : baseKeyFrame( std::move(in_data) )
      , m_wp_relation_texcoordset( in_data.m_wp_relation_texcoordset )
    {}
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    KeyTexCoord
    ( _in<U32               > in_index
    , _in<bool              > in_flag_interpolate
    , _in<wkptr<TexCoordSet>> in_sp_relation_texcoordset
    ) : baseKeyFrame( in_index, in_flag_interpolate )
      , m_wp_relation_texcoordset( in_sp_relation_texcoordset )
    {}

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // クローンの作成
    sdptr<baseData> CreateClone() const override
    {
      return CPL_MAKE_SHARED( KeyTexCoord, *this );
    }
  };

  // _____________________________________________________________________________
  /// @brief キーリスト
  ///
  // *****************************************************************************
  class AnmKeyList
    : public baseDataTreeT< AnmKeyList >
  {
  private:
    using td_base = baseDataTreeT< AnmKeyList >;
    friend class AnmData;

    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );
    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );

    MeshFileInfo::eKeyType
      zzf_getKeyType_to_KeyPointer( _in<sdptr<baseKeyFrame>> in_sp_keyframe ) const;

  protected:
    wkcptr<AnmData>        m_wp_anime_data; // 属するアニメーションオブジェクト
  public:
    MeshFileInfo::eKeyType m_data_type;
    wkptr<baseData>        m_wp_relation_data;
    sdptr<baseKeyFrame>    m_sp_keyframe_top;
    wkptr<baseKeyFrame>    m_wp_keyframe_end;
    wkptr<baseKeyFrame>    m_wp_keyframe_active;

    virtual void
      Release();
    virtual void
      SetRelation( _in<sdptr<MeshData>> in_sp_mesh_for_relation );
    virtual void
      SetPlayKeyFrame( _in<float> in_frame );
    virtual void
      MovePlayKeyFrame( _in<float> in_frame );

    virtual MeshFileInfo::eKeyType
      GetKeyKindType() const { return m_data_type; }
    virtual sdcptr<AnmData>
      GetAnimation() const { return m_wp_anime_data.lock(); }
    virtual float
      GetMaxIndex() const
    {
      return
        m_wp_keyframe_end.expired()
          ? 0.0f
          : (float)m_wp_keyframe_end.lock()->m_index;
    }
    virtual sdcptr<baseKeyFrame>
      GetActiveKeyFrame() const {
        return m_wp_keyframe_active.lock(); }

    virtual sdcptr<baseKeyFrame>
      GetActiveKeyFrameNext() const
    {
      return
        m_wp_keyframe_active.expired()
          ? m_wp_keyframe_active.lock()->GetLinkNext()
          : nullptr;
    }
    virtual void
      SetActiveKeyFrame( _in<sdptr<baseKeyFrame>> in_sp_keyframe )
    {
      m_wp_keyframe_active = in_sp_keyframe;
    }

    // 検索
    virtual sdptr<baseKeyFrame>
      FindPrevKeyFrame_by_Frame( _in<float> in_frame ) const;
    virtual sdptr<baseKeyFrame>
      FindNextKeyFrame_by_Frame( _in<float> in_frame ) const;
    // 存在検査
    virtual bool
      IsKeyFrame( _in<sdptr<baseKeyFrame>> in_sp_keyframe ) const;

    // タイプに順ずる新しいキーフレームを取得
    virtual sdptr<baseKeyFrame>
      NewDefaultKeyFrame
        ( _in<U32 > in_index_of_keyframe = 0
        , _in<bool> in_flag_interpolate  = 0
        ) const;

    // 追加
    virtual sdptr<baseKeyFrame>
      AddKeyFrame( _in<sdptr<baseKeyFrame>> io_sp_new_keyframe );
    // 削除
    virtual bool
      DelKeyFrame( _in<sdptr<baseKeyFrame>> io_keyframe_for_delete );
    virtual void
      DelKeyFrameAll();
    // ペースト
    virtual void
      PastKeyList
        ( cref<AnmKeyList> in_keylist_for_copysource
        , _in <int       > in_frame_of_insert
        );

    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    sdptr<baseData>
      CreateClone() const override
    {
      return CPL_MAKE_SHARED( AnmKeyList, *this );
    }

    AnmKeyList();
    AnmKeyList( cref<AnmKeyList> in_data );
    AnmKeyList( rvref<AnmKeyList> in_data );
    AnmKeyList( _in<sdcptr<AnmData>> in_sp_anm_data );
    ~AnmKeyList(){}
  }; // AnmKeyList

  // _____________________________________________________________________________
  /// @brief アニメデータ
  ///
  // *****************************************************************************
  class AnmData
    : public baseDataT< AnmData >
  {
  private:
    using td_base = baseDataT< AnmData >;
    friend class MeshData;

    TypeGID           m_user_ID;
    float             m_play_index;
    float             m_wait_frame;
    sdptr<AnmKeyList> m_sp_keylist_root;
    wkptr<AnmKeyList> m_wp_active_keylist;

    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr> io_table_for_data_pointer
        , rio<Array_ChunkPtr> io_table_for_chunk_pointer
        );
    void
      zzf_setupData_by_File_
        ( pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );

  public:
//    Array::Dynamic< SmPtr_AnmKeyList > m_keylist_sp_table;

    virtual TypeGID
      GetUserID() const { return m_user_ID; }
    virtual float
      GetPlayIndex() const { return m_play_index; }
    virtual float
      GetMaxIndex() const;
    virtual sdptr<AnmKeyList>
      GetKeyListRoot() const { return m_sp_keylist_root; }
    virtual sdptr<AnmKeyList>
      GetActiveKeyList() const {
        return m_wp_active_keylist.lock(); }

    virtual void
      SetRelation( _in<sdptr<MeshData>> in_sp_mesh_for_relation );
    virtual void
      SetPlayKeyFrame( _in<float> in_frame );
    virtual void
      SetKeyListRoot( _in<sdptr<AnmKeyList>> in_sp_keylist ){
        m_sp_keylist_root = in_sp_keylist; }
    virtual void
      SetActiveKeyList( _in<sdptr<AnmKeyList>> in_sp_keylist ){
        m_wp_active_keylist = in_sp_keylist; }

    virtual void
      MovePlayKeyFrame( _in<float> in_add_frame );
    virtual void
      Release();
    virtual sdptr<AnmKeyList>
      AddKeyList( _in<sdptr<AnmKeyList>> in_sp_keylist_parent );

    virtual bool
      DelKeyFrame( _in<sdptr<baseKeyFrame>> in_sp_del_keyframe );
    virtual void
      DelKeyFrameAll();
    
    virtual sdptr<AnmKeyList>
      FindKeyList_by_ID  ( _in<TypeGID> in_keylist_ID );
    virtual sdcptr<AnmKeyList>
      FindKeyList_by_ID  ( _in<TypeGID> in_keylist_ID ) const;
    virtual sdptr<AnmKeyList>
      FindKeyList_by_Name( pin<char> in_keylist_name );
    virtual sdcptr<AnmKeyList>
      FindKeyList_by_Name( pin<char> in_keylist_name ) const;

    virtual void
      SetUserID( _in<TypeGID> in_user_ID )
    {
      m_user_ID = in_user_ID;
    }
    virtual sdptr<AnmKeyList>
      SetActiveKeyList_by_ID( _in<TypeGID> in_keylist_ID );
    virtual sdptr<AnmKeyList>
      SetActiveKeyList_by_Name( pin<char> in_keylist_name );
    virtual sdptr<AnmKeyList>
      SetActiveKeyList_by_Pointer( _in<sdptr<AnmKeyList>> in_sp_keylist );

    virtual sdptr<AnmKeyList>
      On_NewKeyList( _in<sdcptr<AnmData>> in_sp_anm_data )
    {
      return CPL_MAKE_SHARED( AnmKeyList, in_sp_anm_data );
    }

    sdptr<baseData>
      CreateClone() const override
    {
      return CPL_MAKE_SHARED( AnmData, *this );
    }

    AnmData();
    AnmData( cref<AnmData> in_data );
    AnmData( rvref<AnmData> in_data );
    ~AnmData(){ Release(); }
  };


  // _____________________________________________________________________________
  /// @brief シェーダー
  ///
  // *****************************************************************************
  class Shader
    : public baseDataT< Shader >
  {
  private:
    using td_base = baseDataT< Shader >;
    friend class MeshData;
    friend class Object;

  protected:
    sdptr<CInputLayout > m_sp_input_layout;
    sdptr<CVertexShader> m_sp_vtx_shader;
    sdptr<CPixelShader > m_sp_pxl_shader;
    MFI_ShaderInfoVS     m_vs_param;
    MFI_ShaderInfoPS     m_ps_param;

    void
      zzf_setupData_by_File_
        ( _in<DX::DXDevice*      > in_ptr_d3d_dev
        , pin<MeshFileInfo::Chunk> in_ptr_chunk
        , rio<Array_DataSPtr     > io_table_for_data_pointer
        , rio<Array_ChunkPtr     > io_table_for_chunk_pointer
        );
    void
      zzf_setupRelation_
        ( rio<Array_DataSPtr       > io_table_for_data_pointer
        , rio<Array_ChunkPtr       > io_table_for_chunk_pointer
        , _in<Array_SpLightMaterial> in_light_table
        );
  public:
    virtual sdptr<CInputLayout>
      GetCInputLayout()  const { return m_sp_input_layout; }
    virtual sdptr<CVertexShader>
      GetCVertexShader() const { return m_sp_vtx_shader; }
    virtual sdptr<CPixelShader>
      GetCPixelShader()  const { return m_sp_pxl_shader; }
    virtual MFI_ShaderInfoVS const&
      GetVS_Param()      const { return m_vs_param; }
    virtual MFI_ShaderInfoPS const&
      GetPS_Param()      const { return m_ps_param; }

    //virtual DX::D3DInputLayout::cptr
    //  GetDxVertexLayout()        const { return m_sp_relation_buf_layout->GetLayoutBuffer()->GetDxObject(); }
    //virtual DX::D3DInputLayout::ptr
    //  GetDxVertexLayout()              { return m_sp_relation_buf_layout->GetLayoutBuffer()->GetDxObject(); }
    virtual DX::DXVertexShader const*
      GetDxVertexShader()        const { return m_sp_vtx_shader->GetVS(); }
    virtual DX::DXVertexShader*
      GetDxVertexShader()              { return m_sp_vtx_shader->GetVS(); }
    //virtual DX::D3DConstantTable_cptr
    //  GetDxVertexConstantTable() const { return m_sp_vtx_shader->GetCT(); }
    //virtual DX::D3DConstantTable_ptr
    //  GetDxVertexConstantTable()       { return m_sp_vtx_shader->GetCT(); }
    virtual DX::DXPixelShader const*
      GetDxPixelShader()         const { return m_sp_pxl_shader->GetPS(); }
    virtual DX::DXPixelShader*
      GetDxPixelShader()               { return m_sp_pxl_shader->GetPS(); }
    //virtual DX::D3DConstantTable_cptr
    //  GetDxPixelConstantTable()  const { return m_sp_pxl_shader->GetCT(); }
    //virtual DX::D3DConstantTable_ptr
    //  GetDxPixelConstantTable()        { return m_sp_pxl_shader->GetCT(); }

    virtual void
      Release();
    
    sdptr<baseData>
      CreateClone() const override
    {
      return CPL_MAKE_SHARED( Shader, *this );
    }

    Shader();
    Shader( cref<Shader> in_data );
    Shader( rvref<Shader> in_data );
    ~Shader(){ Release(); }
  };


private:
  // >---------------------------------------------------------------------------
  wkptr<MeshData>       m_wp_myself;
  DX::DXDevice*         m_ptr_d3d_emd_ctx;
  Array_SpVtxLayout     m_vtxlayout_sp_table;
  Array_SpObject        m_object_sp_table;
  Array_SpShader        m_shader_sp_table;
  Array_SpTexture       m_texture_sp_table;
  Array_SpTexMaterial   m_texture_material_sp_table;
  Array_SpMaterial      m_color_material_sp_table;
  Array_SpLightMaterial m_light_material_sp_table;
  Array_SpAnime         m_anime_sp_table;

  wkptr<Object>         m_wp_object_root;
  wkptr<AnmData>        m_wp_active_anime;
  Core::String          m_path;
  // ---------------------------------------------------------------------------<

//  void zzf_setupAnimeRelation_( Array_DataPtr& io_table_for_data_pointer );
//  void zzf_addAnimation_( ScPtr_AnmData in_sp_new_anime );

  void
    zzf_create
      ( _in<Core::MemoryStream> in_stream_for_memory
      , pio<DX::DXDevice>       in_ptr_d3d_dev
      );
  void
    zzf_setupData_by_File_
      ( _in<Core::MemoryStream> in_stream_for_memory
      , _in<DX::DXDevice*     > in_ptr_d3d_dev
      , rio<Array_DataSPtr    > io_table_for_data_pointer
      , rio<Array_ChunkPtr    > io_table_for_chunk_pointer
      );
  void
    zzf_setupRelation_
      ( rio<Array_DataSPtr> io_table_for_data_pointer
      , rio<Array_ChunkPtr> io_table_for_chunk_pointer
      );
  void
    zzf_clearRelation_();
  void
    zzf_getZSortObject_
      ( rout<Array_SpObject> out_object_table
      , _in <CVector3      > in_camera_pos
      );

public:
  virtual Array_SpObject&
    GetObjectTable(){
      return m_object_sp_table; }
  virtual cref<sdptr<Object>>
    GetObject( size_t in_obj_index ){
      return m_object_sp_table[ in_obj_index ]; }

  virtual Array_SpShader&
    GetShaderTable(){
      return m_shader_sp_table; }
  virtual cref<sdptr<Shader>>
    GetShader( size_t in_shader_index ){
      return m_shader_sp_table[ in_shader_index ]; }

  virtual Array_SpTexture&
    GetTextureTable(){
      return m_texture_sp_table; }
  virtual cref<sdptr<Texture>>
    GetTexture( size_t in_tex_index ){
      return m_texture_sp_table[ in_tex_index ]; }

  virtual Array_SpTexMaterial&
    GetTextureMaterialTable(){
      return m_texture_material_sp_table; }
  virtual cref<sdptr<TextureMaterial>>
    GetTextureMaterial( size_t in_tex_mtrl_index ){
      return m_texture_material_sp_table[ in_tex_mtrl_index ]; }

  virtual Array_SpMaterial&
    GetColorMaterialTable(){
      return m_color_material_sp_table; }
  virtual cref<sdptr<ColorMaterial>>
    GetColorMaterial( size_t in_color_mtrl_index ){
      return m_color_material_sp_table[ in_color_mtrl_index ]; }

  virtual Array_SpLightMaterial&
    GetLightMaterialTable(){
      return m_light_material_sp_table; }
  virtual cref<sdptr<LightMaterial>>
    GetLightMaterial( size_t in_light_mtrl_index ){
      return m_light_material_sp_table[ in_light_mtrl_index ]; }

  virtual Array_SpAnime&
    GetAnimeTable(){
      return m_anime_sp_table; }
  virtual cref<sdptr<AnmData>>
    GetAnime( size_t in_anime_index ){
      return m_anime_sp_table[ in_anime_index ]; }

  virtual sdptr<Object>
    GetObjectRoot()       { return m_wp_object_root.lock(); }
  virtual sdcptr<Object>
    GetObjectRoot() const { return m_wp_object_root.lock(); }
  virtual void
    SetObjectRoot( _in<sdptr<Object>> in_sp_object ){
      m_wp_object_root = in_sp_object; }

  virtual void
    Release();
  virtual void
    AnimeRelease();

  virtual bool SetAnimeRelation( _in <size_t> in_index_for_animation );
  virtual size_t
    GetAnimeIndex_by_ID( _in<int> in_user_ID );

  // 現在のアニメーションを取得
  virtual sdptr<AnmData>
    GetActiveAnimation()       { return m_wp_active_anime.lock(); }
  virtual sdcptr<AnmData>
    GetActiveAnimation() const { return m_wp_active_anime.lock(); }
  // 現在のアニメーションの設定
  virtual sdptr<AnmData>
    SetActiveAnimation_by_Index( _in<size_t> in_index_for_animation );
  virtual sdptr<AnmData>
    SetActiveAnimation_by_UserID( _in<int> in_user_id );
  virtual sdptr<AnmData>
    SetActiveAnimation_by_Pointer( _in<sdptr<AnmData>> in_sp_anime );

#define CPL_CDI_MESHDATA_FIND_XXX_SEARCH_DETAIL( TYPe, FUNCNAMe, ARGTYPe, ARGNAMe, CALLFUNc, CONTAINEr, ... )\
  virtual std::shared_ptr<TYPe>\
    FUNCNAMe( ARGTYPe ARGNAMe ) __VA_ARGS__\
    {\
      return\
        CALLFUNc<TYPe>\
        ( ARGNAMe,\
          CONTAINEr.begin(),\
          CONTAINEr.end() );\
    }

#define CPL_CDI_MESHDATA_FIND_XXX_SEARCH_ID( TYPe, FUNCNAMe, ARGNAMe, CONTAINEr )\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_DETAIL( TYPe,       FUNCNAMe, TypeGID, ARGNAMe, zzf_search_by_ID_, CONTAINEr );\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_DETAIL( TYPe const, FUNCNAMe, TypeGID, ARGNAMe, zzf_search_by_ID_, CONTAINEr, const );

#define CPL_CDI_MESHDATA_FIND_XXX_SEARCH_NAME( TYPe, FUNCNAMe, ARGNAMe, CONTAINEr )\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_DETAIL( TYPe,       FUNCNAMe, char_cptr, ARGNAMe, zzf_search_by_Name_, CONTAINEr );\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_DETAIL( TYPe const, FUNCNAMe, char_cptr, ARGNAMe, zzf_search_by_Name_, CONTAINEr, const );

#define CPL_CDI_MESHDATA_FIND_XXX_SEARCH( TYPeNAMe, ARGNAMe, CONTAINEr )\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_ID  ( TYPeNAMe, Find##TYPeNAMe##_by_ID,   ARGNAMe##_ID,   CONTAINEr );\
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH_NAME( TYPeNAMe, Find##TYPeNAMe##_by_Name, ARGNAMe##_name, CONTAINEr );

  // オブジェクト検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( Object, in_object, m_object_sp_table );

  // カラーマテリアル検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( ColorMaterial, in_color_mtrl, m_color_material_sp_table );

  // テクスチャマテリアル検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( TextureMaterial, in_tex_mtrl, m_texture_material_sp_table );

  // ライトマテリアル検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( LightMaterial, in_light_mtrl, m_light_material_sp_table );

  // シェーダー検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( Shader, in_shader, m_shader_sp_table );

  // アニメ検索関数定義。
  CPL_CDI_MESHDATA_FIND_XXX_SEARCH
    ( AnmData, in_animation, m_anime_sp_table );

  // 各オブジェクトの作成
  virtual sdptr<Object>
    CreateObject( _in<sdptr<Object>> in_sp_object_for_parent );
  virtual sdptr<AnmData>
    CreateAnimation
    ( _in<Core::StringA> in_name_for_animation,
      _in<TypeGID>       in_user_ID = -1 );
  virtual sdptr<ColorMaterial>
    CreateColorMaterial();
  virtual sdptr<LightMaterial>
    CreateLightMaterial();
  virtual sdptr<Shader>
    CreateShader();
  virtual sdptr<Texture>
    CreateTexture();
  virtual sdptr<TextureMaterial>
    CreateTextureMaterial();

  // 各オブジェクト追加
  virtual sdptr<Object>
    AddObject
      ( _in<sdptr<Object>> in_sp_object
      , _in<sdptr<Object>> in_sp_object_for_parent
      );
  virtual sdptr<AnmData>
    AddAnimation
      ( _in<sdptr<AnmData>> in_sp_animation
      , _in<int           > in_insert_key_index = -1
      );
  virtual sdptr<ColorMaterial>
    AddColorMaterial
      ( _in<sdptr<ColorMaterial>> in_sp_material_of_color
      , _in<int                 > in_insert_key_index = -1
      );
  virtual sdptr<LightMaterial>
    AddLightMaterial
      ( _in<sdptr<LightMaterial>> in_sp_material_of_light
      , _in<int                 > in_insert_key_index = -1
      );
  virtual sdptr<Shader>
    AddShader
      ( _in<sdptr<Shader>> in_sp_shader
      , _in<int          > in_insert_key_index = -1
      );
  virtual sdptr<Texture>
    AddTexture
      ( _in<sdptr<Texture>> in_sp_texture
      , _in<int           > in_insert_key_index = -1
      );
  virtual sdptr<TextureMaterial>
    AddTextureMaterial
      ( _in<sdptr<TextureMaterial>> in_sp_material_of_texture
      , _in<int                   > in_insert_key_index = -1
      );

  // 各オブジェクトの削除
  virtual bool
    DeleteObject( _in<sdptr<Object>> in_sp_object );
  virtual bool
    DeleteAnimation( _in<sdptr<AnmData>> in_sp_anime );
  virtual bool
    DeleteColorMaterial( _in<sdptr<ColorMaterial>> in_sp_material_of_color );
  virtual bool
    DeleteColorMaterial( _in<size_t> in_index_for_color_material );
  virtual bool
    DeleteLightMaterial( _in<sdptr<LightMaterial>> in_sp_material_of_light );
  virtual bool
    DeleteLightMaterial( _in<size_t> in_index_for_light_material );
  virtual bool
    DeleteShader( _in<sdptr<Shader>> in_sp_shader );
  virtual bool
    DeleteShader( _in<size_t> in_index_for_shader );
  virtual bool
    DeleteTexture( _in<sdptr<Texture>> in_sp_texture );
  virtual bool
    DeleteTexture( _in<size_t> in_index_for_texture );
  virtual bool
    DeleteTextureMaterial( _in<sdptr<TextureMaterial>> in_sp_material_of_texture );
  virtual bool
    DeleteTextureMaterial( _in<size_t> in_index_for_texture_material );

  virtual bool
    CreateMeshFile( rout<Core::MemoryStream> out_stream_for_memory );

  // 
  virtual sdptr<Object>
    On_NewObject()          { return CPL_MAKE_SHARED(Object);          }
  virtual sdptr<AnmData>
    On_NewAnimation()       { return CPL_MAKE_SHARED(AnmData);         }
  virtual sdptr<ColorMaterial>
    On_NewColorMaterial()   { return CPL_MAKE_SHARED(ColorMaterial);   }
  virtual sdptr<LightMaterial>
    On_NewLightMaterial()   { return CPL_MAKE_SHARED(LightMaterial);   }
  virtual sdptr<Shader>
    On_NewShader()          { return CPL_MAKE_SHARED(Shader);          }
  virtual sdptr<Texture>
    On_NewTexture()         { return CPL_MAKE_SHARED(Texture);         }
  virtual sdptr<TextureMaterial>
    On_NewTextureMaterial() { return CPL_MAKE_SHARED(TextureMaterial); }

  virtual void
    On_OtherChunk
      ( pin<MeshFileInfo::Chunk> in_ptr_chunk
      , rio<Array_DataSPtr     > io_table_for_data_pointer
      )
  {}

  virtual void
    Draw
      ( pio<DX::DXDeviceContext> in_ptr_d3d_emd_ctx
      , pin<CMatrix            > in_ptr_mtx_view_proj
      , pin<CMatrix            > in_ptr_mtx_proj
      , pin<CMatrix            > in_ptr_mtx_view
      , _in<CVector3           > in_eye_pos
      , _in<CVector3           > in_look_pos
      );            

protected:
  MeshData
    ( _in<Core::MemoryStream> in_stream_for_memory
    , _in<DX::DXDevice*     > in_ptr_d3d_dev
    );
  MeshData
    ( _in<Core::FileStream> in_file_stream
    , _in<DX::DXDevice*   > in_ptr_d3d_dev
    );
  MeshData();
public:

  friend Factory<MeshData>;
  friend CallPrivateConstructor<MeshData>;

  ~MeshData(){ Release(); }
};


namespace doxycomment
{
/// @param[in] in_flag_interpolate
///   : 次のキーフレームと補間するかどうかを指定します。\n
///   : true  - 直前のキーフレームと次のキーフレームで補間した値を使用します。\n
///   : false - 直前のキーフレームの値を使用します。
void arg_in_flag_interpolate( _in<bool> in_flag_interpolate ){}
/// @param[in,out] io_table_for_data_pointer
///   : データポインタ取得用のデータポインタ配列オブジェクトを渡します。\n
void arg_io_table_for_data_pointer( rio<MeshData::Array_DataSPtr> io_table_for_data_pointer ){}
/// @param[in,out] io_table_for_chunk_pointer
///   : チャンクポインタ取得用のチャンクポインタ配列オブジェクトを渡します。\n
void arg_io_table_for_chunk_pointer( rio<MeshData::Array_ChunkPtr> io_table_for_chunk_pointer ){}
/// @param[in] io_ptr_key_data
///   : キーデータを指すポインタを指定します。\n
///   : 読み込まれたバイト数だけポインタを進めます。\n
void arg_io_ptr_key_data( rio<char_cptr> io_ptr_key_data ){}
/// @param[in] in_sp_object_for_parent
///   : 親となるオブジェクトのスマートポインタを指定します。\n
void arg_in_sp_object_for_parent( _in<sdptr<MeshData::Object>> in_sp_object_for_parent ){}
/// @param[in] in_insert_key_index
///   : 挿入位置のキーフレームインデックスを指定します。\n
///   : フレーム値ではありません。
void arg_in_insert_key_index( _in<int> in_insert_key_index ){}

/// @brief ファイルからデータの構築
/// @param[in] in_ptr_chunk
///   : データを指すチャンクポインタを指定します。
/// @copydetails doxycomment::arg_io_table_for_data_pointer
/// @copydetails doxycomment::arg_io_table_for_chunk_pointer
/// @return なし。
void func_zzf_setupData_by_File_
    ( pin<MeshFileInfo::Chunk     > in_ptr_chunk
    , rio<MeshData::Array_DataSPtr> io_table_for_data_pointer
    , rio<MeshData::Array_ChunkPtr> io_table_for_chunk_pointer
    ){}

/// @brief 関連付けデータの設定
/// @copydetails doxycomment::arg_io_table_for_data_pointer
/// @copydetails doxycomment::arg_io_table_for_chunk_pointer
/// @return なし。
void func_zzf_setupRelation_
    ( rio<MeshData::Array_DataSPtr> io_table_for_data_pointer
    , rio<MeshData::Array_ChunkPtr> io_table_for_chunk_pointer
    ){}
}


} // namespace CDI
} // namespace CPL

