erase dep, constexpr, cleanup
This commit is contained in:
parent
43f59409de
commit
63f034535e
@ -58,8 +58,8 @@ struct qhFace
|
|||||||
b3Vec3 center;
|
b3Vec3 center;
|
||||||
b3Plane plane;
|
b3Plane plane;
|
||||||
|
|
||||||
u32 VertexCount() const;
|
u32 GetVertexCount() const;
|
||||||
u32 EdgeCount() const;
|
u32 GetEdgeCount() const;
|
||||||
qhHalfEdge* FindTwin(const qhVertex* tail, const qhVertex* head) const;
|
qhHalfEdge* FindTwin(const qhVertex* tail, const qhVertex* head) const;
|
||||||
void ComputeCenterAndPlane();
|
void ComputeCenterAndPlane();
|
||||||
};
|
};
|
||||||
@ -89,12 +89,8 @@ struct qhVertex
|
|||||||
qhFace* conflictFace;
|
qhFace* conflictFace;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Given a number of points return the required memory size in bytes for constructing the
|
// A convex hull builder.
|
||||||
// convex hull of those points. Use this function before allocating the memory buffer passed
|
// Given a list of points constructs its convex hull.
|
||||||
// as argument to Construct.
|
|
||||||
u32 qhGetMemorySize(u32 V);
|
|
||||||
|
|
||||||
// A convex hull builder. Given a list of points constructs its convex hull.
|
|
||||||
// The output convex hull might contain polygonal faces and not only triangles.
|
// The output convex hull might contain polygonal faces and not only triangles.
|
||||||
// Coplanar face merging is necessary for stable physics simulation.
|
// Coplanar face merging is necessary for stable physics simulation.
|
||||||
class qhHull
|
class qhHull
|
||||||
@ -102,18 +98,23 @@ class qhHull
|
|||||||
public:
|
public:
|
||||||
qhHull();
|
qhHull();
|
||||||
~qhHull();
|
~qhHull();
|
||||||
|
|
||||||
// Entry point of qhHull.
|
// Construct this hull given a memory buffer and an array of points.
|
||||||
// Construct this hull given a memory buffer and a list of points.
|
// Use qhGetBufferCapacity to get the buffer capacity from the point array size.
|
||||||
// Use qhGetMemorySize to see how many free bytes should be available in the buffer.
|
void Construct(void* buffer, const b3Vec3* vertices, u32 vertexCount);
|
||||||
void Construct(void* memory, const b3Array<b3Vec3>& vertices);
|
|
||||||
|
|
||||||
// Get the list of faces in this hull.
|
|
||||||
const qhList<qhFace>& GetFaceList() const;
|
|
||||||
|
|
||||||
// Get the number of iterations this algorithm ran.
|
// Get the number of iterations this algorithm ran.
|
||||||
u32 GetIterations() const;
|
u32 GetIterations() const;
|
||||||
|
|
||||||
|
// Get the list of faces in this convex hull.
|
||||||
|
const qhList<qhFace>& GetFaceList() const;
|
||||||
|
|
||||||
|
// Get the number of unique edges in this convex hull.
|
||||||
|
// u32 GetEdgeCount() const;
|
||||||
|
|
||||||
|
// Get the number of unique vertices in this convex hull.
|
||||||
|
// u32 GetVertexCount() const;
|
||||||
|
|
||||||
// Validate this hull.
|
// Validate this hull.
|
||||||
void Validate() const;
|
void Validate() const;
|
||||||
void Validate(const qhFace* face) const;
|
void Validate(const qhFace* face) const;
|
||||||
@ -122,7 +123,7 @@ public:
|
|||||||
// Draw this hull.
|
// Draw this hull.
|
||||||
void Draw() const;
|
void Draw() const;
|
||||||
private:
|
private:
|
||||||
bool BuildInitialHull(const b3Array<b3Vec3>& vertices);
|
bool BuildInitialHull(const b3Vec3* vertices, u32 count);
|
||||||
|
|
||||||
qhVertex* NextVertex();
|
qhVertex* NextVertex();
|
||||||
|
|
||||||
@ -146,13 +147,13 @@ private:
|
|||||||
|
|
||||||
// Coplanarity tolerance
|
// Coplanarity tolerance
|
||||||
float32 m_tolerance;
|
float32 m_tolerance;
|
||||||
|
|
||||||
|
// Number of Quickhull iterations
|
||||||
|
u32 m_iteration;
|
||||||
|
|
||||||
// List of faces
|
// List of faces
|
||||||
qhList<qhFace> m_faceList;
|
qhList<qhFace> m_faceList;
|
||||||
|
|
||||||
// Number of Quickhull iterations
|
|
||||||
u32 m_iteration;
|
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
qhVertex* AllocateVertex();
|
qhVertex* AllocateVertex();
|
||||||
void FreeVertex(qhVertex* p);
|
void FreeVertex(qhVertex* p);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
// qhHull.h
|
// qhHull.h
|
||||||
|
|
||||||
|
// Lists
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void qhList<T>::PushFront(T* link)
|
inline void qhList<T>::PushFront(T* link)
|
||||||
{
|
{
|
||||||
@ -38,7 +40,9 @@ inline T* qhList<T>::Remove(T* link)
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 qhFace::VertexCount() const
|
// qhFace
|
||||||
|
|
||||||
|
inline u32 qhFace::GetVertexCount() const
|
||||||
{
|
{
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
qhHalfEdge* e = edge;
|
qhHalfEdge* e = edge;
|
||||||
@ -50,7 +54,7 @@ inline u32 qhFace::VertexCount() const
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u32 qhFace::EdgeCount() const
|
inline u32 qhFace::GetEdgeCount() const
|
||||||
{
|
{
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
qhHalfEdge* e = edge;
|
qhHalfEdge* e = edge;
|
||||||
@ -81,7 +85,7 @@ inline qhHalfEdge* qhFace::FindTwin(const qhVertex* tail, const qhVertex* head)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline b3Vec3 b3Newell(const b3Vec3& a, const b3Vec3& b)
|
static inline b3Vec3 b3Newell(const b3Vec3& a, const b3Vec3& b)
|
||||||
{
|
{
|
||||||
return b3Vec3((a.y - b.y) * (a.z + b.z), (a.z - b.z) * (a.x + b.x), (a.x - b.x) * (a.y + b.y));
|
return b3Vec3((a.y - b.y) * (a.z + b.z), (a.z - b.z) * (a.x + b.x), (a.x - b.x) * (a.y + b.y));
|
||||||
}
|
}
|
||||||
@ -116,29 +120,21 @@ inline void qhFace::ComputeCenterAndPlane()
|
|||||||
center = c;
|
center = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline qhHalfEdge* qhHull::FindTwin(const qhVertex* tail, const qhVertex* head) const
|
// qhHull
|
||||||
{
|
|
||||||
qhFace* face = m_faceList.head;
|
|
||||||
while (face)
|
|
||||||
{
|
|
||||||
qhHalfEdge* e = face->FindTwin(tail, head);
|
|
||||||
if (e)
|
|
||||||
{
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
face = face->next;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 qhGetMemorySize(u32 V)
|
// Given a number of points return the required memory size in
|
||||||
|
// bytes for constructing the convex hull of those points.
|
||||||
|
// This function uses constant expression (C++11). Therefore, you can evaluate
|
||||||
|
// its value at compile-time. That is particularly usefull when you want to
|
||||||
|
// create a stack buffer from a constant number of vertices.
|
||||||
|
// Due to the constexpr specifier, this function is automatically inlined.
|
||||||
|
constexpr u32 qhGetBufferCapacity(u32 pointCount)
|
||||||
{
|
{
|
||||||
|
u32 V = pointCount;
|
||||||
u32 E = 3 * V - 6;
|
u32 E = 3 * V - 6;
|
||||||
u32 HE = 2 * E;
|
u32 HE = 2 * E;
|
||||||
u32 F = 2 * V - 4;
|
u32 F = 2 * V - 4;
|
||||||
|
|
||||||
// V - E + F = 2
|
|
||||||
|
|
||||||
HE *= 2;
|
HE *= 2;
|
||||||
F *= 2;
|
F *= 2;
|
||||||
|
|
||||||
@ -149,16 +145,16 @@ inline u32 qhGetMemorySize(u32 V)
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const qhList<qhFace>& qhHull::GetFaceList() const
|
|
||||||
{
|
|
||||||
return m_faceList;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u32 qhHull::GetIterations() const
|
inline u32 qhHull::GetIterations() const
|
||||||
{
|
{
|
||||||
return m_iteration;
|
return m_iteration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const qhList<qhFace>& qhHull::GetFaceList() const
|
||||||
|
{
|
||||||
|
return m_faceList;
|
||||||
|
}
|
||||||
|
|
||||||
inline qhVertex* qhHull::AllocateVertex()
|
inline qhVertex* qhHull::AllocateVertex()
|
||||||
{
|
{
|
||||||
qhVertex* v = m_freeVertices;
|
qhVertex* v = m_freeVertices;
|
||||||
@ -197,4 +193,19 @@ inline void qhHull::FreeFace(qhFace* f)
|
|||||||
f->state = qhFace::e_deleted;
|
f->state = qhFace::e_deleted;
|
||||||
f->freeNext = m_freeFaces;
|
f->freeNext = m_freeFaces;
|
||||||
m_freeFaces = f;
|
m_freeFaces = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline qhHalfEdge* qhHull::FindTwin(const qhVertex* tail, const qhVertex* head) const
|
||||||
|
{
|
||||||
|
qhFace* face = m_faceList.head;
|
||||||
|
while (face)
|
||||||
|
{
|
||||||
|
qhHalfEdge* e = face->FindTwin(tail, head);
|
||||||
|
if (e)
|
||||||
|
{
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
face = face->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
@ -20,7 +20,7 @@
|
|||||||
#include <bounce/common/template/stack.h>
|
#include <bounce/common/template/stack.h>
|
||||||
#include <bounce/common/draw.h>
|
#include <bounce/common/draw.h>
|
||||||
|
|
||||||
static float32 qhFindAABB(u32 iMin[3], u32 iMax[3], const b3Array<b3Vec3>& vertices)
|
static float32 qhFindAABB(u32 iMin[3], u32 iMax[3], const b3Vec3* vertices, u32 count)
|
||||||
{
|
{
|
||||||
b3Vec3 min(B3_MAX_FLOAT, B3_MAX_FLOAT, B3_MAX_FLOAT);
|
b3Vec3 min(B3_MAX_FLOAT, B3_MAX_FLOAT, B3_MAX_FLOAT);
|
||||||
iMin[0] = 0;
|
iMin[0] = 0;
|
||||||
@ -32,21 +32,21 @@ static float32 qhFindAABB(u32 iMin[3], u32 iMax[3], const b3Array<b3Vec3>& verti
|
|||||||
iMax[1] = 0;
|
iMax[1] = 0;
|
||||||
iMax[2] = 0;
|
iMax[2] = 0;
|
||||||
|
|
||||||
for (u32 i = 0; i < vertices.Count(); ++i)
|
for (u32 i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
b3Vec3 p = vertices[i];
|
b3Vec3 v = vertices[i];
|
||||||
|
|
||||||
for (u32 j = 0; j < 3; ++j)
|
for (u32 j = 0; j < 3; ++j)
|
||||||
{
|
{
|
||||||
if (p[j] < min[j])
|
if (v[j] < min[j])
|
||||||
{
|
{
|
||||||
min[j] = p[j];
|
min[j] = v[j];
|
||||||
iMin[j] = i;
|
iMin[j] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p[j] > max[j])
|
if (v[j] > max[j])
|
||||||
{
|
{
|
||||||
max[j] = p[j];
|
max[j] = v[j];
|
||||||
iMax[j] = i;
|
iMax[j] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,11 +63,11 @@ qhHull::~qhHull()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void qhHull::Construct(void* memory, const b3Array<b3Vec3>& vs)
|
void qhHull::Construct(void* memory, const b3Vec3* vs, u32 count)
|
||||||
{
|
{
|
||||||
// Euler's formula
|
// Euler's formula
|
||||||
// V - E + F = 2
|
// V - E + F = 2
|
||||||
u32 V = vs.Count();
|
u32 V = count;
|
||||||
u32 E = 3 * V - 6;
|
u32 E = 3 * V - 6;
|
||||||
u32 HE = 2 * E;
|
u32 HE = 2 * E;
|
||||||
u32 F = 2 * V - 4;
|
u32 F = 2 * V - 4;
|
||||||
@ -103,7 +103,7 @@ void qhHull::Construct(void* memory, const b3Array<b3Vec3>& vs)
|
|||||||
m_faceList.count = 0;
|
m_faceList.count = 0;
|
||||||
m_iteration = 0;
|
m_iteration = 0;
|
||||||
|
|
||||||
if (!BuildInitialHull(vs))
|
if (!BuildInitialHull(vs, count))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -119,9 +119,9 @@ void qhHull::Construct(void* memory, const b3Array<b3Vec3>& vs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool qhHull::BuildInitialHull(const b3Array<b3Vec3>& vertices)
|
bool qhHull::BuildInitialHull(const b3Vec3* vertices, u32 vertexCount)
|
||||||
{
|
{
|
||||||
if (vertices.Count() < 4)
|
if (vertexCount < 4)
|
||||||
{
|
{
|
||||||
B3_ASSERT(false);
|
B3_ASSERT(false);
|
||||||
return false;
|
return false;
|
||||||
@ -134,7 +134,7 @@ bool qhHull::BuildInitialHull(const b3Array<b3Vec3>& vertices)
|
|||||||
// canonical axes.
|
// canonical axes.
|
||||||
// Store tolerance for coplanarity checks.
|
// Store tolerance for coplanarity checks.
|
||||||
u32 aabbMin[3], aabbMax[3];
|
u32 aabbMin[3], aabbMax[3];
|
||||||
m_tolerance = qhFindAABB(aabbMin, aabbMax, vertices);
|
m_tolerance = qhFindAABB(aabbMin, aabbMax, vertices, vertexCount);
|
||||||
|
|
||||||
// Find the longest segment.
|
// Find the longest segment.
|
||||||
float32 d0 = 0.0f;
|
float32 d0 = 0.0f;
|
||||||
@ -173,7 +173,7 @@ bool qhHull::BuildInitialHull(const b3Array<b3Vec3>& vertices)
|
|||||||
// Find the triangle which has the largest area.
|
// Find the triangle which has the largest area.
|
||||||
float32 a0 = 0.0f;
|
float32 a0 = 0.0f;
|
||||||
|
|
||||||
for (u32 i = 0; i < vertices.Count(); ++i)
|
for (u32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
if (i == i1 || i == i2)
|
if (i == i1 || i == i2)
|
||||||
{
|
{
|
||||||
@ -214,7 +214,7 @@ bool qhHull::BuildInitialHull(const b3Array<b3Vec3>& vertices)
|
|||||||
// Find the furthest point from the triangle plane.
|
// Find the furthest point from the triangle plane.
|
||||||
float32 d0 = 0.0f;
|
float32 d0 = 0.0f;
|
||||||
|
|
||||||
for (u32 i = 0; i < vertices.Count(); ++i)
|
for (u32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
if (i == i1 || i == i2 || i == i3)
|
if (i == i1 || i == i2 || i == i3)
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@ bool qhHull::BuildInitialHull(const b3Array<b3Vec3>& vertices)
|
|||||||
|
|
||||||
// Add remaining points to the hull.
|
// Add remaining points to the hull.
|
||||||
// Assign closest face plane to each of them.
|
// Assign closest face plane to each of them.
|
||||||
for (u32 i = 0; i < vertices.Count(); ++i)
|
for (u32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
if (i == i1 || i == i2 || i == i3 || i == i4)
|
if (i == i1 || i == i2 || i == i3 || i == i4)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user