#include "Mix/Private/Dynamics/ConvexHullShape.h"

#include "BulletCollision/CollisionShapes/btShapeHull.h"

#include "Mix/Graphics/Utility/IPerspectiveRenderer.h"

namespace Mix{ namespace Dynamics{

ConvexHullShape* ConvexHullShape::CreateInstance( void )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_DYNAMICS, ConvexHullShape );
}

ConvexHullShape::ConvexHullShape( void ) :
m_pObject( NULL )
{
}

ConvexHullShape::~ConvexHullShape( void )
{
	MIX_LIB_DELETE( m_pObject );
}

Boolean ConvexHullShape::Initialize( const Mix::Dynamics::MESH& mesh )
{
	btIndexedMesh idxMesh;
	btTriangleMesh* triMesh;
	btConvexShape* convex;
	btShapeHull* hull;

	triMesh = MIX_LIB_NEW btTriangleMesh();
	if( triMesh == NULL )
	{
		return False;
	}

	idxMesh.m_numTriangles        = mesh.polygonCount;
	idxMesh.m_triangleIndexBase   = reinterpret_cast<const UInt8*>( mesh.polygonIndices );
	idxMesh.m_triangleIndexStride = sizeof( UInt32[3] );
	idxMesh.m_numVertices         = mesh.vertexCount;
	idxMesh.m_vertexBase          = reinterpret_cast<const UInt8*>( mesh.vertices );
	idxMesh.m_vertexStride        = sizeof( Mix::Vector3 );
	idxMesh.m_indexType           = PHY_INTEGER;

	triMesh->addIndexedMesh( idxMesh );

	convex = MIX_LIB_NEW btConvexTriangleMeshShape( triMesh );
	if( convex == NULL )
	{
		MIX_LIB_DELETE( triMesh );
		return False;
	}

	hull = MIX_LIB_NEW btShapeHull( convex );
	if( hull == NULL )
	{
		MIX_LIB_DELETE( convex );
		MIX_LIB_DELETE( triMesh );
		return False;
	}

	hull->buildHull( convex->getMargin() );

	m_pObject = MIX_LIB_NEW btConvexHullShape( reinterpret_cast<const btScalar*>( hull->getVertexPointer() ), hull->numVertices() );
	if( m_pObject != NULL )
	{
		Shape::Bullet_SetCollisionShape( m_pObject );
	}
	else
	{
		MIX_LIB_DELETE( hull );
		MIX_LIB_DELETE( convex );
		MIX_LIB_DELETE( triMesh );
		return False;
	}

	MIX_LIB_DELETE( hull );
	MIX_LIB_DELETE( convex );
	MIX_LIB_DELETE( triMesh );

	return True;
}

btConvexShape* ConvexHullShape::Bullet_GetConvexShapePtr( void ) const
{
	return m_pObject;
}

Mix::Dynamics::IShape::TYPE ConvexHullShape::GetType( void ) const
{
	return Mix::Dynamics::IShape::CONVEXHULL;
}

Float32 ConvexHullShape::GetMargin( void ) const
{
	return Shape::Bullet_GetMargin();
}
void ConvexHullShape::SetMargin( Float32 margin )
{
	Shape::Bullet_SetMargin( margin );
}

void ConvexHullShape::DebugDraw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer )
{
}

}}
