diff --git a/DebugUtils/Source/RecastDebugDraw.cpp b/DebugUtils/Source/RecastDebugDraw.cpp index b1a57ef..82050bd 100644 --- a/DebugUtils/Source/RecastDebugDraw.cpp +++ b/DebugUtils/Source/RecastDebugDraw.cpp @@ -806,24 +806,23 @@ void duDebugDrawContours(duDebugDraw* dd, const rcContourSet& cset, const float const rcContour& c = cset.conts[i]; if (!c.nverts) continue; - unsigned int color = duIntToCol(c.reg, a); - - for (int j = 0; j < c.nverts; ++j) + const unsigned int color = duIntToCol(c.reg, a); + const unsigned int bcolor = duLerpCol(color,duRGBA(255,255,255,a),128); + for (int j = 0, k = c.nverts-1; j < c.nverts; k=j++) { - const int* v = &c.verts[j*4]; - float fx = orig[0] + v[0]*cs; - float fy = orig[1] + (v[1]+1+(i&1))*ch; - float fz = orig[2] + v[2]*cs; - dd->vertex(fx,fy,fz, color); - if (j > 0) - dd->vertex(fx,fy,fz, color); + const int* va = &c.verts[k*4]; + const int* vb = &c.verts[j*4]; + unsigned int col = (va[3] & RC_AREA_BORDER) ? bcolor : color; + float fx,fy,fz; + fx = orig[0] + va[0]*cs; + fy = orig[1] + (va[1]+1+(i&1))*ch; + fz = orig[2] + va[2]*cs; + dd->vertex(fx,fy,fz, col); + fx = orig[0] + vb[0]*cs; + fy = orig[1] + (vb[1]+1+(i&1))*ch; + fz = orig[2] + vb[2]*cs; + dd->vertex(fx,fy,fz, col); } - // Loop last segment - const int* v = &c.verts[0]; - float fx = orig[0] + v[0]*cs; - float fy = orig[1] + (v[1]+1+(i&1))*ch; - float fz = orig[2] + v[2]*cs; - dd->vertex(fx,fy,fz, color); } dd->end(); diff --git a/Recast/Source/RecastContour.cpp b/Recast/Source/RecastContour.cpp index 5d58e52..5c324bc 100644 --- a/Recast/Source/RecastContour.cpp +++ b/Recast/Source/RecastContour.cpp @@ -464,7 +464,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, // and the neighbour region is take from the next raw point. const int ai = (simplified[i*4+3]+1) % pn; const int bi = simplified[i*4+3]; - simplified[i*4+3] = (points[ai*4+3] & RC_CONTOUR_REG_MASK) | (points[bi*4+3] & RC_BORDER_VERTEX); + simplified[i*4+3] = (points[ai*4+3] & (RC_CONTOUR_REG_MASK|RC_AREA_BORDER)) | (points[bi*4+3] & RC_BORDER_VERTEX); } } diff --git a/Recast/Source/RecastMesh.cpp b/Recast/Source/RecastMesh.cpp index 012115f..2310e34 100644 --- a/Recast/Source/RecastMesh.cpp +++ b/Recast/Source/RecastMesh.cpp @@ -934,10 +934,18 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe rcScopedDelete vflags = (unsigned char*)rcAlloc(sizeof(unsigned char)*maxVertices, RC_ALLOC_TEMP); if (!vflags) { - ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vflags' (%d).", maxVertices); return false; } memset(vflags, 0, maxVertices); + + rcScopedDelete vportal = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices, RC_ALLOC_TEMP); + if (!vportal) + { + ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'vportal' (%d).", maxVertices); + return false; + } + memset(vportal, 0xff, maxVertices); mesh.verts = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxVertices*3, RC_ALLOC_PERM); if (!mesh.verts) @@ -1053,6 +1061,14 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe vflags[indices[j]] = 1; } } + + // Store portal edges + for (int j = 0; j < cont.nverts; ++j) + { + const int* v = &cont.verts[j*4]; + if ((v[3] & RC_AREA_BORDER) == 0) + vportal[indices[j]] = indices[(j+1) % cont.nverts]; + } // Build initial polygons. int npolys = 0; @@ -1150,8 +1166,17 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe } // Remove vertex // Note: mesh.nverts is already decremented inside removeVertex()! + // Fixup vertex flags for (int j = i; j < mesh.nverts; ++j) vflags[j] = vflags[j+1]; + // Fixup portal indices + for (int j = i; j < mesh.nverts; ++j) + vportal[j] = vportal[j+1]; + for (int j = 0; j < mesh.nverts; ++j) + { + if (vportal[j] > (unsigned short)i) + vportal[j]--; + } --i; } } @@ -1182,6 +1207,10 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe const unsigned short* va = &mesh.verts[p[j]*3]; const unsigned short* vb = &mesh.verts[p[nj]*3]; + // Make sure the edge is marked as portal. + if (vportal[p[j]] != p[nj]) + continue; + if ((int)va[0] == 0 && (int)vb[0] == 0) p[nvp+j] = 0x8000 | 0; else if ((int)va[2] == h && (int)vb[2] == h)