diff --git a/Detour/Include/DetourNavMesh.h b/Detour/Include/DetourNavMesh.h index 8dd638c..6608f4e 100644 --- a/Detour/Include/DetourNavMesh.h +++ b/Detour/Include/DetourNavMesh.h @@ -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. diff --git a/Detour/Source/DetourNavMesh.cpp b/Detour/Source/DetourNavMesh.cpp index 0b76437..b27200a 100644 --- a/Detour/Source/DetourNavMesh.cpp +++ b/Detour/Source/DetourNavMesh.cpp @@ -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; diff --git a/Recast/Source/RecastMesh.cpp b/Recast/Source/RecastMesh.cpp index f364dba..be16fa1 100644 --- a/Recast/Source/RecastMesh.cpp +++ b/Recast/Source/RecastMesh.cpp @@ -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 edges = new int[nrem*nvp*4]; + rcScopedDelete 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 hole = new int[nrem*nvp]; + rcScopedDelete 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 hreg = new int[nrem*nvp]; + rcScopedDelete 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 harea = new int[nrem*nvp]; + rcScopedDelete 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 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 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 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 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; + } } } diff --git a/RecastDemo/Bin/Recast.app/Contents/MacOS/Recast b/RecastDemo/Bin/Recast.app/Contents/MacOS/Recast index a9d01d2..443dd0d 100755 Binary files a/RecastDemo/Bin/Recast.app/Contents/MacOS/Recast and b/RecastDemo/Bin/Recast.app/Contents/MacOS/Recast differ diff --git a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser index 5fa63f3..464655d 100644 --- a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser +++ b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser @@ -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; diff --git a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 index d0a7851..ed8438e 100644 --- a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 +++ b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 @@ -281,14 +281,14 @@ PBXSmartGroupTreeModuleOutlineStateSelectionKey - 52 - 46 + 33 + 21 1 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 429}, {358, 643}} + {{0, 347}, {358, 643}} PBXTopSmartGroupGIDs @@ -323,7 +323,7 @@ PBXProjectModuleGUID 6B8632A30F78115100E2684A PBXProjectModuleLabel - NavMeshTesterTool.cpp + RecastMesh.cpp PBXSplitModuleInNavigatorKey Split0 @@ -331,11 +331,11 @@ PBXProjectModuleGUID 6B8632A40F78115100E2684A PBXProjectModuleLabel - NavMeshTesterTool.cpp + RecastMesh.cpp _historyCapacity 0 bookmark - 6B904C6D1152164400A12E63 + 6B904C7611521D4400A12E63 history 6B8DE70D10B01BBF00DF20FB @@ -372,7 +372,6 @@ 6B8036D0113BAF79005ED67B 6B8036F7113BB746005ED67B 6B803729113D1079005ED67B - 6BC8BE261140ED5F00555B22 6B92D96A1140FBDA00E82EC3 6B92D97A1140FE6000E82EC3 6B92D97D1140FE6000E82EC3 @@ -401,7 +400,8 @@ 6B904C591152139200A12E63 6B904C631152164400A12E63 6B904C641152164400A12E63 - 6B904C651152164400A12E63 + 6B904C6F115218D800A12E63 + 6B904C70115218D800A12E63 prevStack @@ -487,6 +487,7 @@ 6B904C6A1152164400A12E63 6B904C6B1152164400A12E63 6B904C6C1152164400A12E63 + 6B904C71115218D800A12E63 SplitCount