forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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
 | ||
|  | 
 |