make convex hull creation easier for the user

This commit is contained in:
Irlan 2018-05-01 04:49:53 -03:00
parent 6550a92e4b
commit 883cc9059f
3 changed files with 41 additions and 23 deletions

View File

@ -102,9 +102,8 @@ public:
qhHull(); qhHull();
~qhHull(); ~qhHull();
// Construct this hull given a memory buffer and an array of points. // Construct this convex hull from an array of points.
// Use qhGetBufferSize to get the buffer size given the number of points. void Construct(const b3Vec3* vertices, u32 vertexCount);
void Construct(void* buffer, const b3Vec3* vertices, u32 vertexCount);
// Get the list of vertices in this convex hull. // Get the list of vertices in this convex hull.
const qhList<qhVertex>& GetVertexList() const; const qhList<qhVertex>& GetVertexList() const;
@ -150,10 +149,10 @@ private:
void ResolveOrphans(); void ResolveOrphans();
// List of vertices // List of active vertices
qhList<qhVertex> m_vertexList; qhList<qhVertex> m_vertexList;
// List of faces // List of active faces
qhList<qhFace> m_faceList; qhList<qhFace> m_faceList;
// Coplanarity tolerance // Coplanarity tolerance
@ -172,6 +171,8 @@ private:
qhFace* AllocateFace(); qhFace* AllocateFace();
void FreeFace(qhFace* p); void FreeFace(qhFace* p);
void* m_buffer;
qhVertex* m_freeVertices; qhVertex* m_freeVertices;
qhHalfEdge* m_freeEdges; qhHalfEdge* m_freeEdges;
qhFace* m_freeFaces; qhFace* m_freeFaces;

View File

@ -176,26 +176,18 @@ void b3QHull::Set(const b3Vec3* points, u32 count)
} }
// Create a convex hull. // Create a convex hull.
// Allocate memory buffer for the worst case.
u32 qhBufferSize = qhGetBufferSize(B3_MAX_HULL_VERTICES);
void* qhBuffer = b3Alloc(qhBufferSize);
// Build
qhHull hull; qhHull hull;
hull.Construct(qhBuffer, ps, psCount); hull.Construct(ps, psCount);
if (hull.GetVertexList().count > B3_MAX_HULL_VERTICES) if (hull.GetVertexList().count > B3_MAX_HULL_VERTICES)
{ {
// Vertex excess // Vertex excess
b3Free(qhBuffer);
return; return;
} }
if (hull.GetFaceList().count > B3_MAX_HULL_FACES) if (hull.GetFaceList().count > B3_MAX_HULL_FACES)
{ {
// Face excess // Face excess
b3Free(qhBuffer);
return; return;
} }
@ -228,7 +220,6 @@ void b3QHull::Set(const b3Vec3* points, u32 count)
if (iedge == B3_MAX_HULL_EDGES) if (iedge == B3_MAX_HULL_EDGES)
{ {
// Half-edge excess // Half-edge excess
b3Free(qhBuffer);
return; return;
} }
@ -237,7 +228,6 @@ void b3QHull::Set(const b3Vec3* points, u32 count)
if (itwin == B3_MAX_HULL_EDGES) if (itwin == B3_MAX_HULL_EDGES)
{ {
// Half-edge excess // Half-edge excess
b3Free(qhBuffer);
return; return;
} }
@ -287,8 +277,6 @@ void b3QHull::Set(const b3Vec3* points, u32 count)
++iface; ++iface;
} }
b3Free(qhBuffer);
B3_ASSERT(vs.count <= B3_MAX_HULL_VERTICES); B3_ASSERT(vs.count <= B3_MAX_HULL_VERTICES);
vertexCount = vs.count; vertexCount = vs.count;

View File

@ -61,10 +61,42 @@ qhHull::qhHull()
qhHull::~qhHull() qhHull::~qhHull()
{ {
qhVertex* v = m_vertexList.head;
while(v)
{
qhVertex* v0 = v;
v = v->next;
FreeVertex(v0);
} }
void qhHull::Construct(void* memory, const b3Vec3* vs, u32 count) qhFace* f = m_faceList.head;
while (f)
{ {
qhFace* f0 = f;
f = f->next;
qhHalfEdge* e = f0->edge;
do
{
qhHalfEdge* e0 = e;
e = e->next;
FreeEdge(e0);
} while (e != f0->edge);
FreeFace(f0);
}
b3Free(m_buffer);
}
void qhHull::Construct(const b3Vec3* vs, u32 count)
{
// Allocate memory buffer for the worst case.
u32 bufferSize = qhGetBufferSize(count);
m_buffer = b3Alloc(bufferSize);
// Euler's formula // Euler's formula
// V - E + F = 2 // V - E + F = 2
u32 V = count; u32 V = count;
@ -72,11 +104,8 @@ void qhHull::Construct(void* memory, const b3Vec3* vs, u32 count)
u32 HE = 2 * E; u32 HE = 2 * E;
u32 F = 2 * V - 4; u32 F = 2 * V - 4;
HE *= 2;
F *= 2;
m_freeVertices = NULL; m_freeVertices = NULL;
qhVertex* vertices = (qhVertex*)memory; qhVertex* vertices = (qhVertex*)m_buffer;
for (u32 i = 0; i < V; ++i) for (u32 i = 0; i < V; ++i)
{ {
FreeVertex(vertices + i); FreeVertex(vertices + i);