text:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/

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.
*/

#ifndef BT_OBB_BOX_2D_SHAPE_H
#define BT_OBB_BOX_2D_SHAPE_H

#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMinMax.h"

///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape
{

	//btVector3	m_boxHalfExtents1; //use m_implicitShapeDimensions instead

	btVector3 m_centroid;
	btVector3 m_vertices[4];
	btVector3 m_normals[4];

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btVector3 getHalfExtentsWithMargin() const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();
		btVector3 margin(getMargin(),getMargin(),getMargin());
		halfExtents += margin;
		return halfExtents;
	}

	const btVector3& getHalfExtentsWithoutMargin() const
	{
		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
	}

	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();
		btVector3 margin(getMargin(),getMargin(),getMargin());
		halfExtents += margin;

		return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
			btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
			btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
	}

	SIMD_FORCE_INLINE  btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const
	{
		const btVector3& halfExtents = getHalfExtentsWithoutMargin();

		return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
			btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
			btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
	}

	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
	{
		const btVector3& halfExtents = getHalfExtentsWithoutMargin();

		for (int i=0;i<numVectors;i++)
		{
			const btVector3& vec = vectors[i];
			supportVerticesOut[i].setValue(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()),
				btFsels(vec.y(), halfExtents.y(), -halfExtents.y()),
				btFsels(vec.z(), halfExtents.z(), -halfExtents.z()));
		}

	}

	///a btBox2dShape is a flat 2D box in the X-Y plane (Z extents are zero)
	btBox2dShape( const btVector3& boxHalfExtents)
		: btPolyhedralConvexShape(),
		m_centroid(0,0,0)
	{
		m_vertices[0].setValue(-boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
		m_vertices[1].setValue(boxHalfExtents.getX(),-boxHalfExtents.getY(),0);
		m_vertices[2].setValue(boxHalfExtents.getX(),boxHalfExtents.getY(),0);
		m_vertices[3].setValue(-boxHalfExtents.getX(),boxHalfExtents.getY(),0);

		m_normals[0].setValue(0,-1,0);
		m_normals[1].setValue(1,0,0);
		m_normals[2].setValue(0,1,0);
		m_normals[3].setValue(-1,0,0);

		btScalar minDimension = boxHalfExtents.getX();
		if (minDimension>boxHalfExtents.getY())
			minDimension = boxHalfExtents.getY();

		m_shapeType = BOX_2D_SHAPE_PROXYTYPE;
		btVector3 margin(getMargin(),getMargin(),getMargin());
		m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin;

		setSafeMargin(minDimension);
	};

	virtual void setMargin(btScalar collisionMargin)
	{
		//correct the m_implicitShapeDimensions for the margin
		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;

		btConvexInternalShape::setMargin(collisionMargin);
		btVector3 newMargin(getMargin(),getMargin(),getMargin());
		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;

	}
	virtual void	setLocalScaling(const btVector3& scaling)
	{
		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;

		btConvexInternalShape::setLocalScaling(scaling);

		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;

	}

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	int	getVertexCount() const
	{
		return 4;
	}

	virtual int getNumVertices()const
	{
		return 4;
	}

	const btVector3* getVertices() const
	{
		return &m_vertices[0];
	}

	const btVector3* getNormals() const
	{
		return &m_normals[0];
	}

	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
	{
		//this plane might not be aligned...
		btVector4 plane ;
		getPlaneEquation(plane,i);
		planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ());
		planeSupport = localGetSupportingVertex(-planeNormal);
	}

	const btVector3& getCentroid() const
	{
		return m_centroid;
	}

	virtual int getNumPlanes() const
	{
		return 6;
	}

	virtual int getNumEdges() const
	{
		return 12;
	}

	virtual void getVertex(int i,btVector3& vtx) const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();

		vtx = btVector3(
				halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1),
				halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1),
				halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2));
	}

	virtual void	getPlaneEquation(btVector4& plane,int i) const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();

		switch (i)
		{
		case 0:
			plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x());
			break;
		case 1:
			plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x());
			break;
		case 2:
			plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y());
			break;
		case 3:
			plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y());
			break;
		case 4:
			plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z());
			break;
		case 5:
			plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z());
			break;
		default:
			btAssert(0);
		}
	}

	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
	//virtual void getEdge(int i,Edge& edge) const
	{
		int edgeVert0 = 0;
		int edgeVert1 = 0;

		switch (i)
		{
		case 0:
				edgeVert0 = 0;
				edgeVert1 = 1;
			break;
		case 1:
				edgeVert0 = 0;
				edgeVert1 = 2;
			break;
		case 2:
			edgeVert0 = 1;
			edgeVert1 = 3;

			break;
		case 3:
			edgeVert0 = 2;
			edgeVert1 = 3;
			break;
		case 4:
			edgeVert0 = 0;
			edgeVert1 = 4;
			break;
		case 5:
			edgeVert0 = 1;
			edgeVert1 = 5;

			break;
		case 6:
			edgeVert0 = 2;
			edgeVert1 = 6;
			break;
		case 7:
			edgeVert0 = 3;
			edgeVert1 = 7;
			break;
		case 8:
			edgeVert0 = 4;
			edgeVert1 = 5;
			break;
		case 9:
			edgeVert0 = 4;
			edgeVert1 = 6;
			break;
		case 10:
			edgeVert0 = 5;
			edgeVert1 = 7;
			break;
		case 11:
			edgeVert0 = 6;
			edgeVert1 = 7;
			break;
		default:
			btAssert(0);

		}

		getVertex(edgeVert0,pa );
		getVertex(edgeVert1,pb );
	}

	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();

		//btScalar minDist = 2*tolerance;

		bool result =	(pt.x() <= (halfExtents.x()+tolerance)) &&
						(pt.x() >= (-halfExtents.x()-tolerance)) &&
						(pt.y() <= (halfExtents.y()+tolerance)) &&
						(pt.y() >= (-halfExtents.y()-tolerance)) &&
						(pt.z() <= (halfExtents.z()+tolerance)) &&
						(pt.z() >= (-halfExtents.z()-tolerance));

		return result;
	}

	//debugging
	virtual const char*	getName()const
	{
		return "Box2d";
	}

	virtual int		getNumPreferredPenetrationDirections() const
	{
		return 6;
	}

	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
	{
		switch (index)
		{
		case 0:
			penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.));
			break;
		case 1:
			penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.));
			break;
		case 2:
			penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.));
			break;
		case 3:
			penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.));
			break;
		case 4:
			penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.));
			break;
		case 5:
			penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.));
			break;
		default:
			btAssert(0);
		}
	}

};

#endif //BT_OBB_BOX_2D_SHAPE_H


text:
/*
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.
*/

#ifndef BT_TRIANGLE_CALLBACK_H
#define BT_TRIANGLE_CALLBACK_H

#include "LinearMath/btVector3.h"

///The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTriangles.
///This callback is called by processAllTriangles for all btConcaveShape derived class, such as  btBvhTriangleMeshShape, btStaticPlaneShape and btHeightfieldTerrainShape.
class btTriangleCallback
{
public:

	virtual ~btTriangleCallback();
	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0;
};

class btInternalTriangleIndexCallback
{
public:

	virtual ~btInternalTriangleIndexCallback();
	virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex) = 0;
};

#endif //BT_TRIANGLE_CALLBACK_H

repo_name: JoshParnell/libphx

repo_language: C

mime_type: text/x-c++


text:
/*
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.
*/

#ifndef BT_CONE_MINKOWSKI_H
#define BT_CONE_MINKOWSKI_H

#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types

///The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y axis. The btConeShapeX is aligned around the X axis and btConeShapeZ around the Z axis.
ATTRIBUTE_ALIGNED16(class) btConeShape : public btConvexInternalShape

{

	btScalar m_sinAngle;
	btScalar m_radius;
	btScalar m_height;
	int		m_coneIndices[3];
	btVector3 coneLocalSupport(const btVector3& v) const;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btConeShape (btScalar radius,btScalar height);

	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const;
	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const;
	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

	btScalar getRadius() const { return m_radius;}
	btScalar getHeight() const { return m_height;}

	void setRadius(const btScalar radius)
	{
		m_radius = radius;
	}
	void setHeight(const btScalar height)
	{
		m_height = height;
	}

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const
	{
		btTransform identity;
		identity.setIdentity();
		btVector3 aabbMin,aabbMax;
		getAabb(identity,aabbMin,aabbMax);

		btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);

		btScalar margin = getMargin();

		btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
		btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
		btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
		const btScalar x2 = lx*lx;
		const btScalar y2 = ly*ly;
		const btScalar z2 = lz*lz;
		const btScalar scaledmass = mass * btScalar(0.08333333);

		inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));

//		inertia.x() = scaledmass * (y2+z2);
//		inertia.y() = scaledmass * (x2+z2);
//		inertia.z() = scaledmass * (x2+y2);
	}

		virtual const char*	getName()const
		{
			return "Cone";
		}

		///choose upAxis index
		void	setConeUpIndex(int upIndex);

		int	getConeUpIndex() const
		{
			return m_coneIndices[1];
		}

	virtual btVector3	getAnisotropicRollingFrictionDirection() const
	{
		return btVector3 (0,1,0);
	}

	virtual void	setLocalScaling(const btVector3& scaling);

	virtual	int	calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;

};

///btConeShape implements a Cone shape, around the X axis
class btConeShapeX : public btConeShape
{
	public:
		btConeShapeX(btScalar radius,btScalar height);

	virtual btVector3	getAnisotropicRollingFrictionDirection() const
	{
		return btVector3 (1,0,0);
	}

	//debugging
	virtual const char*	getName()const
	{
		return "ConeX";
	}

};

///btConeShapeZ implements a Cone shape, around the Z axis
class btConeShapeZ : public btConeShape
{
public:
	btConeShapeZ(btScalar radius,btScalar height);

	virtual btVector3	getAnisotropicRollingFrictionDirection() const
	{
		return btVector3 (0,0,1);
	}

	//debugging
	virtual const char*	getName()const
	{
		return "ConeZ";
	}

};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct	btConeShapeData
{
	btConvexInternalShapeData	m_convexInternalShapeData;

	int	m_upIndex;

	char	m_padding[4];
};

SIMD_FORCE_INLINE	int	btConeShape::calculateSerializeBufferSize() const
{
	return sizeof(btConeShapeData);
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	const char*	btConeShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btConeShapeData* shapeData = (btConeShapeData*) dataBuffer;

	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);

	shapeData->m_upIndex = m_coneIndices[1];

	// Fill padding with zeros to appease msan.
	shapeData->m_padding[0] = 0;
	shapeData->m_padding[1] = 0;
	shapeData->m_padding[2] = 0;
	shapeData->m_padding[3] = 0;

	return "btConeShapeData";
}

#endif //BT_CONE_MINKOWSKI_H


text:
/*
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.
*/

#ifndef BT_COLLISION_SHAPE_H
#define BT_COLLISION_SHAPE_H

#include "LinearMath/btTransform.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
class btSerializer;

/// The btCollisionShape class provides an interface for collision shapes that
/// can be shared among btCollisionObjects.
ATTRIBUTE_ALIGNED16(class)
btCollisionShape
{
protected:
	int   m_shapeType;
	void* m_userPointer;
	int   m_userIndex;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();
	btCollisionShape() : m_shapeType(INVALID_SHAPE_PROXYTYPE), m_userPointer(0), m_userIndex(-1) {}
	virtual ~btCollisionShape() {}

	/// getAabb returns the axis aligned bounding box in the coordinate frame of
	/// the given transform t.
	virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const = 0;

	virtual void getBoundingSphere(btVector3 & center, btScalar & radius) const;

	/// getAngularMotionDisc returns the maximum radius needed for Conservative
	/// Advancement to handle time-of-impact with rotations.
	virtual btScalar getAngularMotionDisc() const;

	virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const;

	/// calculateTemporalAabb calculates the enclosing aabb for the moving object
	/// over interval [0..timeStep) result is conservative
	void calculateTemporalAabb(const btTransform& curTrans, const btVector3& linvel, const btVector3& angvel, btScalar timeStep, btVector3& temporalAabbMin, btVector3& temporalAabbMax) const;

	SIMD_FORCE_INLINE bool isPolyhedral() const { return btBroadphaseProxy::isPolyhedral(getShapeType()); }
	SIMD_FORCE_INLINE bool isConvex2d() const { return btBroadphaseProxy::isConvex2d(getShapeType()); }
	SIMD_FORCE_INLINE bool isConvex() const { return btBroadphaseProxy::isConvex(getShapeType()); }
	SIMD_FORCE_INLINE bool isNonMoving() const { return btBroadphaseProxy::isNonMoving(getShapeType()); }
	SIMD_FORCE_INLINE bool isConcave() const { return btBroadphaseProxy::isConcave(getShapeType()); }
	SIMD_FORCE_INLINE bool isCompound() const { return btBroadphaseProxy::isCompound(getShapeType()); }
	SIMD_FORCE_INLINE bool isSoftBody() const { return btBroadphaseProxy::isSoftBody(getShapeType()); }

	/// isInfinite is used to catch simulation error (aabb check)
	SIMD_FORCE_INLINE bool isInfinite() const { return btBroadphaseProxy::isInfinite(getShapeType()); }

#ifndef __SPU__
	virtual void             setLocalScaling(const btVector3& scaling)                       = 0;
	virtual const btVector3& getLocalScaling() const                                         = 0;
	virtual void             calculateLocalInertia(btScalar mass, btVector3 & inertia) const = 0;

	/// debugging support
	virtual const char* getName() const = 0;
#endif //__SPU__

	int getShapeType() const { return m_shapeType; }

	/// the getAnisotropicRollingFrictionDirection can be used in combination with
	/// setAnisotropicFriction. See Bullet/Demos/RollingFrictionDemo for an
	/// example.
	virtual btVector3 getAnisotropicRollingFrictionDirection() const { return btVector3(1, 1, 1); }

	virtual void     setMargin(btScalar margin) = 0;
	virtual btScalar getMargin() const          = 0;

	///optional user data pointer
	void setUserPointer(void* userPtr) { m_userPointer = userPtr; }

	void*       getUserPointer() const { return m_userPointer; }
	void        setUserIndex(int index) { m_userIndex = index; }
	int         getUserIndex() const { return m_userIndex; }
	virtual int calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;

	virtual void serializeSingleShape(btSerializer * serializer) const;
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btCollisionShapeData
{
	char* m_name;
	int   m_shapeType;
	char  m_padding[4];
};

SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const
{
	return sizeof(btCollisionShapeData);
}

#endif //BT_COLLISION_SHAPE_H


text:
/*
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.
*/
#ifndef BT_CONVEX_TRIANGLEMESH_SHAPE_H
#define BT_CONVEX_TRIANGLEMESH_SHAPE_H

#include "btPolyhedralConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types

/// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape.
/// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead.
ATTRIBUTE_ALIGNED16(class) btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape
{

	class btStridingMeshInterface*	m_stridingMesh;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true);

	class btStridingMeshInterface*	getMeshInterface()
	{
		return m_stridingMesh;
	}
	const class btStridingMeshInterface* getMeshInterface() const
	{
		return m_stridingMesh;
	}

	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

	//debugging
	virtual const char*	getName()const {return "ConvexTrimesh";}

	virtual int	getNumVertices() const;
	virtual int getNumEdges() const;
	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
	virtual void getVertex(int i,btVector3& vtx) const;
	virtual int	getNumPlanes() const;
	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;

	virtual void	setLocalScaling(const btVector3& scaling);
	virtual const btVector3& getLocalScaling() const;

	///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
	///and the center of mass to the current coordinate system. A mass of 1 is assumed, for other masses just multiply the computed "inertia"
	///by the mass. The resulting transform "principal" has to be applied inversely to the mesh in order for the local coordinate system of the
	///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform
	///of the collision object by the principal transform. This method also computes the volume of the convex mesh.
	void calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const;

};

#endif //BT_CONVEX_TRIANGLEMESH_SHAPE_H


text:
/*
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.
*/

#ifndef BT_CAPSULE_SHAPE_H
#define BT_CAPSULE_SHAPE_H

#include "btConvexInternalShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"

/// The btCapsuleShape represents a capsule around the Y axis, there is also the
/// btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z
/// axis. The total height is height+2*radius, so the height is just the height
/// between the center of each 'sphere' of the capsule caps. The btCapsuleShape
/// is a convex hull of two spheres. The btMultiSphereShape is a more general
/// collision shape that takes the convex hull of multiple sphere, so it can
/// also represent a capsule when just using two spheres.
ATTRIBUTE_ALIGNED16(class)
btCapsuleShape : public btConvexInternalShape
{
protected:
	int m_upAxis;

protected:
	/// only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
	btCapsuleShape() : btConvexInternalShape() { m_shapeType = CAPSULE_SHAPE_PROXYTYPE; };

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btCapsuleShape(btScalar radius, btScalar height);

	/// CollisionShape Interface
	virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const;

	/// btConvexShape Interface
	virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const;

	virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const;

	virtual void setMargin(btScalar /* collisionMargin */)
	{
		//don't override the margin for capsules, their entire radius == margin
	}

	virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
	{
		btVector3 halfExtents(getRadius(), getRadius(), getRadius());
		halfExtents[m_upAxis] = getRadius() + getHalfHeight();
		btMatrix3x3 abs_b     = t.getBasis().absolute();
		btVector3   center    = t.getOrigin();
		btVector3   extent    = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);

		aabbMin = center - extent;
		aabbMax = center + extent;
	}

	virtual const char* getName() const { return "CapsuleShape"; }
	int getUpAxis() const { return m_upAxis; }

	btScalar getRadius() const
	{
		int radiusAxis = (m_upAxis + 2) % 3;
		return m_implicitShapeDimensions[radiusAxis];
	}

	btScalar getHalfHeight() const { return m_implicitShapeDimensions[m_upAxis]; }

	virtual void setLocalScaling(const btVector3& scaling)
	{
		btVector3 unScaledImplicitShapeDimensions = m_implicitShapeDimensions / m_localScaling;
		btConvexInternalShape::setLocalScaling(scaling);
		m_implicitShapeDimensions = (unScaledImplicitShapeDimensions * scaling);
		//update m_collisionMargin, since entire radius==margin
		int radiusAxis    = (m_upAxis + 2) % 3;
		m_collisionMargin = m_implicitShapeDimensions[radiusAxis];
	}

	virtual btVector3 getAnisotropicRollingFrictionDirection() const
	{
		btVector3 aniDir(0, 0, 0);
		aniDir[getUpAxis()] = 1;
		return aniDir;
	}

	virtual int calculateSerializeBufferSize() const;

	/// fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;

	SIMD_FORCE_INLINE void deSerializeFloat(struct btCapsuleShapeData * dataBuffer);
};

/// btCapsuleShapeX represents a capsule around the Z axis. the total height is
/// height+2*radius, so the height is just the height between the center of each
/// 'sphere' of the capsule caps.
class btCapsuleShapeX : public btCapsuleShape
{
public:
	btCapsuleShapeX(btScalar radius, btScalar height);

	/// debugging
	virtual const char* getName() const { return "CapsuleX"; }
};

/// btCapsuleShapeZ represents a capsule around the Z axis. the total height is
/// height+2*radius, so the height is just the height between the center of each
/// 'sphere' of the capsule caps.
class btCapsuleShapeZ : public btCapsuleShape
{
public:
	btCapsuleShapeZ(btScalar radius, btScalar height);

	// debugging
	virtual const char* getName() const { return "CapsuleZ"; }
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btCapsuleShapeData
{
	btConvexInternalShapeData m_convexInternalShapeData;
	int                       m_upAxis;
	char                      m_padding[4];
};

SIMD_FORCE_INLINE int btCapsuleShape::calculateSerializeBufferSize() const
{
	return sizeof(btCapsuleShapeData);
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE const char* btCapsuleShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btCapsuleShapeData* shapeData = (btCapsuleShapeData*) dataBuffer;

	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer);

	shapeData->m_upAxis = m_upAxis;

	// Fill padding with zeros to appease msan.
	shapeData->m_padding[0] = 0;
	shapeData->m_padding[1] = 0;
	shapeData->m_padding[2] = 0;
	shapeData->m_padding[3] = 0;

	return "btCapsuleShapeData";
}

SIMD_FORCE_INLINE void btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer)
{
	m_implicitShapeDimensions.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_implicitShapeDimensions);
	m_collisionMargin = dataBuffer->m_convexInternalShapeData.m_collisionMargin;
	m_localScaling.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_localScaling);
	//it is best to already pre-allocate the matching btCapsuleShape*(X/Z) version to match m_upAxis
	m_upAxis = dataBuffer->m_upAxis;
}

#endif //BT_CAPSULE_SHAPE_H


text:
/*
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.
*/

#ifndef BT_CYLINDER_MINKOWSKI_H
#define BT_CYLINDER_MINKOWSKI_H

#include "btBoxShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "LinearMath/btVector3.h"

/// The btCylinderShape class implements a cylinder shape primitive, centered around the origin. Its central axis aligned with the Y axis. btCylinderShapeX is aligned with the X axis and btCylinderShapeZ around the Z axis.
ATTRIBUTE_ALIGNED16(class) btCylinderShape : public btConvexInternalShape

{

protected:

	int	m_upAxis;

public:

BT_DECLARE_ALIGNED_ALLOCATOR();

	btVector3 getHalfExtentsWithMargin() const
	{
		btVector3 halfExtents = getHalfExtentsWithoutMargin();
		btVector3 margin(getMargin(),getMargin(),getMargin());
		halfExtents += margin;
		return halfExtents;
	}

	const btVector3& getHalfExtentsWithoutMargin() const
	{
		return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included
	}

	btCylinderShape (const btVector3& halfExtents);

	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;

	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

	virtual void setMargin(btScalar collisionMargin)
	{
		//correct the m_implicitShapeDimensions for the margin
		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;

		btConvexInternalShape::setMargin(collisionMargin);
		btVector3 newMargin(getMargin(),getMargin(),getMargin());
		m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin;

	}

	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
	{

		btVector3 supVertex;
		supVertex = localGetSupportingVertexWithoutMargin(vec);

		if ( getMargin()!=btScalar(0.) )
		{
			btVector3 vecnorm = vec;
			if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
			{
				vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
			}
			vecnorm.normalize();
			supVertex+= getMargin() * vecnorm;
		}
		return supVertex;
	}

	//use box inertia
	//	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	int	getUpAxis() const
	{
		return m_upAxis;
	}

	virtual btVector3	getAnisotropicRollingFrictionDirection() const
	{
		btVector3 aniDir(0,0,0);
		aniDir[getUpAxis()]=1;
		return aniDir;
	}

	virtual btScalar getRadius() const
	{
		return getHalfExtentsWithMargin().getX();
	}

	virtual void	setLocalScaling(const btVector3& scaling)
	{
		btVector3 oldMargin(getMargin(),getMargin(),getMargin());
		btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin;
		btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling;

		btConvexInternalShape::setLocalScaling(scaling);

		m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin;

	}

	//debugging
	virtual const char*	getName()const
	{
		return "CylinderY";
	}

	virtual	int	calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;

};

class btCylinderShapeX : public btCylinderShape
{
public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btCylinderShapeX (const btVector3& halfExtents);

	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

		//debugging
	virtual const char*	getName()const
	{
		return "CylinderX";
	}

	virtual btScalar getRadius() const
	{
		return getHalfExtentsWithMargin().getY();
	}

};

class btCylinderShapeZ : public btCylinderShape
{
public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btCylinderShapeZ (const btVector3& halfExtents);

	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

		//debugging
	virtual const char*	getName()const
	{
		return "CylinderZ";
	}

	virtual btScalar getRadius() const
	{
		return getHalfExtentsWithMargin().getX();
	}

};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct	btCylinderShapeData
{
	btConvexInternalShapeData	m_convexInternalShapeData;

	int	m_upAxis;

	char	m_padding[4];
};

SIMD_FORCE_INLINE	int	btCylinderShape::calculateSerializeBufferSize() const
{
	return sizeof(btCylinderShapeData);
}

	///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	const char*	btCylinderShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btCylinderShapeData* shapeData = (btCylinderShapeData*) dataBuffer;

	btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData,serializer);

	shapeData->m_upAxis = m_upAxis;

	// Fill padding with zeros to appease msan.
	shapeData->m_padding[0] = 0;
	shapeData->m_padding[1] = 0;
	shapeData->m_padding[2] = 0;
	shapeData->m_padding[3] = 0;

	return "btCylinderShapeData";
}

#endif //BT_CYLINDER_MINKOWSKI_H


text:
/*
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.
*/

#ifndef BT_SIMPLEX_1TO4_SHAPE
#define BT_SIMPLEX_1TO4_SHAPE

#include "btPolyhedralConvexShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"

///The btBU_Simplex1to4 implements tetrahedron, triangle, line, vertex collision shapes. In most cases it is better to use btConvexHullShape instead.
ATTRIBUTE_ALIGNED16(class) btBU_Simplex1to4 : public btPolyhedralConvexAabbCachingShape
{
protected:

	int	m_numVertices;
	btVector3	m_vertices[4];

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btBU_Simplex1to4();

	btBU_Simplex1to4(const btVector3& pt0);
	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1);
	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2);
	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3);

	void	reset()
	{
		m_numVertices = 0;
	}

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	void addVertex(const btVector3& pt);

	//PolyhedralConvexShape interface

	virtual int	getNumVertices() const;

	virtual int getNumEdges() const;

	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;

	virtual void getVertex(int i,btVector3& vtx) const;

	virtual int	getNumPlanes() const;

	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const;

	virtual int getIndex(int i) const;

	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;

	///getName is for debugging
	virtual const char*	getName()const { return "btBU_Simplex1to4";}

};

#endif //BT_SIMPLEX_1TO4_SHAPE


text:
/*
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.
*/

///Contains contributions from Disney Studio's

#ifndef BT_OPTIMIZED_BVH_H
#define BT_OPTIMIZED_BVH_H

#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h"

class btStridingMeshInterface;

///The btOptimizedBvh extends the btQuantizedBvh to create AABB tree for triangle meshes, through the btStridingMeshInterface.
ATTRIBUTE_ALIGNED16(class) btOptimizedBvh : public btQuantizedBvh
{

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

protected:

public:

	btOptimizedBvh();

	virtual ~btOptimizedBvh();

	void	build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax);

	void	refit(btStridingMeshInterface* triangles,const btVector3& aabbMin,const btVector3& aabbMax);

	void	refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax);

	void	updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index);

	/// Data buffer MUST be 16 byte aligned
	virtual bool serializeInPlace(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const
	{
		return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian);

	}

	///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
	static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);

};

#endif //BT_OPTIMIZED_BVH_H


text:
/*
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.
*/

#ifndef BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H

#include "btStridingMeshInterface.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "LinearMath/btScalar.h"

/// The btIndexedMesh indexes a single vertex and index array. Multiple
/// btIndexedMesh objects can be passed into a btTriangleIndexVertexArray using
/// addIndexedMesh. Instead of the number of indices, we pass the number of
/// triangles.
ATTRIBUTE_ALIGNED16(struct) btIndexedMesh
{
	BT_DECLARE_ALIGNED_ALLOCATOR();

	int                     m_numTriangles;
	const unsigned char *   m_triangleIndexBase;
	int                     m_triangleIndexStride; // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed)
	int                     m_numVertices;
	const unsigned char *   m_vertexBase;
	int                     m_vertexStride;        // Size of a vertex, in bytes

	/// The index type is set when adding an indexed mesh to the
	/// btTriangleIndexVertexArray, do not set it manually
	PHY_ScalarType m_indexType;

	/// The vertex type has a default type similar to Bullet's precision mode
	/// (float or double) but can be set manually if you for example run Bullet
	/// with double precision but have mesh data in single precision..
	PHY_ScalarType m_vertexType;

	btIndexedMesh()
		:m_indexType(PHY_INTEGER),
#ifdef BT_USE_DOUBLE_PRECISION
			m_vertexType(PHY_DOUBLE)
#else // BT_USE_DOUBLE_PRECISION
			m_vertexType(PHY_FLOAT)
#endif // BT_USE_DOUBLE_PRECISION
	{
	}
};

typedef btAlignedObjectArray<btIndexedMesh>	IndexedMeshArray;

/// The btTriangleIndexVertexArray allows to access multiple triangle meshes, by
/// indexing into existing triangle/index arrays. Additional meshes can be added
/// using addIndexedMesh. No duplicate is made of the vertex/index data, it only
/// indexes into external vertex/index arrays. So keep those arrays around
/// during the lifetime of this btTriangleIndexVertexArray.
ATTRIBUTE_ALIGNED16(class) btTriangleIndexVertexArray : public btStridingMeshInterface
{
protected:
	IndexedMeshArray  m_indexedMeshes;
	int               m_pad[2];
	mutable int       m_hasAabb; // using int instead of bool to maintain alignment
	mutable btVector3 m_aabbMin;
	mutable btVector3 m_aabbMax;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btTriangleIndexVertexArray() : m_hasAabb(0) { }
	virtual ~btTriangleIndexVertexArray();

	/// just to be backwards compatible
	btTriangleIndexVertexArray(
	    int       numTriangles,
	    int*      triangleIndexBase,
	    int       triangleIndexStride,
	    int       numVertices,
	    btScalar* vertexBase,
	    int       vertexStride);

	void addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER)
	{
		m_indexedMeshes.push_back(mesh);
		m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType;
	}

	virtual void getLockedVertexIndexBase(
	    unsigned char** vertexbase,
	    int&            numverts,
	    PHY_ScalarType& type,
	    int&            vertexStride,
	    unsigned char** indexbase,
	    int&            indexstride,
	    int&            numfaces,
	    PHY_ScalarType& indicestype,
	    int             subpart = 0);

	virtual void getLockedReadOnlyVertexIndexBase(
	    const unsigned char** vertexbase,
	    int&                  numverts,
	    PHY_ScalarType&       type,
	    int&                  vertexStride,
	    const unsigned char** indexbase,
	    int&                  indexstride,
	    int&                  numfaces,
	    PHY_ScalarType&       indicestype,
	    int                   subpart = 0) const;

	/// unLockVertexBase finishes the access to a subpart of the triangle mesh
	/// make a call to unLockVertexBase when the read and write access (using
	/// getLockedVertexIndexBase) is finished
	virtual void unLockVertexBase(int subpart) { (void) subpart; }

	virtual void unLockReadOnlyVertexBase(int subpart) const { (void) subpart; }

	/// getNumSubParts returns the number of separate subparts. each subpart has a
	/// continuous array of vertices and indices
	virtual int getNumSubParts() const { return (int) m_indexedMeshes.size(); }

	IndexedMeshArray&       getIndexedMeshArray() { return m_indexedMeshes; }
	const IndexedMeshArray& getIndexedMeshArray() const { return m_indexedMeshes; }

	virtual void preallocateVertices(int numverts) { (void) numverts; }
	virtual void preallocateIndices(int numindices) { (void) numindices; }

	virtual bool hasPremadeAabb() const;
	virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax) const;
	virtual void getPremadeAabb(btVector3 * aabbMin, btVector3 * aabbMax) const;
};

#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H


text:
/*
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.
*/

#ifndef BT_TRIANGLE_BUFFER_H
#define BT_TRIANGLE_BUFFER_H

#include "btTriangleCallback.h"
#include "LinearMath/btAlignedObjectArray.h"

struct	btTriangle
{
	btVector3	m_vertex0;
	btVector3	m_vertex1;
	btVector3	m_vertex2;
	int	m_partId;
	int	m_triangleIndex;
};

///The btTriangleBuffer callback can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
///Example usage of this class:
///			btTriangleBuffer	triBuf;
///			concaveShape->processAllTriangles(&triBuf,aabbMin, aabbMax);
///			for (int i=0;i<triBuf.getNumTriangles();i++)
///			{
///				const btTriangle& tri = triBuf.getTriangle(i);
///				//do something useful here with the triangle
///			}
class btTriangleBuffer : public btTriangleCallback
{

	btAlignedObjectArray<btTriangle>	m_triangleBuffer;

public:

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

	int	getNumTriangles() const
	{
		return int(m_triangleBuffer.size());
	}

	const btTriangle&	getTriangle(int index) const
	{
		return m_triangleBuffer[index];
	}

	void	clearBuffer()
	{
		m_triangleBuffer.clear();
	}

};

#endif //BT_TRIANGLE_BUFFER_H


text:
/*
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.
*/

#ifndef BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H
#define BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H

#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"

///The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMeshShape.
///Note that each btBvhTriangleMeshShape still can have its own local scaling, independent from this btScaledBvhTriangleMeshShape 'localScaling'
ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape
{

	btVector3	m_localScaling;

	btBvhTriangleMeshShape*	m_bvhTriMeshShape;

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);

	virtual ~btScaledBvhTriangleMeshShape();

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
	virtual void	setLocalScaling(const btVector3& scaling);
	virtual const btVector3& getLocalScaling() const;
	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;

	btBvhTriangleMeshShape*	getChildShape()
	{
		return m_bvhTriMeshShape;
	}

	const btBvhTriangleMeshShape*	getChildShape() const
	{
		return m_bvhTriMeshShape;
	}

	//debugging
	virtual const char*	getName()const {return "SCALEDBVHTRIANGLEMESH";}

	virtual	int	calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;

};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct	btScaledTriangleMeshShapeData
{
	btTriangleMeshShapeData	m_trimeshShapeData;

	btVector3FloatData	m_localScaling;
};

SIMD_FORCE_INLINE	int	btScaledBvhTriangleMeshShape::calculateSerializeBufferSize() const
{
	return sizeof(btScaledTriangleMeshShapeData);
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	const char*	btScaledBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btScaledTriangleMeshShapeData* scaledMeshData = (btScaledTriangleMeshShapeData*) dataBuffer;
	m_bvhTriMeshShape->serialize(&scaledMeshData->m_trimeshShapeData,serializer);
	scaledMeshData->m_trimeshShapeData.m_collisionShapeData.m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
	m_localScaling.serializeFloat(scaledMeshData->m_localScaling);
	return "btScaledTriangleMeshShapeData";
}

#endif //BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H


text:
/*
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.
*/

#ifndef BT_CONCAVE_SHAPE_H
#define BT_CONCAVE_SHAPE_H

#include "btCollisionShape.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
#include "btTriangleCallback.h"

/// PHY_ScalarType enumerates possible scalar types.
/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use
typedef enum PHY_ScalarType {
	PHY_FLOAT,
	PHY_DOUBLE,
	PHY_INTEGER,
	PHY_SHORT,
	PHY_FIXEDPOINT88,
	PHY_UCHAR
} PHY_ScalarType;

///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
ATTRIBUTE_ALIGNED16(class) btConcaveShape : public btCollisionShape
{
protected:
	btScalar m_collisionMargin;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btConcaveShape();

	virtual ~btConcaveShape();

	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0;

	virtual btScalar getMargin() const {
		return m_collisionMargin;
	}
	virtual void setMargin(btScalar collisionMargin)
	{
		m_collisionMargin = collisionMargin;
	}

};

#endif //BT_CONCAVE_SHAPE_H


text:
/*
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.
*/

///btShapeHull implemented by John McCutchan.

#ifndef BT_SHAPE_HULL_H
#define BT_SHAPE_HULL_H

#include "LinearMath/btAlignedObjectArray.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"

/// The btShapeHull class takes a btConvexShape, builds a simplified convex hull
/// using btConvexHull and provides triangle indices and vertices. It can be
/// useful for to simplify a complex convex object and for visualization of a
/// non-polyhedral convex object. It approximates the convex hull using the
/// supporting vertex of 42 directions.
ATTRIBUTE_ALIGNED16(class) btShapeHull
{
protected:
	btAlignedObjectArray<btVector3>    m_vertices;
	btAlignedObjectArray<unsigned int> m_indices;
	unsigned int                       m_numIndices;
	const btConvexShape*               m_shape;

	static btVector3* getUnitSpherePoints();

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btShapeHull(const btConvexShape* shape);
	~btShapeHull();

	bool buildHull(btScalar margin);

	int numTriangles() const;
	int numVertices() const;
	int numIndices() const;

	const btVector3* getVertexPointer() const { return &m_vertices[0]; }
	const unsigned int* getIndexPointer() const { return &m_indices[0]; }
};

#endif //BT_SHAPE_HULL_H


text:
/*
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.
*/

#ifndef BT_POLYHEDRAL_CONVEX_SHAPE_H
#define BT_POLYHEDRAL_CONVEX_SHAPE_H

#include "LinearMath/btMatrix3x3.h"
#include "btConvexInternalShape.h"
class btConvexPolyhedron;

///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
ATTRIBUTE_ALIGNED16(class) btPolyhedralConvexShape : public btConvexInternalShape
{

protected:

	btConvexPolyhedron* m_polyhedron;

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	btPolyhedralConvexShape();

	virtual ~btPolyhedralConvexShape();

	///optional method mainly used to generate multiple contact points by clipping polyhedral features (faces/edges)
	///experimental/work-in-progress
	virtual bool	initializePolyhedralFeatures(int shiftVerticesByMargin=0);

	const btConvexPolyhedron*	getConvexPolyhedron() const
	{
		return m_polyhedron;
	}

	//brute force implementations

	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual int	getNumVertices() const = 0 ;
	virtual int getNumEdges() const = 0;
	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
	virtual void getVertex(int i,btVector3& vtx) const = 0;
	virtual int	getNumPlanes() const = 0;
	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
//	virtual int getIndex(int i) const = 0 ;

	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const = 0;

};

///The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape
class btPolyhedralConvexAabbCachingShape : public btPolyhedralConvexShape
{

	btVector3	m_localAabbMin;
	btVector3	m_localAabbMax;
	bool		m_isLocalAabbValid;

protected:

	void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
	{
		m_isLocalAabbValid = true;
		m_localAabbMin = aabbMin;
		m_localAabbMax = aabbMax;
	}

	inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const
	{
		btAssert(m_isLocalAabbValid);
		aabbMin = m_localAabbMin;
		aabbMax = m_localAabbMax;
	}

protected:

	btPolyhedralConvexAabbCachingShape();

public:

	inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
	{

		//lazy evaluation of local aabb
		btAssert(m_isLocalAabbValid);
		btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax);
	}

	virtual void	setLocalScaling(const btVector3& scaling);

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	void	recalcLocalAabb();

};

#endif //BT_POLYHEDRAL_CONVEX_SHAPE_H


text:
/*
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.
*/

#ifndef BT_EMPTY_SHAPE_H
#define BT_EMPTY_SHAPE_H

#include "btConcaveShape.h"

#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"

/// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class.
/// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed.
ATTRIBUTE_ALIGNED16(class) btEmptyShape	: public btConcaveShape
{
public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btEmptyShape();

	virtual ~btEmptyShape();

	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	virtual void	setLocalScaling(const btVector3& scaling)
	{
		m_localScaling = scaling;
	}
	virtual const btVector3& getLocalScaling() const
	{
		return m_localScaling;
	}

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual const char*	getName()const
	{
		return "Empty";
	}

	virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const
	{
	}

protected:
	btVector3	m_localScaling;

};

#endif //BT_EMPTY_SHAPE_H


text:
/*
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.
*/

#ifndef BT_HEIGHTFIELD_TERRAIN_SHAPE_H
#define BT_HEIGHTFIELD_TERRAIN_SHAPE_H

#include "btConcaveShape.h"

///btHeightfieldTerrainShape simulates a 2D heightfield terrain
/**
  The caller is responsible for maintaining the heightfield array; this
  class does not make a copy.

  The heightfield can be dynamic so long as the min/max height values
  capture the extremes (heights must always be in that range).

  The local origin of the heightfield is assumed to be the exact
  center (as determined by width and length and height, with each
  axis multiplied by the localScaling).

  \b NOTE: be careful with coordinates.  If you have a heightfield with a local
  min height of -100m, and a max height of +500m, you may be tempted to place it
  at the origin (0,0) and expect the heights in world coordinates to be
  -100 to +500 meters.
  Actually, the heights will be -300 to +300m, because bullet will re-center
  the heightfield based on its AABB (which is determined by the min/max
  heights).  So keep in mind that once you create a btHeightfieldTerrainShape
  object, the heights will be adjusted relative to the center of the AABB.  This
  is different to the behavior of many rendering engines, but is useful for
  physics engines.

  Most (but not all) rendering and heightfield libraries assume upAxis = 1
  (that is, the y-axis is "up").  This class allows any of the 3 coordinates
  to be "up".  Make sure your choice of axis is consistent with your rendering
  system.

  The heightfield heights are determined from the data type used for the
  heightfieldData array.

   - PHY_UCHAR: height at a point is the uchar value at the
       grid point, multipled by heightScale.  uchar isn't recommended
       because of its inability to deal with negative values, and
       low resolution (8-bit).

   - PHY_SHORT: height at a point is the short int value at that grid
       point, multipled by heightScale.

   - PHY_FLOAT: height at a point is the float value at that grid
       point.  heightScale is ignored when using the float heightfield
       data type.

  Whatever the caller specifies as minHeight and maxHeight will be honored.
  The class will not inspect the heightfield to discover the actual minimum
  or maximum heights.  These values are used to determine the heightfield's
  axis-aligned bounding box, multiplied by localScaling.

  For usage and testing see the TerrainDemo.
 */
ATTRIBUTE_ALIGNED16(class) btHeightfieldTerrainShape : public btConcaveShape
{
protected:
	btVector3	m_localAabbMin;
	btVector3	m_localAabbMax;
	btVector3	m_localOrigin;

	///terrain data
	int	m_heightStickWidth;
	int m_heightStickLength;
	btScalar	m_minHeight;
	btScalar	m_maxHeight;
	btScalar m_width;
	btScalar m_length;
	btScalar m_heightScale;
	union
	{
		const unsigned char*	m_heightfieldDataUnsignedChar;
		const short*		m_heightfieldDataShort;
		const btScalar*			m_heightfieldDataFloat;
		const void*	m_heightfieldDataUnknown;
	};

	PHY_ScalarType	m_heightDataType;
	bool	m_flipQuadEdges;
  	bool  m_useDiamondSubdivision;
	bool m_useZigzagSubdivision;

	int	m_upAxis;

	btVector3	m_localScaling;

	virtual btScalar	getRawHeightFieldValue(int x,int y) const;
	void		quantizeWithClamp(int* out, const btVector3& point,int isMax) const;
	void		getVertex(int x,int y,btVector3& vertex) const;

	/// protected initialization
	/**
	  Handles the work of constructors so that public constructors can be
	  backwards-compatible without a lot of copy/paste.
	 */
	void initialize(int heightStickWidth, int heightStickLength,
	                const void* heightfieldData, btScalar heightScale,
	                btScalar minHeight, btScalar maxHeight, int upAxis,
	                PHY_ScalarType heightDataType, bool flipQuadEdges);

public:

	BT_DECLARE_ALIGNED_ALLOCATOR();

	/// preferred constructor
	/**
	  This constructor supports a range of heightfield
	  data types, and allows for a non-zero minimum height value.
	  heightScale is needed for any integer-based heightfield data types.
	 */
	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,
	                          const void* heightfieldData, btScalar heightScale,
	                          btScalar minHeight, btScalar maxHeight,
	                          int upAxis, PHY_ScalarType heightDataType,
	                          bool flipQuadEdges);

	/// legacy constructor
	/**
	  The legacy constructor assumes the heightfield has a minimum height
	  of zero.  Only unsigned char or floats are supported.  For legacy
	  compatibility reasons, heightScale is calculated as maxHeight / 65535
	  (and is only used when useFloatData = false).
 	 */
	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,const void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);

	virtual ~btHeightfieldTerrainShape();

	void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}

	///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
	void setUseZigzagSubdivision(bool useZigzagSubdivision=true) { m_useZigzagSubdivision = useZigzagSubdivision;}

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual void	setLocalScaling(const btVector3& scaling);

	virtual const btVector3& getLocalScaling() const;

	//debugging
	virtual const char*	getName()const {return "HEIGHTFIELD";}

};

#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H


text:
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2010 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.
*/

#ifndef _BT_TRIANGLE_INFO_MAP_H
#define _BT_TRIANGLE_INFO_MAP_H

#include "LinearMath/btHashMap.h"
#include "LinearMath/btSerializer.h"

///for btTriangleInfo m_flags
#define TRI_INFO_V0V1_CONVEX 1
#define TRI_INFO_V1V2_CONVEX 2
#define TRI_INFO_V2V0_CONVEX 4

#define TRI_INFO_V0V1_SWAP_NORMALB 8
#define TRI_INFO_V1V2_SWAP_NORMALB 16
#define TRI_INFO_V2V0_SWAP_NORMALB 32

///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges
///it can be generated using
struct	btTriangleInfo
{
	btTriangleInfo()
	{
		m_edgeV0V1Angle = SIMD_2_PI;
		m_edgeV1V2Angle = SIMD_2_PI;
		m_edgeV2V0Angle = SIMD_2_PI;
		m_flags=0;
	}

	int			m_flags;

	btScalar	m_edgeV0V1Angle;
	btScalar	m_edgeV1V2Angle;
	btScalar	m_edgeV2V0Angle;

};

typedef btHashMap<btHashInt,btTriangleInfo> btInternalTriangleInfoMap;

///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo.
struct	btTriangleInfoMap : public btInternalTriangleInfoMap
{
	btScalar	m_convexEpsilon;///used to determine if an edge or contact normal is convex, using the dot product
	btScalar	m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle
	btScalar	m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared'
	btScalar	m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge"
	btScalar	m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold
	btScalar	m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold)

	btTriangleInfoMap()
	{
		m_convexEpsilon = 0.00f;
		m_planarEpsilon = 0.0001f;
		m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001);
		m_edgeDistanceThreshold = btScalar(0.1);
		m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001);
		m_maxEdgeAngleThreshold = SIMD_2_PI;
	}
	virtual ~btTriangleInfoMap() {}

	virtual	int	calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;

	void	deSerialize(struct btTriangleInfoMapData& data);

};

///those fields have to be float and not btScalar for the serialization to work properly
struct	btTriangleInfoData
{
	int			m_flags;
	float	m_edgeV0V1Angle;
	float	m_edgeV1V2Angle;
	float	m_edgeV2V0Angle;
};

struct	btTriangleInfoMapData
{
	int					*m_hashTablePtr;
	int					*m_nextPtr;
	btTriangleInfoData	*m_valueArrayPtr;
	int					*m_keyArrayPtr;

	float	m_convexEpsilon;
	float	m_planarEpsilon;
	float	m_equalVertexThreshold;
	float	m_edgeDistanceThreshold;
	float	m_zeroAreaThreshold;

	int		m_nextSize;
	int		m_hashTableSize;
	int		m_numValues;
	int		m_numKeys;
	char	m_padding[4];
};

SIMD_FORCE_INLINE	int	btTriangleInfoMap::calculateSerializeBufferSize() const
{
	return sizeof(btTriangleInfoMapData);
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	const char*	btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer;
	tmapData->m_convexEpsilon = (float)m_convexEpsilon;
	tmapData->m_planarEpsilon = (float)m_planarEpsilon;
	tmapData->m_equalVertexThreshold =(float) m_equalVertexThreshold;
	tmapData->m_edgeDistanceThreshold = (float)m_edgeDistanceThreshold;
	tmapData->m_zeroAreaThreshold = (float)m_zeroAreaThreshold;

	tmapData->m_hashTableSize = m_hashTable.size();

	tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0;
	if (tmapData->m_hashTablePtr)
	{
		//serialize an int buffer
		int sz = sizeof(int);
		int numElem = tmapData->m_hashTableSize;
		btChunk* chunk = serializer->allocate(sz,numElem);
		int* memPtr = (int*)chunk->m_oldPtr;
		for (int i=0;i<numElem;i++,memPtr++)
		{
			*memPtr = m_hashTable[i];
		}
		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]);

	}

	tmapData->m_nextSize = m_next.size();
	tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0;
	if (tmapData->m_nextPtr)
	{
		int sz = sizeof(int);
		int numElem = tmapData->m_nextSize;
		btChunk* chunk = serializer->allocate(sz,numElem);
		int* memPtr = (int*)chunk->m_oldPtr;
		for (int i=0;i<numElem;i++,memPtr++)
		{
			*memPtr = m_next[i];
		}
		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]);
	}

	tmapData->m_numValues = m_valueArray.size();
	tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0;
	if (tmapData->m_valueArrayPtr)
	{
		int sz = sizeof(btTriangleInfoData);
		int numElem = tmapData->m_numValues;
		btChunk* chunk = serializer->allocate(sz,numElem);
		btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr;
		for (int i=0;i<numElem;i++,memPtr++)
		{
			memPtr->m_edgeV0V1Angle = (float)m_valueArray[i].m_edgeV0V1Angle;
			memPtr->m_edgeV1V2Angle = (float)m_valueArray[i].m_edgeV1V2Angle;
			memPtr->m_edgeV2V0Angle = (float)m_valueArray[i].m_edgeV2V0Angle;
			memPtr->m_flags = m_valueArray[i].m_flags;
		}
		serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]);
	}

	tmapData->m_numKeys = m_keyArray.size();
	tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0;
	if (tmapData->m_keyArrayPtr)
	{
		int sz = sizeof(int);
		int numElem = tmapData->m_numValues;
		btChunk* chunk = serializer->allocate(sz,numElem);
		int* memPtr = (int*)chunk->m_oldPtr;
		for (int i=0;i<numElem;i++,memPtr++)
		{
			*memPtr = m_keyArray[i].getUid1();
		}
		serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]);

	}

	// Fill padding with zeros to appease msan.
	tmapData->m_padding[0] = 0;
	tmapData->m_padding[1] = 0;
	tmapData->m_padding[2] = 0;
	tmapData->m_padding[3] = 0;

	return "btTriangleInfoMapData";
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	void	btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData )
{

	m_convexEpsilon = tmapData.m_convexEpsilon;
	m_planarEpsilon = tmapData.m_planarEpsilon;
	m_equalVertexThreshold = tmapData.m_equalVertexThreshold;
	m_edgeDistanceThreshold = tmapData.m_edgeDistanceThreshold;
	m_zeroAreaThreshold = tmapData.m_zeroAreaThreshold;
	m_hashTable.resize(tmapData.m_hashTableSize);
	int i =0;
	for (i=0;i<tmapData.m_hashTableSize;i++)
	{
		m_hashTable[i] = tmapData.m_hashTablePtr[i];
	}
	m_next.resize(tmapData.m_nextSize);
	for (i=0;i<tmapData.m_nextSize;i++)
	{
		m_next[i] = tmapData.m_nextPtr[i];
	}
	m_valueArray.resize(tmapData.m_numValues);
	for (i=0;i<tmapData.m_numValues;i++)
	{
		m_valueArray[i].m_edgeV0V1Angle = tmapData.m_valueArrayPtr[i].m_edgeV0V1Angle;
		m_valueArray[i].m_edgeV1V2Angle = tmapData.m_valueArrayPtr[i].m_edgeV1V2Angle;
		m_valueArray[i].m_edgeV2V0Angle = tmapData.m_valueArrayPtr[i].m_edgeV2V0Angle;
		m_valueArray[i].m_flags = tmapData.m_valueArrayPtr[i].m_flags;
	}

	m_keyArray.resize(tmapData.m_numKeys,btHashInt(0));
	for (i=0;i<tmapData.m_numKeys;i++)
	{
		m_keyArray[i].setUid1(tmapData.m_keyArrayPtr[i]);
	}
}

#endif //_BT_TRIANGLE_INFO_MAP_H


text:
/*
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.
*/

/// This file was created by Alex Silverman

#ifndef BT_MATERIAL_H
#define BT_MATERIAL_H

// Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties
class btMaterial
{
    // public members so that materials can change due to world events
public:
    btScalar m_friction;
    btScalar m_restitution;
    int pad[2];

    btMaterial(){}
    btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; }
};

#endif // BT_MATERIAL_H


text:
/*
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.
*/

#ifndef BT_STRIDING_MESHINTERFACE_H
#define BT_STRIDING_MESHINTERFACE_H

#include "LinearMath/btVector3.h"
#include "btTriangleCallback.h"
#include "btConcaveShape.h"

///	The btStridingMeshInterface is the interface class for high performance
/// generic access to triangle meshes, used in combination with
/// btBvhTriangleMeshShape and some other collision shapes. Using index striding
/// of 3*sizeof(integer) it can use triangle arrays, using index striding of
/// 1*sizeof(integer) it can handle triangle strips. It allows for sharing
/// graphics and collision meshes. Also it provides locking/unlocking of
/// graphics meshes that are in gpu memory.
ATTRIBUTE_ALIGNED16(class)
btStridingMeshInterface
{
protected:
	btVector3 m_scaling;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btStridingMeshInterface() : m_scaling(btScalar(1.), btScalar(1.), btScalar(1.)) { }
	virtual ~btStridingMeshInterface();

	virtual void InternalProcessAllTriangles(
	    btInternalTriangleIndexCallback* callback,
	    const btVector3&                 aabbMin,
	    const btVector3&                 aabbMax) const;

	/// brute force method to calculate aabb
	void calculateAabbBruteForce(btVector3 & aabbMin, btVector3 & aabbMax);

	/// get read and write access to a subpart of a triangle mesh this subpart has
	/// a continuous array of vertices and indices in this way the mesh can be
	/// handled as chunks of memory with striding very similar to OpenGL
	/// vertexarray support make a call to unLockVertexBase when the read and
	/// write access is finished
	virtual void getLockedVertexIndexBase(
	    unsigned char** vertexbase,
	    int&            numverts,
	    PHY_ScalarType& type,
	    int&            stride,
	    unsigned char** indexbase,
	    int&            indexstride,
	    int&            numfaces,
	    PHY_ScalarType& indicestype,
	    int             subpart = 0) = 0;

	virtual void getLockedReadOnlyVertexIndexBase(
	    const unsigned char** vertexbase,
	    int&                  numverts,
	    PHY_ScalarType&       type,
	    int&                  stride,
	    const unsigned char** indexbase,
	    int&                  indexstride,
	    int&                  numfaces,
	    PHY_ScalarType&       indicestype,
	    int                   subpart = 0) const = 0;

	/// unLockVertexBase finishes the access to a subpart of the triangle mesh
	/// make a call to unLockVertexBase when the read and write access (using
	/// getLockedVertexIndexBase) is finished
	virtual void unLockVertexBase(int subpart) = 0;

	virtual void unLockReadOnlyVertexBase(int subpart) const = 0;

	/// getNumSubParts returns the number of separate subparts. each subpart has a
	/// continuous array of vertices and indices
	virtual int getNumSubParts() const = 0;

	virtual void preallocateVertices(int numverts)  = 0;
	virtual void preallocateIndices(int numindices) = 0;

	virtual bool hasPremadeAabb() const { return false; }
	virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax) const
	{
		(void) aabbMin;
		(void) aabbMax;
	}
	virtual void getPremadeAabb(btVector3 * aabbMin, btVector3 * aabbMax) const
	{
		(void) aabbMin;
		(void) aabbMax;
	}
	const btVector3& getScaling() const { return m_scaling; }
	void             setScaling(const btVector3& scaling) { m_scaling = scaling; }

	virtual int calculateSerializeBufferSize() const;

	/// fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
};

struct btIntIndexData
{
	int m_value;
};

struct btShortIntIndexData
{
	short m_value;
	char  m_pad[2];
};

struct btShortIntIndexTripletData
{
	short m_values[3];
	char  m_pad[2];
};

struct btCharIndexTripletData
{
	unsigned char m_values[3];
	char          m_pad;
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btMeshPartData
{
	btVector3FloatData*  m_vertices3f;
	btVector3DoubleData* m_vertices3d;

	btIntIndexData*             m_indices32;
	btShortIntIndexTripletData* m_3indices16;
	btCharIndexTripletData*     m_3indices8;

	btShortIntIndexData* m_indices16; //backwards compatibility

	int m_numTriangles; //length of m_indices = m_numTriangles
	int m_numVertices;
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btStridingMeshInterfaceData
{
	btMeshPartData*    m_meshPartsPtr;
	btVector3FloatData m_scaling;
	int                m_numMeshParts;
	char               m_padding[4];
};

SIMD_FORCE_INLINE int btStridingMeshInterface::calculateSerializeBufferSize() const
{
	return sizeof(btStridingMeshInterfaceData);
}

#endif //BT_STRIDING_MESHINTERFACE_H


text:
/*
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.
*/

#ifndef BT_STATIC_PLANE_SHAPE_H
#define BT_STATIC_PLANE_SHAPE_H

#include "btConcaveShape.h"

///The btStaticPlaneShape simulates an infinite non-moving (static) collision plane.
ATTRIBUTE_ALIGNED16(class) btStaticPlaneShape : public btConcaveShape
{
protected:
	btVector3	m_localAabbMin;
	btVector3	m_localAabbMax;

	btVector3	m_planeNormal;
	btScalar      m_planeConstant;
	btVector3	m_localScaling;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant);

	virtual ~btStaticPlaneShape();

	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;

	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;

	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;

	virtual void	setLocalScaling(const btVector3& scaling);
	virtual const btVector3& getLocalScaling() const;

	const btVector3&	getPlaneNormal() const
	{
		return	m_planeNormal;
	}

	const btScalar&	getPlaneConstant() const
	{
		return	m_planeConstant;
	}

	//debugging
	virtual const char*	getName()const {return "STATICPLANE";}

	virtual	int	calculateSerializeBufferSize() const;

	///fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual	const char*	serialize(void* dataBuffer, btSerializer* serializer) const;

};

///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
struct	btStaticPlaneShapeData
{
	btCollisionShapeData	m_collisionShapeData;

	btVector3FloatData	m_localScaling;
	btVector3FloatData	m_planeNormal;
	float			m_planeConstant;
	char	m_pad[4];
};

SIMD_FORCE_INLINE	int	btStaticPlaneShape::calculateSerializeBufferSize() const
{
	return sizeof(btStaticPlaneShapeData);
}

///fills the dataBuffer and returns the struct name (and 0 on failure)
SIMD_FORCE_INLINE	const char*	btStaticPlaneShape::serialize(void* dataBuffer, btSerializer* serializer) const
{
	btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) dataBuffer;
	btCollisionShape::serialize(&planeData->m_collisionShapeData,serializer);

	m_localScaling.serializeFloat(planeData->m_localScaling);
	m_planeNormal.serializeFloat(planeData->m_planeNormal);
	planeData->m_planeConstant = float(m_planeConstant);

	// Fill padding with zeros to appease msan.
	planeData->m_pad[0] = 0;
	planeData->m_pad[1] = 0;
	planeData->m_pad[2] = 0;
	planeData->m_pad[3] = 0;

	return "btStaticPlaneShapeData";
}

#endif //BT_STATIC_PLANE_SHAPE_H


text:
/*
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.
*/

#ifndef BT_COMPOUND_SHAPE_H
#define BT_COMPOUND_SHAPE_H

#include "btCollisionShape.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMatrix3x3.h"
#include "btCollisionMargin.h"
#include "LinearMath/btAlignedObjectArray.h"

struct btDbvt;

ATTRIBUTE_ALIGNED16(struct)
btCompoundShapeChild
{
	BT_DECLARE_ALIGNED_ALLOCATOR();

	btTransform        m_transform;
	btCollisionShape*  m_childShape;
	int                m_childShapeType;
	btScalar           m_childMargin;
	struct btDbvtNode* m_node;
};

SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2)
{
	return (c1.m_transform == c2.m_transform
	     && c1.m_childShape == c2.m_childShape
	     && c1.m_childShapeType == c2.m_childShapeType
	     && c1.m_childMargin == c2.m_childMargin);
}

/// The btCompoundShape allows to store multiple other btCollisionShapes
/// This allows for moving concave collision objects. This is more general then
/// the static concave btBvhTriangleMeshShape. It has an (optional) dynamic
/// aabb tree to accelerate early rejection tests. Currently, removal of child
/// shapes is only supported when disabling the aabb tree (pass 'false' in the
/// constructor of btCompoundShape)
//@todo: This aabb tree can also be use to speed up ray tests on
//btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25
ATTRIBUTE_ALIGNED16(class)
btCompoundShape : public btCollisionShape
{
protected:
	btAlignedObjectArray<btCompoundShapeChild> m_children;
	btVector3                                  m_localAabbMin;
	btVector3                                  m_localAabbMax;
	btDbvt*                                    m_dynamicAabbTree;

	/// increment m_updateRevision when adding/removing/replacing child shapes,
	/// so that some caches can be updated
	int m_updateRevision;

	btScalar  m_collisionMargin;
	btVector3 m_localScaling;

public:
	BT_DECLARE_ALIGNED_ALLOCATOR();

	explicit btCompoundShape(bool enableDynamicAabbTree = true, const int initialChildCapacity = 0);
	virtual ~btCompoundShape();
	void addChildShape(const btTransform& localTransform, btCollisionShape* shape);

	/// Remove all children shapes that contain the specified shape
	virtual void removeChildShape(btCollisionShape* shape);

	void                    removeChildShapeByIndex(int childShapeindex);
	int                     getNumChildShapes() const          { return int(m_children.size()); }
	btCollisionShape*       getChildShape(int index)           { return m_children[index].m_childShape; }
	const btCollisionShape* getChildShape(int index) const     { return m_children[index].m_childShape; }
	btTransform&            getChildTransform(int index)       { return m_children[index].m_transform; }
	const btTransform&      getChildTransform(int index) const { return m_children[index].m_transform; }

	/// set a new transform for a child, and update internal data structures
	/// (local aabb and dynamic tree)
	void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true);

	btCompoundShapeChild* getChildList() { return &m_children[0]; }

	/// getAabb's default implementation is brute force, expected derived classes
	/// to implement a fast dedicated version
	virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;

	/// Re-calculate the local Aabb. Is called at the end of removeChildShapes.
	/// Use this yourself if you modify the children or their transforms.
	virtual void recalculateLocalAabb();

	virtual void             setLocalScaling(const btVector3& scaling);
	virtual const btVector3& getLocalScaling() const    { return m_localScaling; }
	virtual void             calculateLocalInertia(btScalar mass, btVector3& inertia) const;
	virtual void             setMargin(btScalar margin) { m_collisionMargin = margin; }
	virtual btScalar         getMargin() const          { return m_collisionMargin; }
	virtual const char*      getName() const            { return "Compound"; }
	const btDbvt*            getDynamicAabbTree() const { return m_dynamicAabbTree; }
	btDbvt*                  getDynamicAabbTree()       { return m_dynamicAabbTree; }
	void                     createAabbTreeFromChildren();

	/// computes the exact moment of inertia and the transform from the
	/// coordinate system defined by the principal axes of the moment of inertia
	/// and the center of mass to the current coordinate system. "masses" points
	/// to an array of masses of the children. The resulting transform
	/// "principal" has to be applied inversely to all children transforms in
	/// order for the local coordinate system of the compound shape to be
	/// centered at the center of mass and to coincide with the principal axes.
	/// This also necessitates a correction of the world transform of the
	/// collision object by the principal transform.
	void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const;

	int         getUpdateRevision() const { return m_updateRevision; }
	virtual int calculateSerializeBufferSize() const;

	/// fills the dataBuffer and returns the struct name (and 0 on failure)
	virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btCompoundShapeChildData
{
	btTransformFloatData  m_transform;
	btCollisionShapeData* m_childShape;
	int                   m_childShapeType;
	float                 m_childMargin;
};

/// do not change those serialization structures, it requires an updated
/// sBulletDNAstr/sBulletDNAstr64
struct btCompoundShapeData
{
	btCollisionShapeData      m_collisionShapeData;
	btCompoundShapeChildData* m_childShapePtr;
	int                       m_numChildShapes;
	float                     m_collisionMargin;
};

SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const
{
	return sizeof(btCompoundShapeData);
}

#endif //BT_COMPOUND_SHAPE_H