Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pr/index to first link in linked list v2 #67

Merged
merged 4 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

### Added
- Added RcSpans UnitTest
- Added DtNavMesh.Init() interface

### Fixed
- Nothing

### Changed
- RcRecast, DtDetour

- Changed class name of static functions to RcRecast and DtDetour
- Changed DtLink class member variable type from int to byte
- Changed initialization in DtNavMesh constructor to Init() function.

### Removed
- Nothing

### Special Thanks
- [@Doprez](https://github.com/Doprez)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public GraphMeshData Read(ZipArchive file, string filename, GraphMeta meta, int
header.vertCount = vertsCount;
header.detailMeshCount = nodeCount;
header.detailTriCount = nodeCount;
header.maxLinkCount = nodeCount * 3 * 2; // XXX: Needed by Recast, not needed by recast4j
header.maxLinkCount = nodeCount * 3 * 2; // needed by Recast, not needed by recast4j, needed by DotRecast
header.bmin.X = meta.forcedBoundsCenter.x - 0.5f * meta.forcedBoundsSize.x +
meta.cellSize * meta.tileSizeX * x;
header.bmin.Y = ymin;
Expand Down
10 changes: 6 additions & 4 deletions src/DotRecast.Detour/DtLink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

using System;

namespace DotRecast.Detour
{
/// Defines a link between polygons.
Expand All @@ -27,9 +29,9 @@ public class DtLink
{
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.
public int side; //< If a boundary link, defines on which side the link is.
public int bmin; //< If a boundary link, defines the minimum sub-edge area.
public int bmax; //< If a boundary link, defines the maximum sub-edge area.
public byte edge; //< Index of the polygon edge that owns this link.
public byte side; //< If a boundary link, defines on which side the link is.
public byte bmin; //< If a boundary link, defines the minimum sub-edge area.
public byte bmax; //< If a boundary link, defines the maximum sub-edge area.
}
}
8 changes: 1 addition & 7 deletions src/DotRecast.Detour/DtMeshTile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/

using System.Collections.Generic;

namespace DotRecast.Detour
{
using static DtDetour;
Expand All @@ -32,17 +30,13 @@ public class DtMeshTile
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<DtLink> 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<DtLink>();
}
}
}
138 changes: 71 additions & 67 deletions src/DotRecast.Detour/DtNavMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,7 @@ public long GetPolyRefBase(DtMeshTile tile)
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;
Expand Down Expand Up @@ -420,24 +415,31 @@ public DtStatus AddTile(DtMeshData data, int flags, long lastRef, out long resul
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)
{
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.
Expand Down Expand Up @@ -535,9 +537,8 @@ public long RemoveTile(long refs)

// 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.
Expand Down Expand Up @@ -566,7 +567,7 @@ void ConnectIntLinks(DtMeshTile tile)
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)
{
Expand All @@ -586,17 +587,17 @@ void ConnectIntLinks(DtMeshTile tile)
int idx = AllocLink(tile);
DtLink link = tile.links[idx];
link.refs = @base | (long)(poly.neis[j] - 1);
link.edge = j;
link.edge = (byte)j;
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)
Expand All @@ -609,7 +610,7 @@ void UnconnectLinks(DtMeshTile tile, DtMeshTile target)
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)
{
Expand All @@ -619,7 +620,7 @@ void UnconnectLinks(DtMeshTile tile, DtMeshTile target)
int nj = tile.links[j].next;
if (pj == DT_NULL_LINK)
{
tile.polyLinks[poly.index] = nj;
poly.firstLink = nj;
}
else
{
Expand Down Expand Up @@ -679,46 +680,49 @@ void ConnectExtLinks(DtMeshTile tile, DtMeshTile target, int side)
foreach (var connectPoly in connectPolys)
{
int idx = AllocLink(tile);
DtLink link = tile.links[idx];
link.refs = connectPoly.refs;
link.edge = j;
link.side = dir;
if (idx != DT_NULL_LINK)
{
DtLink link = tile.links[idx];
link.refs = connectPoly.refs;
link.edge = (byte)j;
link.side = (byte)dir;

link.next = tile.polyLinks[poly.index];
tile.polyLinks[poly.index] = idx;
link.next = poly.firstLink;
poly.firstLink = idx;

// 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)
// Compress portal limits to a byte value.
if (dir == 0 || dir == 4)
{
float temp = tmin;
tmin = tmax;
tmax = temp;
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 = (byte)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f);
link.bmax = (byte)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f);
}

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)
else if (dir == 2 || dir == 6)
{
float temp = tmin;
tmin = tmax;
tmax = temp;
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 = (byte)MathF.Round(Math.Clamp(tmin, 0.0f, 1.0f) * 255.0f);
link.bmax = (byte)MathF.Round(Math.Clamp(tmax, 0.0f, 1.0f) * 255.0f);
}

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);
}
}
}
Expand Down Expand Up @@ -748,7 +752,7 @@ void ConnectExtOffMeshLinks(DtMeshTile tile, DtMeshTile target, int side)
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;
}
Expand Down Expand Up @@ -786,11 +790,11 @@ void ConnectExtOffMeshLinks(DtMeshTile tile, DtMeshTile target, int side)
DtLink link = target.links[idx];
link.refs = refs;
link.edge = 1;
link.side = oppositeSide;
link.side = (byte)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)
Expand All @@ -801,11 +805,11 @@ void ConnectExtOffMeshLinks(DtMeshTile tile, DtMeshTile target, int side)
link = tile.links[tidx];
link.refs = GetPolyRefBase(target) | (long)targetCon.poly;
link.edge = 0xff;
link.side = (side == -1 ? 0xff : side);
link.side = (byte)(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;
}
}
}
Expand Down Expand Up @@ -963,8 +967,8 @@ void BaseOffMeshLinks(DtMeshTile tile)
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);
Expand All @@ -976,8 +980,8 @@ void BaseOffMeshLinks(DtMeshTile tile)
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;
}
}

Expand Down Expand Up @@ -1411,7 +1415,7 @@ public DtStatus GetOffMeshConnectionPolyEndPoints(long prevRef, long polyRef, re
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)
{
Expand Down
Loading
Loading