bugfix; operations
This commit is contained in:
parent
bd490d7925
commit
abc5f59170
@ -68,19 +68,25 @@ struct qhFace
|
|||||||
|
|
||||||
struct qhHalfEdge
|
struct qhHalfEdge
|
||||||
{
|
{
|
||||||
qhVertex* tail;
|
|
||||||
|
|
||||||
qhHalfEdge* prev;
|
qhHalfEdge* prev;
|
||||||
qhHalfEdge* next;
|
qhHalfEdge* next;
|
||||||
qhHalfEdge* twin;
|
qhHalfEdge* twin;
|
||||||
|
|
||||||
qhFace* face;
|
qhFace* face;
|
||||||
|
|
||||||
|
qhVertex* tail;
|
||||||
|
|
||||||
//
|
//
|
||||||
qhHalfEdge* freeNext;
|
qhHalfEdge* freeNext;
|
||||||
bool active;
|
bool active;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum qhVertexMark
|
||||||
|
{
|
||||||
|
e_conflict,
|
||||||
|
e_hull
|
||||||
|
};
|
||||||
|
|
||||||
struct qhVertex
|
struct qhVertex
|
||||||
{
|
{
|
||||||
qhVertex* prev;
|
qhVertex* prev;
|
||||||
@ -89,6 +95,8 @@ struct qhVertex
|
|||||||
b3Vec3 position;
|
b3Vec3 position;
|
||||||
|
|
||||||
qhFace* conflictFace;
|
qhFace* conflictFace;
|
||||||
|
|
||||||
|
qhVertexMark mark;
|
||||||
|
|
||||||
//
|
//
|
||||||
qhVertex* freeNext;
|
qhVertex* freeNext;
|
||||||
@ -124,6 +132,9 @@ public:
|
|||||||
void Draw() const;
|
void Draw() const;
|
||||||
private:
|
private:
|
||||||
bool BuildInitialHull(const b3Vec3* vertices, u32 count);
|
bool BuildInitialHull(const b3Vec3* vertices, u32 count);
|
||||||
|
|
||||||
|
qhVertex* AddVertex(const b3Vec3& position);
|
||||||
|
|
||||||
qhFace* AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3);
|
qhFace* AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3);
|
||||||
qhFace* RemoveFace(qhFace* face);
|
qhFace* RemoveFace(qhFace* face);
|
||||||
|
|
||||||
|
@ -253,17 +253,10 @@ bool qhHull::BuildInitialHull(const b3Vec3* vertices, u32 vertexCount)
|
|||||||
// Add okay simplex to the hull.
|
// Add okay simplex to the hull.
|
||||||
b3Vec3 D = vertices[i4];
|
b3Vec3 D = vertices[i4];
|
||||||
|
|
||||||
qhVertex* v1 = AllocateVertex();
|
qhVertex* v1 = AddVertex(A);
|
||||||
v1->position = A;
|
qhVertex* v2 = AddVertex(B);
|
||||||
|
qhVertex* v3 = AddVertex(C);
|
||||||
qhVertex* v2 = AllocateVertex();
|
qhVertex* v4 = AddVertex(D);
|
||||||
v2->position = B;
|
|
||||||
|
|
||||||
qhVertex* v3 = AllocateVertex();
|
|
||||||
v3->position = C;
|
|
||||||
|
|
||||||
qhVertex* v4 = AllocateVertex();
|
|
||||||
v4->position = D;
|
|
||||||
|
|
||||||
if (b3Distance(D, plane) < 0.0f)
|
if (b3Distance(D, plane) < 0.0f)
|
||||||
{
|
{
|
||||||
@ -284,10 +277,10 @@ bool qhHull::BuildInitialHull(const b3Vec3* vertices, u32 vertexCount)
|
|||||||
// Connectivity check.
|
// Connectivity check.
|
||||||
Validate();
|
Validate();
|
||||||
|
|
||||||
// Add remaining points to the hull.
|
// Add remaining points to the conflict lists on each face.
|
||||||
// Assign closest face plane to each of them.
|
|
||||||
for (u32 i = 0; i < vertexCount; ++i)
|
for (u32 i = 0; i < vertexCount; ++i)
|
||||||
{
|
{
|
||||||
|
// Skip hull vertices.
|
||||||
if (i == i1 || i == i2 || i == i3 || i == i4)
|
if (i == i1 || i == i2 || i == i3 || i == i4)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -295,7 +288,7 @@ bool qhHull::BuildInitialHull(const b3Vec3* vertices, u32 vertexCount)
|
|||||||
|
|
||||||
b3Vec3 p = vertices[i];
|
b3Vec3 p = vertices[i];
|
||||||
|
|
||||||
// Discard internal points since they can't be in the hull.
|
// Ignore internal points since they can't be in the hull.
|
||||||
float32 d0 = m_tolerance;
|
float32 d0 = m_tolerance;
|
||||||
qhFace* f0 = NULL;
|
qhFace* f0 = NULL;
|
||||||
|
|
||||||
@ -312,6 +305,7 @@ bool qhHull::BuildInitialHull(const b3Vec3* vertices, u32 vertexCount)
|
|||||||
if (f0)
|
if (f0)
|
||||||
{
|
{
|
||||||
qhVertex* v = AllocateVertex();
|
qhVertex* v = AllocateVertex();
|
||||||
|
v->mark = qhVertexMark::e_conflict;
|
||||||
v->position = p;
|
v->position = p;
|
||||||
v->conflictFace = f0;
|
v->conflictFace = f0;
|
||||||
f0->conflictList.PushFront(v);
|
f0->conflictList.PushFront(v);
|
||||||
@ -331,6 +325,11 @@ qhVertex* qhHull::FindEyeVertex() const
|
|||||||
{
|
{
|
||||||
for (qhVertex* v = f->conflictList.head; v != NULL; v = v->next)
|
for (qhVertex* v = f->conflictList.head; v != NULL; v = v->next)
|
||||||
{
|
{
|
||||||
|
if (v->mark == qhVertexMark::e_hull)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
float32 d = b3Distance(v->position, f->plane);
|
float32 d = b3Distance(v->position, f->plane);
|
||||||
if (d > d0)
|
if (d > d0)
|
||||||
{
|
{
|
||||||
@ -391,15 +390,6 @@ void qhHull::FindHorizon(qhVertex* eye)
|
|||||||
} while (edge != begin);
|
} while (edge != begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure unique edges
|
|
||||||
for (u32 i = 0; i < m_horizonCount; ++i)
|
|
||||||
{
|
|
||||||
for (u32 j = i + 1; j < m_horizonCount; ++j)
|
|
||||||
{
|
|
||||||
B3_ASSERT(m_horizon[i] != m_horizon[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the horizon in CCW order
|
// Sort the horizon in CCW order
|
||||||
B3_ASSERT(m_horizonCount > 0);
|
B3_ASSERT(m_horizonCount > 0);
|
||||||
for (u32 i = 0; i < m_horizonCount - 1; ++i)
|
for (u32 i = 0; i < m_horizonCount - 1; ++i)
|
||||||
@ -409,6 +399,9 @@ void qhHull::FindHorizon(qhVertex* eye)
|
|||||||
|
|
||||||
for (u32 j = i + 1; j < m_horizonCount; ++j)
|
for (u32 j = i + 1; j < m_horizonCount; ++j)
|
||||||
{
|
{
|
||||||
|
// Ensure unique edges
|
||||||
|
B3_ASSERT(m_horizon[i] != m_horizon[j]);
|
||||||
|
|
||||||
qhHalfEdge* e2 = m_horizon[j];
|
qhHalfEdge* e2 = m_horizon[j];
|
||||||
qhVertex* v2 = e2->tail;
|
qhVertex* v2 = e2->tail;
|
||||||
|
|
||||||
@ -442,6 +435,8 @@ void qhHull::AddNewFaces(qhVertex* eye)
|
|||||||
qhHalfEdge* edge = m_horizon[i];
|
qhHalfEdge* edge = m_horizon[i];
|
||||||
|
|
||||||
qhVertex* v1 = eye;
|
qhVertex* v1 = eye;
|
||||||
|
v1->mark = qhVertexMark::e_hull;
|
||||||
|
|
||||||
qhVertex* v2 = edge->tail;
|
qhVertex* v2 = edge->tail;
|
||||||
qhVertex* v3 = edge->twin->tail;
|
qhVertex* v3 = edge->twin->tail;
|
||||||
|
|
||||||
@ -464,6 +459,12 @@ void qhHull::AddNewFaces(qhVertex* eye)
|
|||||||
qhVertex* v = f->conflictList.head;
|
qhVertex* v = f->conflictList.head;
|
||||||
while (v)
|
while (v)
|
||||||
{
|
{
|
||||||
|
if (v->mark == qhVertexMark::e_hull)
|
||||||
|
{
|
||||||
|
v = v->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
b3Vec3 p = v->position;
|
b3Vec3 p = v->position;
|
||||||
|
|
||||||
float32 max = m_tolerance;
|
float32 max = m_tolerance;
|
||||||
@ -529,6 +530,14 @@ void qhHull::AddNewFaces(qhVertex* eye)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qhVertex* qhHull::AddVertex(const b3Vec3& position)
|
||||||
|
{
|
||||||
|
qhVertex* v = AllocateVertex();
|
||||||
|
v->mark = qhVertexMark::e_hull;
|
||||||
|
v->position = position;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
qhFace* qhHull::AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3)
|
qhFace* qhHull::AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3)
|
||||||
{
|
{
|
||||||
qhFace* face = AllocateFace();
|
qhFace* face = AllocateFace();
|
||||||
@ -754,13 +763,22 @@ void qhHull::Validate(const qhHalfEdge* edge) const
|
|||||||
B3_ASSERT(edge->active == true);
|
B3_ASSERT(edge->active == true);
|
||||||
|
|
||||||
const qhHalfEdge* twin = edge->twin;
|
const qhHalfEdge* twin = edge->twin;
|
||||||
|
B3_ASSERT(twin->active == true);
|
||||||
B3_ASSERT(twin->twin == edge);
|
B3_ASSERT(twin->twin == edge);
|
||||||
|
|
||||||
//B3_ASSERT(edge->tail->active == true);
|
B3_ASSERT(edge->tail->active == true);
|
||||||
|
B3_ASSERT(edge->tail->mark == qhVertexMark::e_hull);
|
||||||
b3Vec3 A = edge->tail->position;
|
b3Vec3 A = edge->tail->position;
|
||||||
|
|
||||||
|
B3_ASSERT(twin->tail->mark == qhVertexMark::e_hull);
|
||||||
|
B3_ASSERT(twin->tail->active == true);
|
||||||
b3Vec3 B = twin->tail->position;
|
b3Vec3 B = twin->tail->position;
|
||||||
|
|
||||||
B3_ASSERT(b3DistanceSquared(A, B) > B3_EPSILON * B3_EPSILON);
|
B3_ASSERT(b3DistanceSquared(A, B) > B3_EPSILON * B3_EPSILON);
|
||||||
|
|
||||||
|
const qhHalfEdge* next = edge->next;
|
||||||
|
B3_ASSERT(next->active == true);
|
||||||
|
B3_ASSERT(twin->tail == next->tail);
|
||||||
|
|
||||||
u32 count = 0;
|
u32 count = 0;
|
||||||
const qhHalfEdge* begin = edge;
|
const qhHalfEdge* begin = edge;
|
||||||
@ -774,17 +792,15 @@ void qhHull::Validate(const qhHalfEdge* edge) const
|
|||||||
|
|
||||||
void qhHull::Validate(const qhFace* face) const
|
void qhHull::Validate(const qhFace* face) const
|
||||||
{
|
{
|
||||||
|
B3_ASSERT(face->active == true);
|
||||||
|
|
||||||
const qhHalfEdge* begin = face->edge;
|
const qhHalfEdge* begin = face->edge;
|
||||||
const qhHalfEdge* edge = begin;
|
const qhHalfEdge* edge = begin;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
B3_ASSERT(edge->active == true);
|
||||||
B3_ASSERT(edge->face == face);
|
B3_ASSERT(edge->face == face);
|
||||||
|
edge = edge->next;
|
||||||
qhHalfEdge* twin = edge->twin;
|
|
||||||
qhHalfEdge* next = edge->next;
|
|
||||||
B3_ASSERT(twin->tail == next->tail);
|
|
||||||
|
|
||||||
edge = next;
|
|
||||||
} while (edge != begin);
|
} while (edge != begin);
|
||||||
|
|
||||||
Validate(face->edge);
|
Validate(face->edge);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user