abstraction
This commit is contained in:
@ -21,6 +21,8 @@
|
||||
|
||||
#include <bounce/common/geometry.h>
|
||||
|
||||
#define B3_NULL_U32 B3_MAX_U32
|
||||
|
||||
template<class T>
|
||||
struct qhList
|
||||
{
|
||||
@ -31,8 +33,8 @@ struct qhList
|
||||
u32 count;
|
||||
};
|
||||
|
||||
struct qhHalfEdge;
|
||||
struct qhVertex;
|
||||
struct qhHalfEdge;
|
||||
|
||||
enum qhFaceMark
|
||||
{
|
||||
@ -53,13 +55,6 @@ struct qhFace
|
||||
b3Plane plane;
|
||||
|
||||
qhFaceMark mark;
|
||||
|
||||
u32 GetVertexCount() const;
|
||||
u32 GetEdgeCount() const;
|
||||
|
||||
qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const;
|
||||
|
||||
void ComputeCenterAndPlane();
|
||||
|
||||
//
|
||||
qhFace* freeNext;
|
||||
@ -70,6 +65,7 @@ struct qhHalfEdge
|
||||
{
|
||||
qhHalfEdge* prev;
|
||||
qhHalfEdge* next;
|
||||
|
||||
qhHalfEdge* twin;
|
||||
|
||||
qhFace* face;
|
||||
@ -109,15 +105,15 @@ public:
|
||||
// Use qhGetBufferSize to get the buffer size given the number of points.
|
||||
void Construct(void* buffer, const b3Vec3* vertices, u32 vertexCount);
|
||||
|
||||
// Get the number of iterations this algorithm ran.
|
||||
u32 GetIterations() const;
|
||||
|
||||
// Get the list of vertices in this convex hull.
|
||||
const qhList<qhVertex>& GetVertexList() const;
|
||||
|
||||
// Get the list of faces in this convex hull.
|
||||
const qhList<qhFace>& GetFaceList() const;
|
||||
|
||||
// Get the number of iterations this algorithm ran.
|
||||
u32 GetIterations() const;
|
||||
|
||||
// Validate this hull.
|
||||
void Validate() const;
|
||||
void Validate(const qhFace* face) const;
|
||||
@ -126,25 +122,34 @@ public:
|
||||
// Draw this hull.
|
||||
void Draw() const;
|
||||
private:
|
||||
bool BuildInitialHull(const b3Vec3* vertices, u32 count);
|
||||
|
||||
//
|
||||
qhVertex* AddVertex(const b3Vec3& position);
|
||||
|
||||
|
||||
qhFace* RemoveEdge(qhHalfEdge* edge);
|
||||
|
||||
qhFace* AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3);
|
||||
qhFace* RemoveFace(qhFace* face);
|
||||
|
||||
qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const;
|
||||
|
||||
//
|
||||
bool BuildInitialHull(const b3Vec3* vertices, u32 count);
|
||||
|
||||
qhVertex* FindEyeVertex() const;
|
||||
void AddEyeVertex(qhVertex* eye);
|
||||
|
||||
void FindHorizon(qhVertex* eye);
|
||||
|
||||
void AddNewFaces(qhVertex* eye);
|
||||
qhFace* AddNewFace(qhVertex* v1, qhVertex* v2, qhVertex* v3);
|
||||
|
||||
|
||||
void MergeFaces();
|
||||
bool MergeFace(qhFace* face);
|
||||
|
||||
qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const;
|
||||
// List of vertices
|
||||
qhList<qhVertex> m_vertexList;
|
||||
|
||||
// List of faces
|
||||
qhList<qhFace> m_faceList;
|
||||
|
||||
// Coplanarity tolerance
|
||||
float32 m_tolerance;
|
||||
@ -152,12 +157,6 @@ private:
|
||||
// Number of Quickhull iterations
|
||||
u32 m_iterations;
|
||||
|
||||
// List of vertices
|
||||
qhList<qhVertex> m_vertexList;
|
||||
|
||||
// List of faces
|
||||
qhList<qhFace> m_faceList;
|
||||
|
||||
// Memory
|
||||
qhVertex* AllocateVertex();
|
||||
void FreeVertex(qhVertex* p);
|
||||
@ -174,7 +173,11 @@ private:
|
||||
|
||||
qhHalfEdge** m_horizon;
|
||||
u32 m_horizonCount;
|
||||
qhVertex** m_horizonVertices;
|
||||
|
||||
qhVertex** m_conflictVertices;
|
||||
u32 m_conflictCount;
|
||||
|
||||
qhFace** m_newFaces;
|
||||
u32 m_newFaceCount;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
// qhHull.h
|
||||
|
||||
// Lists
|
||||
// qhList
|
||||
|
||||
template<class T>
|
||||
inline void qhList<T>::PushFront(T* link)
|
||||
@ -40,83 +40,6 @@ inline T* qhList<T>::Remove(T* link)
|
||||
return next;
|
||||
}
|
||||
|
||||
// qhFace
|
||||
|
||||
inline u32 qhFace::GetVertexCount() const
|
||||
{
|
||||
u32 count = 0;
|
||||
qhHalfEdge* e = edge;
|
||||
do
|
||||
{
|
||||
++count;
|
||||
e = e->next;
|
||||
} while (e != edge);
|
||||
return count;
|
||||
}
|
||||
|
||||
inline u32 qhFace::GetEdgeCount() const
|
||||
{
|
||||
u32 count = 0;
|
||||
qhHalfEdge* e = edge;
|
||||
do
|
||||
{
|
||||
++count;
|
||||
e = e->next;
|
||||
} while (e != edge);
|
||||
return count;
|
||||
}
|
||||
|
||||
inline qhHalfEdge* qhFace::FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const
|
||||
{
|
||||
qhHalfEdge* e = edge;
|
||||
do
|
||||
{
|
||||
if (e->tail == v1 && e->next->tail == v2)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
} while (e != edge);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
inline void qhFace::ComputeCenterAndPlane()
|
||||
{
|
||||
b3Vec3 c;
|
||||
c.SetZero();
|
||||
|
||||
b3Vec3 n;
|
||||
n.SetZero();
|
||||
|
||||
u32 count = 0;
|
||||
qhHalfEdge* e = edge;
|
||||
do
|
||||
{
|
||||
b3Vec3 v1 = e->tail->position;
|
||||
b3Vec3 v2 = e->next->tail->position;
|
||||
|
||||
n += b3Newell(v1, v2);
|
||||
c += v1;
|
||||
|
||||
++count;
|
||||
e = e->next;
|
||||
} while (e != edge);
|
||||
|
||||
B3_ASSERT(count > 0);
|
||||
c /= float32(count);
|
||||
n.Normalize();
|
||||
plane.normal = n;
|
||||
plane.offset = b3Dot(n, c);
|
||||
center = c;
|
||||
}
|
||||
|
||||
// qhHull
|
||||
|
||||
// Given a number of points return the required memory size in
|
||||
@ -135,13 +58,16 @@ inline u32 qhGetBufferSize(u32 pointCount)
|
||||
size += HE * sizeof(qhHalfEdge);
|
||||
size += F * sizeof(qhFace);
|
||||
|
||||
// Extra
|
||||
size += HE * sizeof(qhHalfEdge);
|
||||
size += F * sizeof(qhFace);
|
||||
|
||||
// Horizon
|
||||
// Horizon
|
||||
size += HE * sizeof(qhHalfEdge*);
|
||||
|
||||
// Saved horizon vertices
|
||||
// One vertex per horizon edge
|
||||
size += HE * sizeof(qhVertex*);
|
||||
|
||||
// Saved conflict vertices
|
||||
size += V * sizeof(qhVertex*);
|
||||
|
||||
// New Faces
|
||||
// One face per horizon edge
|
||||
size += HE * sizeof(qhFace*);
|
||||
@ -149,11 +75,6 @@ inline u32 qhGetBufferSize(u32 pointCount)
|
||||
return size;
|
||||
}
|
||||
|
||||
inline u32 qhHull::GetIterations() const
|
||||
{
|
||||
return m_iterations;
|
||||
}
|
||||
|
||||
inline const qhList<qhVertex>& qhHull::GetVertexList() const
|
||||
{
|
||||
return m_vertexList;
|
||||
@ -164,6 +85,11 @@ inline const qhList<qhFace>& qhHull::GetFaceList() const
|
||||
return m_faceList;
|
||||
}
|
||||
|
||||
inline u32 qhHull::GetIterations() const
|
||||
{
|
||||
return m_iterations;
|
||||
}
|
||||
|
||||
inline qhVertex* qhHull::AllocateVertex()
|
||||
{
|
||||
qhVertex* v = m_freeVertices;
|
||||
@ -219,11 +145,21 @@ inline qhHalfEdge* qhHull::FindHalfEdge(const qhVertex* v1, const qhVertex* v2)
|
||||
{
|
||||
for (qhFace* face = m_faceList.head; face != NULL; face = face->next)
|
||||
{
|
||||
qhHalfEdge* e = face->FindHalfEdge(v1, v2);
|
||||
if (e)
|
||||
qhHalfEdge* e = face->edge;
|
||||
do
|
||||
{
|
||||
return e;
|
||||
}
|
||||
if (e->tail == v1 && e->next->tail == v2)
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
if (e->tail == v2 && e->next->tail == v1)
|
||||
{
|
||||
return e->twin;
|
||||
}
|
||||
|
||||
e = e->next;
|
||||
} while (e != face->edge);
|
||||
}
|
||||
return NULL;
|
||||
}
|
Reference in New Issue
Block a user