Fixed crash in rcBuildPolyMesh() when one of the contours had zero vertices.
This commit is contained in:
parent
f77a7511ed
commit
d142754ad5
@ -617,6 +617,8 @@ void rcDebugDrawContours(rcDebugDraw* dd, const rcContourSet& cset, const float
|
|||||||
for (int i = 0; i < cset.nconts; ++i)
|
for (int i = 0; i < cset.nconts; ++i)
|
||||||
{
|
{
|
||||||
const rcContour& c = cset.conts[i];
|
const rcContour& c = cset.conts[i];
|
||||||
|
if (!c.nverts)
|
||||||
|
continue;
|
||||||
unsigned int color = intToCol(c.reg, a);
|
unsigned int color = intToCol(c.reg, a);
|
||||||
|
|
||||||
for (int j = 0; j < c.nverts; ++j)
|
for (int j = 0; j < c.nverts; ++j)
|
||||||
|
@ -661,20 +661,26 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
|||||||
|
|
||||||
// Triangulate the hole.
|
// Triangulate the hole.
|
||||||
int ntris = triangulate(nhole, &tverts[0], &thole[0], tris);
|
int ntris = triangulate(nhole, &tverts[0], &thole[0], tris);
|
||||||
|
if (ntris < 0)
|
||||||
|
{
|
||||||
|
ntris = -ntris;
|
||||||
|
if (rcGetLog())
|
||||||
|
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: triangulate() returned bad results.");
|
||||||
|
}
|
||||||
|
|
||||||
// Merge the hole triangles back to polygons.
|
// Merge the hole triangles back to polygons.
|
||||||
rcScopedDelete<unsigned short> polys = new unsigned short[(ntris+1)*nvp];
|
rcScopedDelete<unsigned short> polys = new unsigned short[(ntris+1)*nvp];
|
||||||
if (!polys)
|
if (!polys)
|
||||||
{
|
{
|
||||||
if (rcGetLog())
|
if (rcGetLog())
|
||||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'polys' (%d).", (ntris+1)*nvp);
|
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Out of memory 'polys' (%d).", (ntris+1)*nvp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
rcScopedDelete<unsigned short> pregs = new unsigned short[ntris];
|
rcScopedDelete<unsigned short> pregs = new unsigned short[ntris];
|
||||||
if (!pregs)
|
if (!pregs)
|
||||||
{
|
{
|
||||||
if (rcGetLog())
|
if (rcGetLog())
|
||||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'pregs' (%d).", ntris);
|
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Out of memory 'pregs' (%d).", ntris);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -754,6 +760,12 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
|||||||
p[j] = polys[i*nvp+j];
|
p[j] = polys[i*nvp+j];
|
||||||
mesh.regs[mesh.npolys] = pregs[i];
|
mesh.regs[mesh.npolys] = pregs[i];
|
||||||
mesh.npolys++;
|
mesh.npolys++;
|
||||||
|
if (mesh.npolys > maxTris)
|
||||||
|
{
|
||||||
|
if (rcGetLog())
|
||||||
|
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Too many polygons %d (max:%d).", mesh.npolys, maxTris);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -774,6 +786,8 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
int maxVertsPerCont = 0;
|
int maxVertsPerCont = 0;
|
||||||
for (int i = 0; i < cset.nconts; ++i)
|
for (int i = 0; i < cset.nconts; ++i)
|
||||||
{
|
{
|
||||||
|
// Skip null contours.
|
||||||
|
if (cset.conts[i].nverts < 3) continue;
|
||||||
maxVertices += cset.conts[i].nverts;
|
maxVertices += cset.conts[i].nverts;
|
||||||
maxTris += cset.conts[i].nverts - 2;
|
maxTris += cset.conts[i].nverts - 2;
|
||||||
maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts);
|
maxVertsPerCont = rcMax(maxVertsPerCont, cset.conts[i].nverts);
|
||||||
@ -802,14 +816,14 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
|
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mesh.polys = new unsigned short[maxTris*nvp*2];
|
mesh.polys = new unsigned short[maxTris*nvp*2*2];
|
||||||
if (!mesh.polys)
|
if (!mesh.polys)
|
||||||
{
|
{
|
||||||
if (rcGetLog())
|
if (rcGetLog())
|
||||||
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2);
|
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mesh.regs = new unsigned short[maxTris];
|
mesh.regs = new unsigned short[maxTris*2];
|
||||||
if (!mesh.regs)
|
if (!mesh.regs)
|
||||||
{
|
{
|
||||||
if (rcGetLog())
|
if (rcGetLog())
|
||||||
@ -870,7 +884,7 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
{
|
{
|
||||||
rcContour& cont = cset.conts[i];
|
rcContour& cont = cset.conts[i];
|
||||||
|
|
||||||
// Skip empty contours.
|
// Skip null contours.
|
||||||
if (cont.nverts < 3)
|
if (cont.nverts < 3)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -896,6 +910,7 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
}*/
|
}*/
|
||||||
ntris = -ntris;
|
ntris = -ntris;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add and merge vertices.
|
// Add and merge vertices.
|
||||||
for (int j = 0; j < cont.nverts; ++j)
|
for (int j = 0; j < cont.nverts; ++j)
|
||||||
{
|
{
|
||||||
@ -971,7 +986,6 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Store polygons.
|
// Store polygons.
|
||||||
for (int j = 0; j < npolys; ++j)
|
for (int j = 0; j < npolys; ++j)
|
||||||
{
|
{
|
||||||
@ -981,6 +995,12 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
|||||||
p[k] = q[k];
|
p[k] = q[k];
|
||||||
mesh.regs[mesh.npolys] = cont.reg;
|
mesh.regs[mesh.npolys] = cont.reg;
|
||||||
mesh.npolys++;
|
mesh.npolys++;
|
||||||
|
if (mesh.npolys > maxTris)
|
||||||
|
{
|
||||||
|
if (rcGetLog())
|
||||||
|
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Too many polygons %d (max:%d).", mesh.npolys, maxTris);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user