/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   2009/X/X - 2015/11/10
/// 
/// @brief  メッシュ、ボーン関連。
/// 
/// ****************************************************************************

#include "CPL_CDI_MeshData.h"

namespace CPL {
namespace CDI {


// _____________________________________________________________________________
/// @brief デフォルトコンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MeshData::TexCoordSet::TexCoordSet()
  : m_stage_num(1)
  , m_dim_num(2)
{}


// _____________________________________________________________________________
/// @brief コピーコンストラクタ
/// 
/// @param[in] in_tex_coord : コピー元のTexCoordSetを指定します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MeshData::TexCoordSet::TexCoordSet( cref<TexCoordSet> in_tex_coord )
  : td_base( in_tex_coord )
  , m_stage_num( in_tex_coord.m_stage_num )
  , m_dim_num  ( in_tex_coord.m_dim_num )
{
  using DxBufSdrRes = DX::Buffer::DynamicEX_ShaderResource;
  //
  auto size_element = in_tex_coord.GetTexCoordBuf()->GetElementSize();
  auto num_element  = in_tex_coord.GetTexCoordBuf()->GetElementNum();
  auto size         = size_element * num_element;
  Core::DefaultBuffer tmp_buf( size );
  m_sp_vsb_texcoordset =
    CPL_MAKE_SHARED( DxBufSdrRes, size_element, num_element, nullptr );
  in_tex_coord.GetTexCoordBuf()->GetData( 0, tmp_buf.GetDataAddr(), size );
  // コピー
  m_sp_vsb_texcoordset->SetData( 0, tmp_buf.GetDataAddr(), size );
}


// _____________________________________________________________________________
/// @brief TexCoordSet ムーブコンストラクタ
/// 
/// @param[in] in_tex_coord : ムーブ元のTexCoordSetを指定します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MeshData::TexCoordSet::TexCoordSet( rvref<TexCoordSet> in_tex_coord )
  : td_base( std::move(in_tex_coord) )
  , m_stage_num( in_tex_coord.m_stage_num )
  , m_dim_num  ( in_tex_coord.m_dim_num )
{
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャ座標セット　データ構築
// 
// ※ まだ実装不完全
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  MeshData::TexCoordSet::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
    )
{
  char_cptr ptr_data_addr =
    reinterpret_cast<char_cptr>(in_ptr_chunk);
  MFI_TexCoordSet const* ptr_info_texset =
    reinterpret_cast<MFI_TexCoordSet const*>(ptr_data_addr);
  ptr_data_addr =
    static_cast<char_cptr>(ptr_info_texset->DataAddr_()); // データアドレス調整
  // データポインタ登録
  io_table_for_data_pointer.Add( ptr_info_texset->m_GID, this->GetLinkMyself() );
  // チャンクポインタ登録
  io_table_for_chunk_pointer.Add( this, in_ptr_chunk );

  // データ設定
  m_stage_num = ptr_info_texset->m_stage_num;
  m_dim_num   = ptr_info_texset->m_dim_num;
  int tex_element_num = m_dim_num * m_stage_num;
  //int tex_element_total_num = tex_element_num * in_vtx_num;
  if( tex_element_num > 0 )
  {
    //int buf_size = tex_element_total_num * sizeof(float);

    // 頂点ストリーム要素クラスの設定。
    auto sp_layout_buf = zzz_makeLayoutBuffer_();

    // 頂点バッファの作成。
    using DxBufSdrRes = DX::Buffer::DynamicEX_ShaderResource;
    auto const elm_size =
      sp_layout_buf->GetElementsSize( static_cast<size_t>(eBufferIndex::Texture) );
    auto const elm_num  = static_cast<UINT>(sp_layout_buf->GetElementNum());
    m_sp_vsb_texcoordset =
      CPL_MAKE_SHARED( DxBufSdrRes, elm_size, elm_num, ptr_data_addr );
  }
}


// _____________________________________________________________________________
// レイアウトバッファ作成
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
sdptr<DX::Layout::Buffer>
  MeshData::TexCoordSet::zzz_makeLayoutBuffer_()
{
  auto sp_layout_buf = CPL_MAKE_SHARED(DX::Layout::Buffer);
  switch( m_dim_num )
  {
  case 0:  sp_layout_buf->AddElement( DX::Layout::VtxElmTex0() ); break;
  case 1:  sp_layout_buf->AddElement( DX::Layout::VtxElmTex1() ); break;
  case 2:  sp_layout_buf->AddElement( DX::Layout::VtxElmTex2() ); break;
  default: sp_layout_buf->AddElement( DX::Layout::VtxElmTex3() ); break;
  }

  return sp_layout_buf;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャ座標セット　後始末
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MeshData::TexCoordSet::Release()
{
  m_stage_num = 0;
  m_dim_num   = 0;
  m_sp_vsb_texcoordset = nullptr;
}





} // namespace CDI
} // namespace CPL