/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "physic_bullet/bullet_debug.h"
		#include "core/renderer.h"
		#include "core/renderer_toolbox.h"
		#include "core/camera.h"
		#include "gpu/gpu_renderer.h"

		using namespace GS::S3D;


//------------------------------------------------------------------------------
void				BulletDebugDraw::Flush()
{
	renderer.DrawLine(line_count, vtx_cache, col_cache, xray_first_pass ? GS::Core::Material::Blend_Alpha : GS::Core::Material::Blend_None, GS::Core::Material::Render_NoZWrite);
	line_count = 0;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
float				BulletDebugDraw::GetXRayAlpha() const
{	return xray_first_pass ? 0.2f : 1.f;	}
void				BulletDebugDraw::SetXRayFirstPass(bool pass)
{
	// FIXME: WTF!?
	((GS::GPU::Renderer &)renderer).SetDepthFunc(pass ? GS::GPU::Renderer::DepthGreater : GS::GPU::Renderer::DepthLessEqual);
	xray_first_pass = pass;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void 				BulletDebugDraw::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color)
{
	if	(line_count == 2048)
		Flush();

	vtx_cache[(line_count << 1) + 0].Set(from.x(), from.y(), from.z());
	vtx_cache[(line_count << 1) + 1].Set(to.x(), to.y(), to.z());
	col_cache[(line_count << 1) + 0].Set(color.x(), color.y(), color.z(), GetXRayAlpha());
	col_cache[(line_count << 1) + 1].Set(color.x(), color.y(), color.z(), GetXRayAlpha());

	++line_count;
}
void 				BulletDebugDraw::drawContactPoint(const btVector3 &PointOnB, const btVector3 &/*normalOnB*/, btScalar /*distance*/, int /*lifeTime*/, const btVector3 &color)
{
	drawLine(PointOnB - btVector3(0.25, 0, 0), PointOnB + btVector3(0.25, 0, 0), color);
	drawLine(PointOnB - btVector3(0, 0.25, 0), PointOnB + btVector3(0, 0.25, 0), color);
	drawLine(PointOnB - btVector3(0, 0, 0.25), PointOnB + btVector3(0, 0, 0.25), color);
}
void 				BulletDebugDraw::reportErrorWarning(const char *)
{}
void 				BulletDebugDraw::draw3dText(const btVector3 &p, const char *text)
{
	if	(camera && raster_font)
	{
		Matrix4 m = camera->GetMatrix();
		m.SetRow(3, Vector4(p.x(), p.y(), p.z()));
		renderer.SetWorldMatrix(m);

		float x = 0, y = 0;
		Renderer::WriterConfig config(true, false);
		renderer.Write(*raster_font, text, x, y, config, 2.f);

		renderer.SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
	}
}
//------------------------------------------------------------------------------

BulletDebugDraw::BulletDebugDraw(Renderer &r) : renderer(r)
{
	vtx_cache.Allocate(2048 * 2);
	col_cache.Allocate(2048 * 2);
	line_count = 0;

	camera = NULL;
	raster_font = NULL;

	xray_first_pass = true;
}
