From bd490d7925bb8b649584d1a8e6faffc08fdf999c Mon Sep 17 00:00:00 2001 From: Irlan <-> Date: Fri, 27 Apr 2018 02:38:38 -0300 Subject: [PATCH] consistency --- include/bounce/quickhull/qh_hull.h | 46 ++++++----- include/bounce/quickhull/qh_hull.inl | 15 +++- src/bounce/quickhull/qh_hull.cpp | 110 +++++++++++++++------------ 3 files changed, 95 insertions(+), 76 deletions(-) diff --git a/include/bounce/quickhull/qh_hull.h b/include/bounce/quickhull/qh_hull.h index 521e65d..78c6723 100644 --- a/include/bounce/quickhull/qh_hull.h +++ b/include/bounce/quickhull/qh_hull.h @@ -34,49 +34,40 @@ struct qhList struct qhHalfEdge; struct qhVertex; +enum qhFaceMark +{ + e_visible, + e_invisible +}; + struct qhFace { - enum State - { - e_invisible, - e_visible, - e_unknown, - e_deleted - }; - - qhFace* freeNext; - qhFace* prev; qhFace* next; qhHalfEdge* edge; qhList conflictList; - - State state; + b3Vec3 center; b3Plane plane; + qhFaceMark mark; + u32 GetVertexCount() const; u32 GetEdgeCount() const; qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const; void ComputeCenterAndPlane(); + + // + qhFace* freeNext; + bool active; }; struct qhHalfEdge { - enum State - { - e_used, - e_deleted - }; - - State state; - - qhHalfEdge* freeNext; - qhVertex* tail; qhHalfEdge* prev; @@ -84,18 +75,24 @@ struct qhHalfEdge qhHalfEdge* twin; qhFace* face; + + // + qhHalfEdge* freeNext; + bool active; }; struct qhVertex { - qhVertex* freeNext; - qhVertex* prev; qhVertex* next; b3Vec3 position; qhFace* conflictFace; + + // + qhVertex* freeNext; + bool active; }; // A convex hull builder. @@ -128,6 +125,7 @@ public: private: bool BuildInitialHull(const b3Vec3* vertices, u32 count); qhFace* AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3); + qhFace* RemoveFace(qhFace* face); qhVertex* FindEyeVertex() const; void AddVertex(qhVertex* v); diff --git a/include/bounce/quickhull/qh_hull.inl b/include/bounce/quickhull/qh_hull.inl index 6972da7..5ca8dcc 100644 --- a/include/bounce/quickhull/qh_hull.inl +++ b/include/bounce/quickhull/qh_hull.inl @@ -162,12 +162,16 @@ inline const qhList& qhHull::GetFaceList() const inline qhVertex* qhHull::AllocateVertex() { qhVertex* v = m_freeVertices; + B3_ASSERT(v->active == false); + v->active = true; m_freeVertices = v->freeNext; return v; } inline void qhHull::FreeVertex(qhVertex* v) { + //B3_ASSERT(v->active == true); + v->active = false; v->freeNext = m_freeVertices; m_freeVertices = v; } @@ -175,14 +179,16 @@ inline void qhHull::FreeVertex(qhVertex* v) inline qhHalfEdge* qhHull::AllocateEdge() { qhHalfEdge* e = m_freeEdges; - e->state = qhHalfEdge::e_used; + B3_ASSERT(e->active == false); + e->active = true; m_freeEdges = e->freeNext; return e; } inline void qhHull::FreeEdge(qhHalfEdge* e) { - e->state = qhHalfEdge::e_deleted; + //B3_ASSERT(e->active == true); + e->active = false; e->freeNext = m_freeEdges; m_freeEdges = e; } @@ -190,13 +196,16 @@ inline void qhHull::FreeEdge(qhHalfEdge* e) inline qhFace* qhHull::AllocateFace() { qhFace* f = m_freeFaces; + B3_ASSERT(f->active == false); + f->active = true; m_freeFaces = f->freeNext; return f; } inline void qhHull::FreeFace(qhFace* f) { - f->state = qhFace::e_deleted; + //B3_ASSERT(f->active == true); + f->active = false; f->freeNext = m_freeFaces; m_freeFaces = f; } diff --git a/src/bounce/quickhull/qh_hull.cpp b/src/bounce/quickhull/qh_hull.cpp index b10619d..b95ec90 100644 --- a/src/bounce/quickhull/qh_hull.cpp +++ b/src/bounce/quickhull/qh_hull.cpp @@ -352,17 +352,17 @@ void qhHull::AddVertex(qhVertex* eye) void qhHull::FindHorizon(qhVertex* eye) { - // Classify faces + // Mark faces for (qhFace* face = m_faceList.head; face != NULL; face = face->next) { float32 d = b3Distance(eye->position, face->plane); if (d > m_tolerance) { - face->state = qhFace::e_visible; + face->mark = qhFaceMark::e_visible; } else { - face->state = qhFace::e_invisible; + face->mark = qhFaceMark::e_invisible; } } @@ -370,7 +370,7 @@ void qhHull::FindHorizon(qhVertex* eye) m_horizonCount = 0; for (qhFace* face = m_faceList.head; face != NULL; face = face->next) { - if (face->state == qhFace::e_invisible) + if (face->mark == qhFaceMark::e_invisible) { continue; } @@ -382,7 +382,7 @@ void qhHull::FindHorizon(qhVertex* eye) qhHalfEdge* twin = edge->twin; qhFace* other = twin->face; - if (other->state == qhFace::e_invisible) + if (other->mark == qhFaceMark::e_invisible) { m_horizon[m_horizonCount++] = edge; } @@ -453,16 +453,14 @@ void qhHull::AddNewFaces(qhVertex* eye) while (f) { // Invisible faces are maintained. - if (f->state == qhFace::e_invisible) + if (f->mark == qhFaceMark::e_invisible) { f = f->next; continue; } - // Remove the face - - // Assign orphaned vertices to the new faces - // Also discard internal points + // Move the orphaned vertices into the new faces + // Also remove internal points qhVertex* v = f->conflictList.head; while (v) { @@ -499,37 +497,21 @@ void qhHull::AddNewFaces(qhVertex* eye) } } - // Remove face half-edges - qhHalfEdge* e = f->edge; - do - { - if (e->twin) - { - e->twin = NULL; - } - - qhHalfEdge* e0 = e; - e = e->next; - FreeEdge(e0); - } while (e != f->edge); - - // Remove face - qhFace* f0 = f; - f = m_faceList.Remove(f); - FreeFace(f0); + // Remove the face + f = RemoveFace(f); } - // Connect the created faces with the remaining faces in the hull + // Add the new faces to the hull for (u32 i = 0; i < m_newFaceCount; ++i) { qhFace* face = m_newFaces[i]; - + qhHalfEdge* begin = face->edge; qhHalfEdge* edge = begin; do { qhVertex* v1 = edge->tail; - + qhHalfEdge* next = edge->next; qhVertex* v2 = next->tail; @@ -602,13 +584,40 @@ qhFace* qhHull::AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3) face->edge = e1; face->center = (v1->position + v2->position + v3->position) / 3.0f; face->plane = b3Plane(v1->position, v2->position, v3->position); - face->state = qhFace::e_invisible; m_faceList.PushFront(face); return face; } +qhFace* qhHull::RemoveFace(qhFace* face) +{ + // Remove half-edges + qhHalfEdge* e = face->edge; + do + { + qhHalfEdge* twin = e->twin; + + // Remove half-edge and its twin if twin face does not exist + if (twin->face == NULL || twin->face == e->face) + { + e->twin = NULL; + + FreeEdge(twin); + + qhHalfEdge* e0 = e; + e = e->next; + FreeEdge(e0); + } + + } while (e != face->edge); + + // Remove face + qhFace* nextFace = m_faceList.Remove(face); + FreeFace(face); + return nextFace; +} + qhFace* qhHull::AddNewFace(qhVertex* v1, qhVertex* v2, qhVertex* v3) { qhFace* face = AllocateFace(); @@ -626,7 +635,7 @@ qhFace* qhHull::AddNewFace(qhVertex* v1, qhVertex* v2, qhVertex* v3) qhHalfEdge* e3 = AllocateEdge(); e3->face = face; e3->twin = NULL; - e3->tail = v3; + e3->tail = v3; e1->prev = e3; e1->next = e2; @@ -640,7 +649,6 @@ qhFace* qhHull::AddNewFace(qhVertex* v1, qhVertex* v2, qhVertex* v3) face->edge = e1; face->center = (v1->position + v2->position + v3->position) / 3.0f; face->plane = b3Plane(v1->position, v2->position, v3->position); - face->state = qhFace::e_invisible; face->prev = NULL; face->next = NULL; @@ -729,9 +737,9 @@ void qhHull::MergeFaces() for (u32 i = 0; i < m_newFaceCount; ++i) { qhFace* face = m_newFaces[i]; - - // Was the face merged? - if (face->state == qhFace::e_deleted) + + // Was the face deleted due to merging? + if (face->active == false) { continue; } @@ -743,9 +751,13 @@ void qhHull::MergeFaces() void qhHull::Validate(const qhHalfEdge* edge) const { + B3_ASSERT(edge->active == true); + const qhHalfEdge* twin = edge->twin; B3_ASSERT(twin->twin == edge); + //B3_ASSERT(edge->tail->active == true); + b3Vec3 A = edge->tail->position; b3Vec3 B = twin->tail->position; B3_ASSERT(b3DistanceSquared(A, B) > B3_EPSILON * B3_EPSILON); @@ -766,8 +778,6 @@ void qhHull::Validate(const qhFace* face) const const qhHalfEdge* edge = begin; do { - B3_ASSERT(edge->state != qhHalfEdge::e_deleted); - B3_ASSERT(edge->face == face); qhHalfEdge* twin = edge->twin; @@ -784,23 +794,24 @@ void qhHull::Validate() const { for (qhFace* face = m_faceList.head; face != NULL; face = face->next) { - B3_ASSERT(face->state != face->e_deleted); + B3_ASSERT(face->active == true); + + for (qhVertex* vertex = face->conflictList.head; vertex != NULL; vertex = vertex->next) + { + B3_ASSERT(vertex->active == true); + } + Validate(face); } } void qhHull::Draw() const { - b3StackArray polygon; - - qhFace* face = m_faceList.head; - while (face) + for (qhFace* face = m_faceList.head; face != NULL; face = face->next) { + b3StackArray polygon; polygon.Resize(0); - b3Vec3 c = face->center; - b3Vec3 n = face->plane.normal; - const qhHalfEdge* begin = face->edge; const qhHalfEdge* edge = begin; do @@ -809,6 +820,9 @@ void qhHull::Draw() const edge = edge->next; } while (edge != begin); + b3Vec3 c = face->center; + b3Vec3 n = face->plane.normal; + b3Draw_draw->DrawSolidPolygon(n, polygon.Begin(), polygon.Count(), b3Color(1.0f, 1.0f, 1.0f, 0.5f)); qhVertex* v = face->conflictList.head; @@ -820,7 +834,5 @@ void qhHull::Draw() const } b3Draw_draw->DrawSegment(c, c + n, b3Color(1.0f, 1.0f, 1.0f)); - - face = face->next; } } \ No newline at end of file