Fixed crash in rcBuildPolyMesh() when one of the contours had zero vertices.

This commit is contained in:
Mikko Mononen 2009-11-25 15:21:49 +00:00
parent f77a7511ed
commit d142754ad5
2 changed files with 29 additions and 7 deletions

View File

@ -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)

View File

@ -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;
}
} }
} }