//=========================================================================
//	CSceneMeshクラス [ sceneMesh.cpp ]
//	作成日：2017/05/02
//	作成者：小暮大樹
//=========================================================================
//=========================================================================
//	インクルードファイル
//=========================================================================
#include	"sceneMesh3D.h"
#include	"manager.h"
#include	"renderer.h"
//=========================================================================
//	定数定義
//=========================================================================
#define	TEXTURE_NAME ("data/TEXTURE/field000.jpg")

//=========================================================================
//	インストラクタ
//=========================================================================
CSceneMesh3D::CSceneMesh3D( int sheetTate , int sheetYoko , D3DXVECTOR3 Size )
{

}

//=========================================================================
//	初期化
//=========================================================================
void	CSceneMesh3D::Init( void )
{
	//デバイスの取得
	LPDIRECT3DDEVICE9	pDevice;
	pDevice = CRenderer::GetDevice();

	//hrに関数がはいいているので、FAILEDマクロに入れれば横に長くならない
	if( FAILED( D3DXCreateTextureFromFile( pDevice , TEXTURE_NAME , &m_pTexture ) ) )
	{	//FALEDマクロ　失敗か成功かを判断する
		UINT nID = MessageBox( NULL , "ポリゴンファイルがありません\n" , "ERROR[ sceneMesh3D.cpp ]" , MB_OK | MB_ICONEXCLAMATION );		
	}
	//FAILEDマクロでエラーチェックする

	//中心位置
	SetPosition( D3DXVECTOR3( 0 , 0 , 0 ) );

	float fLengthYoko = GetSize().x;
	float fLengthTate = GetSize().y;
	unsigned int nFieldYoko = ( unsigned int )GetSheet().x;
	unsigned int nFieldTate = ( unsigned int )GetSheet().y;

	//対角線の長さ
	SetLength( sqrtf( ( fLengthYoko * nFieldYoko ) * ( fLengthTate * nFieldTate) / 2 ));

	SetAngle( (atan2f( fLengthTate * nFieldTate , fLengthYoko * nFieldYoko ) ) );

	//フィールドの左上
	SetStartPos( D3DXVECTOR3( -( GetLength() * cosf( GetAngle() )) , 0.0f , ( GetLength() * sinf( GetAngle() ) ) ) );

	SetNumVertex( ( nFieldTate + 1 ) * ( nFieldYoko + 1 ) );

	MakeVertex( pDevice );
}

//=========================================================================
//	終了処理
//=========================================================================
void	CSceneMesh3D::Uninit( void )
{
	if(m_pVtxBuffer != NULL)
	{
		m_pVtxBuffer->Release();
		m_pVtxBuffer = NULL;
	}

	if(m_pTexture != NULL)
	{
		m_pTexture->Release();
		m_pTexture = NULL;
	}
}

//=========================================================================
//	更新処理
//=========================================================================
void	CSceneMesh3D::Update( void )
{/*変化しないので無し*/}

//=========================================================================
//	描画処理
//=========================================================================
void	CSceneMesh3D::Draw( void )
{
	//デバイスの取得
	LPDIRECT3DDEVICE9	pDevice;
	pDevice = CRenderer::GetDevice();

	D3DXMATRIX	mtxWorld;	//ワールドマトリクス
	D3DXMatrixIdentity( &mtxWorld );

	//拡大の処理
	D3DXMATRIX	mtxKakudai;	//拡大行列
	D3DXMatrixScaling( &mtxKakudai , 1.0f , 1.0f , 1.0f );

	//回転の処理
	D3DXMATRIX	mtxKaiten;	//回転行列
	D3DXMatrixRotationYawPitchRoll( &mtxKaiten , 0.0f , 0.0f , 0.0f );	
	
	D3DXMATRIX	mtxHeikou;	//並行移動行列
	D3DXMatrixTranslation( &mtxHeikou , GetPosition().x , GetPosition().y , GetPosition().z );

	//行列の掛け算
	D3DXMatrixMultiply( &mtxWorld , &mtxWorld , &mtxKakudai );	
	D3DXMatrixMultiply( &mtxWorld , &mtxWorld , &mtxKaiten );	
	D3DXMatrixMultiply( &mtxWorld , &mtxWorld , &mtxHeikou );	

	//デバイスにワールド変換行列を登録
	pDevice->SetTransform( D3DTS_WORLD , &mtxWorld );

	pDevice->SetStreamSource( 0 , m_pVtxBuffer , 0 , sizeof(VERTEX_3D) );

	pDevice->SetIndices( m_pIndexBuffer );

	pDevice->SetFVF( FVF_VERTEX_3D );

	pDevice->SetTexture( 0,  m_pTexture );

	//ポリゴンの描画
	pDevice->DrawIndexedPrimitive( 
		D3DPT_TRIANGLESTRIP ,
		 0 , //最初の頂点インデックスまでのオフセット
		 0 , //最小頂点インデックス
		 GetNumIndex() ,	//頂点数
		 0 , //スタートインデックス
		 GetPolygonNum() - 2 //プリミティブ数
	 );
}

//=========================================================================
//	頂点の編集
//=========================================================================
HRESULT	CSceneMesh3D::MakeVertex( LPDIRECT3DDEVICE9 pDevice )
{
	unsigned int nFieldTate = ( unsigned int )GetSheet().z;
	unsigned int nFieldYoko = ( unsigned int )GetSheet().x;

	float	fLengthTate = GetSize().z;
	float	fLengthYoko = GetSize().x;

	//頂点バッファの生成
	//FALEDマクロでくくる
	if( FAILED(pDevice->CreateVertexBuffer( sizeof(VERTEX_3D) * GetNumVertex() , //確保するバッファサイズ(byte)
											D3DUSAGE_WRITEONLY , //メモリの使用方法  とりあえずこれだけ書いておけば早い　絵を描くだけのやつ
											FVF_VERTEX_3D , //使用する頂点フォーマット でも実は０で大丈夫
											D3DPOOL_MANAGED , //バッファの管理方法　今回のはおまかせのやつ
											&m_pVtxBuffer , //ポインタの格納先
											NULL ))) //なんだかわかんないやつ)
	{										
		UINT nID = MessageBox( NULL , "頂点バッファが生成できません\n" , "ERROR[ sceneMesh3D.cpp ]" , MB_OK | MB_ICONEXCLAMATION );		
		return E_FAIL;
	}

	//VERTEX_2D型のポインタ
	VERTEX_3D* pVtx = NULL;

	//バッファをロックし仮想アドレスを取得する
	m_pVtxBuffer->Lock( 0 , 0 , (void**)&pVtx ,0 );	//引数の最初２つに００を指定すると全部

	
	//頂点座標の設定				 X		   Y		Z
	//縦のやつ
	for( unsigned int numTate = 0 ; numTate <= nFieldTate ; numTate++ )
	{
		//横のやつ
		for( unsigned int numYoko = 0 ; numYoko <= nFieldYoko ; numYoko++ )
		{
			pVtx[ numTate * ( nFieldYoko + 1 ) + numYoko ].pos = D3DXVECTOR3( GetStartPos().x + ( fLengthYoko * numYoko ) , 0.0f , GetStartPos().z - ( numTate * fLengthTate ) );
			pVtx[ numTate * ( nFieldYoko + 1 ) + numYoko ].tex = D3DXVECTOR2( (float)numYoko , (float)numTate );

			float	x = GetStartPos().x + ( fLengthYoko * numYoko);
			float	z = GetStartPos().z - ( numTate * fLengthTate);
			x = x;
		}
	}

	//法線
	for( unsigned int i = 0 ; i < GetNumVertex() ; i++ )
	{
		pVtx[i].normal = D3DXVECTOR3(  0.0f , -1.0f , 0.0f );
		pVtx[i].color = D3DCOLOR_RGBA( 255, 255 , 255  , 255); 
	}


	m_pVtxBuffer->Unlock();

	//■インデックスバッファの作成
	if( pDevice->CreateIndexBuffer(
	sizeof( DWORD ) * GetNumIndex(),	//バッファ量(32にしたらDWORDにする)
	D3DUSAGE_WRITEONLY ,		//使用方法フラグ
	D3DFMT_INDEX16 ,			//インデックスフォーマット
	D3DPOOL_MANAGED ,			//メモリ管理方法
	&m_pIndexBuffer ,		//インデックスバッファーインターフェースへのポインタのアドレス
	NULL ) )
	{
		UINT nID = MessageBox( NULL , "インデックスバッファが生成できません\n" , "エラー" , MB_YESNO | MB_ICONEXCLAMATION );		
		return E_FAIL;
	}


	
	WORD* pIdx;
	m_pIndexBuffer->Lock( 0 , 0 , (void**)&pIdx , 0 );	//引数の意味はバーテックスバッファーのときと同じ

	int	index = 0;
	for( unsigned int nCntZ = 0 ; nCntZ < nFieldYoko ; nCntZ++ )
	{
		if( nCntZ != 0  )
		{
			pIdx[ index ] = (nFieldYoko + 1) * nCntZ+ (nFieldYoko + 1);
			index++;
		}
		pIdx[ index ] = (nFieldYoko+1)  * ( nCntZ + 1 );
		index++;
		pIdx[ index ] = (nFieldYoko+1) * nCntZ ;
		index++;
	
		for( unsigned int nCntX = 0 ; nCntX < nFieldYoko ; nCntX++ )
		{
			pIdx[ index ] = ( nFieldYoko + 1 ) * (nCntZ + 1) + (nCntX + 1);
			index++;
			pIdx[ index ] = ( nFieldYoko + 1 ) * nCntZ + (nCntX +1);
			index++;
		}
		if(nCntZ != (nFieldTate -1) )
		{
			pIdx[ index ] = nFieldYoko + ( nCntZ * (nFieldYoko+1) );
			index++;
 		}
	}

	m_pIndexBuffer->Unlock();
	

	return	S_OK;
}