Improve triangulateHull to start from an ear with shortest perimeter

This commit is contained in:
MoYummy 2018-08-23 23:18:20 +08:00 committed by Jakob Botsch Nielsen
parent 05b2b8da80
commit 13dc549bbe

View File

@ -557,15 +557,16 @@ static float polyMinExtent(const float* verts, const int nverts)
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; } inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; } inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, rcIntArray& tris) static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, const int nin, rcIntArray& tris)
{ {
int start = 0, left = 1, right = nhull-1; int start = 0, left = 1, right = nhull-1;
// Start from an ear with shortest perimeter. // Start from an ear with shortest perimeter.
// This tends to favor well formed triangles as starting point. // This tends to favor well formed triangles as starting point.
float dmin = 0; float dmin = FLT_MAX;
for (int i = 0; i < nhull; i++) for (int i = 0; i < nhull; i++)
{ {
if (hull[i] >= nin) continue; // Ears are triangles with original vertices as middle vertex while others are actually line segments on edges
int pi = prev(i, nhull); int pi = prev(i, nhull);
int ni = next(i, nhull); int ni = next(i, nhull);
const float* pv = &verts[hull[pi]*3]; const float* pv = &verts[hull[pi]*3];
@ -770,7 +771,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points. // If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points.
if (minExtent < sampleDist*2) if (minExtent < sampleDist*2)
{ {
triangulateHull(nverts, verts, nhull, hull, tris); triangulateHull(nverts, verts, nhull, hull, nin, tris);
return true; return true;
} }
@ -778,7 +779,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// We're using the triangulateHull instead of delaunayHull as it tends to // We're using the triangulateHull instead of delaunayHull as it tends to
// create a bit better triangulation for long thin triangles when there // create a bit better triangulation for long thin triangles when there
// are no internal points. // are no internal points.
triangulateHull(nverts, verts, nhull, hull, tris); triangulateHull(nverts, verts, nhull, hull, nin, tris);
if (tris.size() == 0) if (tris.size() == 0)
{ {