add demotool, toolable

This commit is contained in:
ikpil 2023-08-20 12:40:05 +09:00
parent a94965ac40
commit bac7a76258
33 changed files with 390 additions and 389 deletions

View File

@ -21,11 +21,12 @@ freely, subject to the following restrictions:
using System;
using System.Collections.Generic;
using DotRecast.Detour;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset
namespace DotRecast.Recast.Demo
{
public class Sample
public class DemoSample
{
private DemoInputGeomProvider _inputGeom;
private DtNavMesh _navMesh;
@ -34,7 +35,7 @@ namespace DotRecast.Recast.Toolset
private IList<RecastBuilderResult> _recastResults;
private bool _changed;
public Sample(DemoInputGeomProvider inputGeom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh)
public DemoSample(DemoInputGeomProvider inputGeom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh)
{
_inputGeom = inputGeom;
_recastResults = recastResults;

View File

@ -44,7 +44,7 @@ public class NavMeshRenderer
return _debugDraw;
}
public void Render(Sample sample, DrawMode drawMode)
public void Render(DemoSample sample, DrawMode drawMode)
{
if (sample == null)
{

View File

@ -73,7 +73,7 @@ public class RecastDemo : IRecastDemoChannel
private readonly TileNavMeshBuilder tileNavMeshBuilder = new TileNavMeshBuilder();
private string _lastGeomFileName;
private Sample _sample;
private DemoSample _sample;
private bool processHitTest = false;
private bool processHitTestShift;
@ -375,20 +375,20 @@ public class RecastDemo : IRecastDemoChannel
_imgui = new ImGuiController(_gl, window, _input, imGuiFontConfig);
DemoInputGeomProvider geom = LoadInputMesh("nav_test.obj");
_sample = new Sample(geom, ImmutableArray<RecastBuilderResult>.Empty, null);
_sample = new DemoSample(geom, ImmutableArray<RecastBuilderResult>.Empty, null);
settingsView = new RcSettingsView(this);
settingsView.SetSample(_sample);
toolset = new RcToolsetView(
new TestNavmeshTool(),
new TileTool(),
new ObstacleTool(),
new OffMeshConnectionTool(),
new ConvexVolumeTool(),
new CrowdTool(),
new JumpLinkBuilderTool(),
new DynamicUpdateTool()
new TestNavmeshDemoTool(),
new TileDemoTool(),
new ObstacleDemoTool(),
new OffMeshConnectionDemoTool(),
new ConvexVolumeDemoTool(),
new CrowdDemoTool(),
new JumpLinkBuilderDemoTool(),
new DynamicUpdateDemoTool()
);
toolset.SetEnabled(true);
logView = new RcLogView();
@ -610,10 +610,10 @@ public class RecastDemo : IRecastDemoChannel
dd.Fog(camr * 0.1f, camr * 1.25f);
renderer.Render(_sample, settingsView.GetDrawMode());
IRcTool tool = toolset.GetTool();
if (tool != null)
IRcDemoTool demoTool = toolset.GetTool();
if (demoTool != null)
{
tool.HandleRender(renderer);
demoTool.HandleRender(renderer);
}
dd.Fog(false);
@ -788,12 +788,12 @@ public class RecastDemo : IRecastDemoChannel
}
RcVec3f rayDir = RcVec3f.Of(rayEnd.x - rayStart.x, rayEnd.y - rayStart.y, rayEnd.z - rayStart.z);
IRcTool rayTool = toolset.GetTool();
IRcDemoTool rayDemoTool = toolset.GetTool();
rayDir.Normalize();
if (rayTool != null)
if (rayDemoTool != null)
{
Logger.Information($"click ray - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({rayDir.x:0.#},{rayDir.y:0.#},{rayDir.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClickRay(rayStart, rayDir, processHitTestShift);
Logger.Information($"click ray - tool({rayDemoTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({rayDir.x:0.#},{rayDir.y:0.#},{rayDir.z:0.#}) shift({processHitTestShift})");
rayDemoTool.HandleClickRay(rayStart, rayDir, processHitTestShift);
}
if (hit)
@ -812,10 +812,10 @@ public class RecastDemo : IRecastDemoChannel
pos.x = rayStart.x + (rayEnd.x - rayStart.x) * hitTime;
pos.y = rayStart.y + (rayEnd.y - rayStart.y) * hitTime;
pos.z = rayStart.z + (rayEnd.z - rayStart.z) * hitTime;
if (rayTool != null)
if (rayDemoTool != null)
{
Logger.Information($"click - tool({rayTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({pos.x:0.#},{pos.y:0.#},{pos.z:0.#}) shift({processHitTestShift})");
rayTool.HandleClick(rayStart, pos, processHitTestShift);
Logger.Information($"click - tool({rayDemoTool.GetTool().GetName()}) rayStart({rayStart.x:0.#},{rayStart.y:0.#},{rayStart.z:0.#}) pos({pos.x:0.#},{pos.y:0.#},{pos.z:0.#}) shift({processHitTestShift})");
rayDemoTool.HandleClick(rayStart, pos, processHitTestShift);
}
}
}

View File

@ -23,17 +23,22 @@ using System.Collections.Generic;
using DotRecast.Core;
using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Geom;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
namespace DotRecast.Recast.Demo.Tools;
public class ConvexVolumeTool : IRcTool
public class ConvexVolumeDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<ConvexVolumeDemoTool>();
private DemoSample _sample;
private readonly ConvexVolumeToolImpl _impl;
private int areaTypeValue = SampleAreaModifications.SAMPLE_AREAMOD_GRASS.Value;
@ -44,16 +49,22 @@ public class ConvexVolumeTool : IRcTool
private readonly List<RcVec3f> pts = new();
private readonly List<int> hull = new();
public ConvexVolumeTool()
public ConvexVolumeDemoTool()
{
_impl = new ConvexVolumeToolImpl();
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
// ..
@ -61,15 +72,13 @@ public class ConvexVolumeTool : IRcTool
public void HandleClick(RcVec3f s, RcVec3f p, bool shift)
{
DemoInputGeomProvider geom = _impl.GetSample().GetInputGeom();
if (geom == null)
{
return;
}
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var navMesh = _sample.GetNavMesh();
if (shift)
{
_impl.RemoveByPos(p);
_impl.RemoveByPos(geom, p);
}
else
{
@ -80,7 +89,9 @@ public class ConvexVolumeTool : IRcTool
{
var vol = ConvexVolumeToolImpl.CreateConvexVolume(pts, hull, areaType, boxDescent, boxHeight, polyOffset);
if (null != vol)
_impl.Add(vol);
{
_impl.Add(geom, vol);
}
pts.Clear();
hull.Clear();
@ -181,7 +192,7 @@ public class ConvexVolumeTool : IRcTool
hull.Clear();
pts.Clear();
DemoInputGeomProvider geom = _impl.GetSample().GetInputGeom();
var geom = _sample.GetInputGeom();
if (geom != null)
{
geom.ClearConvexVolumes();

View File

@ -29,13 +29,17 @@ using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
namespace DotRecast.Recast.Demo.Tools;
public class CrowdTool : IRcTool
public class CrowdDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<CrowdDemoTool>();
private DemoSample _sample;
private readonly CrowdToolImpl _impl;
private readonly CrowdToolParams toolParams = new CrowdToolParams();
private DtNavMesh m_nav;
@ -50,29 +54,36 @@ public class CrowdTool : IRcTool
private int m_modeIdx = CrowdToolMode.CREATE.Idx;
private long crowdUpdateTime;
public CrowdTool()
public CrowdDemoTool()
{
m_agentDebug.vod = new DtObstacleAvoidanceDebugData(2048);
profilingTool = new CrowdProfilingTool(GetAgentParams);
_impl = new();
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
DtNavMesh nav = _impl.GetSample().GetNavMesh();
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var navMesh = _sample.GetNavMesh();
if (nav != null && m_nav != nav)
if (navMesh != null && m_nav != navMesh)
{
m_nav = nav;
m_nav = navMesh;
DtCrowdConfig config = new DtCrowdConfig(_impl.GetSample().GetSettings().agentRadius);
DtCrowdConfig config = new DtCrowdConfig(settings.agentRadius);
crowd = new DtCrowd(config, nav, __ => new DtQueryDefaultFilter(SampleAreaModifications.SAMPLE_POLYFLAGS_ALL,
crowd = new DtCrowd(config, navMesh, __ => new DtQueryDefaultFilter(SampleAreaModifications.SAMPLE_POLYFLAGS_ALL,
SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED, new float[] { 1f, 10f, 1f, 1f, 2f, 1.5f }));
// Setup local avoidance option to different qualities.
@ -108,7 +119,7 @@ public class CrowdTool : IRcTool
crowd.SetObstacleAvoidanceParams(3, option);
profilingTool.Setup(_impl.GetSample().GetSettings().agentRadius, m_nav);
profilingTool.Setup(settings.agentRadius, m_nav);
}
}
@ -153,8 +164,8 @@ public class CrowdTool : IRcTool
}
else if (m_mode == CrowdToolMode.TOGGLE_POLYS)
{
DtNavMesh nav = _impl.GetSample().GetNavMesh();
DtNavMeshQuery navquery = _impl.GetSample().GetNavMeshQuery();
DtNavMesh nav = _sample.GetNavMesh();
DtNavMeshQuery navquery = _sample.GetNavMeshQuery();
if (nav != null && navquery != null)
{
IDtQueryFilter filter = new DtQueryDefaultFilter();
@ -210,11 +221,13 @@ public class CrowdTool : IRcTool
private DtCrowdAgentParams GetAgentParams()
{
var settings = _sample.GetSettings();
DtCrowdAgentParams ap = new DtCrowdAgentParams();
ap.radius = _impl.GetSample().GetSettings().agentRadius;
ap.height = _impl.GetSample().GetSettings().agentHeight;
ap.maxAcceleration = _impl.GetSample().GetSettings().agentMaxAcceleration;
ap.maxSpeed = _impl.GetSample().GetSettings().agentMaxSpeed;
ap.radius = settings.agentRadius;
ap.height = settings.agentHeight;
ap.maxAcceleration = settings.agentMaxAcceleration;
ap.maxSpeed = settings.agentMaxSpeed;
ap.collisionQueryRange = ap.radius * 12.0f;
ap.pathOptimizationRange = ap.radius * 30.0f;
ap.updateFlags = GetUpdateFlags();
@ -261,11 +274,11 @@ public class CrowdTool : IRcTool
private void SetMoveTarget(RcVec3f p, bool adjust)
{
if (_impl.GetSample() == null || crowd == null)
if (crowd == null)
return;
// Find nearest point on navmesh and set move request to that location.
DtNavMeshQuery navquery = _impl.GetSample().GetNavMeshQuery();
DtNavMeshQuery navquery = _sample.GetNavMeshQuery();
IDtQueryFilter filter = crowd.GetFilter(0);
RcVec3f halfExtents = crowd.GetQueryExtents();
@ -320,8 +333,9 @@ public class CrowdTool : IRcTool
}
RecastDebugDraw dd = renderer.GetDebugDraw();
float rad = _impl.GetSample().GetSettings().agentRadius;
DtNavMesh nav = _impl.GetSample().GetNavMesh();
var settings = _sample.GetSettings();
float rad = settings.agentRadius;
DtNavMesh nav = _sample.GetNavMesh();
if (nav == null || crowd == null)
return;
@ -633,7 +647,7 @@ public class CrowdTool : IRcTool
if (crowd == null)
return;
DtNavMesh nav = _impl.GetSample().GetNavMesh();
DtNavMesh nav = _sample.GetNavMesh();
if (nav == null)
return;

View File

@ -34,13 +34,17 @@ using DotRecast.Recast.Demo.UI;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
namespace DotRecast.Recast.Demo.Tools;
public class DynamicUpdateTool : IRcTool
public class DynamicUpdateDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<DynamicUpdateDemoTool>();
private DemoSample _sample;
private readonly DynamicUpdateToolImpl _impl;
private int toolModeIdx = DynamicUpdateToolMode.BUILD.Idx;
private DynamicUpdateToolMode mode = DynamicUpdateToolMode.BUILD;
@ -85,7 +89,7 @@ public class DynamicUpdateTool : IRcTool
private bool raycastHit;
private RcVec3f raycastHitPos;
public DynamicUpdateTool()
public DynamicUpdateDemoTool()
{
_impl = new();
executor = Task.Factory;
@ -94,11 +98,16 @@ public class DynamicUpdateTool : IRcTool
convexGeom = DemoObjImporter.Load(Loader.ToBytes("convex.obj"));
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
// ..
@ -447,9 +456,10 @@ public class DynamicUpdateTool : IRcTool
private void DrawAgent(RecastDebugDraw dd, RcVec3f pos, int col)
{
float r = _impl.GetSample().GetSettings().agentRadius;
float h = _impl.GetSample().GetSettings().agentHeight;
float c = _impl.GetSample().GetSettings().agentMaxClimb;
var settings = _sample.GetSettings();
float r = settings.agentRadius;
float h = settings.agentHeight;
float c = settings.agentMaxClimb;
dd.DepthMask(false);
// Agent dimensions.
dd.DebugDrawCylinderWire(pos.x - r, pos.y + 0.02f, pos.z - r, pos.x + r, pos.y + h, pos.z + r, col, 2.0f);
@ -483,8 +493,8 @@ public class DynamicUpdateTool : IRcTool
if (updated)
{
buildTime = (RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond;
_impl.GetSample().Update(null, dynaMesh.RecastResults(), dynaMesh.NavMesh());
_impl.GetSample().SetChanged(false);
_sample.Update(null, dynaMesh.RecastResults(), dynaMesh.NavMesh());
_sample.SetChanged(false);
}
}
catch (Exception e)
@ -615,7 +625,7 @@ public class DynamicUpdateTool : IRcTool
if (dynaMesh != null)
{
BuildDynaMesh();
_impl.GetSample().SetChanged(false);
_sample.SetChanged(false);
}
}
}
@ -716,7 +726,7 @@ public class DynamicUpdateTool : IRcTool
}
buildTime = (RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond;
_impl.GetSample().Update(null, dynaMesh.RecastResults(), dynaMesh.NavMesh());
_sample.Update(null, dynaMesh.RecastResults(), dynaMesh.NavMesh());
}
private void ConfigDynaMesh()

View File

@ -24,10 +24,12 @@ using DotRecast.Recast.Toolset;
namespace DotRecast.Recast.Demo.Tools;
public interface IRcTool
public interface IRcDemoTool
{
ISampleTool GetTool();
void SetSample(DemoSample sample);
void OnSampleChanged();
IRcToolable GetTool();
void Layout();
void HandleClick(RcVec3f s, RcVec3f p, bool shift);
void HandleRender(NavMeshRenderer renderer);

View File

@ -16,41 +16,48 @@ freely, subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
using System.Collections.Generic;
using DotRecast.Core;
using DotRecast.Detour.Extras.Jumplink;
using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Geom;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
namespace DotRecast.Recast.Demo.Tools;
public class JumpLinkBuilderTool : IRcTool
public class JumpLinkBuilderDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<JumpLinkBuilderDemoTool>();
private DemoSample _sample;
private readonly JumpLinkBuilderToolImpl _impl;
private readonly JumpLinkBuilderToolOption _option;
public JumpLinkBuilderTool()
public JumpLinkBuilderDemoTool()
{
_impl = new();
_option = new();
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
_impl.Clear();
}
public void HandleClick(RcVec3f s, RcVec3f p, bool shift)
{
}
@ -336,7 +343,7 @@ public class JumpLinkBuilderTool : IRcTool
public void Layout()
{
if (0 >= _impl.GetSample().GetRecastResults().Count)
if (0 >= _sample.GetRecastResults().Count)
return;
ImGui.Text("Options");
@ -379,7 +386,12 @@ public class JumpLinkBuilderTool : IRcTool
if (build || buildOffMeshConnections)
{
_impl.Build(buildOffMeshConnections,
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
_impl.Build(
geom, settings, _sample.GetRecastResults(),
buildOffMeshConnections,
_option.buildTypes,
_option.groundTolerance,
_option.climbDownDistance,

View File

@ -8,23 +8,31 @@ using Serilog;
namespace DotRecast.Recast.Demo.Tools;
public class ObstacleTool : IRcTool
public class ObstacleDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<ObstacleTool>();
private static readonly ILogger Logger = Log.ForContext<ObstacleDemoTool>();
private DemoSample _sample;
private readonly ObstacleToolImpl _impl;
private bool _hitPosSet;
private RcVec3f _hitPos;
public ObstacleTool()
public ObstacleDemoTool()
{
_impl = new(DtTileCacheCompressorFactory.Shared);
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
}

View File

@ -20,32 +20,41 @@ freely, subject to the following restrictions:
using System;
using DotRecast.Core;
using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Geom;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
namespace DotRecast.Recast.Demo.Tools;
public class OffMeshConnectionTool : IRcTool
public class OffMeshConnectionDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<OffMeshConnectionDemoTool>();
private DemoSample _sample;
private readonly OffMeshConnectionToolImpl _impl;
private bool hitPosSet;
private RcVec3f hitPos;
public OffMeshConnectionTool()
public OffMeshConnectionDemoTool()
{
_impl = new();
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
// ..
@ -53,15 +62,17 @@ public class OffMeshConnectionTool : IRcTool
public void HandleClick(RcVec3f s, RcVec3f p, bool shift)
{
DemoInputGeomProvider geom = _impl.GetSample().GetInputGeom();
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (geom == null)
{
return;
}
var settings = _sample.GetSettings();
if (shift)
{
_impl.Remove(p);
_impl.Remove(geom, settings, p);
}
else
{
@ -73,7 +84,7 @@ public class OffMeshConnectionTool : IRcTool
}
else
{
_impl.Add(hitPos, p);
_impl.Add(geom, settings, hitPos, p);
hitPosSet = false;
}
}
@ -81,20 +92,17 @@ public class OffMeshConnectionTool : IRcTool
public void HandleRender(NavMeshRenderer renderer)
{
if (_impl.GetSample() == null)
{
return;
}
RecastDebugDraw dd = renderer.GetDebugDraw();
float s = _impl.GetSample().GetSettings().agentRadius;
var settings = _sample.GetSettings();
float s = settings.agentRadius;
if (hitPosSet)
{
dd.DebugDrawCross(hitPos.x, hitPos.y + 0.1f, hitPos.z, s, DuRGBA(0, 0, 0, 128), 2.0f);
}
DemoInputGeomProvider geom = _impl.GetSample().GetInputGeom();
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (geom != null)
{
renderer.DrawOffMeshConnections(geom, true);

View File

@ -7,15 +7,19 @@ using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
using static DotRecast.Recast.Demo.Draw.DebugDraw;
using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives;
namespace DotRecast.Recast.Demo.Tools;
public class TestNavmeshTool : IRcTool
public class TestNavmeshDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<TestNavmeshDemoTool>();
private const int MAX_POLYS = 256;
private DemoSample _sample;
private readonly TestNavmeshToolImpl _impl;
private bool m_sposSet;
@ -43,7 +47,7 @@ public class TestNavmeshTool : IRcTool
private DtStatus m_pathFindStatus = DtStatus.DT_FAILURE;
private readonly List<RcVec3f> randomPoints = new();
public TestNavmeshTool()
public TestNavmeshDemoTool()
{
_impl = new();
m_filter = new DtQueryDefaultFilter(
@ -53,11 +57,16 @@ public class TestNavmeshTool : IRcTool
);
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
// ..
@ -162,15 +171,17 @@ public class TestNavmeshTool : IRcTool
private void Recalc()
{
if (_impl.GetSample().GetNavMesh() == null)
{
return;
}
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var navMesh = _sample.GetNavMesh();
var navQuery = _sample.GetNavMeshQuery();
if (null == geom || null == navQuery)
return;
DtNavMeshQuery m_navQuery = _impl.GetSample().GetNavMeshQuery();
if (m_sposSet)
{
m_navQuery.FindNearestPoly(m_spos, m_polyPickExt, m_filter, out m_startRef, out var _, out var _);
navQuery.FindNearestPoly(m_spos, m_polyPickExt, m_filter, out m_startRef, out var _, out var _);
}
else
{
@ -179,7 +190,7 @@ public class TestNavmeshTool : IRcTool
if (m_eposSet)
{
m_navQuery.FindNearestPoly(m_epos, m_polyPickExt, m_filter, out m_endRef, out var _, out var _);
navQuery.FindNearestPoly(m_epos, m_polyPickExt, m_filter, out m_endRef, out var _, out var _);
}
else
{
@ -194,7 +205,8 @@ public class TestNavmeshTool : IRcTool
{
var polys = new List<long>();
var smoothPath = new List<RcVec3f>();
var status = _impl.FindFollowPath(m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast,
var status = _impl.FindFollowPath(navMesh, navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast,
ref polys, ref smoothPath);
if (status.Succeeded())
@ -215,7 +227,7 @@ public class TestNavmeshTool : IRcTool
{
var polys = new List<long>();
var straightPath = new List<StraightPathItem>();
var status = _impl.FindStraightPath(m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast,
var status = _impl.FindStraightPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast,
ref polys, ref straightPath, option.straightPathOptions);
if (status.Succeeded())
@ -236,7 +248,7 @@ public class TestNavmeshTool : IRcTool
if (m_sposSet && m_eposSet && m_startRef != 0 && m_endRef != 0)
{
m_pathFindStatus = _impl.InitSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast);
m_pathFindStatus = _impl.InitSlicedFindPath(navQuery, m_startRef, m_endRef, m_spos, m_epos, m_filter, option.enableRaycast);
}
}
else if (option.mode == TestNavmeshToolMode.RAYCAST)
@ -246,7 +258,7 @@ public class TestNavmeshTool : IRcTool
{
var polys = new List<long>();
var straightPath = new List<StraightPathItem>();
var status = _impl.Raycast(m_startRef, m_spos, m_epos, m_filter,
var status = _impl.Raycast(navQuery, m_startRef, m_spos, m_epos, m_filter,
ref polys, ref straightPath, out var hitPos, out var hitNormal, out var hitResult);
if (status.Succeeded())
@ -264,7 +276,7 @@ public class TestNavmeshTool : IRcTool
m_distanceToWall = 0;
if (m_sposSet && m_startRef != 0)
{
var result = m_navQuery.FindDistanceToWall(m_startRef, m_spos, 100.0f, m_filter, out var hitDist, out var hitPos, out var hitNormal);
var result = navQuery.FindDistanceToWall(m_startRef, m_spos, 100.0f, m_filter, out var hitDist, out var hitPos, out var hitNormal);
if (result.Succeeded())
{
m_distanceToWall = hitDist;
@ -280,7 +292,7 @@ public class TestNavmeshTool : IRcTool
List<long> refs = new();
List<long> parentRefs = new();
var status = _impl.FindPolysAroundCircle(m_startRef, m_spos, m_epos, m_filter, ref refs, ref parentRefs);
var status = _impl.FindPolysAroundCircle(navQuery, m_startRef, m_spos, m_epos, m_filter, ref refs, ref parentRefs);
if (status.Succeeded())
{
m_polys = refs;
@ -295,7 +307,7 @@ public class TestNavmeshTool : IRcTool
var refs = new List<long>();
var parentRefs = new List<long>();
var status = _impl.FindPolysAroundShape(m_startRef, m_spos, m_epos, m_filter, ref refs, ref parentRefs, out var queryPoly);
var status = _impl.FindPolysAroundShape(navQuery, settings, m_startRef, m_spos, m_epos, m_filter, ref refs, ref parentRefs, out var queryPoly);
if (status.Succeeded())
{
m_queryPoly = queryPoly;
@ -308,10 +320,10 @@ public class TestNavmeshTool : IRcTool
{
if (m_sposSet && m_startRef != 0)
{
m_neighbourhoodRadius = _impl.GetSample().GetSettings().agentRadius * 20.0f;
m_neighbourhoodRadius = settings.agentRadius * 20.0f;
List<long> resultRef = new();
List<long> resultParent = new();
var status = m_navQuery.FindLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, m_filter, ref resultRef, ref resultParent);
var status = navQuery.FindLocalNeighbourhood(m_startRef, m_spos, m_neighbourhoodRadius, m_filter, ref resultRef, ref resultParent);
if (status.Succeeded())
{
m_polys = resultRef;
@ -325,7 +337,7 @@ public class TestNavmeshTool : IRcTool
if (m_sposSet && m_startRef != 0 && m_eposSet)
{
var points = new List<RcVec3f>();
_impl.FindRandomPointAroundCircle(m_startRef, m_spos, m_epos, m_filter, option.constrainByCircle, 500, ref points);
_impl.FindRandomPointAroundCircle(navQuery, m_startRef, m_spos, m_epos, m_filter, option.constrainByCircle, 500, ref points);
randomPoints.AddRange(points);
}
}
@ -333,19 +345,15 @@ public class TestNavmeshTool : IRcTool
public void HandleRender(NavMeshRenderer renderer)
{
if (_impl.GetSample() == null)
{
return;
}
RecastDebugDraw dd = renderer.GetDebugDraw();
int startCol = DuRGBA(128, 25, 0, 192);
int endCol = DuRGBA(51, 102, 0, 129);
int pathCol = DuRGBA(0, 0, 0, 64);
float agentRadius = _impl.GetSample().GetSettings().agentRadius;
float agentHeight = _impl.GetSample().GetSettings().agentHeight;
float agentClimb = _impl.GetSample().GetSettings().agentMaxClimb;
var settings = _sample.GetSettings();
float agentRadius = settings.agentRadius;
float agentHeight = settings.agentHeight;
float agentClimb = settings.agentMaxClimb;
if (m_sposSet)
{
@ -359,7 +367,7 @@ public class TestNavmeshTool : IRcTool
dd.DepthMask(true);
DtNavMesh m_navMesh = _impl.GetSample().GetNavMesh();
DtNavMesh m_navMesh = _sample.GetNavMesh();
if (m_navMesh == null)
{
return;
@ -666,9 +674,9 @@ public class TestNavmeshTool : IRcTool
}
dd.DepthMask(true);
if (_impl.GetSample().GetNavMeshQuery() != null)
if (_sample.GetNavMeshQuery() != null)
{
var result = _impl.GetSample()
var result = _sample
.GetNavMeshQuery()
.GetPolyWallSegments(m_polys[i], false, m_filter, ref segmentVerts, ref segmentRefs);
@ -759,9 +767,10 @@ public class TestNavmeshTool : IRcTool
private void DrawAgent(RecastDebugDraw dd, RcVec3f pos, int col)
{
float r = _impl.GetSample().GetSettings().agentRadius;
float h = _impl.GetSample().GetSettings().agentHeight;
float c = _impl.GetSample().GetSettings().agentMaxClimb;
var settings = _sample.GetSettings();
float r = settings.agentRadius;
float h = settings.agentHeight;
float c = settings.agentMaxClimb;
dd.DepthMask(false);
// Agent dimensions.
dd.DebugDrawCylinderWire(pos.x - r, pos.y + 0.02f, pos.z - r, pos.x + r, pos.y + h, pos.z + r, col, 2.0f);
@ -785,7 +794,7 @@ public class TestNavmeshTool : IRcTool
var option = _impl.GetOption();
if (option.mode == TestNavmeshToolMode.PATHFIND_SLICED)
{
DtNavMeshQuery m_navQuery = _impl.GetSample().GetNavMeshQuery();
DtNavMeshQuery m_navQuery = _sample.GetNavMeshQuery();
if (m_pathFindStatus.InProgress())
{
m_pathFindStatus = m_navQuery.UpdateSlicedFindPath(1, out var _);

View File

@ -2,6 +2,7 @@
using DotRecast.Core;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Toolset.Tools;
using ImGuiNET;
using Serilog;
@ -9,38 +10,49 @@ using static DotRecast.Recast.Demo.Draw.DebugDraw;
namespace DotRecast.Recast.Demo.Tools;
public class TileTool : IRcTool
public class TileDemoTool : IRcDemoTool
{
private static readonly ILogger Logger = Log.ForContext<TileTool>();
private static readonly ILogger Logger = Log.ForContext<TileDemoTool>();
private DemoSample _sample;
private readonly TileToolImpl _impl;
private bool _hitPosSet;
private RcVec3f _hitPos;
public TileTool()
public TileDemoTool()
{
_impl = new();
}
public ISampleTool GetTool()
public IRcToolable GetTool()
{
return _impl;
}
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged()
{
}
public void Layout()
{
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var navMesh = _sample.GetNavMesh();
if (ImGui.Button("Create All Tile"))
{
_impl.BuildAllTiles();
_impl.BuildAllTiles(geom, settings, navMesh);
}
if (ImGui.Button("Remove All Tile"))
{
_impl.RemoveAllTiles();
_impl.RemoveAllTiles(geom, settings, navMesh);
}
}
@ -49,17 +61,17 @@ public class TileTool : IRcTool
_hitPosSet = true;
_hitPos = p;
var sample = _impl.GetSample();
if (null == sample)
return;
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var navMesh = _sample.GetNavMesh();
if (shift)
{
_impl.RemoveTile(_hitPos);
_impl.RemoveTile(geom, settings, navMesh, _hitPos);
}
else
{
bool built = _impl.BuildTile(_hitPos, out var tileBuildTicks, out var tileTriCount, out var tileMemUsage);
bool built = _impl.BuildTile(geom, settings, navMesh, _hitPos, out var tileBuildTicks, out var tileTriCount, out var tileMemUsage);
if (!built)
{
Logger.Error($"failed to build tile - check!");
@ -73,11 +85,9 @@ public class TileTool : IRcTool
public void HandleRender(NavMeshRenderer renderer)
{
var sample = _impl.GetSample();
if (null == sample)
return;
var geom = _sample.GetInputGeom();
var settings = _sample.GetSettings();
var geom = sample.GetInputGeom();
if (null == geom)
return;
@ -87,7 +97,6 @@ public class TileTool : IRcTool
var bmin = geom.GetMeshBoundsMin();
var bmax = geom.GetMeshBoundsMax();
var settings = sample.GetSettings();
var s = settings.agentRadius;
float ts = settings.tileSize * settings.cellSize;

View File

@ -47,7 +47,7 @@ public class RcSettingsView : IRcView
private bool _isHovered;
public bool IsHovered() => _isHovered;
private Sample _sample;
private DemoSample _sample;
private RcCanvas _canvas;
public RcSettingsView(IRecastDemoChannel channel)
@ -55,7 +55,7 @@ public class RcSettingsView : IRcView
_channel = channel;
}
public void SetSample(Sample sample)
public void SetSample(DemoSample sample)
{
_sample = sample;
}

View File

@ -31,15 +31,15 @@ public class RcToolsetView : IRcView
{
//private readonly NkColor white = NkColor.Create();
private int _currentToolIdx = 0;
private IRcTool currentTool;
private IRcDemoTool _currentDemoTool;
private bool enabled;
private readonly IRcTool[] tools;
private readonly IRcDemoTool[] tools;
private bool _isHovered;
public bool IsHovered() => _isHovered;
private RcCanvas _canvas;
public RcToolsetView(params IRcTool[] tools)
public RcToolsetView(params IRcDemoTool[] tools)
{
this.tools = tools;
}
@ -82,10 +82,10 @@ public class RcToolsetView : IRcView
return;
}
currentTool = tools[_currentToolIdx];
ImGui.Text(currentTool.GetTool().GetName());
_currentDemoTool = tools[_currentToolIdx];
ImGui.Text(_currentDemoTool.GetTool().GetName());
ImGui.Separator();
currentTool.Layout();
_currentDemoTool.Layout();
ImGui.End();
}
@ -95,14 +95,14 @@ public class RcToolsetView : IRcView
this.enabled = enabled;
}
public IRcTool GetTool()
public IRcDemoTool GetTool()
{
return currentTool;
return _currentDemoTool;
}
public void SetSample(Sample sample)
public void SetSample(DemoSample sample)
{
tools.ForEach(t => t.GetTool().SetSample(sample));
tools.ForEach(t => t.SetSample(sample));
tools.ForEach(t => t.OnSampleChanged());
}

View File

@ -6,7 +6,7 @@ namespace DotRecast.Recast.Toolset.Builder
{
public static class DemoNavMeshBuilder
{
public static DtNavMeshCreateParams GetNavMeshCreateParams(DemoInputGeomProvider geom, float cellSize,
public static DtNavMeshCreateParams GetNavMeshCreateParams(IInputGeomProvider geom, float cellSize,
float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
RecastBuilderResult rcResult)
{
@ -52,7 +52,7 @@ namespace DotRecast.Recast.Toolset.Builder
option.offMeshConUserID = new int[option.offMeshConCount];
for (int i = 0; i < option.offMeshConCount; i++)
{
DemoOffMeshConnection offMeshCon = geom.GetOffMeshConnections()[i];
DtOffMeshConnectionParam offMeshCon = geom.GetOffMeshConnections()[i];
for (int j = 0; j < 6; j++)
{
option.offMeshConVerts[6 * i + j] = offMeshCon.verts[j];

View File

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using DotRecast.Detour;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Builder
@ -89,7 +90,7 @@ namespace DotRecast.Recast.Toolset.Builder
return navMesh;
}
public List<DtMeshData> BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
public List<DtMeshData> BuildMeshData(IInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight,
float agentRadius, float agentMaxClimb, IList<RecastBuilderResult> results)
{
// Add tiles to nav mesh

View File

@ -32,8 +32,9 @@ namespace DotRecast.Recast.Toolset.Geom
public readonly float[] normals;
private readonly RcVec3f bmin;
private readonly RcVec3f bmax;
private readonly List<RcConvexVolume> _convexVolumes = new List<RcConvexVolume>();
private readonly List<DemoOffMeshConnection> _offMeshConnections = new List<DemoOffMeshConnection>();
private readonly List<DtOffMeshConnectionParam> _offMeshConnections = new List<DtOffMeshConnectionParam>();
private readonly RcTriMesh _mesh;
public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) :
@ -109,17 +110,17 @@ namespace DotRecast.Recast.Toolset.Geom
return RcImmutableArray.Create(_mesh);
}
public List<DemoOffMeshConnection> GetOffMeshConnections()
public List<DtOffMeshConnectionParam> GetOffMeshConnections()
{
return _offMeshConnections;
}
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
{
_offMeshConnections.Add(new DemoOffMeshConnection(start, end, radius, bidir, area, flags));
_offMeshConnections.Add(new DtOffMeshConnectionParam(start, end, radius, bidir, area, flags));
}
public void RemoveOffMeshConnections(Predicate<DemoOffMeshConnection> filter)
public void RemoveOffMeshConnections(Predicate<DtOffMeshConnectionParam> filter)
{
//offMeshConnections.RetainAll(offMeshConnections.Stream().Filter(c -> !filter.Test(c)).Collect(ToList()));
_offMeshConnections.RemoveAll(filter); // TODO : 확인 필요

View File

@ -0,0 +1,7 @@
namespace DotRecast.Recast.Toolset
{
public interface IRcToolable
{
string GetName();
}
}

View File

@ -1,9 +0,0 @@
namespace DotRecast.Recast.Toolset
{
public interface ISampleTool
{
string GetName();
void SetSample(Sample sample);
Sample GetSample();
}
}

View File

@ -1,32 +1,19 @@
using System;
using System.Collections.Generic;
using DotRecast.Core;
using DotRecast.Recast.Geom;
namespace DotRecast.Recast.Toolset.Tools
{
public class ConvexVolumeToolImpl : ISampleTool
public class ConvexVolumeToolImpl : IRcToolable
{
private Sample _sample;
public string GetName()
{
return "Create Convex Volumes";
}
public void SetSample(Sample sample)
public RcConvexVolume RemoveByPos(IInputGeomProvider geom, RcVec3f pos)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public RcConvexVolume RemoveByPos(RcVec3f pos)
{
var geom = _sample.GetInputGeom();
// Delete
int nearestIndex = -1;
IList<RcConvexVolume> vols = geom.ConvexVolumes();
@ -48,9 +35,8 @@ namespace DotRecast.Recast.Toolset.Tools
return removal;
}
public void Add(RcConvexVolume volume)
public void Add(IInputGeomProvider geom, RcConvexVolume volume)
{
var geom = _sample.GetInputGeom();
geom.AddConvexVolume(volume);
}
@ -58,7 +44,9 @@ namespace DotRecast.Recast.Toolset.Tools
{
//
if (hull.Count <= 2)
{
return null;
}
// Create shape.
float[] verts = new float[hull.Count * 3];

View File

@ -1,22 +1,10 @@
namespace DotRecast.Recast.Toolset.Tools
{
public class CrowdToolImpl : ISampleTool
public class CrowdToolImpl : IRcToolable
{
private Sample _sample;
public string GetName()
{
return "Create Crowd";
}
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
}
}

View File

@ -1,22 +1,10 @@
namespace DotRecast.Recast.Toolset.Tools
{
public class DynamicUpdateToolImpl : ISampleTool
public class DynamicUpdateToolImpl : IRcToolable
{
public string GetName()
{
return "Dynamic Updates";
}
private Sample _sample;
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
}
}

View File

@ -1,15 +1,14 @@
using System.Collections.Generic;
using DotRecast.Core;
using DotRecast.Detour.Extras.Jumplink;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Tools
{
public class JumpLinkBuilderToolImpl : ISampleTool
public class JumpLinkBuilderToolImpl : IRcToolable
{
private Sample _sample;
private readonly List<JumpLink> _links;
private JumpLinkBuilder _annotationBuilder;
private readonly int _selEdge = -1;
@ -25,15 +24,6 @@ namespace DotRecast.Recast.Toolset.Tools
return "Annotation Builder";
}
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public void Clear()
{
@ -55,22 +45,22 @@ namespace DotRecast.Recast.Toolset.Tools
return _links;
}
public void Build(bool buildOffMeshConnections, int buildTypes,
public void Build(IInputGeomProvider geom, RcNavMeshBuildSettings settings, IList<RecastBuilderResult> results,
bool buildOffMeshConnections, int buildTypes,
float groundTolerance, float climbDownDistance, float climbDownMaxHeight, float climbDownMinHeight,
float edgeJumpEndDistance, float edgeJumpHeight, float edgeJumpDownMaxHeight, float edgeJumpUpMaxHeight)
{
if (_annotationBuilder == null)
{
if (_sample != null && 0 < _sample.GetRecastResults().Count)
if (0 < results.Count)
{
_annotationBuilder = new JumpLinkBuilder(_sample.GetRecastResults());
_annotationBuilder = new JumpLinkBuilder(results);
}
}
_links.Clear();
if (_annotationBuilder != null)
{
var settings = _sample.GetSettings();
float cellSize = settings.cellSize;
float agentHeight = settings.agentHeight;
float agentRadius = settings.agentRadius;
@ -114,9 +104,6 @@ namespace DotRecast.Recast.Toolset.Tools
}
if (buildOffMeshConnections)
{
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (geom != null)
{
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
geom.RemoveOffMeshConnections(c => c.area == area);
@ -124,9 +111,8 @@ namespace DotRecast.Recast.Toolset.Tools
}
}
}
}
private void AddOffMeshLink(JumpLink link, DemoInputGeomProvider geom, float agentRadius)
private void AddOffMeshLink(JumpLink link, IInputGeomProvider geom, float agentRadius)
{
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP;

View File

@ -7,17 +7,16 @@ using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Tools
{
public class ObstacleToolImpl : ISampleTool
public class ObstacleToolImpl : IRcToolable
{
private Sample _sample;
private readonly IDtTileCacheCompressorFactory _compFactory;
private readonly IDtTileCacheMeshProcess _mProc;
private readonly IDtTileCacheMeshProcess _proc;
private DtTileCache _tc;
public ObstacleToolImpl(IDtTileCacheCompressorFactory compFactory, IDtTileCacheMeshProcess meshProcessor = null)
{
_compFactory = compFactory;
_mProc = meshProcessor ?? new DemoDtTileCacheMeshProcess();
_proc = meshProcessor ?? new DemoDtTileCacheMeshProcess();
}
public string GetName()
@ -25,16 +24,6 @@ namespace DotRecast.Recast.Toolset.Tools
return "Create Temp Obstacles";
}
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public void ClearAllTempObstacles()
{
}
@ -50,36 +39,38 @@ namespace DotRecast.Recast.Toolset.Tools
//m_tileCache->addObstacle(p, 1.0f, 2.0f, 0);
}
public DtTileCache GetTileCache(IInputGeomProvider geom, RcByteOrder order, bool cCompatibility)
public DtTileCache CreateTileCache(IInputGeomProvider geom, RcNavMeshBuildSettings setting, RcByteOrder order, bool cCompatibility)
{
// DtTileCacheParams option = new DtTileCacheParams();
// RcUtils.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th);
// option.ch = m_cellHeight;
// option.cs = m_cellSize;
// option.orig = geom.GetMeshBoundsMin();
// option.height = m_tileSize;
// option.width = m_tileSize;
// option.walkableHeight = m_agentHeight;
// option.walkableRadius = m_agentRadius;
// option.walkableClimb = m_agentMaxClimb;
// option.maxSimplificationError = m_edgeMaxError;
// option.maxTiles = tw * th * EXPECTED_LAYERS_PER_TILE;
// option.maxObstacles = 128;
//
// DtNavMeshParams navMeshParams = new DtNavMeshParams();
// navMeshParams.orig = geom.GetMeshBoundsMin();
// navMeshParams.tileWidth = m_tileSize * m_cellSize;
// navMeshParams.tileHeight = m_tileSize * m_cellSize;
// navMeshParams.maxTiles = 256;
// navMeshParams.maxPolys = 16384;
//
// var navMesh = new DtNavMesh(navMeshParams, 6);
// var comp = _compFactory.Get(cCompatibility);
// var storageParams = new DtTileCacheStorageParams(order, cCompatibility);
// var process = new TestTileCacheMeshProcess();
// DtTileCache tc = new DtTileCache(option, storageParams, navMesh, comp, process);
// return tc;
return null;
RcUtils.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(),
setting.cellSize, setting.tileSize, setting.tileSize,
out var tw, out var th
);
DtTileCacheParams option = new DtTileCacheParams();
option.ch = setting.cellHeight;
option.cs = setting.cellSize;
option.orig = geom.GetMeshBoundsMin();
option.height = setting.tileSize;
option.width = setting.tileSize;
option.walkableHeight = setting.agentHeight;
option.walkableRadius = setting.agentRadius;
option.walkableClimb = setting.agentMaxClimb;
option.maxSimplificationError = setting.edgeMaxError;
option.maxTiles = tw * th * 4; // for test EXPECTED_LAYERS_PER_TILE;
option.maxObstacles = 128;
DtNavMeshParams navMeshParams = new DtNavMeshParams();
navMeshParams.orig = geom.GetMeshBoundsMin();
navMeshParams.tileWidth = setting.tileSize * setting.cellSize;
navMeshParams.tileHeight = setting.tileSize * setting.cellSize;
navMeshParams.maxTiles = 256; // ..
navMeshParams.maxPolys = 16384;
var navMesh = new DtNavMesh(navMeshParams, 6);
var comp = _compFactory.Create(cCompatibility ? 0 : 1);
var storageParams = new DtTileCacheStorageParams(order, cCompatibility);
DtTileCache tc = new DtTileCache(option, storageParams, navMesh, comp, _proc);
return tc;
}
}
}

View File

@ -6,9 +6,8 @@ using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Tools
{
public class OffMeshConnectionToolImpl : ISampleTool
public class OffMeshConnectionToolImpl : IRcToolable
{
private Sample _sample;
private readonly OffMeshConnectionToolOption _option;
public OffMeshConnectionToolImpl()
@ -21,47 +20,31 @@ namespace DotRecast.Recast.Toolset.Tools
return "Create Off-Mesh Links";
}
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public OffMeshConnectionToolOption GetOption()
{
return _option;
}
public void Add(RcVec3f start, RcVec3f end)
public void Add(IInputGeomProvider geom, RcNavMeshBuildSettings settings, RcVec3f start, RcVec3f end)
{
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (null == geom)
return;
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP;
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP;
geom.AddOffMeshConnection(start, end, _sample.GetSettings().agentRadius, 0 == _option.bidir, area, flags);
geom.AddOffMeshConnection(start, end, settings.agentRadius, 0 == _option.bidir, area, flags);
}
public void Remove(RcVec3f p)
public void Remove(IInputGeomProvider geom, RcNavMeshBuildSettings settings, RcVec3f p)
{
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (null == geom)
return;
// Delete
// Find nearest link end-point
float nearestDist = float.MaxValue;
DemoOffMeshConnection nearestConnection = null;
foreach (DemoOffMeshConnection offMeshCon in geom.GetOffMeshConnections())
DtOffMeshConnectionParam nearestConnection = null;
foreach (DtOffMeshConnectionParam offMeshCon in geom.GetOffMeshConnections())
{
float d = Math.Min(RcVec3f.DistSqr(p, offMeshCon.verts, 0), RcVec3f.DistSqr(p, offMeshCon.verts, 3));
if (d < nearestDist && Math.Sqrt(d) < _sample.GetSettings().agentRadius)
if (d < nearestDist && Math.Sqrt(d) < settings.agentRadius)
{
nearestDist = d;
nearestConnection = offMeshCon;

View File

@ -5,12 +5,11 @@ using DotRecast.Detour;
namespace DotRecast.Recast.Toolset.Tools
{
public class TestNavmeshToolImpl : ISampleTool
public class TestNavmeshToolImpl : IRcToolable
{
public const int MAX_POLYS = 256;
public const int MAX_SMOOTH = 2048;
private Sample _sample;
private readonly TestNavmeshToolOption _option;
public TestNavmeshToolImpl()
@ -23,28 +22,14 @@ namespace DotRecast.Recast.Toolset.Tools
return "Test Navmesh";
}
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public TestNavmeshToolOption GetOption()
{
return _option;
}
public DtStatus FindFollowPath(long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
public DtStatus FindFollowPath(DtNavMesh navMesh, DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
ref List<long> polys, ref List<RcVec3f> smoothPath)
{
var navMesh = _sample.GetNavMesh();
var navQuery = _sample.GetNavMeshQuery();
navQuery.FindPath(startRef, endRef, startPt, endPt, filter, ref polys,
new DtFindPathOption(enableRaycast ? DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE : 0, float.MaxValue));
@ -171,11 +156,9 @@ namespace DotRecast.Recast.Toolset.Tools
return DtStatus.DT_SUCCSESS;
}
public DtStatus FindStraightPath(long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
public DtStatus FindStraightPath(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPt, RcVec3f endPt, IDtQueryFilter filter, bool enableRaycast,
ref List<long> polys, ref List<StraightPathItem> straightPath, int straightPathOptions)
{
var navQuery = _sample.GetNavMeshQuery();
navQuery.FindPath(startRef, endRef, startPt, endPt, filter, ref polys,
new DtFindPathOption(enableRaycast ? DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE : 0, float.MaxValue));
@ -198,23 +181,21 @@ namespace DotRecast.Recast.Toolset.Tools
return DtStatus.DT_SUCCSESS;
}
public DtStatus InitSlicedFindPath(long startRef, long endRef, RcVec3f startPos, RcVec3f m_epos, IDtQueryFilter filter, bool enableRaycast)
public DtStatus InitSlicedFindPath(DtNavMeshQuery navQuery, long startRef, long endRef, RcVec3f startPos, RcVec3f m_epos, IDtQueryFilter filter, bool enableRaycast)
{
var navQuery = _sample.GetNavMeshQuery();
return navQuery.InitSlicedFindPath(startRef, endRef, startPos, m_epos, filter,
enableRaycast ? DtNavMeshQuery.DT_FINDPATH_ANY_ANGLE : 0,
float.MaxValue
);
}
public DtStatus Raycast(long startRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter,
public DtStatus Raycast(DtNavMeshQuery navQuery, long startRef, RcVec3f startPos, RcVec3f endPos, IDtQueryFilter filter,
ref List<long> polys, ref List<StraightPathItem> straightPath, out RcVec3f hitPos, out RcVec3f hitNormal, out bool hitResult)
{
hitPos = RcVec3f.Zero;
hitNormal = RcVec3f.Zero;
hitResult = false;
var navQuery = _sample.GetNavMeshQuery();
var status = navQuery.Raycast(startRef, startPos, endPos, filter, 0, 0, out var rayHit);
if (!status.Succeeded())
return status;
@ -251,23 +232,21 @@ namespace DotRecast.Recast.Toolset.Tools
return status;
}
public DtStatus FindPolysAroundCircle(long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, ref List<long> resultRef, ref List<long> resultParent)
public DtStatus FindPolysAroundCircle(DtNavMeshQuery navQuery, long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, ref List<long> resultRef, ref List<long> resultParent)
{
float dx = epos.x - spos.x;
float dz = epos.z - spos.z;
float dist = (float)Math.Sqrt(dx * dx + dz * dz);
List<float> costs = new List<float>();
var navQuery = _sample.GetNavMeshQuery();
return navQuery.FindPolysAroundCircle(startRef, spos, dist, filter, ref resultRef, ref resultParent, ref costs);
}
public DtStatus FindPolysAroundShape(long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, ref List<long> resultRef, ref List<long> resultParent, out RcVec3f[] queryPoly)
public DtStatus FindPolysAroundShape(DtNavMeshQuery navQuery, RcNavMeshBuildSettings settings, long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, ref List<long> resultRef, ref List<long> resultParent, out RcVec3f[] queryPoly)
{
float nx = (epos.z - spos.z) * 0.25f;
float nz = -(epos.x - spos.x) * 0.25f;
float agentHeight = GetSample() != null ? GetSample().GetSettings().agentHeight : 0;
float agentHeight = settings != null ? settings.agentHeight : 0;
queryPoly = new RcVec3f[4];
queryPoly[0].x = spos.x + nx * 1.2f;
@ -287,11 +266,10 @@ namespace DotRecast.Recast.Toolset.Tools
queryPoly[3].z = epos.z + nz;
var costs = new List<float>();
var navQuery = _sample.GetNavMeshQuery();
return navQuery.FindPolysAroundShape(startRef, queryPoly, filter, ref resultRef, ref resultParent, ref costs);
}
public DtStatus FindRandomPointAroundCircle(long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, bool constrainByCircle, int count, ref List<RcVec3f> points)
public DtStatus FindRandomPointAroundCircle(DtNavMeshQuery navQuery, long startRef, RcVec3f spos, RcVec3f epos, IDtQueryFilter filter, bool constrainByCircle, int count, ref List<RcVec3f> points)
{
float dx = epos.x - spos.x;
float dz = epos.z - spos.z;
@ -302,8 +280,6 @@ namespace DotRecast.Recast.Toolset.Tools
: DtNoOpDtPolygonByCircleConstraint.Shared;
var frand = new FRand();
var navQuery = _sample.GetNavMeshQuery();
int prevCnt = points.Count;
while (0 < count && points.Count < prevCnt + count)

View File

@ -1,34 +1,20 @@
using System.Linq;
using DotRecast.Core;
using DotRecast.Detour;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Builder;
namespace DotRecast.Recast.Toolset.Tools
{
public class TileToolImpl : ISampleTool
public class TileToolImpl : IRcToolable
{
private Sample _sample;
public string GetName()
{
return "Create Tiles";
}
public void SetSample(Sample sample)
public void RemoveAllTiles(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public void RemoveAllTiles()
{
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
if (null == settings || null == geom || navMesh == null)
return;
@ -51,12 +37,8 @@ namespace DotRecast.Recast.Toolset.Tools
}
}
public void BuildAllTiles()
public void BuildAllTiles(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh)
{
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
if (null == settings || null == geom || navMesh == null)
return;
@ -73,21 +55,17 @@ namespace DotRecast.Recast.Toolset.Tools
{
for (int x = 0; x < tw; ++x)
{
BuildTile(x, y, out var tileBuildTicks, out var tileTriCount, out var tileMemUsage);
BuildTile(geom, settings, navMesh, x, y, out var tileBuildTicks, out var tileTriCount, out var tileMemUsage);
}
}
}
public bool BuildTile(int tx, int ty, out long tileBuildTicks, out int tileTriCount, out int tileMemUsage)
public bool BuildTile(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh, int tx, int ty, out long tileBuildTicks, out int tileTriCount, out int tileMemUsage)
{
tileBuildTicks = 0;
tileTriCount = 0; // ...
tileMemUsage = 0; // ...
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
var availableTileCount = navMesh.GetAvailableTileCount();
if (0 >= availableTileCount)
{
@ -128,8 +106,7 @@ namespace DotRecast.Recast.Toolset.Tools
var result = rb.BuildTile(geom, cfg, bmin, bmax, tx, ty, new RcAtomicInteger(0), 1);
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)
).FirstOrDefault();
if (null == meshData)
@ -144,12 +121,8 @@ namespace DotRecast.Recast.Toolset.Tools
return true;
}
public bool BuildTile(RcVec3f pos, out long tileBuildTicks, out int tileTriCount, out int tileMemUsage)
public bool BuildTile(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh, RcVec3f pos, out long tileBuildTicks, out int tileTriCount, out int tileMemUsage)
{
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
tileBuildTicks = 0;
tileTriCount = 0;
tileMemUsage = 0;
@ -165,15 +138,11 @@ namespace DotRecast.Recast.Toolset.Tools
int tx = (int)((pos.x - bmin[0]) / ts);
int ty = (int)((pos.z - bmin[2]) / ts);
return BuildTile(tx, ty, out tileBuildTicks, out tileTriCount, out tileMemUsage);
return BuildTile(geom, settings, navMesh, tx, ty, out tileBuildTicks, out tileTriCount, out tileMemUsage);
}
public bool RemoveTile(RcVec3f pos)
public bool RemoveTile(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh, RcVec3f pos)
{
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
if (null == settings || null == geom || navMesh == null)
return false;

View File

@ -19,19 +19,20 @@ freely, subject to the following restrictions:
*/
using DotRecast.Core;
using DotRecast.Detour;
namespace DotRecast.Recast.Toolset.Geom
namespace DotRecast.Recast.Geom
{
public class DemoOffMeshConnection
public class DtOffMeshConnectionParam
{
public readonly float[] verts;
public readonly float radius;
public readonly bool bidir;
public readonly int area;
public readonly int flags;
public DemoOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
public DtOffMeshConnectionParam(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
{
verts = new float[6];
verts[0] = start.x;

View File

@ -23,6 +23,7 @@ namespace DotRecast.Recast.Geom
{
public interface IConvexVolumeProvider
{
void AddConvexVolume(RcConvexVolume convexVolume);
IList<RcConvexVolume> ConvexVolumes();
}
}

View File

@ -18,6 +18,7 @@ freely, subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
using System;
using System.Collections.Generic;
using DotRecast.Core;
@ -30,5 +31,11 @@ namespace DotRecast.Recast.Geom
RcVec3f GetMeshBoundsMax();
IEnumerable<RcTriMesh> Meshes();
// off mesh connections
public List<DtOffMeshConnectionParam> GetOffMeshConnections();
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags);
public void RemoveOffMeshConnections(Predicate<DtOffMeshConnectionParam> filter);
}
}

View File

@ -31,6 +31,7 @@ namespace DotRecast.Recast.Geom
public readonly float[] normals;
private RcVec3f bmin;
private RcVec3f bmax;
private readonly List<RcConvexVolume> volumes = new List<RcConvexVolume>();
private readonly RcTriMesh _mesh;
@ -102,7 +103,11 @@ namespace DotRecast.Recast.Geom
vol.hmax = maxh;
vol.verts = verts;
vol.areaMod = areaMod;
volumes.Add(vol);
}
public void AddConvexVolume(RcConvexVolume convexVolume)
{
volumes.Add(convexVolume);
}
public IEnumerable<RcTriMesh> Meshes()
@ -110,6 +115,21 @@ namespace DotRecast.Recast.Geom
return RcImmutableArray.Create(_mesh);
}
public List<DtOffMeshConnectionParam> GetOffMeshConnections()
{
throw new NotImplementedException();
}
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
{
throw new NotImplementedException();
}
public void RemoveOffMeshConnections(Predicate<DtOffMeshConnectionParam> filter)
{
throw new NotImplementedException();
}
public void CalculateNormals()
{
for (int i = 0; i < faces.Length; i += 3)

View File

@ -59,9 +59,29 @@ namespace DotRecast.Recast.Geom
return RcImmutableArray.Create(_mesh);
}
public List<DtOffMeshConnectionParam> GetOffMeshConnections()
{
throw new NotImplementedException();
}
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags)
{
throw new NotImplementedException();
}
public void RemoveOffMeshConnections(Predicate<DtOffMeshConnectionParam> filter)
{
throw new NotImplementedException();
}
public IList<RcConvexVolume> ConvexVolumes()
{
return RcImmutableArray<RcConvexVolume>.Empty;
}
public void AddConvexVolume(RcConvexVolume convexVolume)
{
throw new NotImplementedException();
}
}
}

View File

@ -166,8 +166,7 @@ namespace DotRecast.Recast
return Build(builderCfg.tileX, builderCfg.tileZ, geom, cfg, solid, ctx);
}
public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid,
RcTelemetry ctx)
public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid, RcTelemetry ctx)
{
FilterHeightfield(solid, cfg, ctx);
RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid);