From b4204ba9a20a8f13ff222ef74ab7b8ef5b3b1184 Mon Sep 17 00:00:00 2001 From: axelrodR Date: Mon, 20 Jan 2014 00:12:53 +0200 Subject: [PATCH 1/3] bugfix: minor typo caused stack overrun when several vertices happen to fall exactly on cell boundaries --- Recast/Source/RecastRasterization.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Recast/Source/RecastRasterization.cpp b/Recast/Source/RecastRasterization.cpp index f082438..e1b2bf3 100644 --- a/Recast/Source/RecastRasterization.cpp +++ b/Recast/Source/RecastRasterization.cpp @@ -200,7 +200,7 @@ static void dividePoly(const float* in, int nbIn, out1[m*3+1] = in[i*3+1]; out1[m*3+2] = in[i*3+2]; m++; - if (d[0] != 0) // not on the line + if (d[i] != 0) // not on the line continue; } From 0c4016590897051fdd89a3c9d60c52fd0460373f Mon Sep 17 00:00:00 2001 From: axelrodR Date: Mon, 20 Jan 2014 00:54:18 +0200 Subject: [PATCH 2/3] bugfix in RecastMeshDetail: in some rare dense cases the polygon simplification moves the polygon to a point where the center is very far from the region. For now we just fall back to the old code (flood-fill from the vertices) --- Recast/Source/RecastMeshDetail.cpp | 94 ++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/Recast/Source/RecastMeshDetail.cpp b/Recast/Source/RecastMeshDetail.cpp index 3b94663..e615e0a 100644 --- a/Recast/Source/RecastMeshDetail.cpp +++ b/Recast/Source/RecastMeshDetail.cpp @@ -794,6 +794,100 @@ static void getHeightData(const rcCompactHeightfield& chf, break; } + // in some dense cases the polygon simplification moves the polygon to a point where the center + // is very far from the region. So we search the span in flood-fill fashion from the vertics + if (stack.size() == 0) + { + memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height); + + // Use poly vertices as seed points for the flood fill. + for (int j = 0; j < npoly; ++j) + { + int cx = 0, cz = 0, ci =-1; + int dmin = RC_UNSET_HEIGHT; + for (int k = 0; k < 9; ++k) + { + const int ax = (int)verts[poly[j]*3+0] + offset[k*2+0]; + const int ay = (int)verts[poly[j]*3+1]; + const int az = (int)verts[poly[j]*3+2] + offset[k*2+1]; + if (ax < hp.xmin || ax >= hp.xmin+hp.width || + az < hp.ymin || az >= hp.ymin+hp.height) + continue; + + const rcCompactCell& c = chf.cells[(ax+bs)+(az+bs)*chf.width]; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + int d = rcAbs(ay - (int)s.y); + if (d < dmin) + { + cx = ax; + cz = az; + ci = i; + dmin = d; + } + } + } + if (ci != -1) + { + stack.push(cx); + stack.push(cz); + stack.push(ci); + } + } + + for (int i = 0; i < stack.size(); i += 3) + { + int cx = stack[i+0]; + int cy = stack[i+1]; + int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width; + hp.data[idx] = 1; + } + + while (stack.size() > 0) + { + int ci = stack.pop(); + int cy = stack.pop(); + int cx = stack.pop(); + + // Check if close to center of the polygon. + if (rcAbs(cx-pcx) <= 1 && rcAbs(cy-pcz) <= 1) + { + stack.resize(0); + stack.push(cx); + stack.push(cy); + stack.push(ci); + break; + } + + const rcCompactSpan& cs = chf.spans[ci]; + + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) continue; + + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + + if (ax < hp.xmin || ax >= (hp.xmin+hp.width) || + ay < hp.ymin || ay >= (hp.ymin+hp.height)) + continue; + + if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != 0) + continue; + + const int ai = (int)chf.cells[(ax+bs)+(ay+bs)*chf.width].index + rcGetCon(cs, dir); + + int idx = ax-hp.xmin+(ay-hp.ymin)*hp.width; + hp.data[idx] = 1; + + stack.push(ax); + stack.push(ay); + stack.push(ai); + } + } + } + // Floodfill the heightfield to get 2D height data, // starting at center location found above as seed. From 4d657b9561f9cf692b58f4d4870276cee7b5bfbc Mon Sep 17 00:00:00 2001 From: axelrodR Date: Mon, 20 Jan 2014 00:55:40 +0200 Subject: [PATCH 3/3] changed remarks --- Recast/Source/RecastMeshDetail.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Recast/Source/RecastMeshDetail.cpp b/Recast/Source/RecastMeshDetail.cpp index e615e0a..f7cd77e 100644 --- a/Recast/Source/RecastMeshDetail.cpp +++ b/Recast/Source/RecastMeshDetail.cpp @@ -794,8 +794,8 @@ static void getHeightData(const rcCompactHeightfield& chf, break; } - // in some dense cases the polygon simplification moves the polygon to a point where the center - // is very far from the region. So we search the span in flood-fill fashion from the vertics + // in some rare dense cases the polygon simplification moves the polygon to a point where the center + // is very far from the region. So we search the span in flood-fill fashion from the vertices if (stack.size() == 0) { memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height);