fix bug where return value of dynamic update result is reversed

This commit is contained in:
ikpil 2024-04-13 12:43:54 +09:00
parent 668ebd0128
commit 26a1dfddeb
7 changed files with 65 additions and 68 deletions

View File

@ -3,5 +3,7 @@
public interface IRcRand
{
float Next();
double NextDouble();
int NextInt32();
}
}

View File

@ -6,9 +6,13 @@ namespace DotRecast.Core
{
private readonly Random _r;
public RcRand()
public RcRand() : this(new Random())
{
_r = new Random();
}
public RcRand(Random r)
{
_r = r;
}
public RcRand(long seed)
@ -21,6 +25,11 @@ namespace DotRecast.Core
return (float)_r.NextDouble();
}
public double NextDouble()
{
return _r.NextDouble();
}
public int NextInt32()
{
return _r.Next();

View File

@ -40,7 +40,7 @@ namespace DotRecast.Detour.Dynamic
private readonly BlockingCollection<IDtDaynmicTileJob> updateQueue = new BlockingCollection<IDtDaynmicTileJob>();
private readonly RcAtomicLong currentColliderId = new RcAtomicLong(0);
private DtNavMesh _navMesh;
private bool dirty = true;
private bool _dirty = true;
public DtDynamicNavMesh(DtVoxelFile voxelFile)
{
@ -105,29 +105,6 @@ namespace DotRecast.Detour.Dynamic
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()
{
@ -159,27 +136,49 @@ namespace DotRecast.Detour.Dynamic
}
}
/**
* Perform full build concurrently using the given {@link ExecutorService}
*/
public Task<bool> Build(TaskFactory executor)
// Perform full build of the navmesh
public void Build()
{
ProcessQueue();
Rebuild(_tiles.Values);
}
// Perform full build concurrently using the given {@link ExecutorService}
public bool Build(TaskFactory executor)
{
ProcessQueue();
return Rebuild(_tiles.Values, executor);
}
/**
* Perform incremental update concurrently using the given {@link ExecutorService}
*/
public Task<bool> Update(TaskFactory executor)
// Perform incremental update of the navmesh
public bool Update()
{
return Rebuild(ProcessQueue());
}
// Perform incremental update concurrently using the given {@link ExecutorService}
public bool Update(TaskFactory executor)
{
return Rebuild(ProcessQueue(), executor);
}
private Task<bool> Rebuild(ICollection<DtDynamicTile> tiles, TaskFactory executor)
private bool Rebuild(ICollection<DtDynamicTile> tiles)
{
var tasks = tiles.Select(tile => executor.StartNew(() => Rebuild(tile))).ToArray();
return Task.WhenAll(tasks).ContinueWith(k => UpdateNavMesh());
foreach (var tile in tiles)
Rebuild(tile);
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)
@ -218,19 +217,19 @@ namespace DotRecast.Detour.Dynamic
{
DtNavMeshCreateParams option = new DtNavMeshCreateParams();
option.walkableHeight = config.walkableHeight;
dirty = dirty | tile.Build(builder, config, _context);
_dirty = _dirty | tile.Build(builder, config, _context);
}
private bool UpdateNavMesh()
{
if (dirty)
if (_dirty)
{
DtNavMesh navMesh = new DtNavMesh(navMeshParams, MAX_VERTS_PER_POLY);
foreach (var t in _tiles.Values)
t.AddTo(navMesh);
this._navMesh = navMesh;
dirty = false;
_navMesh = navMesh;
_dirty = false;
return true;
}

View File

@ -91,7 +91,7 @@ public class DynamicUpdateSampleTool : ISampleTool
var bridgeGeom = DemoInputGeomProvider.LoadFile("bridge.obj");
var houseGeom = DemoInputGeomProvider.LoadFile("house.obj");
var convexGeom = DemoInputGeomProvider.LoadFile("convex.obj");
_tool = new(Random.Shared, bridgeGeom, houseGeom, convexGeom);
_tool = new(new RcRand(Random.Shared), bridgeGeom, houseGeom, convexGeom);
executor = Task.Factory;
}
@ -406,7 +406,7 @@ public class DynamicUpdateSampleTool : ISampleTool
long t = RcFrequency.Ticks;
try
{
bool updated = _tool.UpdateDynaMesh(executor);
bool updated = _tool.Update(executor);
if (updated)
{
buildTime = (RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond;
@ -450,7 +450,7 @@ public class DynamicUpdateSampleTool : ISampleTool
long t = RcFrequency.Ticks;
try
{
var _ = dynaMesh.Build(executor).Result;
var _ = dynaMesh.Build(executor);
}
catch (Exception e)
{

View File

@ -18,12 +18,12 @@ namespace DotRecast.Recast.Toolset.Tools
private DtDynamicNavMesh dynaMesh;
private readonly Dictionary<long, RcGizmo> colliderGizmos;
private readonly Random random;
private readonly IRcRand random;
private readonly DemoInputGeomProvider bridgeGeom;
private readonly DemoInputGeomProvider houseGeom;
private readonly DemoInputGeomProvider convexGeom;
public RcDynamicUpdateTool(Random rand, DemoInputGeomProvider bridgeGeom, DemoInputGeomProvider houseGeom, DemoInputGeomProvider convexGeom)
public RcDynamicUpdateTool(IRcRand rand, DemoInputGeomProvider bridgeGeom, DemoInputGeomProvider houseGeom, DemoInputGeomProvider convexGeom)
{
this.colliderGizmos = new Dictionary<long, RcGizmo>();
this.random = rand;
@ -339,20 +339,14 @@ namespace DotRecast.Recast.Toolset.Tools
return resultvector;
}
public bool UpdateDynaMesh(TaskFactory executor)
public bool Update(TaskFactory executor)
{
if (dynaMesh == null)
{
return false;
}
bool updated = dynaMesh.Update(executor).Result;
if (updated)
{
return false;
}
return true;
return dynaMesh.Update(executor);
}
public bool Raycast(RcVec3f spos, RcVec3f epos, out float hitPos, out RcVec3f raycastHitPos)

View File

@ -10,7 +10,6 @@ using NUnit.Framework;
namespace DotRecast.Detour.Dynamic.Test;
public class DynamicNavMeshTest
{
private static readonly RcVec3f START_POS = new RcVec3f(70.87453f, 0.0010070801f, 86.69021f);
@ -32,9 +31,7 @@ public class DynamicNavMeshTest
// create dynamic navmesh
DtDynamicNavMesh mesh = new DtDynamicNavMesh(f);
// build navmesh asynchronously using multiple threads
Task<bool> future = mesh.Build(Task.Factory);
// wait for build to complete
bool _ = future.Result;
mesh.Build(Task.Factory);
// create new query
DtNavMeshQuery query = new DtNavMeshQuery(mesh.NavMesh());
@ -54,9 +51,8 @@ public class DynamicNavMeshTest
long colliderId = mesh.AddCollider(colldier);
// update navmesh asynchronously
future = mesh.Update(Task.Factory);
// wait for update to complete
_ = future.Result;
mesh.Update(Task.Factory);
// create new query
query = new DtNavMeshQuery(mesh.NavMesh());
@ -70,9 +66,7 @@ public class DynamicNavMeshTest
// remove obstacle
mesh.RemoveCollider(colliderId);
// update navmesh asynchronously
future = mesh.Update(Task.Factory);
// wait for update to complete
_ = future.Result;
mesh.Update(Task.Factory);
// create new query
query = new DtNavMeshQuery(mesh.NavMesh());

View File

@ -31,7 +31,6 @@ using NUnit.Framework;
namespace DotRecast.Detour.Dynamic.Test;
public class VoxelQueryTest
{
private const int TILE_WIDTH = 100;
@ -101,12 +100,12 @@ public class VoxelQueryTest
// load voxels from file
DtVoxelFileReader reader = new DtVoxelFileReader(DtVoxelTileLZ4ForTestCompressor.Shared);
DtVoxelFile f = reader.Read(br);
// create dynamic navmesh
var mesh = new DtDynamicNavMesh(f);
// build navmesh asynchronously using multiple threads
Task<bool> future = mesh.Build(Task.Factory);
// wait for build to complete
var _ = future.Result;
mesh.Build(Task.Factory);
return mesh;
}
}