242 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
 | 
						|
/*
 | 
						|
Stan Melax Convex Hull Computation
 | 
						|
Copyright (c) 2008 Stan Melax http://www.melax.com/
 | 
						|
 | 
						|
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.
 | 
						|
*/
 | 
						|
 | 
						|
///includes modifications/improvements by John Ratcliff, see BringOutYourDead below.
 | 
						|
 | 
						|
#ifndef BT_CD_HULL_H
 | 
						|
#define BT_CD_HULL_H
 | 
						|
 | 
						|
#include "btVector3.h"
 | 
						|
#include "btAlignedObjectArray.h"
 | 
						|
 | 
						|
typedef btAlignedObjectArray<unsigned int> TUIntArray;
 | 
						|
 | 
						|
class HullResult
 | 
						|
{
 | 
						|
public:
 | 
						|
	HullResult(void)
 | 
						|
	{
 | 
						|
		mPolygons = true;
 | 
						|
		mNumOutputVertices = 0;
 | 
						|
		mNumFaces = 0;
 | 
						|
		mNumIndices = 0;
 | 
						|
	}
 | 
						|
	bool                    mPolygons;                  // true if indices represents polygons, false indices are triangles
 | 
						|
	unsigned int            mNumOutputVertices;         // number of vertices in the output hull
 | 
						|
	btAlignedObjectArray<btVector3>	m_OutputVertices;            // array of vertices
 | 
						|
	unsigned int            mNumFaces;                  // the number of faces produced
 | 
						|
	unsigned int            mNumIndices;                // the total number of indices
 | 
						|
	btAlignedObjectArray<unsigned int>    m_Indices;                   // pointer to indices.
 | 
						|
 | 
						|
// If triangles, then indices are array indexes into the vertex list.
 | 
						|
// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
 | 
						|
};
 | 
						|
 | 
						|
enum HullFlag
 | 
						|
{
 | 
						|
	QF_TRIANGLES         = (1<<0),             // report results as triangles, not polygons.
 | 
						|
	QF_REVERSE_ORDER     = (1<<1),             // reverse order of the triangle indices.
 | 
						|
	QF_DEFAULT           = QF_TRIANGLES
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class HullDesc
 | 
						|
{
 | 
						|
public:
 | 
						|
	HullDesc(void)
 | 
						|
	{
 | 
						|
		mFlags          = QF_DEFAULT;
 | 
						|
		mVcount         = 0;
 | 
						|
		mVertices       = 0;
 | 
						|
		mVertexStride   = sizeof(btVector3);
 | 
						|
		mNormalEpsilon  = 0.001f;
 | 
						|
		mMaxVertices	= 4096; // maximum number of points to be considered for a convex hull.
 | 
						|
		mMaxFaces	= 4096;
 | 
						|
	};
 | 
						|
 | 
						|
	HullDesc(HullFlag flag,
 | 
						|
		 unsigned int vcount,
 | 
						|
		 const btVector3 *vertices,
 | 
						|
		 unsigned int stride = sizeof(btVector3))
 | 
						|
	{
 | 
						|
		mFlags          = flag;
 | 
						|
		mVcount         = vcount;
 | 
						|
		mVertices       = vertices;
 | 
						|
		mVertexStride   = stride;
 | 
						|
		mNormalEpsilon  = btScalar(0.001);
 | 
						|
		mMaxVertices    = 4096;
 | 
						|
	}
 | 
						|
 | 
						|
	bool HasHullFlag(HullFlag flag) const
 | 
						|
	{
 | 
						|
		if ( mFlags & flag ) return true;
 | 
						|
		return false;
 | 
						|
	}
 | 
						|
 | 
						|
	void SetHullFlag(HullFlag flag)
 | 
						|
	{
 | 
						|
		mFlags|=flag;
 | 
						|
	}
 | 
						|
 | 
						|
	void ClearHullFlag(HullFlag flag)
 | 
						|
	{
 | 
						|
		mFlags&=~flag;
 | 
						|
	}
 | 
						|
 | 
						|
	unsigned int      mFlags;           // flags to use when generating the convex hull.
 | 
						|
	unsigned int      mVcount;          // number of vertices in the input point cloud
 | 
						|
	const btVector3  *mVertices;        // the array of vertices.
 | 
						|
	unsigned int      mVertexStride;    // the stride of each vertex, in bytes.
 | 
						|
	btScalar             mNormalEpsilon;   // the epsilon for removing duplicates.  This is a normalized value, if normalized bit is on.
 | 
						|
	unsigned int      mMaxVertices;     // maximum number of vertices to be considered for the hull!
 | 
						|
	unsigned int      mMaxFaces;
 | 
						|
};
 | 
						|
 | 
						|
enum HullError
 | 
						|
{
 | 
						|
	QE_OK,            // success!
 | 
						|
	QE_FAIL           // failed.
 | 
						|
};
 | 
						|
 | 
						|
class btPlane
 | 
						|
{
 | 
						|
	public:
 | 
						|
	btVector3	normal;
 | 
						|
	btScalar	dist;   // distance below origin - the D from plane equasion Ax+By+Cz+D=0
 | 
						|
			btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){}
 | 
						|
			btPlane():normal(),dist(0){}
 | 
						|
	
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class ConvexH 
 | 
						|
{
 | 
						|
  public:
 | 
						|
	class HalfEdge
 | 
						|
	{
 | 
						|
	  public:
 | 
						|
		short ea;         // the other half of the edge (index into edges list)
 | 
						|
		unsigned char v;  // the vertex at the start of this edge (index into vertices list)
 | 
						|
		unsigned char p;  // the facet on which this edge lies (index into facets list)
 | 
						|
		HalfEdge(){}
 | 
						|
		HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){}
 | 
						|
	};
 | 
						|
	ConvexH()
 | 
						|
	{
 | 
						|
	}
 | 
						|
	~ConvexH()
 | 
						|
	{
 | 
						|
	}
 | 
						|
	btAlignedObjectArray<btVector3> vertices;
 | 
						|
	btAlignedObjectArray<HalfEdge> edges;
 | 
						|
	btAlignedObjectArray<btPlane>  facets;
 | 
						|
	ConvexH(int vertices_size,int edges_size,int facets_size);
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class int4
 | 
						|
{
 | 
						|
public:
 | 
						|
	int x,y,z,w;
 | 
						|
	int4(){};
 | 
						|
	int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;}
 | 
						|
	const int& operator[](int i) const {return (&x)[i];}
 | 
						|
	int& operator[](int i) {return (&x)[i];}
 | 
						|
};
 | 
						|
 | 
						|
class PHullResult
 | 
						|
{
 | 
						|
public:
 | 
						|
 | 
						|
	PHullResult(void)
 | 
						|
	{
 | 
						|
		mVcount = 0;
 | 
						|
		mIndexCount = 0;
 | 
						|
		mFaceCount = 0;
 | 
						|
		mVertices = 0;
 | 
						|
	}
 | 
						|
 | 
						|
	unsigned int mVcount;
 | 
						|
	unsigned int mIndexCount;
 | 
						|
	unsigned int mFaceCount;
 | 
						|
	btVector3*   mVertices;
 | 
						|
	TUIntArray m_Indices;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
 | 
						|
///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method.
 | 
						|
///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape.
 | 
						|
class HullLibrary
 | 
						|
{
 | 
						|
 | 
						|
	btAlignedObjectArray<class btHullTriangle*> m_tris;
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
	btAlignedObjectArray<int> m_vertexIndexMapping;
 | 
						|
 | 
						|
 | 
						|
	HullError CreateConvexHull(const HullDesc& desc, // describes the input request
 | 
						|
				   HullResult&     result);        // contains the resulst
 | 
						|
	HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
 | 
						|
 | 
						|
private:
 | 
						|
 | 
						|
	bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
 | 
						|
 | 
						|
	class btHullTriangle*	allocateTriangle(int a,int b,int c);
 | 
						|
	void	deAllocateTriangle(btHullTriangle*);
 | 
						|
	void b2bfix(btHullTriangle* s,btHullTriangle*t);
 | 
						|
 | 
						|
	void removeb2b(btHullTriangle* s,btHullTriangle*t);
 | 
						|
 | 
						|
	void checkit(btHullTriangle *t);
 | 
						|
 | 
						|
	btHullTriangle* extrudable(btScalar epsilon);
 | 
						|
 | 
						|
	int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
 | 
						|
 | 
						|
	int calchullgen(btVector3 *verts,int verts_count, int vlimit);
 | 
						|
 | 
						|
	int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray<int> &allow);
 | 
						|
 | 
						|
	class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
 | 
						|
 | 
						|
	void extrude(class btHullTriangle* t0,int v);
 | 
						|
 | 
						|
	ConvexH* test_cube();
 | 
						|
 | 
						|
	//BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'. 
 | 
						|
	//After the hull is generated it give you back a set of polygon faces which index the *original* point cloud.
 | 
						|
	//The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull.
 | 
						|
	//The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation.
 | 
						|
	void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount);
 | 
						|
 | 
						|
	bool CleanupVertices(unsigned int svcount,
 | 
						|
			     const btVector3* svertices,
 | 
						|
			     unsigned int stride,
 | 
						|
			     unsigned int &vcount, // output number of vertices
 | 
						|
			     btVector3* vertices, // location to store the results.
 | 
						|
			     btScalar  normalepsilon,
 | 
						|
			     btVector3& scale);
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
#endif //BT_CD_HULL_H
 | 
						|
 |