forked from mirror/DotRecast
Compare commits
No commits in common. "005ab583f726352293fc1426aba8d88b4f5804a8" and "6a57c067acba1ae2ce6f09183e3cdb97a3c6b3f9" have entirely different histories.
005ab583f7
...
6a57c067ac
|
@ -20,7 +20,6 @@ dotnet_sort_system_directives_first = true
|
||||||
csharp_preserve_single_line_statements = false
|
csharp_preserve_single_line_statements = false
|
||||||
csharp_preserve_single_line_blocks = true
|
csharp_preserve_single_line_blocks = true
|
||||||
|
|
||||||
# ReSharper properties
|
#
|
||||||
resharper_csharp_wrap_lines = false
|
|
||||||
resharper_csharp_space_before_trailing_comment = true
|
resharper_csharp_space_before_trailing_comment = true
|
||||||
resharper_csharp_space_after_operator_keyword = true
|
resharper_csharp_space_after_operator_keyword = true
|
||||||
|
|
|
@ -49,7 +49,7 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up .NET 8.0
|
- name: Set up .NET 8.0
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: 8.x
|
dotnet-version: 8.x
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ jobs:
|
||||||
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
||||||
|
|
||||||
- name: Setup .NET
|
- name: Setup .NET
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet-version }}.x
|
dotnet-version: ${{ matrix.dotnet-version }}.x
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
||||||
|
|
||||||
- name: Setup Dotnet
|
- name: Setup Dotnet
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.x'
|
dotnet-version: '8.x'
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ jobs:
|
||||||
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
fetch-depth: 0 # Get all history to allow automatic versioning using MinVer
|
||||||
|
|
||||||
- name: Setup Dotnet
|
- name: Setup Dotnet
|
||||||
uses: actions/setup-dotnet@v4
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '8.x'
|
dotnet-version: '8.x'
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,5 @@
|
||||||
public interface IRcRand
|
public interface IRcRand
|
||||||
{
|
{
|
||||||
float Next();
|
float Next();
|
||||||
double NextDouble();
|
|
||||||
int NextInt32();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,13 +6,9 @@ namespace DotRecast.Core
|
||||||
{
|
{
|
||||||
private readonly Random _r;
|
private readonly Random _r;
|
||||||
|
|
||||||
public RcRand() : this(new Random())
|
public RcRand()
|
||||||
{
|
{
|
||||||
}
|
_r = new Random();
|
||||||
|
|
||||||
public RcRand(Random r)
|
|
||||||
{
|
|
||||||
_r = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RcRand(long seed)
|
public RcRand(long seed)
|
||||||
|
@ -25,11 +21,6 @@ namespace DotRecast.Core
|
||||||
return (float)_r.NextDouble();
|
return (float)_r.NextDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double NextDouble()
|
|
||||||
{
|
|
||||||
return _r.NextDouble();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NextInt32()
|
public int NextInt32()
|
||||||
{
|
{
|
||||||
return _r.Next();
|
return _r.Next();
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace DotRecast.Detour.Dynamic
|
||||||
private readonly BlockingCollection<IDtDaynmicTileJob> updateQueue = new BlockingCollection<IDtDaynmicTileJob>();
|
private readonly BlockingCollection<IDtDaynmicTileJob> updateQueue = new BlockingCollection<IDtDaynmicTileJob>();
|
||||||
private readonly RcAtomicLong currentColliderId = new RcAtomicLong(0);
|
private readonly RcAtomicLong currentColliderId = new RcAtomicLong(0);
|
||||||
private DtNavMesh _navMesh;
|
private DtNavMesh _navMesh;
|
||||||
private bool _dirty = true;
|
private bool dirty = true;
|
||||||
|
|
||||||
public DtDynamicNavMesh(DtVoxelFile voxelFile)
|
public DtDynamicNavMesh(DtVoxelFile voxelFile)
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,29 @@ namespace DotRecast.Detour.Dynamic
|
||||||
updateQueue.Add(new DtDynamicTileColliderRemovalJob(colliderId, GetTilesByCollider(colliderId)));
|
updateQueue.Add(new DtDynamicTileColliderRemovalJob(colliderId, GetTilesByCollider(colliderId)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform full build of the nav mesh
|
||||||
|
*/
|
||||||
|
public void Build()
|
||||||
|
{
|
||||||
|
ProcessQueue();
|
||||||
|
Rebuild(_tiles.Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform incremental update of the nav mesh
|
||||||
|
*/
|
||||||
|
public bool Update()
|
||||||
|
{
|
||||||
|
return Rebuild(ProcessQueue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Rebuild(ICollection<DtDynamicTile> stream)
|
||||||
|
{
|
||||||
|
foreach (var dynamicTile in stream)
|
||||||
|
Rebuild(dynamicTile);
|
||||||
|
return UpdateNavMesh();
|
||||||
|
}
|
||||||
|
|
||||||
private HashSet<DtDynamicTile> ProcessQueue()
|
private HashSet<DtDynamicTile> ProcessQueue()
|
||||||
{
|
{
|
||||||
|
@ -136,49 +159,27 @@ namespace DotRecast.Detour.Dynamic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform full build of the navmesh
|
/**
|
||||||
public void Build()
|
* Perform full build concurrently using the given {@link ExecutorService}
|
||||||
{
|
*/
|
||||||
ProcessQueue();
|
public Task<bool> Build(TaskFactory executor)
|
||||||
Rebuild(_tiles.Values);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform full build concurrently using the given {@link ExecutorService}
|
|
||||||
public bool Build(TaskFactory executor)
|
|
||||||
{
|
{
|
||||||
ProcessQueue();
|
ProcessQueue();
|
||||||
return Rebuild(_tiles.Values, executor);
|
return Rebuild(_tiles.Values, executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
// Perform incremental update of the navmesh
|
* Perform incremental update concurrently using the given {@link ExecutorService}
|
||||||
public bool Update()
|
*/
|
||||||
{
|
public Task<bool> Update(TaskFactory executor)
|
||||||
return Rebuild(ProcessQueue());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform incremental update concurrently using the given {@link ExecutorService}
|
|
||||||
public bool Update(TaskFactory executor)
|
|
||||||
{
|
{
|
||||||
return Rebuild(ProcessQueue(), executor);
|
return Rebuild(ProcessQueue(), executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Rebuild(ICollection<DtDynamicTile> tiles)
|
private Task<bool> Rebuild(ICollection<DtDynamicTile> tiles, TaskFactory executor)
|
||||||
{
|
{
|
||||||
foreach (var tile in tiles)
|
var tasks = tiles.Select(tile => executor.StartNew(() => Rebuild(tile))).ToArray();
|
||||||
Rebuild(tile);
|
return Task.WhenAll(tasks).ContinueWith(k => UpdateNavMesh());
|
||||||
|
|
||||||
return UpdateNavMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Rebuild(ICollection<DtDynamicTile> tiles, TaskFactory executor)
|
|
||||||
{
|
|
||||||
var tasks = tiles
|
|
||||||
.Select(tile => executor.StartNew(() => Rebuild(tile)))
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
Task.WaitAll(tasks);
|
|
||||||
return UpdateNavMesh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICollection<DtDynamicTile> GetTiles(float[] bounds)
|
private ICollection<DtDynamicTile> GetTiles(float[] bounds)
|
||||||
|
@ -217,19 +218,19 @@ namespace DotRecast.Detour.Dynamic
|
||||||
{
|
{
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
option.walkableHeight = config.walkableHeight;
|
option.walkableHeight = config.walkableHeight;
|
||||||
_dirty = _dirty | tile.Build(builder, config, _context);
|
dirty = dirty | tile.Build(builder, config, _context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool UpdateNavMesh()
|
private bool UpdateNavMesh()
|
||||||
{
|
{
|
||||||
if (_dirty)
|
if (dirty)
|
||||||
{
|
{
|
||||||
DtNavMesh navMesh = new DtNavMesh(navMeshParams, MAX_VERTS_PER_POLY);
|
DtNavMesh navMesh = new DtNavMesh(navMeshParams, MAX_VERTS_PER_POLY);
|
||||||
foreach (var t in _tiles.Values)
|
foreach (var t in _tiles.Values)
|
||||||
t.AddTo(navMesh);
|
t.AddTo(navMesh);
|
||||||
|
|
||||||
_navMesh = navMesh;
|
this._navMesh = navMesh;
|
||||||
_dirty = false;
|
dirty = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ namespace DotRecast.Detour.Dynamic
|
||||||
Math.Min(DtDynamicNavMesh.MAX_VERTS_PER_POLY, config.vertsPerPoly),
|
Math.Min(DtDynamicNavMesh.MAX_VERTS_PER_POLY, config.vertsPerPoly),
|
||||||
config.detailSampleDistance, config.detailSampleMaxError,
|
config.detailSampleDistance, config.detailSampleMaxError,
|
||||||
true, true, true, default, true);
|
true, true, true, default, true);
|
||||||
RcBuilderResult r = builder.Build(context, vt.tileX, vt.tileZ, null, rcConfig, heightfield, false);
|
RcBuilderResult r = builder.Build(context, vt.tileX, vt.tileZ, null, rcConfig, heightfield);
|
||||||
if (config.keepIntermediateResults)
|
if (config.keepIntermediateResults)
|
||||||
{
|
{
|
||||||
recastResult = r;
|
recastResult = r;
|
||||||
|
@ -132,8 +132,8 @@ namespace DotRecast.Detour.Dynamic
|
||||||
private DtNavMeshCreateParams NavMeshCreateParams(int tilex, int tileZ, float cellSize, float cellHeight,
|
private DtNavMeshCreateParams NavMeshCreateParams(int tilex, int tileZ, float cellSize, float cellHeight,
|
||||||
DtDynamicNavMeshConfig config, RcBuilderResult rcResult)
|
DtDynamicNavMeshConfig config, RcBuilderResult rcResult)
|
||||||
{
|
{
|
||||||
RcPolyMesh m_pmesh = rcResult.Mesh;
|
RcPolyMesh m_pmesh = rcResult.GetMesh();
|
||||||
RcPolyMeshDetail m_dmesh = rcResult.MeshDetail;
|
RcPolyMeshDetail m_dmesh = rcResult.GetMeshDetail();
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
for (int i = 0; i < m_pmesh.npolys; ++i)
|
for (int i = 0; i < m_pmesh.npolys; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,13 +109,13 @@ namespace DotRecast.Detour.Dynamic.Io
|
||||||
};
|
};
|
||||||
foreach (RcBuilderResult r in results)
|
foreach (RcBuilderResult r in results)
|
||||||
{
|
{
|
||||||
f.tiles.Add(new DtVoxelTile(r.TileX, r.TileZ, r.SolidHeightfiled));
|
f.tiles.Add(new DtVoxelTile(r.tileX, r.tileZ, r.GetSolidHeightfield()));
|
||||||
f.bounds[0] = Math.Min(f.bounds[0], r.SolidHeightfiled.bmin.X);
|
f.bounds[0] = Math.Min(f.bounds[0], r.GetSolidHeightfield().bmin.X);
|
||||||
f.bounds[1] = Math.Min(f.bounds[1], r.SolidHeightfiled.bmin.Y);
|
f.bounds[1] = Math.Min(f.bounds[1], r.GetSolidHeightfield().bmin.Y);
|
||||||
f.bounds[2] = Math.Min(f.bounds[2], r.SolidHeightfiled.bmin.Z);
|
f.bounds[2] = Math.Min(f.bounds[2], r.GetSolidHeightfield().bmin.Z);
|
||||||
f.bounds[3] = Math.Max(f.bounds[3], r.SolidHeightfiled.bmax.X);
|
f.bounds[3] = Math.Max(f.bounds[3], r.GetSolidHeightfield().bmax.X);
|
||||||
f.bounds[4] = Math.Max(f.bounds[4], r.SolidHeightfiled.bmax.Y);
|
f.bounds[4] = Math.Max(f.bounds[4], r.GetSolidHeightfield().bmax.Y);
|
||||||
f.bounds[5] = Math.Max(f.bounds[5], r.SolidHeightfiled.bmax.Z);
|
f.bounds[5] = Math.Max(f.bounds[5], r.GetSolidHeightfield().bmax.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace DotRecast.Detour.Extras.Jumplink
|
||||||
public JumpLinkBuilder(IList<RcBuilderResult> results)
|
public JumpLinkBuilder(IList<RcBuilderResult> results)
|
||||||
{
|
{
|
||||||
this.results = results;
|
this.results = results;
|
||||||
edges = results.Select(r => edgeExtractor.ExtractEdges(r.Mesh)).ToList();
|
edges = results.Select(r => edgeExtractor.ExtractEdges(r.GetMesh())).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JumpLink> Build(JumpLinkBuilderConfig acfg, JumpLinkType type)
|
public List<JumpLink> Build(JumpLinkBuilderConfig acfg, JumpLinkType type)
|
||||||
|
@ -43,7 +43,7 @@ namespace DotRecast.Detour.Extras.Jumplink
|
||||||
{
|
{
|
||||||
EdgeSampler es = edgeSamplerFactory.Get(acfg, type, edge);
|
EdgeSampler es = edgeSamplerFactory.Get(acfg, type, edge);
|
||||||
groundSampler.Sample(acfg, result, es);
|
groundSampler.Sample(acfg, result, es);
|
||||||
trajectorySampler.Sample(acfg, result.SolidHeightfiled, es);
|
trajectorySampler.Sample(acfg, result.GetSolidHeightfield(), es);
|
||||||
JumpSegment[] jumpSegments = jumpSegmentBuilder.Build(acfg, es);
|
JumpSegment[] jumpSegments = jumpSegmentBuilder.Build(acfg, es);
|
||||||
return BuildJumpLinks(acfg, es, jumpSegments);
|
return BuildJumpLinks(acfg, es, jumpSegments);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,25 @@ namespace DotRecast.Detour.Extras.Jumplink
|
||||||
private DtNavMeshQuery CreateNavMesh(RcBuilderResult r, float agentRadius, float agentHeight, float agentClimb)
|
private DtNavMeshQuery CreateNavMesh(RcBuilderResult r, float agentRadius, float agentHeight, float agentClimb)
|
||||||
{
|
{
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
option.verts = r.Mesh.verts;
|
option.verts = r.GetMesh().verts;
|
||||||
option.vertCount = r.Mesh.nverts;
|
option.vertCount = r.GetMesh().nverts;
|
||||||
option.polys = r.Mesh.polys;
|
option.polys = r.GetMesh().polys;
|
||||||
option.polyAreas = r.Mesh.areas;
|
option.polyAreas = r.GetMesh().areas;
|
||||||
option.polyFlags = r.Mesh.flags;
|
option.polyFlags = r.GetMesh().flags;
|
||||||
option.polyCount = r.Mesh.npolys;
|
option.polyCount = r.GetMesh().npolys;
|
||||||
option.nvp = r.Mesh.nvp;
|
option.nvp = r.GetMesh().nvp;
|
||||||
option.detailMeshes = r.MeshDetail.meshes;
|
option.detailMeshes = r.GetMeshDetail().meshes;
|
||||||
option.detailVerts = r.MeshDetail.verts;
|
option.detailVerts = r.GetMeshDetail().verts;
|
||||||
option.detailVertsCount = r.MeshDetail.nverts;
|
option.detailVertsCount = r.GetMeshDetail().nverts;
|
||||||
option.detailTris = r.MeshDetail.tris;
|
option.detailTris = r.GetMeshDetail().tris;
|
||||||
option.detailTriCount = r.MeshDetail.ntris;
|
option.detailTriCount = r.GetMeshDetail().ntris;
|
||||||
option.walkableRadius = agentRadius;
|
option.walkableRadius = agentRadius;
|
||||||
option.walkableHeight = agentHeight;
|
option.walkableHeight = agentHeight;
|
||||||
option.walkableClimb = agentClimb;
|
option.walkableClimb = agentClimb;
|
||||||
option.bmin = r.Mesh.bmin;
|
option.bmin = r.GetMesh().bmin;
|
||||||
option.bmax = r.Mesh.bmax;
|
option.bmax = r.GetMesh().bmax;
|
||||||
option.cs = r.Mesh.cs;
|
option.cs = r.GetMesh().cs;
|
||||||
option.ch = r.Mesh.ch;
|
option.ch = r.GetMesh().ch;
|
||||||
option.buildBvTree = true;
|
option.buildBvTree = true;
|
||||||
return new DtNavMeshQuery(new DtNavMesh(DtNavMeshBuilder.CreateNavMeshData(option), option.nvp, 0));
|
return new DtNavMeshQuery(new DtNavMesh(DtNavMeshBuilder.CreateNavMeshData(option), option.nvp, 0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,8 +359,8 @@ namespace DotRecast.Detour
|
||||||
var tbmax = tile.data.header.bmax;
|
var tbmax = tile.data.header.bmax;
|
||||||
float qfac = tile.data.header.bvQuantFactor;
|
float qfac = tile.data.header.bvQuantFactor;
|
||||||
// Calculate quantized box
|
// Calculate quantized box
|
||||||
Span<int> bmin = stackalloc int[3];
|
int[] bmin = new int[3];
|
||||||
Span<int> bmax = stackalloc int[3];
|
int[] bmax = new int[3];
|
||||||
// dtClamp query box to world box.
|
// dtClamp query box to world box.
|
||||||
float minx = Math.Clamp(qmin.X, tbmin.X, tbmax.X) - tbmin.X;
|
float minx = Math.Clamp(qmin.X, tbmin.X, tbmax.X) - tbmin.X;
|
||||||
float miny = Math.Clamp(qmin.Y, tbmin.Y, tbmax.Y) - tbmin.Y;
|
float miny = Math.Clamp(qmin.Y, tbmin.Y, tbmax.Y) - tbmin.Y;
|
||||||
|
|
|
@ -584,8 +584,8 @@ namespace DotRecast.Detour
|
||||||
var tbmax = tile.data.header.bmax;
|
var tbmax = tile.data.header.bmax;
|
||||||
float qfac = tile.data.header.bvQuantFactor;
|
float qfac = tile.data.header.bvQuantFactor;
|
||||||
// Calculate quantized box
|
// Calculate quantized box
|
||||||
Span<int> bmin = stackalloc int[3];
|
int[] bmin = new int[3];
|
||||||
Span<int> bmax = stackalloc int[3];
|
int[] bmax = new int[3];
|
||||||
// dtClamp query box to world box.
|
// dtClamp query box to world box.
|
||||||
float minx = Math.Clamp(qmin.X, tbmin.X, tbmax.X) - tbmin.X;
|
float minx = Math.Clamp(qmin.X, tbmin.X, tbmax.X) - tbmin.X;
|
||||||
float miny = Math.Clamp(qmin.Y, tbmin.Y, tbmax.Y) - tbmin.Y;
|
float miny = Math.Clamp(qmin.Y, tbmin.Y, tbmax.Y) - tbmin.Y;
|
||||||
|
@ -1827,9 +1827,6 @@ namespace DotRecast.Detour
|
||||||
|
|
||||||
using var verts = RcRentedArray.Rent<float>(m_nav.GetMaxVertsPerPoly() * 3);
|
using var verts = RcRentedArray.Rent<float>(m_nav.GetMaxVertsPerPoly() * 3);
|
||||||
|
|
||||||
const int MAX_NEIS = 8;
|
|
||||||
Span<long> neis = stackalloc long[MAX_NEIS];
|
|
||||||
|
|
||||||
while (0 < stack.Count)
|
while (0 < stack.Count)
|
||||||
{
|
{
|
||||||
// Pop front.
|
// Pop front.
|
||||||
|
@ -1860,7 +1857,9 @@ namespace DotRecast.Detour
|
||||||
for (int i = 0, j = curPoly.vertCount - 1; i < curPoly.vertCount; j = i++)
|
for (int i = 0, j = curPoly.vertCount - 1; i < curPoly.vertCount; j = i++)
|
||||||
{
|
{
|
||||||
// Find links to neighbours.
|
// Find links to neighbours.
|
||||||
|
int MAX_NEIS = 8;
|
||||||
int nneis = 0;
|
int nneis = 0;
|
||||||
|
using var neis = RcRentedArray.Rent<long>(MAX_NEIS);
|
||||||
|
|
||||||
if ((curPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
if ((curPoly.neis[j] & DtNavMesh.DT_EXT_LINK) != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace DotRecast.Detour
|
||||||
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
||||||
/// @return True if the two AABB's overlap.
|
/// @return True if the two AABB's overlap.
|
||||||
/// @see dtOverlapBounds
|
/// @see dtOverlapBounds
|
||||||
public static bool OverlapQuantBounds(Span<int> amin, Span<int> amax, Span<int> bmin, Span<int> bmax)
|
public static bool OverlapQuantBounds(int[] amin, int[] amax, int[] bmin, int[] bmax)
|
||||||
{
|
{
|
||||||
bool overlap = true;
|
bool overlap = true;
|
||||||
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
||||||
|
|
|
@ -26,9 +26,9 @@
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0"/>
|
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0"/>
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0"/>
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0"/>
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.6"/>
|
||||||
<PackageReference Include="Silk.NET" Version="2.21.0" />
|
<PackageReference Include="Silk.NET" Version="2.20.0" />
|
||||||
<PackageReference Include="Silk.NET.OpenGL.Extensions.ImGui" Version="2.21.0" />
|
<PackageReference Include="Silk.NET.OpenGL.Extensions.ImGui" Version="2.20.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -32,18 +32,15 @@ public class GLCheckerTexture
|
||||||
_gl = gl;
|
_gl = gl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Release()
|
public void Release()
|
||||||
{
|
{
|
||||||
if (m_texId != 0)
|
if (m_texId != 0)
|
||||||
{
|
{
|
||||||
fixed (uint* p = &m_texId)
|
_gl.DeleteTextures(1, m_texId);
|
||||||
{
|
|
||||||
_gl.DeleteTextures(1, p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Bind()
|
public void Bind()
|
||||||
{
|
{
|
||||||
if (m_texId == 0)
|
if (m_texId == 0)
|
||||||
{
|
{
|
||||||
|
@ -53,11 +50,7 @@ public class GLCheckerTexture
|
||||||
uint TSIZE = 64;
|
uint TSIZE = 64;
|
||||||
int[] data = new int[TSIZE * TSIZE];
|
int[] data = new int[TSIZE * TSIZE];
|
||||||
|
|
||||||
fixed (uint* p = &m_texId)
|
_gl.GenTextures(1, out m_texId);
|
||||||
{
|
|
||||||
_gl.GenTextures(1, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
_gl.BindTexture(GLEnum.Texture2D, m_texId);
|
_gl.BindTexture(GLEnum.Texture2D, m_texId);
|
||||||
|
|
||||||
int level = 0;
|
int level = 0;
|
||||||
|
@ -77,10 +70,8 @@ public class GLCheckerTexture
|
||||||
level++;
|
level++;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint linearMipmapNearest = (uint)GLEnum.LinearMipmapNearest;
|
_gl.TexParameterI(GLEnum.Texture2D, GLEnum.TextureMinFilter, (uint)GLEnum.LinearMipmapNearest);
|
||||||
uint linear = (uint)GLEnum.Linear;
|
_gl.TexParameterI(GLEnum.Texture2D, GLEnum.TextureMagFilter, (uint)GLEnum.Linear);
|
||||||
_gl.TexParameterI(GLEnum.Texture2D, GLEnum.TextureMinFilter, &linearMipmapNearest);
|
|
||||||
_gl.TexParameterI(GLEnum.Texture2D, GLEnum.TextureMagFilter, &linear);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,80 +123,80 @@ public class NavMeshRenderer
|
||||||
|
|
||||||
foreach (RcBuilderResult rcBuilderResult in rcBuilderResults)
|
foreach (RcBuilderResult rcBuilderResult in rcBuilderResults)
|
||||||
{
|
{
|
||||||
if (rcBuilderResult.CompactHeightfield != null && drawMode == DrawMode.DRAWMODE_COMPACT)
|
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT)
|
||||||
{
|
{
|
||||||
_debugDraw.DebugDrawCompactHeightfieldSolid(rcBuilderResult.CompactHeightfield);
|
_debugDraw.DebugDrawCompactHeightfieldSolid(rcBuilderResult.GetCompactHeightfield());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.CompactHeightfield != null && drawMode == DrawMode.DRAWMODE_COMPACT_DISTANCE)
|
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT_DISTANCE)
|
||||||
{
|
{
|
||||||
_debugDraw.DebugDrawCompactHeightfieldDistance(rcBuilderResult.CompactHeightfield);
|
_debugDraw.DebugDrawCompactHeightfieldDistance(rcBuilderResult.GetCompactHeightfield());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.CompactHeightfield != null && drawMode == DrawMode.DRAWMODE_COMPACT_REGIONS)
|
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT_REGIONS)
|
||||||
{
|
{
|
||||||
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.CompactHeightfield);
|
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.SolidHeightfiled != null && drawMode == DrawMode.DRAWMODE_VOXELS)
|
if (rcBuilderResult.GetSolidHeightfield() != null && drawMode == DrawMode.DRAWMODE_VOXELS)
|
||||||
{
|
{
|
||||||
_debugDraw.Fog(true);
|
_debugDraw.Fog(true);
|
||||||
_debugDraw.DebugDrawHeightfieldSolid(rcBuilderResult.SolidHeightfiled);
|
_debugDraw.DebugDrawHeightfieldSolid(rcBuilderResult.GetSolidHeightfield());
|
||||||
_debugDraw.Fog(false);
|
_debugDraw.Fog(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.SolidHeightfiled != null && drawMode == DrawMode.DRAWMODE_VOXELS_WALKABLE)
|
if (rcBuilderResult.GetSolidHeightfield() != null && drawMode == DrawMode.DRAWMODE_VOXELS_WALKABLE)
|
||||||
{
|
{
|
||||||
_debugDraw.Fog(true);
|
_debugDraw.Fog(true);
|
||||||
_debugDraw.DebugDrawHeightfieldWalkable(rcBuilderResult.SolidHeightfiled);
|
_debugDraw.DebugDrawHeightfieldWalkable(rcBuilderResult.GetSolidHeightfield());
|
||||||
_debugDraw.Fog(false);
|
_debugDraw.Fog(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.ContourSet != null && drawMode == DrawMode.DRAWMODE_RAW_CONTOURS)
|
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_RAW_CONTOURS)
|
||||||
{
|
{
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
_debugDraw.DebugDrawRawContours(rcBuilderResult.ContourSet, 1f);
|
_debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 1f);
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.ContourSet != null && drawMode == DrawMode.DRAWMODE_BOTH_CONTOURS)
|
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_BOTH_CONTOURS)
|
||||||
{
|
{
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
_debugDraw.DebugDrawRawContours(rcBuilderResult.ContourSet, 0.5f);
|
_debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 0.5f);
|
||||||
_debugDraw.DebugDrawContours(rcBuilderResult.ContourSet);
|
_debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.ContourSet != null && drawMode == DrawMode.DRAWMODE_CONTOURS)
|
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_CONTOURS)
|
||||||
{
|
{
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
_debugDraw.DebugDrawContours(rcBuilderResult.ContourSet);
|
_debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.CompactHeightfield != null && drawMode == DrawMode.DRAWMODE_REGION_CONNECTIONS)
|
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_REGION_CONNECTIONS)
|
||||||
{
|
{
|
||||||
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.CompactHeightfield);
|
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
if (rcBuilderResult.ContourSet != null)
|
if (rcBuilderResult.GetContourSet() != null)
|
||||||
{
|
{
|
||||||
_debugDraw.DebugDrawRegionConnections(rcBuilderResult.ContourSet);
|
_debugDraw.DebugDrawRegionConnections(rcBuilderResult.GetContourSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.Mesh != null && drawMode == DrawMode.DRAWMODE_POLYMESH)
|
if (rcBuilderResult.GetMesh() != null && drawMode == DrawMode.DRAWMODE_POLYMESH)
|
||||||
{
|
{
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
_debugDraw.DebugDrawPolyMesh(rcBuilderResult.Mesh);
|
_debugDraw.DebugDrawPolyMesh(rcBuilderResult.GetMesh());
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcBuilderResult.MeshDetail != null && drawMode == DrawMode.DRAWMODE_POLYMESH_DETAIL)
|
if (rcBuilderResult.GetMeshDetail() != null && drawMode == DrawMode.DRAWMODE_POLYMESH_DETAIL)
|
||||||
{
|
{
|
||||||
_debugDraw.DepthMask(false);
|
_debugDraw.DepthMask(false);
|
||||||
_debugDraw.DebugDrawPolyMeshDetail(rcBuilderResult.MeshDetail);
|
_debugDraw.DebugDrawPolyMeshDetail(rcBuilderResult.GetMeshDetail());
|
||||||
_debugDraw.DepthMask(true);
|
_debugDraw.DepthMask(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,7 +368,7 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
|
|
||||||
var scale = (float)_resolution.X / 1920;
|
var scale = (float)_resolution.X / 1920;
|
||||||
int fontSize = Math.Max(10, (int)(16 * scale));
|
int fontSize = Math.Max(10, (int)(16 * scale));
|
||||||
|
|
||||||
// for windows : Microsoft Visual C++ Redistributable Package
|
// for windows : Microsoft Visual C++ Redistributable Package
|
||||||
// link - https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
|
// link - https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist
|
||||||
var imGuiFontConfig = new ImGuiFontConfig(Path.Combine("resources\\fonts", "DroidSans.ttf"), fontSize, null);
|
var imGuiFontConfig = new ImGuiFontConfig(Path.Combine("resources\\fonts", "DroidSans.ttf"), fontSize, null);
|
||||||
|
@ -379,7 +379,7 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
|
|
||||||
DemoInputGeomProvider geom = LoadInputMesh("nav_test.obj");
|
DemoInputGeomProvider geom = LoadInputMesh("nav_test.obj");
|
||||||
_sample = new DemoSample(geom, ImmutableArray<RcBuilderResult>.Empty, null);
|
_sample = new DemoSample(geom, ImmutableArray<RcBuilderResult>.Empty, null);
|
||||||
|
|
||||||
_menuView = new RcMenuView();
|
_menuView = new RcMenuView();
|
||||||
settingsView = new RcSettingsView(this);
|
settingsView = new RcSettingsView(this);
|
||||||
settingsView.SetSample(_sample);
|
settingsView.SetSample(_sample);
|
||||||
|
@ -537,7 +537,6 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
bool hasBound = false;
|
bool hasBound = false;
|
||||||
RcVec3f bminN = RcVec3f.Zero;
|
RcVec3f bminN = RcVec3f.Zero;
|
||||||
RcVec3f bmaxN = RcVec3f.Zero;
|
RcVec3f bmaxN = RcVec3f.Zero;
|
||||||
|
|
||||||
if (_sample.GetInputGeom() != null)
|
if (_sample.GetInputGeom() != null)
|
||||||
{
|
{
|
||||||
bminN = _sample.GetInputGeom().GetMeshBoundsMin();
|
bminN = _sample.GetInputGeom().GetMeshBoundsMin();
|
||||||
|
@ -553,7 +552,7 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
{
|
{
|
||||||
foreach (RcBuilderResult result in _sample.GetRecastResults())
|
foreach (RcBuilderResult result in _sample.GetRecastResults())
|
||||||
{
|
{
|
||||||
if (result.CompactHeightfield != null)
|
if (result.GetSolidHeightfield() != null)
|
||||||
{
|
{
|
||||||
if (!hasBound)
|
if (!hasBound)
|
||||||
{
|
{
|
||||||
|
@ -562,15 +561,15 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
}
|
}
|
||||||
|
|
||||||
bminN = new RcVec3f(
|
bminN = new RcVec3f(
|
||||||
Math.Min(bminN.X, result.CompactHeightfield.bmin.X),
|
Math.Min(bminN.X, result.GetSolidHeightfield().bmin.X),
|
||||||
Math.Min(bminN.Y, result.CompactHeightfield.bmin.Y),
|
Math.Min(bminN.Y, result.GetSolidHeightfield().bmin.Y),
|
||||||
Math.Min(bminN.Z, result.CompactHeightfield.bmin.Z)
|
Math.Min(bminN.Z, result.GetSolidHeightfield().bmin.Z)
|
||||||
);
|
);
|
||||||
|
|
||||||
bmaxN = new RcVec3f(
|
bmaxN = new RcVec3f(
|
||||||
Math.Max(bmaxN.X, result.CompactHeightfield.bmax.X),
|
Math.Max(bmaxN.X, result.GetSolidHeightfield().bmax.X),
|
||||||
Math.Max(bmaxN.Y, result.CompactHeightfield.bmax.Y),
|
Math.Max(bmaxN.Y, result.GetSolidHeightfield().bmax.Y),
|
||||||
Math.Max(bmaxN.Z, result.CompactHeightfield.bmax.Z)
|
Math.Max(bmaxN.Z, result.GetSolidHeightfield().bmax.Z)
|
||||||
);
|
);
|
||||||
|
|
||||||
hasBound = true;
|
hasBound = true;
|
||||||
|
@ -578,15 +577,12 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset camera and fog to match the mesh bounds.
|
|
||||||
if (hasBound)
|
if (hasBound)
|
||||||
{
|
{
|
||||||
RcVec3f bmin = bminN;
|
RcVec3f bmin = bminN;
|
||||||
RcVec3f bmax = bmaxN;
|
RcVec3f bmax = bmaxN;
|
||||||
|
|
||||||
camr = (float)(Math.Sqrt(RcMath.Sqr(bmax.X - bmin.X) +
|
camr = (float)(Math.Sqrt(RcMath.Sqr(bmax.X - bmin.X) + RcMath.Sqr(bmax.Y - bmin.Y) + RcMath.Sqr(bmax.Z - bmin.Z)) / 2);
|
||||||
RcMath.Sqr(bmax.Y - bmin.Y) +
|
|
||||||
RcMath.Sqr(bmax.Z - bmin.Z)) / 2);
|
|
||||||
cameraPos.X = (bmax.X + bmin.X) / 2 + camr;
|
cameraPos.X = (bmax.X + bmin.X) / 2 + camr;
|
||||||
cameraPos.Y = (bmax.Y + bmin.Y) / 2 + camr;
|
cameraPos.Y = (bmax.Y + bmin.Y) / 2 + camr;
|
||||||
cameraPos.Z = (bmax.Z + bmin.Z) / 2 + camr;
|
cameraPos.Z = (bmax.Z + bmin.Z) / 2 + camr;
|
||||||
|
@ -692,15 +688,14 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
|
|
||||||
NavMeshBuildResult buildResult;
|
NavMeshBuildResult buildResult;
|
||||||
|
|
||||||
var geom = _sample.GetInputGeom();
|
|
||||||
var settings = _sample.GetSettings();
|
var settings = _sample.GetSettings();
|
||||||
if (settings.tiled)
|
if (settings.tiled)
|
||||||
{
|
{
|
||||||
buildResult = tileNavMeshBuilder.Build(geom, settings);
|
buildResult = tileNavMeshBuilder.Build(_sample.GetInputGeom(), settings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buildResult = soloNavMeshBuilder.Build(geom, settings);
|
buildResult = soloNavMeshBuilder.Build(_sample.GetInputGeom(), settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!buildResult.Success)
|
if (!buildResult.Success)
|
||||||
|
@ -718,7 +713,7 @@ public class RecastDemo : IRecastDemoChannel
|
||||||
Logger.Information($"build times");
|
Logger.Information($"build times");
|
||||||
Logger.Information($"-----------------------------------------");
|
Logger.Information($"-----------------------------------------");
|
||||||
var telemetries = buildResult.RecastBuilderResults
|
var telemetries = buildResult.RecastBuilderResults
|
||||||
.Select(x => x.Context)
|
.Select(x => x.GetTelemetry())
|
||||||
.SelectMany(x => x.ToList())
|
.SelectMany(x => x.ToList())
|
||||||
.GroupBy(x => x.Key)
|
.GroupBy(x => x.Key)
|
||||||
.ToImmutableSortedDictionary(x => x.Key, x => x.Sum(y => y.Millis));
|
.ToImmutableSortedDictionary(x => x.Key, x => x.Sum(y => y.Millis));
|
||||||
|
|
|
@ -91,7 +91,7 @@ public class DynamicUpdateSampleTool : ISampleTool
|
||||||
var bridgeGeom = DemoInputGeomProvider.LoadFile("bridge.obj");
|
var bridgeGeom = DemoInputGeomProvider.LoadFile("bridge.obj");
|
||||||
var houseGeom = DemoInputGeomProvider.LoadFile("house.obj");
|
var houseGeom = DemoInputGeomProvider.LoadFile("house.obj");
|
||||||
var convexGeom = DemoInputGeomProvider.LoadFile("convex.obj");
|
var convexGeom = DemoInputGeomProvider.LoadFile("convex.obj");
|
||||||
_tool = new(new RcRand(Random.Shared), bridgeGeom, houseGeom, convexGeom);
|
_tool = new(Random.Shared, bridgeGeom, houseGeom, convexGeom);
|
||||||
executor = Task.Factory;
|
executor = Task.Factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,7 +406,7 @@ public class DynamicUpdateSampleTool : ISampleTool
|
||||||
long t = RcFrequency.Ticks;
|
long t = RcFrequency.Ticks;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool updated = _tool.Update(executor);
|
bool updated = _tool.UpdateDynaMesh(executor);
|
||||||
if (updated)
|
if (updated)
|
||||||
{
|
{
|
||||||
buildTime = (RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond;
|
buildTime = (RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond;
|
||||||
|
@ -450,7 +450,7 @@ public class DynamicUpdateSampleTool : ISampleTool
|
||||||
long t = RcFrequency.Ticks;
|
long t = RcFrequency.Ticks;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var _ = dynaMesh.Build(executor);
|
var _ = dynaMesh.Build(executor).Result;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,6 @@ freely, subject to the following restrictions:
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using DotRecast.Core.Numerics;
|
using DotRecast.Core.Numerics;
|
||||||
using DotRecast.Detour.Extras.Jumplink;
|
using DotRecast.Detour.Extras.Jumplink;
|
||||||
using DotRecast.Recast.Demo.Draw;
|
using DotRecast.Recast.Demo.Draw;
|
||||||
|
@ -97,25 +96,13 @@ public class JumpLinkBuilderSampleTool : ISampleTool
|
||||||
|
|
||||||
if (build || _cfg.buildOffMeshConnections)
|
if (build || _cfg.buildOffMeshConnections)
|
||||||
{
|
{
|
||||||
do
|
if (0 < _sample.GetRecastResults().Count)
|
||||||
{
|
{
|
||||||
if (0 >= _sample.GetRecastResults().Count)
|
|
||||||
{
|
|
||||||
Logger.Error("build navmesh");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_sample.GetRecastResults().Any(x => null == x.SolidHeightfiled))
|
|
||||||
{
|
|
||||||
Logger.Error("Tick 'Keep Itermediate Results' option");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var geom = _sample.GetInputGeom();
|
var geom = _sample.GetInputGeom();
|
||||||
var settings = _sample.GetSettings();
|
var settings = _sample.GetSettings();
|
||||||
|
|
||||||
_tool.Build(geom, settings, _sample.GetRecastResults(), _cfg);
|
_tool.Build(geom, settings, _sample.GetRecastResults(), _cfg);
|
||||||
} while (false);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
|
@ -166,10 +166,6 @@ public class RcSettingsView : IRcView
|
||||||
ImGui.SliderFloat("Max Sample Error", ref settings.detailSampleMaxError, 0f, 16f, "%.1f");
|
ImGui.SliderFloat("Max Sample Error", ref settings.detailSampleMaxError, 0f, 16f, "%.1f");
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
ImGui.Checkbox("Keep Itermediate Results", ref settings.keepInterResults);
|
|
||||||
ImGui.Checkbox("Build All Tiles", ref settings.buildAll);
|
|
||||||
ImGui.NewLine();
|
|
||||||
|
|
||||||
ImGui.Text("Tiling");
|
ImGui.Text("Tiling");
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
ImGui.Checkbox("Enable", ref settings.tiled);
|
ImGui.Checkbox("Enable", ref settings.tiled);
|
||||||
|
@ -232,12 +228,6 @@ public class RcSettingsView : IRcView
|
||||||
DrawMode.Values.ForEach(dm => { ImGui.RadioButton(dm.Text, ref drawMode, dm.Idx); });
|
DrawMode.Values.ForEach(dm => { ImGui.RadioButton(dm.Text, ref drawMode, dm.Idx); });
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.Text("Tick 'Keep Itermediate Results'");
|
|
||||||
ImGui.Text("rebuild some tiles to see");
|
|
||||||
ImGui.Text("more debug mode options.");
|
|
||||||
ImGui.NewLine();
|
|
||||||
|
|
||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,4 +262,4 @@ public class RcSettingsView : IRcView
|
||||||
{
|
{
|
||||||
this.maxPolys = maxPolys;
|
this.maxPolys = maxPolys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
|
||||||
RcBuilderResult rcResult)
|
RcBuilderResult rcResult)
|
||||||
{
|
{
|
||||||
RcPolyMesh pmesh = rcResult.Mesh;
|
RcPolyMesh pmesh = rcResult.GetMesh();
|
||||||
RcPolyMeshDetail dmesh = rcResult.MeshDetail;
|
RcPolyMeshDetail dmesh = rcResult.GetMeshDetail();
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
for (int i = 0; i < pmesh.npolys; ++i)
|
for (int i = 0; i < pmesh.npolys; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,8 +34,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
settings.edgeMaxLen, settings.edgeMaxError,
|
settings.edgeMaxLen, settings.edgeMaxError,
|
||||||
settings.vertsPerPoly,
|
settings.vertsPerPoly,
|
||||||
settings.detailSampleDist, settings.detailSampleMaxError,
|
settings.detailSampleDist, settings.detailSampleMaxError,
|
||||||
settings.filterLowHangingObstacles, settings.filterLedgeSpans, settings.filterWalkableLowHeightSpans,
|
settings.filterLowHangingObstacles, settings.filterLedgeSpans, settings.filterWalkableLowHeightSpans);
|
||||||
settings.keepInterResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavMeshBuildResult Build(DemoInputGeomProvider geom,
|
public NavMeshBuildResult Build(DemoInputGeomProvider geom,
|
||||||
|
@ -46,8 +45,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
float edgeMaxLen, float edgeMaxError,
|
float edgeMaxLen, float edgeMaxError,
|
||||||
int vertsPerPoly,
|
int vertsPerPoly,
|
||||||
float detailSampleDist, float detailSampleMaxError,
|
float detailSampleDist, float detailSampleMaxError,
|
||||||
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans,
|
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans)
|
||||||
bool keepInterResults)
|
|
||||||
{
|
{
|
||||||
RcConfig cfg = new RcConfig(
|
RcConfig cfg = new RcConfig(
|
||||||
partitionType,
|
partitionType,
|
||||||
|
@ -60,7 +58,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans,
|
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans,
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
||||||
|
|
||||||
RcBuilderResult rcResult = BuildRecastResult(geom, cfg, keepInterResults);
|
RcBuilderResult rcResult = BuildRecastResult(geom, cfg);
|
||||||
var meshData = BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult);
|
var meshData = BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult);
|
||||||
if (null == meshData)
|
if (null == meshData)
|
||||||
{
|
{
|
||||||
|
@ -76,11 +74,11 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
return new DtNavMesh(meshData, vertsPerPoly, 0);
|
return new DtNavMesh(meshData, vertsPerPoly, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RcBuilderResult BuildRecastResult(DemoInputGeomProvider geom, RcConfig cfg, bool keepInterResults)
|
private RcBuilderResult BuildRecastResult(DemoInputGeomProvider geom, RcConfig cfg)
|
||||||
{
|
{
|
||||||
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
return rcBuilder.Build(geom, bcfg, keepInterResults);
|
return rcBuilder.Build(geom, bcfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtMeshData BuildMeshData(DemoInputGeomProvider geom,
|
public DtMeshData BuildMeshData(DemoInputGeomProvider geom,
|
||||||
|
|
|
@ -41,8 +41,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
settings.minRegionSize, settings.mergedRegionSize,
|
settings.minRegionSize, settings.mergedRegionSize,
|
||||||
settings.edgeMaxLen, settings.edgeMaxError,
|
settings.edgeMaxLen, settings.edgeMaxError,
|
||||||
settings.vertsPerPoly, settings.detailSampleDist, settings.detailSampleMaxError,
|
settings.vertsPerPoly, settings.detailSampleDist, settings.detailSampleMaxError,
|
||||||
settings.filterLowHangingObstacles, settings.filterLedgeSpans, settings.filterWalkableLowHeightSpans,
|
settings.filterLowHangingObstacles, settings.filterLedgeSpans, settings.filterWalkableLowHeightSpans);
|
||||||
settings.keepInterResults, settings.buildAll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NavMeshBuildResult Build(IInputGeomProvider geom,
|
public NavMeshBuildResult Build(IInputGeomProvider geom,
|
||||||
|
@ -54,8 +53,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
float edgeMaxLen, float edgeMaxError,
|
float edgeMaxLen, float edgeMaxError,
|
||||||
int vertsPerPoly,
|
int vertsPerPoly,
|
||||||
float detailSampleDist, float detailSampleMaxError,
|
float detailSampleDist, float detailSampleMaxError,
|
||||||
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans,
|
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans)
|
||||||
bool keepInterResults, bool buildAll)
|
|
||||||
{
|
{
|
||||||
List<RcBuilderResult> results = BuildRecastResult(
|
List<RcBuilderResult> results = BuildRecastResult(
|
||||||
geom,
|
geom,
|
||||||
|
@ -67,8 +65,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
edgeMaxLen, edgeMaxError,
|
edgeMaxLen, edgeMaxError,
|
||||||
vertsPerPoly,
|
vertsPerPoly,
|
||||||
detailSampleDist, detailSampleMaxError,
|
detailSampleDist, detailSampleMaxError,
|
||||||
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans,
|
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans
|
||||||
keepInterResults, buildAll
|
|
||||||
);
|
);
|
||||||
|
|
||||||
var tileMeshData = BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, results);
|
var tileMeshData = BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, results);
|
||||||
|
@ -85,8 +82,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
float edgeMaxLen, float edgeMaxError,
|
float edgeMaxLen, float edgeMaxError,
|
||||||
int vertsPerPoly,
|
int vertsPerPoly,
|
||||||
float detailSampleDist, float detailSampleMaxError,
|
float detailSampleDist, float detailSampleMaxError,
|
||||||
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans,
|
bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans)
|
||||||
bool keepInterResults, bool buildAll)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
RcConfig cfg = new RcConfig(true, tileSize, tileSize,
|
RcConfig cfg = new RcConfig(true, tileSize, tileSize,
|
||||||
|
@ -101,7 +97,7 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans,
|
filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans,
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true);
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
return rcBuilder.BuildTiles(geom, cfg, keepInterResults, buildAll, Environment.ProcessorCount + 1, Task.Factory);
|
return rcBuilder.BuildTiles(geom, cfg, Task.Factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DtNavMesh BuildNavMesh(IInputGeomProvider geom, List<DtMeshData> meshData, float cellSize, int tileSize, int vertsPerPoly)
|
public DtNavMesh BuildNavMesh(IInputGeomProvider geom, List<DtMeshData> meshData, float cellSize, int tileSize, int vertsPerPoly)
|
||||||
|
@ -127,9 +123,10 @@ namespace DotRecast.Recast.Toolset.Builder
|
||||||
List<DtMeshData> meshData = new List<DtMeshData>();
|
List<DtMeshData> meshData = new List<DtMeshData>();
|
||||||
foreach (RcBuilderResult result in results)
|
foreach (RcBuilderResult result in results)
|
||||||
{
|
{
|
||||||
int x = result.TileX;
|
int x = result.tileX;
|
||||||
int z = result.TileZ;
|
int z = result.tileZ;
|
||||||
DtNavMeshCreateParams option = DemoNavMeshBuilder.GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, result);
|
DtNavMeshCreateParams option = DemoNavMeshBuilder
|
||||||
|
.GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, result);
|
||||||
|
|
||||||
option.tileX = x;
|
option.tileX = x;
|
||||||
option.tileZ = z;
|
option.tileZ = z;
|
||||||
|
|
|
@ -31,8 +31,5 @@
|
||||||
|
|
||||||
public bool tiled = false;
|
public bool tiled = false;
|
||||||
public int tileSize = 32;
|
public int tileSize = 32;
|
||||||
|
|
||||||
public bool keepInterResults = false;
|
|
||||||
public bool buildAll = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,12 +18,12 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
private DtDynamicNavMesh dynaMesh;
|
private DtDynamicNavMesh dynaMesh;
|
||||||
private readonly Dictionary<long, RcGizmo> colliderGizmos;
|
private readonly Dictionary<long, RcGizmo> colliderGizmos;
|
||||||
|
|
||||||
private readonly IRcRand random;
|
private readonly Random random;
|
||||||
private readonly DemoInputGeomProvider bridgeGeom;
|
private readonly DemoInputGeomProvider bridgeGeom;
|
||||||
private readonly DemoInputGeomProvider houseGeom;
|
private readonly DemoInputGeomProvider houseGeom;
|
||||||
private readonly DemoInputGeomProvider convexGeom;
|
private readonly DemoInputGeomProvider convexGeom;
|
||||||
|
|
||||||
public RcDynamicUpdateTool(IRcRand rand, DemoInputGeomProvider bridgeGeom, DemoInputGeomProvider houseGeom, DemoInputGeomProvider convexGeom)
|
public RcDynamicUpdateTool(Random rand, DemoInputGeomProvider bridgeGeom, DemoInputGeomProvider houseGeom, DemoInputGeomProvider convexGeom)
|
||||||
{
|
{
|
||||||
this.colliderGizmos = new Dictionary<long, RcGizmo>();
|
this.colliderGizmos = new Dictionary<long, RcGizmo>();
|
||||||
this.random = rand;
|
this.random = rand;
|
||||||
|
@ -339,14 +339,20 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
return resultvector;
|
return resultvector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Update(TaskFactory executor)
|
public bool UpdateDynaMesh(TaskFactory executor)
|
||||||
{
|
{
|
||||||
if (dynaMesh == null)
|
if (dynaMesh == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return dynaMesh.Update(executor);
|
bool updated = dynaMesh.Update(executor).Result;
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Raycast(RcVec3f spos, RcVec3f epos, out float hitPos, out RcVec3f raycastHitPos)
|
public bool Raycast(RcVec3f spos, RcVec3f epos, out float hitPos, out RcVec3f raycastHitPos)
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace DotRecast.Recast.Toolset.Tools
|
||||||
|
|
||||||
var beginTick = RcFrequency.Ticks;
|
var beginTick = RcFrequency.Ticks;
|
||||||
var rb = new RcBuilder();
|
var rb = new RcBuilder();
|
||||||
var result = rb.BuildTile(geom, cfg, bmin, bmax, tx, ty, new RcAtomicInteger(0), 1, settings.keepInterResults);
|
var result = rb.BuildTile(geom, cfg, bmin, bmax, tx, ty, new RcAtomicInteger(0), 1);
|
||||||
|
|
||||||
var tb = new TileNavMeshBuilder();
|
var tb = new TileNavMeshBuilder();
|
||||||
var meshData = tb.BuildMeshData(geom, settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, RcImmutableArray.Create(result)
|
var meshData = tb.BuildMeshData(geom, settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, RcImmutableArray.Create(result)
|
||||||
|
|
|
@ -19,9 +19,7 @@ freely, subject to the following restrictions:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DotRecast.Core;
|
using DotRecast.Core;
|
||||||
|
@ -47,113 +45,132 @@ namespace DotRecast.Recast
|
||||||
_progressListener = progressListener;
|
_progressListener = progressListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RcBuilderResult> BuildTiles(IInputGeomProvider geom, RcConfig cfg, bool keepInterResults, bool buildAll,
|
public List<RcBuilderResult> BuildTiles(IInputGeomProvider geom, RcConfig cfg, TaskFactory taskFactory)
|
||||||
int threads = 0, TaskFactory taskFactory = null, CancellationToken cancellation = default)
|
|
||||||
{
|
{
|
||||||
RcVec3f bmin = geom.GetMeshBoundsMin();
|
RcVec3f bmin = geom.GetMeshBoundsMin();
|
||||||
RcVec3f bmax = geom.GetMeshBoundsMax();
|
RcVec3f bmax = geom.GetMeshBoundsMax();
|
||||||
CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th);
|
CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th);
|
||||||
|
List<RcBuilderResult> results = new List<RcBuilderResult>();
|
||||||
if (1 < threads)
|
if (null != taskFactory)
|
||||||
{
|
{
|
||||||
return BuildMultiThread(geom, cfg, bmin, bmax, tw, th, threads, taskFactory ?? Task.Factory, cancellation, keepInterResults, buildAll);
|
BuildMultiThreadAsync(geom, cfg, bmin, bmax, tw, th, results, taskFactory, default);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return BuildSingleThread(geom, cfg, bmin, bmax, tw, th, keepInterResults, buildAll);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<RcBuilderResult> BuildSingleThread(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tw, int th,
|
|
||||||
bool keepInterResults, bool buildAll)
|
|
||||||
{
|
|
||||||
var results = new List<RcBuilderResult>(th * tw);
|
|
||||||
RcAtomicInteger counter = new RcAtomicInteger(0);
|
|
||||||
|
|
||||||
for (int y = 0; y < th; ++y)
|
|
||||||
{
|
{
|
||||||
for (int x = 0; x < tw; ++x)
|
BuildSingleThreadAsync(geom, cfg, bmin, bmax, tw, th, results);
|
||||||
{
|
|
||||||
var result = BuildTile(geom, cfg, bmin, bmax, x, y, counter, tw * th, keepInterResults);
|
|
||||||
results.Add(result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RcBuilderResult> BuildMultiThread(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tw, int th,
|
|
||||||
int threads, TaskFactory taskFactory, CancellationToken cancellation,
|
|
||||||
bool keepInterResults, bool buildAll)
|
|
||||||
{
|
|
||||||
var results = new ConcurrentQueue<RcBuilderResult>();
|
|
||||||
RcAtomicInteger progress = new RcAtomicInteger(0);
|
|
||||||
|
|
||||||
List<Task> limits = new List<Task>(threads);
|
public Task BuildTilesAsync(IInputGeomProvider geom, RcConfig cfg, int threads, List<RcBuilderResult> results, TaskFactory taskFactory, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
RcVec3f bmin = geom.GetMeshBoundsMin();
|
||||||
|
RcVec3f bmax = geom.GetMeshBoundsMax();
|
||||||
|
CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th);
|
||||||
|
Task task;
|
||||||
|
if (1 < threads)
|
||||||
|
{
|
||||||
|
task = BuildMultiThreadAsync(geom, cfg, bmin, bmax, tw, th, results, taskFactory, cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
task = BuildSingleThreadAsync(geom, cfg, bmin, bmax, tw, th, results);
|
||||||
|
}
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BuildSingleThreadAsync(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax,
|
||||||
|
int tw, int th, List<RcBuilderResult> results)
|
||||||
|
{
|
||||||
|
RcAtomicInteger counter = new RcAtomicInteger(0);
|
||||||
|
for (int y = 0; y < th; ++y)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < tw; ++x)
|
||||||
|
{
|
||||||
|
results.Add(BuildTile(geom, cfg, bmin, bmax, x, y, counter, tw * th));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task BuildMultiThreadAsync(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax,
|
||||||
|
int tw, int th, List<RcBuilderResult> results, TaskFactory taskFactory, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
RcAtomicInteger counter = new RcAtomicInteger(0);
|
||||||
|
CountdownEvent latch = new CountdownEvent(tw * th);
|
||||||
|
List<Task> tasks = new List<Task>();
|
||||||
|
|
||||||
for (int x = 0; x < tw; ++x)
|
for (int x = 0; x < tw; ++x)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < th; ++y)
|
for (int y = 0; y < th; ++y)
|
||||||
{
|
{
|
||||||
int tx = x;
|
int tx = x;
|
||||||
int ty = y;
|
int ty = y;
|
||||||
var task = taskFactory.StartNew(state =>
|
var task = taskFactory.StartNew(() =>
|
||||||
{
|
{
|
||||||
if (cancellation.IsCancellationRequested)
|
if (cancellationToken.IsCancellationRequested)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RcBuilderResult result = BuildTile(geom, cfg, bmin, bmax, tx, ty, progress, tw * th, keepInterResults);
|
RcBuilderResult tile = BuildTile(geom, cfg, bmin, bmax, tx, ty, counter, tw * th);
|
||||||
results.Enqueue(result);
|
lock (results)
|
||||||
|
{
|
||||||
|
results.Add(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
}
|
}
|
||||||
}, null, cancellation);
|
|
||||||
|
|
||||||
limits.Add(task);
|
|
||||||
if (threads <= limits.Count)
|
latch.Signal();
|
||||||
{
|
}, cancellationToken);
|
||||||
Task.WaitAll(limits.ToArray());
|
|
||||||
limits.Clear();
|
tasks.Add(task);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 < limits.Count)
|
try
|
||||||
|
{
|
||||||
|
latch.Wait();
|
||||||
|
}
|
||||||
|
catch (ThreadInterruptedException)
|
||||||
{
|
{
|
||||||
Task.WaitAll(limits.ToArray());
|
|
||||||
limits.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var list = results.ToList();
|
return Task.WhenAll(tasks.ToArray());
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RcBuilderResult BuildTile(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tx, int ty, RcAtomicInteger progress, int total, bool keepInterResults)
|
public RcBuilderResult BuildTile(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tx,
|
||||||
|
int ty, RcAtomicInteger counter, int total)
|
||||||
{
|
{
|
||||||
var bcfg = new RcBuilderConfig(cfg, bmin, bmax, tx, ty);
|
RcBuilderResult result = Build(geom, new RcBuilderConfig(cfg, bmin, bmax, tx, ty));
|
||||||
RcBuilderResult result = Build(geom, bcfg, keepInterResults);
|
|
||||||
if (_progressListener != null)
|
if (_progressListener != null)
|
||||||
{
|
{
|
||||||
_progressListener.OnProgress(progress.IncrementAndGet(), total);
|
_progressListener.OnProgress(counter.IncrementAndGet(), total);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RcBuilderResult Build(IInputGeomProvider geom, RcBuilderConfig bcfg, bool keepInterResults)
|
public RcBuilderResult Build(IInputGeomProvider geom, RcBuilderConfig builderCfg)
|
||||||
{
|
{
|
||||||
RcConfig cfg = bcfg.cfg;
|
RcConfig cfg = builderCfg.cfg;
|
||||||
RcContext ctx = new RcContext();
|
RcContext ctx = new RcContext();
|
||||||
//
|
//
|
||||||
// Step 1. Rasterize input polygon soup.
|
// Step 1. Rasterize input polygon soup.
|
||||||
//
|
//
|
||||||
RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(ctx, geom, bcfg);
|
RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(ctx, geom, builderCfg);
|
||||||
return Build(ctx, bcfg.tileX, bcfg.tileZ, geom, cfg, solid, keepInterResults);
|
return Build(ctx, builderCfg.tileX, builderCfg.tileZ, geom, cfg, solid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RcBuilderResult Build(RcContext ctx, int tileX, int tileZ, IInputGeomProvider geom, RcConfig cfg, RcHeightfield solid, bool keepInterResults)
|
public RcBuilderResult Build(RcContext ctx, int tileX, int tileZ, IInputGeomProvider geom, RcConfig cfg, RcHeightfield solid)
|
||||||
{
|
{
|
||||||
FilterHeightfield(ctx, solid, cfg);
|
FilterHeightfield(ctx, solid, cfg);
|
||||||
RcCompactHeightfield chf = BuildCompactHeightfield(ctx, geom, cfg, solid);
|
RcCompactHeightfield chf = BuildCompactHeightfield(ctx, geom, cfg, solid);
|
||||||
|
@ -188,7 +205,7 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
// Prepare for region partitioning, by calculating distance field along the walkable surface.
|
// Prepare for region partitioning, by calculating distance field along the walkable surface.
|
||||||
RcRegions.BuildDistanceField(ctx, chf);
|
RcRegions.BuildDistanceField(ctx, chf);
|
||||||
|
|
||||||
// Partition the walkable surface into simple regions without holes.
|
// Partition the walkable surface into simple regions without holes.
|
||||||
RcRegions.BuildRegions(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea);
|
RcRegions.BuildRegions(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea);
|
||||||
}
|
}
|
||||||
|
@ -224,17 +241,7 @@ namespace DotRecast.Recast
|
||||||
RcPolyMeshDetail dmesh = cfg.BuildMeshDetail
|
RcPolyMeshDetail dmesh = cfg.BuildMeshDetail
|
||||||
? RcMeshDetails.BuildPolyMeshDetail(ctx, pmesh, chf, cfg.DetailSampleDist, cfg.DetailSampleMaxError)
|
? RcMeshDetails.BuildPolyMeshDetail(ctx, pmesh, chf, cfg.DetailSampleDist, cfg.DetailSampleMaxError)
|
||||||
: null;
|
: null;
|
||||||
|
return new RcBuilderResult(tileX, tileZ, solid, chf, cset, pmesh, dmesh, ctx);
|
||||||
return new RcBuilderResult(
|
|
||||||
tileX,
|
|
||||||
tileZ,
|
|
||||||
keepInterResults ? solid : null,
|
|
||||||
keepInterResults ? chf : null,
|
|
||||||
keepInterResults ? cset : null,
|
|
||||||
pmesh,
|
|
||||||
dmesh,
|
|
||||||
ctx
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -291,7 +298,7 @@ namespace DotRecast.Recast
|
||||||
RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(ctx, geom, builderCfg);
|
RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(ctx, geom, builderCfg);
|
||||||
FilterHeightfield(ctx, solid, builderCfg.cfg);
|
FilterHeightfield(ctx, solid, builderCfg.cfg);
|
||||||
RcCompactHeightfield chf = BuildCompactHeightfield(ctx, geom, builderCfg.cfg, solid);
|
RcCompactHeightfield chf = BuildCompactHeightfield(ctx, geom, builderCfg.cfg, solid);
|
||||||
|
|
||||||
RcLayers.BuildHeightfieldLayers(ctx, chf, builderCfg.cfg.BorderSize, builderCfg.cfg.WalkableHeight, out var lset);
|
RcLayers.BuildHeightfieldLayers(ctx, chf, builderCfg.cfg.BorderSize, builderCfg.cfg.WalkableHeight, out var lset);
|
||||||
return lset;
|
return lset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,56 @@ namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
public class RcBuilderResult
|
public class RcBuilderResult
|
||||||
{
|
{
|
||||||
public readonly int TileX;
|
public readonly int tileX;
|
||||||
public readonly int TileZ;
|
public readonly int tileZ;
|
||||||
|
|
||||||
|
private readonly RcCompactHeightfield chf;
|
||||||
|
private readonly RcContourSet cs;
|
||||||
|
private readonly RcPolyMesh pmesh;
|
||||||
|
private readonly RcPolyMeshDetail dmesh;
|
||||||
|
private readonly RcHeightfield solid;
|
||||||
|
private readonly RcContext _context;
|
||||||
|
|
||||||
public readonly RcHeightfield SolidHeightfiled;
|
public RcBuilderResult(int tileX, int tileZ, RcHeightfield solid, RcCompactHeightfield chf, RcContourSet cs, RcPolyMesh pmesh, RcPolyMeshDetail dmesh, RcContext ctx)
|
||||||
public readonly RcCompactHeightfield CompactHeightfield;
|
|
||||||
public readonly RcContourSet ContourSet;
|
|
||||||
public readonly RcPolyMesh Mesh;
|
|
||||||
public readonly RcPolyMeshDetail MeshDetail;
|
|
||||||
public readonly RcContext Context;
|
|
||||||
|
|
||||||
public RcBuilderResult(int tileX, int tileZ, RcHeightfield solidHeightfiled, RcCompactHeightfield compactHeightfield, RcContourSet contourSet, RcPolyMesh mesh, RcPolyMeshDetail meshDetail, RcContext ctx)
|
|
||||||
{
|
{
|
||||||
TileX = tileX;
|
this.tileX = tileX;
|
||||||
TileZ = tileZ;
|
this.tileZ = tileZ;
|
||||||
SolidHeightfiled = solidHeightfiled;
|
this.solid = solid;
|
||||||
CompactHeightfield = compactHeightfield;
|
this.chf = chf;
|
||||||
ContourSet = contourSet;
|
this.cs = cs;
|
||||||
Mesh = mesh;
|
this.pmesh = pmesh;
|
||||||
MeshDetail = meshDetail;
|
this.dmesh = dmesh;
|
||||||
Context = ctx;
|
_context = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcPolyMesh GetMesh()
|
||||||
|
{
|
||||||
|
return pmesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcPolyMeshDetail GetMeshDetail()
|
||||||
|
{
|
||||||
|
return dmesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcCompactHeightfield GetCompactHeightfield()
|
||||||
|
{
|
||||||
|
return chf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcContourSet GetContourSet()
|
||||||
|
{
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcHeightfield GetSolidHeightfield()
|
||||||
|
{
|
||||||
|
return solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RcContext GetTelemetry()
|
||||||
|
{
|
||||||
|
return _context;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,21 +22,29 @@ using DotRecast.Core.Numerics;
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
namespace DotRecast.Recast
|
||||||
{
|
{
|
||||||
/// A dynamic heightfield representing obstructed space.
|
/** Represents a heightfield layer within a layer set. */
|
||||||
/// @ingroup recast
|
|
||||||
public class RcHeightfield
|
public class RcHeightfield
|
||||||
{
|
{
|
||||||
public readonly int width; //< The width of the heightfield. (Along the x-axis in cell units.)
|
/** The width of the heightfield. (Along the x-axis in cell units.) */
|
||||||
public readonly int height; //< The height of the heightfield. (Along the z-axis in cell units.)
|
public readonly int width;
|
||||||
public readonly RcVec3f bmin; //< The minimum bounds in world space. [(x, y, z)]
|
|
||||||
public RcVec3f bmax; //< The maximum bounds in world space. [(x, y, z)]
|
|
||||||
public readonly float cs; //< The size of each cell. (On the xz-plane.)
|
|
||||||
public readonly float ch; //< The height of each cell. (The minimum increment along the y-axis.)
|
|
||||||
public readonly RcSpan[] spans; //< Heightfield of spans (width*height).
|
|
||||||
|
|
||||||
// memory pool for rcSpan instances.
|
/** The height of the heightfield. (Along the z-axis in cell units.) */
|
||||||
public RcSpanPool pools; //< Linked list of span pools.
|
public readonly int height;
|
||||||
public RcSpan freelist; //< The next free span.
|
|
||||||
|
/** The minimum bounds in world space. [(x, y, z)] */
|
||||||
|
public readonly RcVec3f bmin;
|
||||||
|
|
||||||
|
/** The maximum bounds in world space. [(x, y, z)] */
|
||||||
|
public RcVec3f bmax;
|
||||||
|
|
||||||
|
/** The size of each cell. (On the xz-plane.) */
|
||||||
|
public readonly float cs;
|
||||||
|
|
||||||
|
/** The height of each cell. (The minimum increment along the y-axis.) */
|
||||||
|
public readonly float ch;
|
||||||
|
|
||||||
|
/** Heightfield of spans (width*height). */
|
||||||
|
public readonly RcSpan[] spans;
|
||||||
|
|
||||||
/** Border size in cell units */
|
/** Border size in cell units */
|
||||||
public readonly int borderSize;
|
public readonly int borderSize;
|
||||||
|
|
|
@ -30,9 +30,9 @@ namespace DotRecast.Recast
|
||||||
hitTime = 0.0f;
|
hitTime = 0.0f;
|
||||||
foreach (RcBuilderResult result in results)
|
foreach (RcBuilderResult result in results)
|
||||||
{
|
{
|
||||||
if (result.MeshDetail != null)
|
if (result.GetMeshDetail() != null)
|
||||||
{
|
{
|
||||||
if (Raycast(result.Mesh, result.MeshDetail, src, dst, out hitTime))
|
if (Raycast(result.GetMesh(), result.GetMeshDetail(), src, dst, out hitTime))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,63 +41,6 @@ namespace DotRecast.Recast
|
||||||
aMin.Y <= bMax.Y && aMax.Y >= bMin.Y &&
|
aMin.Y <= bMax.Y && aMax.Y >= bMin.Y &&
|
||||||
aMin.Z <= bMax.Z && aMax.Z >= bMin.Z;
|
aMin.Z <= bMax.Z && aMax.Z >= bMin.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a new span in the heightfield.
|
|
||||||
/// Use a memory pool and free list to minimize actual allocations.
|
|
||||||
///
|
|
||||||
/// @param[in] heightfield The heightfield
|
|
||||||
/// @returns A pointer to the allocated or re-used span memory.
|
|
||||||
private static RcSpan AllocSpan(RcHeightfield heightfield)
|
|
||||||
{
|
|
||||||
// If necessary, allocate new page and update the freelist.
|
|
||||||
if (heightfield.freelist == null || heightfield.freelist.next == null)
|
|
||||||
{
|
|
||||||
// Create new page.
|
|
||||||
// Allocate memory for the new pool.
|
|
||||||
RcSpanPool spanPool = new RcSpanPool();
|
|
||||||
if (spanPool == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the pool into the list of pools.
|
|
||||||
spanPool.next = heightfield.pools;
|
|
||||||
heightfield.pools = spanPool;
|
|
||||||
|
|
||||||
// Add new spans to the free list.
|
|
||||||
RcSpan freeList = heightfield.freelist;
|
|
||||||
int head = 0;
|
|
||||||
int it = RC_SPANS_PER_POOL;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
--it;
|
|
||||||
spanPool.items[it].next = freeList;
|
|
||||||
freeList = spanPool.items[it];
|
|
||||||
} while (it != head);
|
|
||||||
|
|
||||||
heightfield.freelist = spanPool.items[it];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop item from the front of the free list.
|
|
||||||
RcSpan newSpan = heightfield.freelist;
|
|
||||||
heightfield.freelist = heightfield.freelist.next;
|
|
||||||
return newSpan;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Releases the memory used by the span back to the heightfield, so it can be re-used for new spans.
|
|
||||||
/// @param[in] heightfield The heightfield.
|
|
||||||
/// @param[in] span A pointer to the span to free
|
|
||||||
private static void FreeSpan(RcHeightfield heightfield, RcSpan span)
|
|
||||||
{
|
|
||||||
if (span == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the span to the front of the free list.
|
|
||||||
span.next = heightfield.freelist;
|
|
||||||
heightfield.freelist = span;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Adds a span to the heightfield. If the new span overlaps existing spans,
|
/// Adds a span to the heightfield. If the new span overlaps existing spans,
|
||||||
|
@ -213,7 +156,7 @@ namespace DotRecast.Recast
|
||||||
float axisOffset, int axis)
|
float axisOffset, int axis)
|
||||||
{
|
{
|
||||||
// How far positive or negative away from the separating axis is each vertex.
|
// How far positive or negative away from the separating axis is each vertex.
|
||||||
Span<float> inVertAxisDelta = stackalloc float[12];
|
float[] inVertAxisDelta = new float[12];
|
||||||
for (int inVert = 0; inVert < inVertsCount; ++inVert)
|
for (int inVert = 0; inVert < inVertsCount; ++inVert)
|
||||||
{
|
{
|
||||||
inVertAxisDelta[inVert] = axisOffset - inVerts[inVertsOffset + inVert * 3 + axis];
|
inVertAxisDelta[inVert] = axisOffset - inVerts[inVertsOffset + inVert * 3 + axis];
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
|
||||||
DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com
|
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
|
||||||
arising from the use of this software.
|
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
|
||||||
freely, subject to the following restrictions:
|
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
|
||||||
in a product, an acknowledgment in the product documentation would be
|
|
||||||
appreciated but is not required.
|
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
misrepresented as being the original software.
|
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace DotRecast.Recast
|
|
||||||
{
|
|
||||||
/// A memory pool used for quick allocation of spans within a heightfield.
|
|
||||||
/// @see rcHeightfield
|
|
||||||
public class RcSpanPool
|
|
||||||
{
|
|
||||||
public RcSpanPool next; //< The next span pool.
|
|
||||||
public readonly RcSpan[] items; //< Array of spans in the pool.
|
|
||||||
|
|
||||||
public RcSpanPool()
|
|
||||||
{
|
|
||||||
items = new RcSpan[RcConstants.RC_SPANS_PER_POOL];
|
|
||||||
for (int i = 0; i < items.Length; ++i)
|
|
||||||
{
|
|
||||||
items[i] = new RcSpan();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,13 +9,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -72,14 +72,14 @@ public class RecastTestMeshBuilder
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
||||||
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg, false);
|
RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg);
|
||||||
RcPolyMesh m_pmesh = rcResult.Mesh;
|
RcPolyMesh m_pmesh = rcResult.GetMesh();
|
||||||
for (int i = 0; i < m_pmesh.npolys; ++i)
|
for (int i = 0; i < m_pmesh.npolys; ++i)
|
||||||
{
|
{
|
||||||
m_pmesh.flags[i] = 1;
|
m_pmesh.flags[i] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
RcPolyMeshDetail m_dmesh = rcResult.MeshDetail;
|
RcPolyMeshDetail m_dmesh = rcResult.GetMeshDetail();
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
option.verts = m_pmesh.verts;
|
option.verts = m_pmesh.verts;
|
||||||
option.vertCount = m_pmesh.nverts;
|
option.vertCount = m_pmesh.nverts;
|
||||||
|
|
|
@ -9,17 +9,17 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -10,6 +10,7 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Dynamic.Test;
|
namespace DotRecast.Detour.Dynamic.Test;
|
||||||
|
|
||||||
|
|
||||||
public class DynamicNavMeshTest
|
public class DynamicNavMeshTest
|
||||||
{
|
{
|
||||||
private static readonly RcVec3f START_POS = new RcVec3f(70.87453f, 0.0010070801f, 86.69021f);
|
private static readonly RcVec3f START_POS = new RcVec3f(70.87453f, 0.0010070801f, 86.69021f);
|
||||||
|
@ -31,7 +32,9 @@ public class DynamicNavMeshTest
|
||||||
// create dynamic navmesh
|
// create dynamic navmesh
|
||||||
DtDynamicNavMesh mesh = new DtDynamicNavMesh(f);
|
DtDynamicNavMesh mesh = new DtDynamicNavMesh(f);
|
||||||
// build navmesh asynchronously using multiple threads
|
// build navmesh asynchronously using multiple threads
|
||||||
mesh.Build(Task.Factory);
|
Task<bool> future = mesh.Build(Task.Factory);
|
||||||
|
// wait for build to complete
|
||||||
|
bool _ = future.Result;
|
||||||
|
|
||||||
// create new query
|
// create new query
|
||||||
DtNavMeshQuery query = new DtNavMeshQuery(mesh.NavMesh());
|
DtNavMeshQuery query = new DtNavMeshQuery(mesh.NavMesh());
|
||||||
|
@ -51,8 +54,9 @@ public class DynamicNavMeshTest
|
||||||
long colliderId = mesh.AddCollider(colldier);
|
long colliderId = mesh.AddCollider(colldier);
|
||||||
|
|
||||||
// update navmesh asynchronously
|
// update navmesh asynchronously
|
||||||
mesh.Update(Task.Factory);
|
future = mesh.Update(Task.Factory);
|
||||||
|
// wait for update to complete
|
||||||
|
_ = future.Result;
|
||||||
// create new query
|
// create new query
|
||||||
query = new DtNavMeshQuery(mesh.NavMesh());
|
query = new DtNavMeshQuery(mesh.NavMesh());
|
||||||
|
|
||||||
|
@ -66,7 +70,9 @@ public class DynamicNavMeshTest
|
||||||
// remove obstacle
|
// remove obstacle
|
||||||
mesh.RemoveCollider(colliderId);
|
mesh.RemoveCollider(colliderId);
|
||||||
// update navmesh asynchronously
|
// update navmesh asynchronously
|
||||||
mesh.Update(Task.Factory);
|
future = mesh.Update(Task.Factory);
|
||||||
|
// wait for update to complete
|
||||||
|
_ = future.Result;
|
||||||
// create new query
|
// create new query
|
||||||
query = new DtNavMeshQuery(mesh.NavMesh());
|
query = new DtNavMeshQuery(mesh.NavMesh());
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Detour.Dynamic.Test;
|
namespace DotRecast.Detour.Dynamic.Test;
|
||||||
|
|
||||||
|
|
||||||
public class VoxelQueryTest
|
public class VoxelQueryTest
|
||||||
{
|
{
|
||||||
private const int TILE_WIDTH = 100;
|
private const int TILE_WIDTH = 100;
|
||||||
|
@ -100,12 +101,12 @@ public class VoxelQueryTest
|
||||||
// load voxels from file
|
// load voxels from file
|
||||||
DtVoxelFileReader reader = new DtVoxelFileReader(DtVoxelTileLZ4ForTestCompressor.Shared);
|
DtVoxelFileReader reader = new DtVoxelFileReader(DtVoxelTileLZ4ForTestCompressor.Shared);
|
||||||
DtVoxelFile f = reader.Read(br);
|
DtVoxelFile f = reader.Read(br);
|
||||||
|
|
||||||
// create dynamic navmesh
|
// create dynamic navmesh
|
||||||
var mesh = new DtDynamicNavMesh(f);
|
var mesh = new DtDynamicNavMesh(f);
|
||||||
|
|
||||||
// build navmesh asynchronously using multiple threads
|
// build navmesh asynchronously using multiple threads
|
||||||
mesh.Build(Task.Factory);
|
Task<bool> future = mesh.Build(Task.Factory);
|
||||||
|
// wait for build to complete
|
||||||
|
var _ = future.Result;
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,13 +9,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -72,14 +72,14 @@ public class RecastTestMeshBuilder
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
||||||
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax());
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg, false);
|
RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg);
|
||||||
RcPolyMesh m_pmesh = rcResult.Mesh;
|
RcPolyMesh m_pmesh = rcResult.GetMesh();
|
||||||
for (int i = 0; i < m_pmesh.npolys; ++i)
|
for (int i = 0; i < m_pmesh.npolys; ++i)
|
||||||
{
|
{
|
||||||
m_pmesh.flags[i] = 1;
|
m_pmesh.flags[i] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
RcPolyMeshDetail m_dmesh = rcResult.MeshDetail;
|
RcPolyMeshDetail m_dmesh = rcResult.GetMeshDetail();
|
||||||
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
|
||||||
option.verts = m_pmesh.verts;
|
option.verts = m_pmesh.verts;
|
||||||
option.vertCount = m_pmesh.nverts;
|
option.vertCount = m_pmesh.nverts;
|
||||||
|
|
|
@ -27,8 +27,8 @@ public class TestDetourBuilder : DetourBuilder
|
||||||
float agentMaxClimb, int x, int y, bool applyRecastDemoFlags)
|
float agentMaxClimb, int x, int y, bool applyRecastDemoFlags)
|
||||||
{
|
{
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
RcBuilderResult rcResult = rcBuilder.Build(geom, rcConfig, false);
|
RcBuilderResult rcResult = rcBuilder.Build(geom, rcConfig);
|
||||||
RcPolyMesh pmesh = rcResult.Mesh;
|
RcPolyMesh pmesh = rcResult.GetMesh();
|
||||||
|
|
||||||
if (applyRecastDemoFlags)
|
if (applyRecastDemoFlags)
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ public class TestDetourBuilder : DetourBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RcPolyMeshDetail dmesh = rcResult.MeshDetail;
|
RcPolyMeshDetail dmesh = rcResult.GetMeshDetail();
|
||||||
DtNavMeshCreateParams option = GetNavMeshCreateParams(rcConfig.cfg, pmesh, dmesh, agentHeight, agentRadius,
|
DtNavMeshCreateParams option = GetNavMeshCreateParams(rcConfig.cfg, pmesh, dmesh, agentHeight, agentRadius,
|
||||||
agentMaxClimb);
|
agentMaxClimb);
|
||||||
return Build(option, x, y);
|
return Build(option, x, y);
|
||||||
|
|
|
@ -78,13 +78,13 @@ public class TestTiledNavMeshBuilder
|
||||||
true, true, true,
|
true, true, true,
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
||||||
RcBuilder rcBuilder = new RcBuilder();
|
RcBuilder rcBuilder = new RcBuilder();
|
||||||
List<RcBuilderResult> rcResult = rcBuilder.BuildTiles(geom, cfg, false, true);
|
List<RcBuilderResult> rcResult = rcBuilder.BuildTiles(geom, cfg, null);
|
||||||
|
|
||||||
// Add tiles to nav mesh
|
// Add tiles to nav mesh
|
||||||
|
|
||||||
foreach (RcBuilderResult result in rcResult)
|
foreach (RcBuilderResult result in rcResult)
|
||||||
{
|
{
|
||||||
RcPolyMesh pmesh = result.Mesh;
|
RcPolyMesh pmesh = result.GetMesh();
|
||||||
if (pmesh.npolys == 0)
|
if (pmesh.npolys == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
@ -103,7 +103,7 @@ public class TestTiledNavMeshBuilder
|
||||||
option.polyFlags = pmesh.flags;
|
option.polyFlags = pmesh.flags;
|
||||||
option.polyCount = pmesh.npolys;
|
option.polyCount = pmesh.npolys;
|
||||||
option.nvp = pmesh.nvp;
|
option.nvp = pmesh.nvp;
|
||||||
RcPolyMeshDetail dmesh = result.MeshDetail;
|
RcPolyMeshDetail dmesh = result.GetMeshDetail();
|
||||||
option.detailMeshes = dmesh.meshes;
|
option.detailMeshes = dmesh.meshes;
|
||||||
option.detailVerts = dmesh.verts;
|
option.detailVerts = dmesh.verts;
|
||||||
option.detailVertsCount = dmesh.nverts;
|
option.detailVertsCount = dmesh.nverts;
|
||||||
|
@ -116,8 +116,8 @@ public class TestTiledNavMeshBuilder
|
||||||
option.bmax = pmesh.bmax;
|
option.bmax = pmesh.bmax;
|
||||||
option.cs = cellSize;
|
option.cs = cellSize;
|
||||||
option.ch = cellHeight;
|
option.ch = cellHeight;
|
||||||
option.tileX = result.TileX;
|
option.tileX = result.tileX;
|
||||||
option.tileZ = result.TileZ;
|
option.tileZ = result.tileZ;
|
||||||
option.buildBvTree = true;
|
option.buildBvTree = true;
|
||||||
navMesh.AddTile(DtNavMeshBuilder.CreateNavMeshData(option), 0, 0);
|
navMesh.AddTile(DtNavMeshBuilder.CreateNavMeshData(option), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,17 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.8" />
|
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.6" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="Moq" Version="4.20.70" />
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
<PackageReference Include="NUnit" Version="4.0.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
|
||||||
<PackageReference Include="NUnit.Analyzers" Version="4.1.0">
|
<PackageReference Include="NUnit.Analyzers" Version="4.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.2">
|
<PackageReference Include="coverlet.collector" Version="6.0.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -27,6 +27,7 @@ using NUnit.Framework;
|
||||||
|
|
||||||
namespace DotRecast.Recast.Test;
|
namespace DotRecast.Recast.Test;
|
||||||
|
|
||||||
|
|
||||||
public class RecastTileMeshTest
|
public class RecastTileMeshTest
|
||||||
{
|
{
|
||||||
private const float m_cellSize = 0.3f;
|
private const float m_cellSize = 0.3f;
|
||||||
|
@ -69,29 +70,29 @@ public class RecastTileMeshTest
|
||||||
true, true, true,
|
true, true, true,
|
||||||
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true);
|
||||||
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 7, 8);
|
RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 7, 8);
|
||||||
RcBuilderResult rcResult = builder.Build(geom, bcfg, false);
|
RcBuilderResult rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(1));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(1));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(5));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(5));
|
||||||
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 6, 9);
|
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 6, 9);
|
||||||
rcResult = builder.Build(geom, bcfg, false);
|
rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(2));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(7));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(7));
|
||||||
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 9);
|
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 9);
|
||||||
rcResult = builder.Build(geom, bcfg, false);
|
rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(2));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(9));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(9));
|
||||||
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 4, 3);
|
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 4, 3);
|
||||||
rcResult = builder.Build(geom, bcfg, false);
|
rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(3));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(3));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(6));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(6));
|
||||||
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 8);
|
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 8);
|
||||||
rcResult = builder.Build(geom, bcfg, false);
|
rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(5));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(5));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(17));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(17));
|
||||||
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 0, 8);
|
bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 0, 8);
|
||||||
rcResult = builder.Build(geom, bcfg, false);
|
rcResult = builder.Build(geom, bcfg);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(6));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(6));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(15));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -137,27 +138,28 @@ public class RecastTileMeshTest
|
||||||
private void Build(IInputGeomProvider geom, RcBuilder builder, RcConfig cfg, int threads, bool validate)
|
private void Build(IInputGeomProvider geom, RcBuilder builder, RcConfig cfg, int threads, bool validate)
|
||||||
{
|
{
|
||||||
CancellationTokenSource cts = new CancellationTokenSource();
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
List<RcBuilderResult> tiles = builder.BuildTiles(geom, cfg, false, true, threads, Task.Factory, cts.Token);
|
List<RcBuilderResult> tiles = new();
|
||||||
|
var task = builder.BuildTilesAsync(geom, cfg, threads, tiles, Task.Factory, cts.Token);
|
||||||
if (validate)
|
if (validate)
|
||||||
{
|
{
|
||||||
RcBuilderResult rcResult = GetTile(tiles, 7, 8);
|
RcBuilderResult rcResult = GetTile(tiles, 7, 8);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(1));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(1));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(5));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(5));
|
||||||
rcResult = GetTile(tiles, 6, 9);
|
rcResult = GetTile(tiles, 6, 9);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(2));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(7));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(7));
|
||||||
rcResult = GetTile(tiles, 2, 9);
|
rcResult = GetTile(tiles, 2, 9);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(2));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(9));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(9));
|
||||||
rcResult = GetTile(tiles, 4, 3);
|
rcResult = GetTile(tiles, 4, 3);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(3));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(3));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(6));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(6));
|
||||||
rcResult = GetTile(tiles, 2, 8);
|
rcResult = GetTile(tiles, 2, 8);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(5));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(5));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(17));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(17));
|
||||||
rcResult = GetTile(tiles, 0, 8);
|
rcResult = GetTile(tiles, 0, 8);
|
||||||
Assert.That(rcResult.Mesh.npolys, Is.EqualTo(6));
|
Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(6));
|
||||||
Assert.That(rcResult.Mesh.nverts, Is.EqualTo(15));
|
Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(15));
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -173,6 +175,6 @@ public class RecastTileMeshTest
|
||||||
|
|
||||||
private RcBuilderResult GetTile(List<RcBuilderResult> tiles, int x, int z)
|
private RcBuilderResult GetTile(List<RcBuilderResult> tiles, int x, int z)
|
||||||
{
|
{
|
||||||
return tiles.FirstOrDefault(tile => tile.TileX == x && tile.TileZ == z);
|
return tiles.FirstOrDefault(tile => tile.tileX == x && tile.tileZ == z);
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue