From c3208f79680c4692b4005c3a07c1371b03650653 Mon Sep 17 00:00:00 2001 From: ikpil Date: Thu, 16 May 2024 00:30:07 +0900 Subject: [PATCH] changed polyLinks to firstLinks --- src/DotRecast.Detour/DtLink.cs | 3 + src/DotRecast.Detour/DtMeshTile.cs | 8 +- src/DotRecast.Detour/DtNavMesh.cs | 138 +++++++++--------- src/DotRecast.Detour/DtNavMeshQuery.cs | 30 ++-- src/DotRecast.Detour/DtPathUtils.cs | 2 +- src/DotRecast.Detour/DtPoly.cs | 4 +- .../Draw/RecastDebugDraw.cs | 4 +- 7 files changed, 96 insertions(+), 93 deletions(-) diff --git a/src/DotRecast.Detour/DtLink.cs b/src/DotRecast.Detour/DtLink.cs index d249ce4..13360e4 100644 --- a/src/DotRecast.Detour/DtLink.cs +++ b/src/DotRecast.Detour/DtLink.cs @@ -18,6 +18,8 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ +using System; + namespace DotRecast.Detour { /// Defines a link between polygons. @@ -25,6 +27,7 @@ namespace DotRecast.Detour /// @see dtMeshTile public class DtLink { + public readonly int index; // DtMeshTile.links array index public long refs; //< Neighbour reference. (The neighbor that is linked to.) public int next; //< Index of the next link. public int edge; //< Index of the polygon edge that owns this link. diff --git a/src/DotRecast.Detour/DtMeshTile.cs b/src/DotRecast.Detour/DtMeshTile.cs index 4a34ef5..3f56287 100644 --- a/src/DotRecast.Detour/DtMeshTile.cs +++ b/src/DotRecast.Detour/DtMeshTile.cs @@ -18,8 +18,6 @@ freely, subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -using System.Collections.Generic; - namespace DotRecast.Detour { using static DtDetour; @@ -32,17 +30,13 @@ namespace DotRecast.Detour public int linksFreeList = DT_NULL_LINK; //< Index to the next free link. public int salt; //< Counter describing modifications to the tile. public DtMeshData data; // The tile data. - - public int[] polyLinks; - - public readonly List links; // The tile links. [Size: dtMeshHeader::maxLinkCount] + public DtLink[] links; // The tile links. [Size: dtMeshHeader::maxLinkCount] public int flags; //< Tile flags. (See: #dtTileFlags) public DtMeshTile(int index) { this.index = index; - this.links = new List(); } } } \ No newline at end of file diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index 2166f2b..e1cc0ea 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -129,12 +129,7 @@ namespace DotRecast.Detour private int AllocLink(DtMeshTile tile) { if (tile.linksFreeList == DT_NULL_LINK) - { - DtLink link = new DtLink(); - link.next = DT_NULL_LINK; - tile.links.Add(link); - return tile.links.Count - 1; - } + return DT_NULL_LINK; int linkIdx = tile.linksFreeList; tile.linksFreeList = tile.links[linkIdx].next; @@ -420,16 +415,16 @@ namespace DotRecast.Detour return DtStatus.DT_FAILURE | DtStatus.DT_OUT_OF_MEMORY; } - tile.data = data; - tile.flags = flags; - tile.links.Clear(); - tile.polyLinks = new int[data.polys.Length]; - Array.Fill(tile.polyLinks, DT_NULL_LINK); - // Insert tile into the position lut. GetTileListByPos(header.x, header.y).Add(tile); // Patch header pointers. + tile.data = data; + tile.links = new DtLink[data.header.maxLinkCount]; + for (int i = 0; i < tile.links.Length; ++i) + { + tile.links[i] = new DtLink(); + } // If there are no items in the bvtree, reset the tree pointer. if (tile.data.bvTree != null && tile.data.bvTree.Length == 0) @@ -437,7 +432,14 @@ namespace DotRecast.Detour tile.data.bvTree = null; } + // Build links freelist + tile.linksFreeList = 0; + tile.links[data.header.maxLinkCount - 1].next = DT_NULL_LINK; + for (int i = 0; i < data.header.maxLinkCount - 1; ++i) + tile.links[i].next = i + 1; + // Init tile. + tile.flags = flags; ConnectIntLinks(tile); // Base off-mesh connections to their starting polygons and connect connections inside the tile. @@ -535,9 +537,8 @@ namespace DotRecast.Detour // Reset tile. tile.data = null; - tile.flags = 0; - tile.links.Clear(); + tile.links = null; tile.linksFreeList = DT_NULL_LINK; // Update salt, salt should never be zero. @@ -566,7 +567,7 @@ namespace DotRecast.Detour for (int i = 0; i < tile.data.header.polyCount; ++i) { DtPoly poly = tile.data.polys[i]; - tile.polyLinks[poly.index] = DT_NULL_LINK; + poly.firstLink = DT_NULL_LINK; if (poly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION) { @@ -590,13 +591,13 @@ namespace DotRecast.Detour link.side = 0xff; link.bmin = link.bmax = 0; // Add to linked list. - link.next = tile.polyLinks[poly.index]; - tile.polyLinks[poly.index] = idx; + link.next = poly.firstLink; + poly.firstLink = idx; } } } - /// Removes external links at specified side.V + /// Removes external links at specified side. void UnconnectLinks(DtMeshTile tile, DtMeshTile target) { if (tile == null || target == null) @@ -609,7 +610,7 @@ namespace DotRecast.Detour for (int i = 0; i < tile.data.header.polyCount; ++i) { DtPoly poly = tile.data.polys[i]; - int j = tile.polyLinks[poly.index]; + int j = poly.firstLink; int pj = DT_NULL_LINK; while (j != DT_NULL_LINK) { @@ -619,7 +620,7 @@ namespace DotRecast.Detour int nj = tile.links[j].next; if (pj == DT_NULL_LINK) { - tile.polyLinks[poly.index] = nj; + poly.firstLink = nj; } else { @@ -679,46 +680,49 @@ namespace DotRecast.Detour foreach (var connectPoly in connectPolys) { int idx = AllocLink(tile); - DtLink link = tile.links[idx]; - link.refs = connectPoly.refs; - link.edge = j; - link.side = dir; - - link.next = tile.polyLinks[poly.index]; - tile.polyLinks[poly.index] = idx; - - // Compress portal limits to a byte value. - if (dir == 0 || dir == 4) + if (idx != DT_NULL_LINK) { - float tmin = (connectPoly.tmin - tile.data.verts[va + 2]) - / (tile.data.verts[vb + 2] - tile.data.verts[va + 2]); - float tmax = (connectPoly.tmax - tile.data.verts[va + 2]) - / (tile.data.verts[vb + 2] - tile.data.verts[va + 2]); - if (tmin > tmax) - { - float temp = tmin; - tmin = tmax; - tmax = temp; - } + DtLink link = tile.links[idx]; + link.refs = connectPoly.refs; + link.edge = j; + link.side = dir; - link.bmin = (int)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f); - link.bmax = (int)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f); - } - else if (dir == 2 || dir == 6) - { - float tmin = (connectPoly.tmin - tile.data.verts[va]) - / (tile.data.verts[vb] - tile.data.verts[va]); - float tmax = (connectPoly.tmax - tile.data.verts[va]) - / (tile.data.verts[vb] - tile.data.verts[va]); - if (tmin > tmax) - { - float temp = tmin; - tmin = tmax; - tmax = temp; - } + link.next = poly.firstLink; + poly.firstLink = idx; - link.bmin = (int)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f); - link.bmax = (int)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f); + // Compress portal limits to a byte value. + if (dir == 0 || dir == 4) + { + float tmin = (connectPoly.tmin - tile.data.verts[va + 2]) + / (tile.data.verts[vb + 2] - tile.data.verts[va + 2]); + float tmax = (connectPoly.tmax - tile.data.verts[va + 2]) + / (tile.data.verts[vb + 2] - tile.data.verts[va + 2]); + if (tmin > tmax) + { + float temp = tmin; + tmin = tmax; + tmax = temp; + } + + link.bmin = (int)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f); + link.bmax = (int)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f); + } + else if (dir == 2 || dir == 6) + { + float tmin = (connectPoly.tmin - tile.data.verts[va]) + / (tile.data.verts[vb] - tile.data.verts[va]); + float tmax = (connectPoly.tmax - tile.data.verts[va]) + / (tile.data.verts[vb] - tile.data.verts[va]); + if (tmin > tmax) + { + float temp = tmin; + tmin = tmax; + tmax = temp; + } + + link.bmin = (int)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f); + link.bmax = (int)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f); + } } } } @@ -748,7 +752,7 @@ namespace DotRecast.Detour DtPoly targetPoly = target.data.polys[targetCon.poly]; // Skip off-mesh connections which start location could not be // connected at all. - if (target.polyLinks[targetPoly.index] == DT_NULL_LINK) + if (targetPoly.firstLink == DT_NULL_LINK) { continue; } @@ -789,8 +793,8 @@ namespace DotRecast.Detour link.side = oppositeSide; link.bmin = link.bmax = 0; // Add to linked list. - link.next = target.polyLinks[targetPoly.index]; - target.polyLinks[targetPoly.index] = idx; + link.next = targetPoly.firstLink; + targetPoly.firstLink = idx; // Link target poly to off-mesh connection. if ((targetCon.flags & DT_OFFMESH_CON_BIDIR) != 0) @@ -804,8 +808,8 @@ namespace DotRecast.Detour link.side = (side == -1 ? 0xff : side); link.bmin = link.bmax = 0; // Add to linked list. - link.next = tile.polyLinks[landPoly.index]; - tile.polyLinks[landPoly.index] = tidx; + link.next = landPoly.firstLink; + landPoly.firstLink = tidx; } } } @@ -963,8 +967,8 @@ namespace DotRecast.Detour link.side = 0xff; link.bmin = link.bmax = 0; // Add to linked list. - link.next = tile.polyLinks[poly.index]; - tile.polyLinks[poly.index] = idx; + link.next = poly.firstLink; + poly.firstLink = idx; // Start end-point is always connect back to off-mesh connection. int tidx = AllocLink(tile); @@ -976,8 +980,8 @@ namespace DotRecast.Detour link.side = 0xff; link.bmin = link.bmax = 0; // Add to linked list. - link.next = tile.polyLinks[landPoly.index]; - tile.polyLinks[landPoly.index] = tidx; + link.next = landPoly.firstLink; + landPoly.firstLink = tidx; } } @@ -1411,7 +1415,7 @@ namespace DotRecast.Detour int idx0 = 0, idx1 = 1; // Find link that points to first vertex. - for (int i = tile.polyLinks[poly.index]; i != DT_NULL_LINK; i = tile.links[i].next) + for (int i = poly.firstLink; i != DT_NULL_LINK; i = tile.links[i].next) { if (tile.links[i].edge == 0) { diff --git a/src/DotRecast.Detour/DtNavMeshQuery.cs b/src/DotRecast.Detour/DtNavMeshQuery.cs index 894e77a..2bfa491 100644 --- a/src/DotRecast.Detour/DtNavMeshQuery.cs +++ b/src/DotRecast.Detour/DtNavMeshQuery.cs @@ -302,7 +302,7 @@ namespace DotRecast.Detour parentRef = m_nodePool.GetNodeAtIdx(bestNode.pidx).id; } - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { DtLink link = bestTile.links[i]; long neighbourRef = link.refs; @@ -853,7 +853,7 @@ namespace DotRecast.Detour } } - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { long neighbourRef = bestTile.links[i].refs; @@ -1174,7 +1174,7 @@ namespace DotRecast.Detour } } - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { long neighbourRef = bestTile.links[i].refs; @@ -1867,7 +1867,7 @@ namespace DotRecast.Detour if ((curPoly.neis[j] & DT_EXT_LINK) != 0) { // Tile border. - for (int k = curTile.polyLinks[curPoly.index]; k != DT_NULL_LINK; k = curTile.links[k].next) + for (int k = curPoly.firstLink; k != DT_NULL_LINK; k = curTile.links[k].next) { DtLink link = curTile.links[k]; if (link.edge == j) @@ -2013,7 +2013,7 @@ namespace DotRecast.Detour // Find the link that points to the 'to' polygon. DtLink link = null; - for (int i = fromTile.polyLinks[fromPoly.index]; i != DT_NULL_LINK; i = fromTile.links[i].next) + for (int i = fromPoly.firstLink; i != DT_NULL_LINK; i = fromTile.links[i].next) { if (fromTile.links[i].refs == to) { @@ -2031,7 +2031,7 @@ namespace DotRecast.Detour if (fromPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION) { // Find link that points to first vertex. - for (int i = fromTile.polyLinks[fromPoly.index]; i != DT_NULL_LINK; i = fromTile.links[i].next) + for (int i = fromPoly.firstLink; i != DT_NULL_LINK; i = fromTile.links[i].next) { if (fromTile.links[i].refs == to) { @@ -2053,7 +2053,7 @@ namespace DotRecast.Detour if (toPoly.GetPolyType() == DtPolyTypes.DT_POLYTYPE_OFFMESH_CONNECTION) { - for (int i = toTile.polyLinks[toPoly.index]; i != DT_NULL_LINK; i = toTile.links[i].next) + for (int i = toPoly.firstLink; i != DT_NULL_LINK; i = toTile.links[i].next) { if (toTile.links[i].refs == from) { @@ -2329,7 +2329,7 @@ namespace DotRecast.Detour // Follow neighbours. long nextRef = 0; - for (int i = tile.polyLinks[poly.index]; i != DT_NULL_LINK; i = tile.links[i].next) + for (int i = poly.firstLink; i != DT_NULL_LINK; i = tile.links[i].next) { DtLink link = tile.links[i]; @@ -2570,7 +2570,7 @@ namespace DotRecast.Detour resultParent.Add(parentRef); resultCost.Add(bestNode.total); - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { DtLink link = bestTile.links[i]; long neighbourRef = link.refs; @@ -2747,7 +2747,7 @@ namespace DotRecast.Detour resultParent.Add(parentRef); resultCost.Add(bestNode.total); - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { DtLink link = bestTile.links[i]; long neighbourRef = link.refs; @@ -2902,7 +2902,7 @@ namespace DotRecast.Detour long curRef = curNode.id; m_nav.GetTileAndPolyByRefUnsafe(curRef, out var curTile, out var curPoly); - for (int i = curTile.polyLinks[curPoly.index]; i != DT_NULL_LINK; i = curTile.links[i].next) + for (int i = curPoly.firstLink; i != DT_NULL_LINK; i = curTile.links[i].next) { DtLink link = curTile.links[i]; long neighbourRef = link.refs; @@ -2970,7 +2970,7 @@ namespace DotRecast.Detour // Connected polys do not overlap. bool connected = false; - for (int k = curTile.polyLinks[curPoly.index]; k != DT_NULL_LINK; k = curTile.links[k].next) + for (int k = curPoly.firstLink; k != DT_NULL_LINK; k = curTile.links[k].next) { if (curTile.links[k].refs == pastRef) { @@ -3079,7 +3079,7 @@ namespace DotRecast.Detour if ((poly.neis[j] & DT_EXT_LINK) != 0) { // Tile border. - for (int k = tile.polyLinks[poly.index]; k != DT_NULL_LINK; k = tile.links[k].next) + for (int k = poly.firstLink; k != DT_NULL_LINK; k = tile.links[k].next) { DtLink link = tile.links[k]; if (link.edge == j) @@ -3247,7 +3247,7 @@ namespace DotRecast.Detour { // Tile border. bool solid = true; - for (int k = bestTile.polyLinks[bestPoly.index]; k != DT_NULL_LINK; k = bestTile.links[k].next) + for (int k = bestPoly.firstLink; k != DT_NULL_LINK; k = bestTile.links[k].next) { DtLink link = bestTile.links[k]; if (link.edge == j) @@ -3303,7 +3303,7 @@ namespace DotRecast.Detour bestvi = RcVecUtils.Create(bestTile.data.verts, vi); } - for (int i = bestTile.polyLinks[bestPoly.index]; i != DT_NULL_LINK; i = bestTile.links[i].next) + for (int i = bestPoly.firstLink; i != DT_NULL_LINK; i = bestTile.links[i].next) { DtLink link = bestTile.links[i]; long neighbourRef = link.refs; diff --git a/src/DotRecast.Detour/DtPathUtils.cs b/src/DotRecast.Detour/DtPathUtils.cs index b018467..3141ba1 100644 --- a/src/DotRecast.Detour/DtPathUtils.cs +++ b/src/DotRecast.Detour/DtPathUtils.cs @@ -109,7 +109,7 @@ namespace DotRecast.Detour } - for (int k = tile.polyLinks[poly.index]; k != DT_NULL_LINK; k = tile.links[k].next) + for (int k = poly.firstLink; k != DT_NULL_LINK; k = tile.links[k].next) { DtLink link = tile.links[k]; if (link.refs != 0) diff --git a/src/DotRecast.Detour/DtPoly.cs b/src/DotRecast.Detour/DtPoly.cs index c60039d..5faa88a 100644 --- a/src/DotRecast.Detour/DtPoly.cs +++ b/src/DotRecast.Detour/DtPoly.cs @@ -24,8 +24,10 @@ namespace DotRecast.Detour /// @ingroup detour public class DtPoly { - /// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.) public readonly int index; + + /// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.) + public int firstLink; /// The indices of the polygon's vertices. /// The actual vertices are located in dtMeshTile::verts. diff --git a/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs b/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs index 9c4374e..5e68a52 100644 --- a/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs +++ b/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs @@ -202,7 +202,7 @@ public class RecastDebugDraw : DebugDraw // Check to see if start and end end-points have links. bool startSet = false; bool endSet = false; - for (int k = tile.polyLinks[p.index]; k != DT_NULL_LINK; k = tile.links[k].next) + for (int k = p.firstLink; k != DT_NULL_LINK; k = tile.links[k].next) { if (tile.links[k].edge == 0) { @@ -326,7 +326,7 @@ public class RecastDebugDraw : DebugDraw if ((p.neis[j] & DT_EXT_LINK) != 0) { bool con = false; - for (int k = tile.polyLinks[p.index]; k != DT_NULL_LINK; k = tile.links[k].next) + for (int k = p.firstLink; k != DT_NULL_LINK; k = tile.links[k].next) { if (tile.links[k].edge == j) {