mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 20:54:46 +00:00
581 lines
13 KiB
C++
581 lines
13 KiB
C++
|
|
#include "math/util/decomposePoly.h"
|
||
|
|
|
||
|
|
// twoIndices Methods
|
||
|
|
|
||
|
|
twoIndices::twoIndices()
|
||
|
|
{
|
||
|
|
i1 = i2 = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices::twoIndices(U8 a, U8 b)
|
||
|
|
{
|
||
|
|
i1 = a;
|
||
|
|
i2 = b;
|
||
|
|
}
|
||
|
|
|
||
|
|
// decompTri Methods
|
||
|
|
|
||
|
|
decompTri::decompTri()
|
||
|
|
{
|
||
|
|
mVertIdx[0] = 0;
|
||
|
|
mVertIdx[1] = 0;
|
||
|
|
mVertIdx[2] = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompTri::orderVerts()
|
||
|
|
{
|
||
|
|
// Bubble sort, smallest to largest
|
||
|
|
U8 temp;
|
||
|
|
|
||
|
|
for (U8 i = 2; i > 0; i--)
|
||
|
|
{
|
||
|
|
for (U8 j = 0; j < i; j++)
|
||
|
|
{
|
||
|
|
if (mVertIdx[j] > mVertIdx[j + 1])
|
||
|
|
{
|
||
|
|
temp = mVertIdx[j];
|
||
|
|
mVertIdx[j] = mVertIdx[j + 1];
|
||
|
|
mVertIdx[j + 1] = temp;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompTri::setVert(U8 val, U8 idx)
|
||
|
|
{
|
||
|
|
if(idx < 3)
|
||
|
|
mVertIdx[idx] = val;
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompTri::getVert(U8 idx)
|
||
|
|
{
|
||
|
|
if(idx < 3)
|
||
|
|
return mVertIdx[idx];
|
||
|
|
|
||
|
|
return mVertIdx[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompTri::getOtherVerts(U8 idx)
|
||
|
|
{
|
||
|
|
if(idx == mVertIdx[0])
|
||
|
|
return twoIndices(mVertIdx[1], mVertIdx[2]);
|
||
|
|
|
||
|
|
if(idx == mVertIdx[1])
|
||
|
|
return twoIndices(mVertIdx[0], mVertIdx[2]);
|
||
|
|
|
||
|
|
if(idx == mVertIdx[2])
|
||
|
|
return twoIndices(mVertIdx[0], mVertIdx[1]);
|
||
|
|
|
||
|
|
return twoIndices(0,0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// decompPoly Methods
|
||
|
|
|
||
|
|
void decompPoly::addVert(Point3F &newVert)
|
||
|
|
{
|
||
|
|
bool found = false;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(newVert == mVertList[i])
|
||
|
|
found = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!found)
|
||
|
|
mVertList.push_back(newVert);
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompPoly::initEdgeList()
|
||
|
|
{
|
||
|
|
mEdgeList.clear();
|
||
|
|
|
||
|
|
S32 next = 0;
|
||
|
|
|
||
|
|
for(S32 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(i == mVertList.size()-1)
|
||
|
|
next = 0;
|
||
|
|
else
|
||
|
|
next = i+1;
|
||
|
|
|
||
|
|
mEdgeList.push_back(twoIndices(i, next));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
bool decompPoly::sameSide(Point3F &p1, Point3F &p2, Point3F &l1, Point3F &l2)
|
||
|
|
{
|
||
|
|
return ((p1.x-l1.x)*(l2.y-l1.y)-(l2.x-l1.x)*(p1.y-l1.y))*((p2.x-l1.x)*(l2.y-l1.y)-(l2.x-l1.x)*(p2.y-l1.y)) > 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool decompPoly::isInside(decompTri &tri, U8 vertIdx)
|
||
|
|
{
|
||
|
|
Point3F a(mVertList[tri.getVert(0)]);
|
||
|
|
Point3F b(mVertList[tri.getVert(1)]);
|
||
|
|
Point3F c(mVertList[tri.getVert(2)]);
|
||
|
|
Point3F p(mVertList[vertIdx]);
|
||
|
|
|
||
|
|
return (sameSide(p,a,b,c) && sameSide(p,b,a,c) && sameSide(p,c,a,b));
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompPoly::leftmost()
|
||
|
|
{
|
||
|
|
F32 xMin = 9999999.f;
|
||
|
|
U8 idx = 0;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mVertList[i].x < xMin && isVertInEdgeList(i))
|
||
|
|
{
|
||
|
|
xMin = mVertList[i].x;
|
||
|
|
idx = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return idx;
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompPoly::rightmost()
|
||
|
|
{
|
||
|
|
F32 xMax = -9999999.f;
|
||
|
|
U8 idx = 0;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mVertList[i].x > xMax && isVertInEdgeList(i))
|
||
|
|
{
|
||
|
|
xMax = mVertList[i].x;
|
||
|
|
idx = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return idx;
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompPoly::uppermost()
|
||
|
|
{
|
||
|
|
F32 yMax = -9999999.f;
|
||
|
|
U8 idx = 0;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mVertList[i].y > yMax && isVertInEdgeList(i))
|
||
|
|
{
|
||
|
|
yMax = mVertList[i].y;
|
||
|
|
idx = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return idx;
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompPoly::lowermost()
|
||
|
|
{
|
||
|
|
F32 yMin = 9999999.f;
|
||
|
|
U8 idx = 0;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mVertList[i].y < yMin && isVertInEdgeList(i))
|
||
|
|
{
|
||
|
|
yMin = mVertList[i].y;
|
||
|
|
idx = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return idx;
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompPoly::findEdges(U8 vertIdx, bool ¬Unique)
|
||
|
|
{
|
||
|
|
U8 found = 0;
|
||
|
|
U8 edgeIdx[2];
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mEdgeList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mEdgeList[i].i1 == vertIdx || mEdgeList[i].i2 == vertIdx)
|
||
|
|
{
|
||
|
|
edgeIdx[found++] = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
notUnique = found > 2;
|
||
|
|
|
||
|
|
return twoIndices(edgeIdx[0], edgeIdx[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
decompTri decompPoly::formTriFromEdges(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
decompTri tri;
|
||
|
|
|
||
|
|
tri.setVert(mEdgeList[idx1].i1, 0);
|
||
|
|
tri.setVert(mEdgeList[idx1].i2, 1);
|
||
|
|
|
||
|
|
if(mEdgeList[idx2].i1 == tri.getVert(0) || mEdgeList[idx2].i1 == tri.getVert(1))
|
||
|
|
{
|
||
|
|
tri.setVert(mEdgeList[idx2].i2, 2);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
tri.setVert(mEdgeList[idx2].i1, 2);
|
||
|
|
}
|
||
|
|
|
||
|
|
return tri;
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompPoly::leftmostInsideVerts(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
F32 xMin = 9999999.f;
|
||
|
|
S32 left[] = {-1, -1};
|
||
|
|
|
||
|
|
for(U8 i = 0; i < 2; i++)
|
||
|
|
{
|
||
|
|
for(U8 j = 0; j < mInsideVerts.size(); j++)
|
||
|
|
{
|
||
|
|
if(mVertList[mInsideVerts[j]].x < xMin && mInsideVerts[j] != left[0])
|
||
|
|
{
|
||
|
|
xMin = mVertList[mInsideVerts[j]].x;
|
||
|
|
left[i] = mInsideVerts[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx1].x < xMin && idx1 != left[0])
|
||
|
|
{
|
||
|
|
xMin = mVertList[idx1].x;
|
||
|
|
left[i] = idx1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx2].x < xMin && idx2 != left[0])
|
||
|
|
{
|
||
|
|
xMin = mVertList[idx2].x;
|
||
|
|
left[i] = idx2;
|
||
|
|
}
|
||
|
|
|
||
|
|
xMin = 9999999.f;
|
||
|
|
}
|
||
|
|
|
||
|
|
return twoIndices(left[0], left[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompPoly::rightmostInsideVerts(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
F32 xMax = -9999999.f;
|
||
|
|
S32 right[] = {-1, -1};
|
||
|
|
|
||
|
|
for(U8 i = 0; i < 2; i++)
|
||
|
|
{
|
||
|
|
for(U8 j = 0; j < mInsideVerts.size(); j++)
|
||
|
|
{
|
||
|
|
if(mVertList[mInsideVerts[j]].x > xMax && mInsideVerts[j] != right[0])
|
||
|
|
{
|
||
|
|
xMax = mVertList[mInsideVerts[j]].x;
|
||
|
|
right[i] = mInsideVerts[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx1].x > xMax && idx1 != right[0])
|
||
|
|
{
|
||
|
|
xMax = mVertList[idx1].x;
|
||
|
|
right[i] = idx1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx2].x > xMax && idx2 != right[0])
|
||
|
|
{
|
||
|
|
xMax = mVertList[idx2].x;
|
||
|
|
right[i] = idx2;
|
||
|
|
}
|
||
|
|
|
||
|
|
xMax = -9999999.f;
|
||
|
|
}
|
||
|
|
|
||
|
|
return twoIndices(right[0], right[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompPoly::uppermostInsideVerts(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
F32 yMax = -9999999.f;
|
||
|
|
S32 up[] = {-1, -1};
|
||
|
|
|
||
|
|
for(U8 i = 0; i < 2; i++)
|
||
|
|
{
|
||
|
|
for(U8 j = 0; j < mInsideVerts.size(); j++)
|
||
|
|
{
|
||
|
|
if(mVertList[mInsideVerts[j]].y > yMax && mInsideVerts[j] != up[0])
|
||
|
|
{
|
||
|
|
yMax = mVertList[mInsideVerts[j]].y;
|
||
|
|
up[i] = mInsideVerts[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx1].y > yMax && idx1 != up[0])
|
||
|
|
{
|
||
|
|
yMax = mVertList[idx1].y;
|
||
|
|
up[i] = idx1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx2].y > yMax && idx2 != up[0])
|
||
|
|
{
|
||
|
|
yMax = mVertList[idx2].y;
|
||
|
|
up[i] = idx2;
|
||
|
|
}
|
||
|
|
|
||
|
|
yMax = -9999999.f;
|
||
|
|
}
|
||
|
|
|
||
|
|
return twoIndices(up[0], up[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
twoIndices decompPoly::lowermostInsideVerts(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
F32 yMin = 9999999.f;
|
||
|
|
S32 down[] = {-1, -1};
|
||
|
|
|
||
|
|
for(U8 i = 0; i < 2; i++)
|
||
|
|
{
|
||
|
|
for(U8 j = 0; j < mInsideVerts.size(); j++)
|
||
|
|
{
|
||
|
|
if(mVertList[mInsideVerts[j]].y < yMin && mInsideVerts[j] != down[0])
|
||
|
|
{
|
||
|
|
yMin = mVertList[mInsideVerts[j]].y;
|
||
|
|
down[i] = mInsideVerts[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx1].y < yMin && idx1 != down[0])
|
||
|
|
{
|
||
|
|
yMin = mVertList[idx1].y;
|
||
|
|
down[i] = idx1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(mVertList[idx2].y < yMin && idx2 != down[0])
|
||
|
|
{
|
||
|
|
yMin = mVertList[idx2].y;
|
||
|
|
down[i] = idx2;
|
||
|
|
}
|
||
|
|
|
||
|
|
yMin = 9999999.f;
|
||
|
|
}
|
||
|
|
|
||
|
|
return twoIndices(down[0], down[1]);
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompPoly::findPointsInside()
|
||
|
|
{
|
||
|
|
mInsideVerts.clear();
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mVertList.size(); i++)
|
||
|
|
{
|
||
|
|
if(i != mTestTri.getVert(0) && i != mTestTri.getVert(1) && i != mTestTri.getVert(2))
|
||
|
|
{
|
||
|
|
if(isInside(mTestTri, i))
|
||
|
|
{
|
||
|
|
mInsideVerts.push_back(i);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompPoly::addRemoveEdge(U8 idx1, U8 idx2)
|
||
|
|
{
|
||
|
|
twoIndices edge1(idx1, idx2);
|
||
|
|
|
||
|
|
if(!mEdgeList.remove(edge1))
|
||
|
|
mEdgeList.push_back(edge1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void decompPoly::newPoly()
|
||
|
|
{
|
||
|
|
mVertList.clear();
|
||
|
|
mEdgeList.clear();
|
||
|
|
mInsideVerts.clear();
|
||
|
|
mTris.clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool decompPoly::isVertInEdgeList(U8 idx)
|
||
|
|
{
|
||
|
|
for(U8 i = 0; i < mEdgeList.size(); i++)
|
||
|
|
{
|
||
|
|
if(mEdgeList[i].i1 == idx || mEdgeList[i].i2 == idx)
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Point3F decompPoly::getVert(U8 idx)
|
||
|
|
{
|
||
|
|
if(idx < mVertList.size())
|
||
|
|
return mVertList[idx];
|
||
|
|
|
||
|
|
return Point3F(0.0f, 0.0f, 0.0f);
|
||
|
|
}
|
||
|
|
|
||
|
|
U8 decompPoly::getTriIdx(U32 tri, U8 idx)
|
||
|
|
{
|
||
|
|
if(tri < mTris.size() && idx < 3)
|
||
|
|
return mTris[tri].getVert(idx);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool decompPoly::checkEdgeLength(F32 len)
|
||
|
|
{
|
||
|
|
Point3F p1, p2;
|
||
|
|
|
||
|
|
for(U8 i = 0; i < mEdgeList.size(); i++)
|
||
|
|
{
|
||
|
|
p1 = mVertList[mEdgeList[i].i1];
|
||
|
|
p2 = mVertList[mEdgeList[i].i2];
|
||
|
|
|
||
|
|
p1 = p2 - p1;
|
||
|
|
|
||
|
|
if(p1.len() < len)
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//---------------------------------------------------
|
||
|
|
// Concave polygon decomposition into triangles
|
||
|
|
//
|
||
|
|
// Based upon this resource:
|
||
|
|
// http://www.siggraph.org/education/materials/HyperGraph/scanline/outprims/polygon1.htm
|
||
|
|
//
|
||
|
|
// 1. Find leftmost vertex in polygon (smallest value along x-axis).
|
||
|
|
// 2. Find the two edges adjacent to this vertex.
|
||
|
|
// 3. Form a test tri by connecting the open side of these two edges.
|
||
|
|
// 4. See if any of the vertices in the poly, besides the ones that form the test tri, are inside the
|
||
|
|
// test tri.
|
||
|
|
// 5. If there are verts inside, find the 3 leftmost of the inside verts and the test tri verts, form
|
||
|
|
// a new test tri from these verts, and repeat from step 4. When no verts are inside, continue.
|
||
|
|
// 6. Save test tri as a valid triangle.
|
||
|
|
// 7. Remove the edges that the test tri and poly share, and add the new edges from the test tri to
|
||
|
|
// the poly to form a new closed poly with the test tri subtracted out.
|
||
|
|
//
|
||
|
|
// Note: our polygon can contain no more than 255 verts. Complex polygons can create situations where
|
||
|
|
// a vertex has more than 2 adjacent edges, causing step 2 to fail. This method improves on the resource
|
||
|
|
// listed above by not limiting the decomposition to the leftmost side only. If step 2 fails, the
|
||
|
|
// algorithm also tries to decompose the polygon from the top, right, and bottom until one succeeds or
|
||
|
|
// they all fail. If they all fail, the polygon is too complex to be decomposed with this method.
|
||
|
|
|
||
|
|
bool decompPoly::decompose()
|
||
|
|
{
|
||
|
|
// Must have at least 3 verts to form a poly
|
||
|
|
if(mVertList.size() < 3)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
// Clear out any previously stored tris
|
||
|
|
mTris.clear();
|
||
|
|
|
||
|
|
// Initialize the edge list with the default edges
|
||
|
|
initEdgeList();
|
||
|
|
|
||
|
|
twoIndices otherVerts, outerVerts2;
|
||
|
|
U32 counter = 0;
|
||
|
|
U8 uniqueVertAttempt = 0;
|
||
|
|
U8 formTriAttempt = 0;
|
||
|
|
bool notUnique = false;
|
||
|
|
|
||
|
|
// The main decomposition loop
|
||
|
|
while(mEdgeList.size() > 3)
|
||
|
|
{
|
||
|
|
// Find outermost vert in poly, LMV
|
||
|
|
U8 outerVertIdx;
|
||
|
|
|
||
|
|
switch(uniqueVertAttempt)
|
||
|
|
{
|
||
|
|
case 0: outerVertIdx = leftmost(); break;
|
||
|
|
case 1: outerVertIdx = rightmost(); break;
|
||
|
|
case 2: outerVertIdx = uppermost(); break;
|
||
|
|
case 3: outerVertIdx = uppermost(); break;
|
||
|
|
default: outerVertIdx = leftmost();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Find edges that share LMV
|
||
|
|
twoIndices edgesIdx = findEdges(outerVertIdx, notUnique);
|
||
|
|
|
||
|
|
// If vert shares more than two edges, try decomposing from different direction
|
||
|
|
if(notUnique)
|
||
|
|
{
|
||
|
|
if(uniqueVertAttempt < 4)
|
||
|
|
{
|
||
|
|
uniqueVertAttempt++;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
newPoly();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Sanity check
|
||
|
|
if(edgesIdx.i1 >= mEdgeList.size() || edgesIdx.i2 >= mEdgeList.size())
|
||
|
|
{
|
||
|
|
newPoly();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Form the test tri from these 2 edges
|
||
|
|
mTestTri = formTriFromEdges(edgesIdx.i1, edgesIdx.i2);
|
||
|
|
|
||
|
|
// See if there are any other poly verts inside the test tri
|
||
|
|
findPointsInside();
|
||
|
|
|
||
|
|
// If there are verts inside, repeat procedure until there are none
|
||
|
|
while(mInsideVerts.size() > 0 && formTriAttempt++ < mVertList.size())
|
||
|
|
{
|
||
|
|
// Get the two verts of the test tri that are not the LMV
|
||
|
|
otherVerts = mTestTri.getOtherVerts(outerVertIdx);
|
||
|
|
|
||
|
|
// Get the 2 outermost verts of the inside and test tri verts (excluding LMV)
|
||
|
|
switch(uniqueVertAttempt)
|
||
|
|
{
|
||
|
|
case 0: outerVerts2 = leftmostInsideVerts(otherVerts.i1, otherVerts.i2); break;
|
||
|
|
case 1: outerVerts2 = rightmostInsideVerts(otherVerts.i1, otherVerts.i2); break;
|
||
|
|
case 2: outerVerts2 = uppermostInsideVerts(otherVerts.i1, otherVerts.i2); break;
|
||
|
|
case 3: outerVerts2 = uppermostInsideVerts(otherVerts.i1, otherVerts.i2); break;
|
||
|
|
default: outerVerts2 = leftmostInsideVerts(otherVerts.i1, otherVerts.i2);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Form a new test tri from LMV, and the 2 new leftmost verts above
|
||
|
|
mTestTri.setVert(outerVerts2.i1, 0);
|
||
|
|
mTestTri.setVert(outerVertIdx, 1);
|
||
|
|
mTestTri.setVert(outerVerts2.i2, 2);
|
||
|
|
|
||
|
|
// See if there are verts inside this new test tri
|
||
|
|
findPointsInside();
|
||
|
|
}
|
||
|
|
|
||
|
|
// We have found a valid tri
|
||
|
|
mTris.push_back(mTestTri);
|
||
|
|
|
||
|
|
// Remove edges common to test tri and poly... add unique edges from test tri to poly
|
||
|
|
addRemoveEdge(mTestTri.getVert(0), mTestTri.getVert(1));
|
||
|
|
addRemoveEdge(mTestTri.getVert(1), mTestTri.getVert(2));
|
||
|
|
addRemoveEdge(mTestTri.getVert(0), mTestTri.getVert(2));
|
||
|
|
|
||
|
|
// This should never take 255 iterations... we must be stuck in an infinite loop
|
||
|
|
if(counter++ > 255)
|
||
|
|
{
|
||
|
|
newPoly();
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Reset attempts
|
||
|
|
formTriAttempt = 0;
|
||
|
|
uniqueVertAttempt = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
// The last tri
|
||
|
|
mTris.push_back(formTriFromEdges(0,1));
|
||
|
|
|
||
|
|
// The verts need to be ordered to draw correctly
|
||
|
|
for(U8 i = 0; i < mTris.size(); i++)
|
||
|
|
{
|
||
|
|
mTris[i].orderVerts();
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|