/***************************************************************/
//
//
//		DirectX	[ meshsphere.cpp ]
//
//											Author	kazuki tanaka
//											Date	2017 6/19
/*---------------------------------------------------------------
■Update : 2017/6/19
			meshsphere.cppの作成

/*---------------------------------------------------------------
	Include File
---------------------------------------------------------------*/



#include "meshsphere.h"


#include "mathematics.h"

#include "mesh_rendererinverse.h"

#include "vertexbuffer_manager.h"
#include "texture_manager.h"
#include "indexbuffer_manager.h"

#include "d_console.h"


/*---------------------------------------------------------------
	Macro Difinition
---------------------------------------------------------------*/

#define Z_SDW_ROTATION ( 360 )
#define Y_SDW_ROTATION ( 90 )

using namespace Mathematics;

/*----------------------------------------------------------------
	static member variable Initialize 
----------------------------------------------------------------*/




// MeshSphere Constructor
MeshSphere::MeshSphere( const std::string& filename )
	: pVtxBuf(nullptr)
	, pIdxBuf(nullptr)
	, pTexture(nullptr)
	, renderer(nullptr) 
	, vertical(0)
	, horizonal(0)
	, radius(0)
	, theta(0)
	, phy(0)
{

	// Member Clear Process
	pTexture = TextureManager::LoadFromManager( filename.data() );

}

// MeshSphere Destructor
MeshSphere::~MeshSphere( )
{

	// Do Nothing!!

}

// MeshSphere Create Instance 
MeshSphere* MeshSphere::Create( const std::string& filename )
{

	// Create Class Instance
	return new MeshSphere( filename );

}

// MeshSphere Initialize
void MeshSphere::Init( void )
{

	// Initialize Process
	vertical  = 10;
	horizonal = 10;
	radius    = 10;

	pVtxBuf = VertexBufferManager::PlatformSelect( );
	pIdxBuf = IndexBufferManager::PlatformSelect( );

	if( !pVtxBuf->CreateVertexBuffer( FVF_VERTEX_3D, (( vertical*((vertical*4)+1) ) + 1 ))) return;
	if( !pIdxBuf->CreateIndexBuffer( ((vertical)*(vertical*4+1) + (vertical-1)) *2 )) return;

	// Set Buffer < Vertex & Index >
	SetBuffer( );

	// Component Set
	renderer = MeshRendererInverse::SetComponent( &pVtxBuf, &pIdxBuf, &pTexture, &world );


}

// MeshSphere Uninitialize
void MeshSphere::Uninit( void )
{

	// Uninitialize Process
	pVtxBuf->Release( );
	pIdxBuf->Release( );
	RenderInterfaceManager::Delete( renderer );
	GameObjectManager::Release( this );

}

// MeshSphere Update
void MeshSphere::Update( void )
{

	// Update Process


}

// MeshSphere SetBuffer
void MeshSphere::SetBuffer( void )
{

	// Vertual Pointer
	Vertex3D*       pVtx;
	unsigned short* pIndex;

	{ // 頂点バッファの設定

		pVtxBuf->Lock( &pVtx );

		for( unsigned int y = 0,x = 0; y < vertical; y++ ){

			theta = (float)(Y_SDW_ROTATION/vertical) * y;

			for( x = 0; x < (vertical*4)+1 ; x++ ){

				phy = (float)(Z_SDW_ROTATION/((vertical*4))) * x;
		
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].pos    = Vector3(
					radius*sinf( ToRadian( 90-theta ))*cosf( ToRadian( phy )),
					radius*cosf( ToRadian( 90-theta )),
					radius*sinf( ToRadian( 90-theta ))*sinf( ToRadian( phy )) );
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex    = Vector2( (( 1.0f/(vertical*4)) * x), 1.0f-(( 1.0f/vertical) * y) );
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].color  = D3DCOLOR_RGBA(255,255,255,255);
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].nor = Vector3( 0.0f, 1.0f, 0.0f );

				//Console::DebugLog(" index : %d : coord : %f, %f \n", ((vertical*4)+1)*y + (x),  pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex.x, pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex.y );
			}
			if( y+1 == vertical ){

				x = 0;
				y++;

				theta = (float)(Y_SDW_ROTATION/vertical) * y+1;
				phy = 0;
		
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].pos    = Vector3(
					radius*sinf( ToRadian( 90-theta ))*cosf( ToRadian( phy )),
					radius*cosf( ToRadian( 90-theta )),
					radius*sinf( ToRadian( 90-theta ))*sinf( ToRadian( phy )) );
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex    = Vector2( 0.0f, 0.0f );//Vector2( (( 1.0f/(vertical*4+1)) * x), (( 1.0f/vertical) * y) );
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].color  = D3DCOLOR_RGBA( 255, 255, 255, 255 );
				pVtx[ ((vertical*4)+1)*y + (x) + 0 ].nor = Vector3( 0.0f, 1.0f, 0.0f );
				//Console::DebugLog(" index : %d : coord : %f, %f \n", ((vertical*4)+1)*y + (x),  pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex.x, pVtx[ ((vertical*4)+1)*y + (x) + 0 ].tex.y );
			}
		}

		pVtxBuf->Unlock( );

	} // -> END


	{ // 頂点インデックスの設定

		pIdxBuf->Lock( &pIndex );

		for( unsigned int y = 0,x = 0,index = 0,alignNumber = 0,line = vertical*4+1; y < vertical; y++ ){

			// 縮退ポリゴンの作成
			if( y ){
			
				x = 0;
				pIndex[ ((2)*line)*y + (2*x) + 1 + alignNumber*2 ] = pIndex[ ((2)*line)*y + (2*x) - 1 + alignNumber*2 ];
				pIndex[ ((2)*line)*y + (2*x) + 0 + alignNumber*2 ] = pIndex[ ((2)*line)*y + (2*x) - 1 + alignNumber*2 ] + (vertical*4)+2;
				alignNumber++;
			}

			for( x = 0; x < line; x++ ){

				pIndex[ ((2)*line)*y + (2*x) + 0 + alignNumber*2 ] = index;

				if( (y+1) == vertical ){
					pIndex[ ((2)*line)*y + (2*x) + 1 + alignNumber*2 ] = ( vertical*4+1 )*vertical;
				}else{
					pIndex[ ((2)*line)*y + (2*x) + 1 + alignNumber*2 ] = index + (vertical*4+1);
				}
				index++;
			
			}
		}

		pIdxBuf->Unlock( );

	} // -> END

}

// MeshSphere Resize
void MeshSphere::Resize( const float radius, const int vertical, const int horizonal )
{

	// Reset Member Variable
	MeshSphere::radius = radius;
	MeshSphere::vertical  = vertical;
	MeshSphere::horizonal = horizonal;

	// MeshField SetBuffer
	SetBuffer( );

}







