Fix for Issue 54: Bug when a non-shared vertex is marked for remove
This commit is contained in:
parent
70c17e8212
commit
8291ceace2
@ -297,7 +297,7 @@ public:
|
||||
// startRef - (in) ref to the polygon where the start lies.
|
||||
// startPos[3] - (in) start position of the query.
|
||||
// endPos[3] - (in) end position of the query.
|
||||
// t - (out) hit parameter along the segment, 0 if no hit.
|
||||
// t - (out) hit parameter along the segment, FLT_MAX if no hit.
|
||||
// hitNormal[3] - (out) normal of the nearest hit.
|
||||
// filter - (in) path polygon filter.
|
||||
// path - (out) visited path polygons.
|
||||
|
@ -1826,8 +1826,16 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
if (tmax > t)
|
||||
t = tmax;
|
||||
|
||||
// Store visited polygons.
|
||||
if (n < pathSize)
|
||||
path[n++] = curRef;
|
||||
|
||||
// Ray end is completely inside the polygon.
|
||||
if (segMax == -1)
|
||||
{
|
||||
t = FLT_MAX;
|
||||
return n;
|
||||
}
|
||||
|
||||
// Follow neighbours.
|
||||
dtPolyRef nextRef = 0;
|
||||
|
@ -483,53 +483,70 @@ static void pushBack(int v, int* arr, int& an)
|
||||
an++;
|
||||
}
|
||||
|
||||
static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int maxTris)
|
||||
|
||||
static int removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int maxTris)
|
||||
{
|
||||
const int nvp = mesh.nvp;
|
||||
|
||||
// Count number of polygons to remove.
|
||||
int nrem = 0;
|
||||
int numRemovedVerts = 0;
|
||||
int numRemainingEdges = 0;
|
||||
for (int i = 0; i < mesh.npolys; ++i)
|
||||
{
|
||||
unsigned short* p = &mesh.polys[i*nvp*2];
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
if (p[j] == rem) { nrem++; break; }
|
||||
{
|
||||
if (p[j] == RC_MESH_NULL_IDX) break;
|
||||
numRemainingEdges++;
|
||||
if (p[j] == rem)
|
||||
{
|
||||
numRemovedVerts++;
|
||||
numRemainingEdges -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// There would be too few edges remaining to create a polygon.
|
||||
// This can happen for example when a tip of a triangle is marked
|
||||
// as deletion, but there are no other polys that share the vertex.
|
||||
// In this case, the vertex should not be removed.
|
||||
if (numRemainingEdges <= 2)
|
||||
return -1;
|
||||
|
||||
int nedges = 0;
|
||||
rcScopedDelete<int> edges = new int[nrem*nvp*4];
|
||||
rcScopedDelete<int> edges = new int[numRemovedVerts*nvp*4];
|
||||
if (!edges)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'edges' (%d).", nrem*nvp*4);
|
||||
return false;
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'edges' (%d).", numRemovedVerts*nvp*4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nhole = 0;
|
||||
rcScopedDelete<int> hole = new int[nrem*nvp];
|
||||
rcScopedDelete<int> hole = new int[numRemovedVerts*nvp];
|
||||
if (!hole)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hole' (%d).", nrem*nvp);
|
||||
return false;
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hole' (%d).", numRemovedVerts*nvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nhreg = 0;
|
||||
rcScopedDelete<int> hreg = new int[nrem*nvp];
|
||||
rcScopedDelete<int> hreg = new int[numRemovedVerts*nvp];
|
||||
if (!hreg)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hreg' (%d).", nrem*nvp);
|
||||
return false;
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hreg' (%d).", numRemovedVerts*nvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nharea = 0;
|
||||
rcScopedDelete<int> harea = new int[nrem*nvp];
|
||||
rcScopedDelete<int> harea = new int[numRemovedVerts*nvp];
|
||||
if (!harea)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'harea' (%d).", nrem*nvp);
|
||||
return false;
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'harea' (%d).", numRemovedVerts*nvp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < mesh.npolys; ++i)
|
||||
@ -588,7 +605,7 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
}
|
||||
|
||||
if (nedges == 0)
|
||||
return true;
|
||||
return 1;
|
||||
|
||||
// Start with one vertex, keep appending connected
|
||||
// segments to the start and end of the hole.
|
||||
@ -645,7 +662,7 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tris' (%d).", nhole*3);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcScopedDelete<int> tverts = new int[nhole*4];
|
||||
@ -653,7 +670,7 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tverts' (%d).", nhole*4);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcScopedDelete<int> thole = new int[nhole];
|
||||
@ -661,7 +678,7 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'thole' (%d).", nhole);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Generate temp vertex array for triangulation.
|
||||
@ -690,21 +707,21 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Out of memory 'polys' (%d).", (ntris+1)*nvp);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
rcScopedDelete<unsigned short> pregs = new unsigned short[ntris];
|
||||
if (!pregs)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Out of memory 'pregs' (%d).", ntris);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
rcScopedDelete<unsigned char> pareas = new unsigned char[ntris];
|
||||
if (!pregs)
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Out of memory 'pareas' (%d).", ntris);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short* tmpPoly = &polys[ntris*nvp];
|
||||
@ -726,7 +743,7 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
}
|
||||
}
|
||||
if (!npolys)
|
||||
return true;
|
||||
return 1;
|
||||
|
||||
// Merge polygons.
|
||||
if (nvp > 3)
|
||||
@ -790,11 +807,11 @@ static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int m
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "removeVertex: Too many polygons %d (max:%d).", mesh.npolys, maxTris);
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1046,16 +1063,27 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
|
||||
{
|
||||
if (vflags[i])
|
||||
{
|
||||
if (!removeVertex(mesh, i, maxTris))
|
||||
int res = removeVertex(mesh, i, maxTris);
|
||||
if (!res)
|
||||
{
|
||||
// Failed to remove vertex
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Failed to remove edge vertex %d.", i);
|
||||
return false;
|
||||
}
|
||||
// Note: mesh.nverts is already decremented inside removeVertex()!
|
||||
for (int j = i; j < mesh.nverts; ++j)
|
||||
vflags[j] = vflags[j+1];
|
||||
--i;
|
||||
else if (res == -1)
|
||||
{
|
||||
// Vertex should not be removed.
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove vertex
|
||||
// Note: mesh.nverts is already decremented inside removeVertex()!
|
||||
for (int j = i; j < mesh.nverts; ++j)
|
||||
vflags[j] = vflags[j+1];
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -16,8 +16,8 @@
|
||||
8D1107260486CEB800E47090 /* Recast */,
|
||||
);
|
||||
breakpoints = (
|
||||
6B8037A6113D1788005ED67B /* RecastMesh.cpp:504 */,
|
||||
6B8037B4113D193D005ED67B /* RecastMesh.cpp:532 */,
|
||||
6B8037A6113D1788005ED67B /* RecastMesh.cpp:521 */,
|
||||
6B8037B4113D193D005ED67B /* RecastMesh.cpp:549 */,
|
||||
6B904B781144F2B000A12E63 /* Sample_Debug.cpp:87 */,
|
||||
6B904B941144F35E00A12E63 /* Sample_Debug.cpp:120 */,
|
||||
);
|
||||
@ -310,6 +310,12 @@
|
||||
6B904C6B1152164400A12E63 /* PBXTextBookmark */ = 6B904C6B1152164400A12E63 /* PBXTextBookmark */;
|
||||
6B904C6C1152164400A12E63 /* PBXTextBookmark */ = 6B904C6C1152164400A12E63 /* PBXTextBookmark */;
|
||||
6B904C6D1152164400A12E63 /* PBXTextBookmark */ = 6B904C6D1152164400A12E63 /* PBXTextBookmark */;
|
||||
6B904C6F115218D800A12E63 /* PBXTextBookmark */ = 6B904C6F115218D800A12E63 /* PBXTextBookmark */;
|
||||
6B904C70115218D800A12E63 /* PBXTextBookmark */ = 6B904C70115218D800A12E63 /* PBXTextBookmark */;
|
||||
6B904C71115218D800A12E63 /* PBXTextBookmark */ = 6B904C71115218D800A12E63 /* PBXTextBookmark */;
|
||||
6B904C72115218D800A12E63 /* PBXTextBookmark */ = 6B904C72115218D800A12E63 /* PBXTextBookmark */;
|
||||
6B904C7411521CEA00A12E63 /* PBXTextBookmark */ = 6B904C7411521CEA00A12E63 /* PBXTextBookmark */;
|
||||
6B904C7611521D4400A12E63 /* PBXTextBookmark */ = 6B904C7611521D4400A12E63 /* PBXTextBookmark */;
|
||||
6B92D9121140F58200E82EC3 = 6B92D9121140F58200E82EC3 /* PBXTextBookmark */;
|
||||
6B92D91C1140F5F800E82EC3 = 6B92D91C1140F5F800E82EC3 /* PBXTextBookmark */;
|
||||
6B92D9411140F84100E82EC3 = 6B92D9411140F84100E82EC3 /* PBXTextBookmark */;
|
||||
@ -522,9 +528,9 @@
|
||||
};
|
||||
6B137C870F7FCC1100459200 /* RecastMesh.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {815, 19904}}";
|
||||
sepNavSelRange = "{14617, 0}";
|
||||
sepNavVisRange = "{10934, 788}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {815, 20224}}";
|
||||
sepNavSelRange = "{13330, 0}";
|
||||
sepNavVisRange = "{12592, 895}";
|
||||
};
|
||||
};
|
||||
6B137C880F7FCC1100459200 /* RecastRasterization.cpp */ = {
|
||||
@ -1072,7 +1078,7 @@
|
||||
vrLen = 868;
|
||||
vrLoc = 21829;
|
||||
};
|
||||
6B8037A6113D1788005ED67B /* RecastMesh.cpp:504 */ = {
|
||||
6B8037A6113D1788005ED67B /* RecastMesh.cpp:521 */ = {
|
||||
isa = PBXFileBreakpoint;
|
||||
actions = (
|
||||
);
|
||||
@ -1084,12 +1090,12 @@
|
||||
functionName = "checkNullPolys(rcPolyMesh& mesh)";
|
||||
hitCount = 0;
|
||||
ignoreCount = 0;
|
||||
lineNumber = 504;
|
||||
lineNumber = 521;
|
||||
location = Recast;
|
||||
modificationTime = 290591670.511081;
|
||||
state = 1;
|
||||
};
|
||||
6B8037B4113D193D005ED67B /* RecastMesh.cpp:532 */ = {
|
||||
6B8037B4113D193D005ED67B /* RecastMesh.cpp:549 */ = {
|
||||
isa = PBXFileBreakpoint;
|
||||
actions = (
|
||||
);
|
||||
@ -1101,7 +1107,7 @@
|
||||
functionName = "removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int maxTris)";
|
||||
hitCount = 0;
|
||||
ignoreCount = 0;
|
||||
lineNumber = 532;
|
||||
lineNumber = 549;
|
||||
location = Recast;
|
||||
modificationTime = 290591670.511272;
|
||||
state = 1;
|
||||
@ -2642,6 +2648,66 @@
|
||||
vrLen = 1021;
|
||||
vrLoc = 16495;
|
||||
};
|
||||
6B904C6F115218D800A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */;
|
||||
name = "NavMeshTesterTool.cpp: 633";
|
||||
rLen = 0;
|
||||
rLoc = 17051;
|
||||
rType = 0;
|
||||
vrLen = 1021;
|
||||
vrLoc = 16495;
|
||||
};
|
||||
6B904C70115218D800A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 568";
|
||||
rLen = 0;
|
||||
rLoc = 15139;
|
||||
rType = 0;
|
||||
vrLen = 723;
|
||||
vrLoc = 10999;
|
||||
};
|
||||
6B904C71115218D800A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */;
|
||||
name = "NavMeshTesterTool.cpp: 633";
|
||||
rLen = 0;
|
||||
rLoc = 17051;
|
||||
rType = 0;
|
||||
vrLen = 1021;
|
||||
vrLoc = 16495;
|
||||
};
|
||||
6B904C72115218D800A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 498";
|
||||
rLen = 0;
|
||||
rLoc = 13375;
|
||||
rType = 0;
|
||||
vrLen = 758;
|
||||
vrLoc = 12451;
|
||||
};
|
||||
6B904C7411521CEA00A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 1072";
|
||||
rLen = 0;
|
||||
rLoc = 27474;
|
||||
rType = 0;
|
||||
vrLen = 707;
|
||||
vrLoc = 26829;
|
||||
};
|
||||
6B904C7611521D4400A12E63 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 512";
|
||||
rLen = 0;
|
||||
rLoc = 13330;
|
||||
rType = 0;
|
||||
vrLen = 895;
|
||||
vrLoc = 12592;
|
||||
};
|
||||
6B92D9121140F58200E82EC3 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */;
|
||||
@ -2881,7 +2947,7 @@
|
||||
6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {831, 15024}}";
|
||||
sepNavSelRange = "{16816, 0}";
|
||||
sepNavSelRange = "{17051, 0}";
|
||||
sepNavVisRange = "{16495, 1021}";
|
||||
};
|
||||
};
|
||||
@ -3041,7 +3107,7 @@
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 568";
|
||||
rLen = 0;
|
||||
rLoc = 14617;
|
||||
rLoc = 15139;
|
||||
rType = 0;
|
||||
vrLen = 788;
|
||||
vrLoc = 10934;
|
||||
@ -3051,7 +3117,7 @@
|
||||
fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */;
|
||||
name = "RecastMesh.cpp: 568";
|
||||
rLen = 0;
|
||||
rLoc = 14617;
|
||||
rLoc = 15139;
|
||||
rType = 0;
|
||||
vrLen = 788;
|
||||
vrLoc = 10934;
|
||||
|
@ -281,14 +281,14 @@
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>52</integer>
|
||||
<integer>46</integer>
|
||||
<integer>33</integer>
|
||||
<integer>21</integer>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 429}, {358, 643}}</string>
|
||||
<string>{{0, 347}, {358, 643}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
@ -323,7 +323,7 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>NavMeshTesterTool.cpp</string>
|
||||
<string>RecastMesh.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
@ -331,11 +331,11 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A40F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>NavMeshTesterTool.cpp</string>
|
||||
<string>RecastMesh.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>6B904C6D1152164400A12E63</string>
|
||||
<string>6B904C7611521D4400A12E63</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>6B8DE70D10B01BBF00DF20FB</string>
|
||||
@ -372,7 +372,6 @@
|
||||
<string>6B8036D0113BAF79005ED67B</string>
|
||||
<string>6B8036F7113BB746005ED67B</string>
|
||||
<string>6B803729113D1079005ED67B</string>
|
||||
<string>6BC8BE261140ED5F00555B22</string>
|
||||
<string>6B92D96A1140FBDA00E82EC3</string>
|
||||
<string>6B92D97A1140FE6000E82EC3</string>
|
||||
<string>6B92D97D1140FE6000E82EC3</string>
|
||||
@ -401,7 +400,8 @@
|
||||
<string>6B904C591152139200A12E63</string>
|
||||
<string>6B904C631152164400A12E63</string>
|
||||
<string>6B904C641152164400A12E63</string>
|
||||
<string>6B904C651152164400A12E63</string>
|
||||
<string>6B904C6F115218D800A12E63</string>
|
||||
<string>6B904C70115218D800A12E63</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -487,6 +487,7 @@
|
||||
<string>6B904C6A1152164400A12E63</string>
|
||||
<string>6B904C6B1152164400A12E63</string>
|
||||
<string>6B904C6C1152164400A12E63</string>
|
||||
<string>6B904C71115218D800A12E63</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
|
Loading…
x
Reference in New Issue
Block a user