/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org

This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, 
including commercial applications, and to alter it and redistribute it freely, 
subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"

btStridingMeshInterface::~btStridingMeshInterface()
{

}


void	btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
{
	(void)aabbMin;
	(void)aabbMax;
	int numtotalphysicsverts = 0;
	int part,graphicssubparts = getNumSubParts();
	const unsigned char * vertexbase;
	const unsigned char * indexbase;
	int indexstride;
	PHY_ScalarType type;
	PHY_ScalarType gfxindextype;
	int stride,numverts,numtriangles;
	int gfxindex;
	btVector3 triangle[3];

	btVector3 meshScaling = getScaling();

	///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
	for (part=0;part<graphicssubparts ;part++)
	{
		getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
		numtotalphysicsverts+=numtriangles*3; //upper bound

		///unlike that developers want to pass in double-precision meshes in single-precision Bullet build
		///so disable this feature by default
		///see patch http://code.google.com/p/bullet/issues/detail?id=213

		switch (type)
		{
		case PHY_FLOAT:
		 {

			 float* graphicsbase;

			 switch (gfxindextype)
			 {
			 case PHY_INTEGER:
				 {
					 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
					 {
						 unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
						 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
						 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
						 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
						 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
						 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
						 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
						 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
					 }
					 break;
				 }
			 case PHY_SHORT:
				 {
					 for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
					 {
						 unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
						 graphicsbase = (float*)(vertexbase+tri_indices[0]*stride);
						 triangle[0].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());
						 graphicsbase = (float*)(vertexbase+tri_indices[1]*stride);
						 triangle[1].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
						 graphicsbase = (float*)(vertexbase+tri_indices[2]*stride);
						 triangle[2].setValue(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),	graphicsbase[2]*meshScaling.getZ());
						 callback->internalProcessTriangleIndex(triangle,part,gfxindex);
					 }
					 break;
				 }
			 default:
				 btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
			 }
			 break;
		 }

		case PHY_DOUBLE:
			{
				double* graphicsbase;

				switch (gfxindextype)
				{
				case PHY_INTEGER:
					{
						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
						{
							unsigned int* tri_indices= (unsigned int*)(indexbase+gfxindex*indexstride);
							graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
							triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
							graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
							triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
							graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
							triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
							callback->internalProcessTriangleIndex(triangle,part,gfxindex);
						}
						break;
					}
				case PHY_SHORT:
					{
						for (gfxindex=0;gfxindex<numtriangles;gfxindex++)
						{
							unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride);
							graphicsbase = (double*)(vertexbase+tri_indices[0]*stride);
							triangle[0].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),(btScalar)graphicsbase[2]*meshScaling.getZ());
							graphicsbase = (double*)(vertexbase+tri_indices[1]*stride);
							triangle[1].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
							graphicsbase = (double*)(vertexbase+tri_indices[2]*stride);
							triangle[2].setValue((btScalar)graphicsbase[0]*meshScaling.getX(),(btScalar)graphicsbase[1]*meshScaling.getY(),  (btScalar)graphicsbase[2]*meshScaling.getZ());
							callback->internalProcessTriangleIndex(triangle,part,gfxindex);
						}
						break;
					}
				default:
					btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
				}
				break;
			}
		default:
			btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE));
		}

		unLockReadOnlyVertexBase(part);
	}
}

void	btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
{

	struct	AabbCalculationCallback : public btInternalTriangleIndexCallback
	{
		btVector3	m_aabbMin;
		btVector3	m_aabbMax;

		AabbCalculationCallback()
		{
			m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
			m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
		}

		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
		{
			(void)partId;
			(void)triangleIndex;

			m_aabbMin.setMin(triangle[0]);
			m_aabbMax.setMax(triangle[0]);
			m_aabbMin.setMin(triangle[1]);
			m_aabbMax.setMax(triangle[1]);
			m_aabbMin.setMin(triangle[2]);
			m_aabbMax.setMax(triangle[2]);
		}
	};

	//first calculate the total aabb for all triangles
	AabbCalculationCallback	aabbCallback;
	aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
	aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
	InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);

	aabbMin = aabbCallback.m_aabbMin;
	aabbMax = aabbCallback.m_aabbMax;
}
