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;
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Detour; using DotRecast.Detour;
using DotRecast.Recast.Toolset;
using DotRecast.Recast.Toolset.Geom; using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset namespace DotRecast.Recast.Demo
{ {
public class Sample public class DemoSample
{ {
private DemoInputGeomProvider _inputGeom; private DemoInputGeomProvider _inputGeom;
private DtNavMesh _navMesh; private DtNavMesh _navMesh;
@ -34,7 +35,7 @@ namespace DotRecast.Recast.Toolset
private IList<RecastBuilderResult> _recastResults; private IList<RecastBuilderResult> _recastResults;
private bool _changed; private bool _changed;
public Sample(DemoInputGeomProvider inputGeom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh) public DemoSample(DemoInputGeomProvider inputGeom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh)
{ {
_inputGeom = inputGeom; _inputGeom = inputGeom;
_recastResults = recastResults; _recastResults = recastResults;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,23 +8,31 @@ using Serilog;
namespace DotRecast.Recast.Demo.Tools; 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 readonly ObstacleToolImpl _impl;
private bool _hitPosSet; private bool _hitPosSet;
private RcVec3f _hitPos; private RcVec3f _hitPos;
public ObstacleTool() public ObstacleDemoTool()
{ {
_impl = new(DtTileCacheCompressorFactory.Shared); _impl = new(DtTileCacheCompressorFactory.Shared);
} }
public ISampleTool GetTool() public IRcToolable GetTool()
{ {
return _impl; return _impl;
} }
public void SetSample(DemoSample sample)
{
_sample = sample;
}
public void OnSampleChanged() public void OnSampleChanged()
{ {
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@ namespace DotRecast.Recast.Toolset.Builder
{ {
public static class DemoNavMeshBuilder 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, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb,
RecastBuilderResult rcResult) RecastBuilderResult rcResult)
{ {
@ -52,7 +52,7 @@ namespace DotRecast.Recast.Toolset.Builder
option.offMeshConUserID = new int[option.offMeshConCount]; option.offMeshConUserID = new int[option.offMeshConCount];
for (int i = 0; i < option.offMeshConCount; i++) 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++) for (int j = 0; j < 6; j++)
{ {
option.offMeshConVerts[6 * i + j] = offMeshCon.verts[j]; option.offMeshConVerts[6 * i + j] = offMeshCon.verts[j];

View File

@ -20,6 +20,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using DotRecast.Detour; using DotRecast.Detour;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Geom; using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Builder namespace DotRecast.Recast.Toolset.Builder
@ -89,7 +90,7 @@ namespace DotRecast.Recast.Toolset.Builder
return navMesh; 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) float agentRadius, float agentMaxClimb, IList<RecastBuilderResult> results)
{ {
// Add tiles to nav mesh // Add tiles to nav mesh

View File

@ -32,8 +32,9 @@ namespace DotRecast.Recast.Toolset.Geom
public readonly float[] normals; public readonly float[] normals;
private readonly RcVec3f bmin; private readonly RcVec3f bmin;
private readonly RcVec3f bmax; private readonly RcVec3f bmax;
private readonly List<RcConvexVolume> _convexVolumes = new List<RcConvexVolume>(); 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; private readonly RcTriMesh _mesh;
public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) : public DemoInputGeomProvider(List<float> vertexPositions, List<int> meshFaces) :
@ -109,17 +110,17 @@ namespace DotRecast.Recast.Toolset.Geom
return RcImmutableArray.Create(_mesh); return RcImmutableArray.Create(_mesh);
} }
public List<DemoOffMeshConnection> GetOffMeshConnections() public List<DtOffMeshConnectionParam> GetOffMeshConnections()
{ {
return _offMeshConnections; return _offMeshConnections;
} }
public void AddOffMeshConnection(RcVec3f start, RcVec3f end, float radius, bool bidir, int area, int flags) 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.RetainAll(offMeshConnections.Stream().Filter(c -> !filter.Test(c)).Collect(ToList()));
_offMeshConnections.RemoveAll(filter); // TODO : 확인 필요 _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;
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Recast.Geom;
namespace DotRecast.Recast.Toolset.Tools namespace DotRecast.Recast.Toolset.Tools
{ {
public class ConvexVolumeToolImpl : ISampleTool public class ConvexVolumeToolImpl : IRcToolable
{ {
private Sample _sample;
public string GetName() public string GetName()
{ {
return "Create Convex Volumes"; 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 // Delete
int nearestIndex = -1; int nearestIndex = -1;
IList<RcConvexVolume> vols = geom.ConvexVolumes(); IList<RcConvexVolume> vols = geom.ConvexVolumes();
@ -48,9 +35,8 @@ namespace DotRecast.Recast.Toolset.Tools
return removal; return removal;
} }
public void Add(RcConvexVolume volume) public void Add(IInputGeomProvider geom, RcConvexVolume volume)
{ {
var geom = _sample.GetInputGeom();
geom.AddConvexVolume(volume); geom.AddConvexVolume(volume);
} }
@ -58,7 +44,9 @@ namespace DotRecast.Recast.Toolset.Tools
{ {
// //
if (hull.Count <= 2) if (hull.Count <= 2)
{
return null; return null;
}
// Create shape. // Create shape.
float[] verts = new float[hull.Count * 3]; float[] verts = new float[hull.Count * 3];

View File

@ -1,22 +1,10 @@
namespace DotRecast.Recast.Toolset.Tools namespace DotRecast.Recast.Toolset.Tools
{ {
public class CrowdToolImpl : ISampleTool public class CrowdToolImpl : IRcToolable
{ {
private Sample _sample;
public string GetName() public string GetName()
{ {
return "Create Crowd"; 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 namespace DotRecast.Recast.Toolset.Tools
{ {
public class DynamicUpdateToolImpl : ISampleTool public class DynamicUpdateToolImpl : IRcToolable
{ {
public string GetName() public string GetName()
{ {
return "Dynamic Updates"; 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 System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Detour.Extras.Jumplink; using DotRecast.Detour.Extras.Jumplink;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Builder; using DotRecast.Recast.Toolset.Builder;
using DotRecast.Recast.Toolset.Geom; using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Tools namespace DotRecast.Recast.Toolset.Tools
{ {
public class JumpLinkBuilderToolImpl : ISampleTool public class JumpLinkBuilderToolImpl : IRcToolable
{ {
private Sample _sample;
private readonly List<JumpLink> _links; private readonly List<JumpLink> _links;
private JumpLinkBuilder _annotationBuilder; private JumpLinkBuilder _annotationBuilder;
private readonly int _selEdge = -1; private readonly int _selEdge = -1;
@ -25,15 +24,6 @@ namespace DotRecast.Recast.Toolset.Tools
return "Annotation Builder"; return "Annotation Builder";
} }
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public void Clear() public void Clear()
{ {
@ -55,22 +45,22 @@ namespace DotRecast.Recast.Toolset.Tools
return _links; 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 groundTolerance, float climbDownDistance, float climbDownMaxHeight, float climbDownMinHeight,
float edgeJumpEndDistance, float edgeJumpHeight, float edgeJumpDownMaxHeight, float edgeJumpUpMaxHeight) float edgeJumpEndDistance, float edgeJumpHeight, float edgeJumpDownMaxHeight, float edgeJumpUpMaxHeight)
{ {
if (_annotationBuilder == null) 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(); _links.Clear();
if (_annotationBuilder != null) if (_annotationBuilder != null)
{ {
var settings = _sample.GetSettings();
float cellSize = settings.cellSize; float cellSize = settings.cellSize;
float agentHeight = settings.agentHeight; float agentHeight = settings.agentHeight;
float agentRadius = settings.agentRadius; float agentRadius = settings.agentRadius;
@ -114,9 +104,6 @@ namespace DotRecast.Recast.Toolset.Tools
} }
if (buildOffMeshConnections) if (buildOffMeshConnections)
{
DemoInputGeomProvider geom = _sample.GetInputGeom();
if (geom != null)
{ {
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO; int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
geom.RemoveOffMeshConnections(c => c.area == area); 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 area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP; int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP;

View File

@ -7,17 +7,16 @@ using DotRecast.Recast.Toolset.Geom;
namespace DotRecast.Recast.Toolset.Tools namespace DotRecast.Recast.Toolset.Tools
{ {
public class ObstacleToolImpl : ISampleTool public class ObstacleToolImpl : IRcToolable
{ {
private Sample _sample;
private readonly IDtTileCacheCompressorFactory _compFactory; private readonly IDtTileCacheCompressorFactory _compFactory;
private readonly IDtTileCacheMeshProcess _mProc; private readonly IDtTileCacheMeshProcess _proc;
private DtTileCache _tc; private DtTileCache _tc;
public ObstacleToolImpl(IDtTileCacheCompressorFactory compFactory, IDtTileCacheMeshProcess meshProcessor = null) public ObstacleToolImpl(IDtTileCacheCompressorFactory compFactory, IDtTileCacheMeshProcess meshProcessor = null)
{ {
_compFactory = compFactory; _compFactory = compFactory;
_mProc = meshProcessor ?? new DemoDtTileCacheMeshProcess(); _proc = meshProcessor ?? new DemoDtTileCacheMeshProcess();
} }
public string GetName() public string GetName()
@ -25,16 +24,6 @@ namespace DotRecast.Recast.Toolset.Tools
return "Create Temp Obstacles"; return "Create Temp Obstacles";
} }
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public void ClearAllTempObstacles() public void ClearAllTempObstacles()
{ {
} }
@ -50,36 +39,38 @@ namespace DotRecast.Recast.Toolset.Tools
//m_tileCache->addObstacle(p, 1.0f, 2.0f, 0); //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(),
// RcUtils.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th); setting.cellSize, setting.tileSize, setting.tileSize,
// option.ch = m_cellHeight; out var tw, out var th
// option.cs = m_cellSize; );
// option.orig = geom.GetMeshBoundsMin();
// option.height = m_tileSize; DtTileCacheParams option = new DtTileCacheParams();
// option.width = m_tileSize; option.ch = setting.cellHeight;
// option.walkableHeight = m_agentHeight; option.cs = setting.cellSize;
// option.walkableRadius = m_agentRadius; option.orig = geom.GetMeshBoundsMin();
// option.walkableClimb = m_agentMaxClimb; option.height = setting.tileSize;
// option.maxSimplificationError = m_edgeMaxError; option.width = setting.tileSize;
// option.maxTiles = tw * th * EXPECTED_LAYERS_PER_TILE; option.walkableHeight = setting.agentHeight;
// option.maxObstacles = 128; option.walkableRadius = setting.agentRadius;
// option.walkableClimb = setting.agentMaxClimb;
// DtNavMeshParams navMeshParams = new DtNavMeshParams(); option.maxSimplificationError = setting.edgeMaxError;
// navMeshParams.orig = geom.GetMeshBoundsMin(); option.maxTiles = tw * th * 4; // for test EXPECTED_LAYERS_PER_TILE;
// navMeshParams.tileWidth = m_tileSize * m_cellSize; option.maxObstacles = 128;
// navMeshParams.tileHeight = m_tileSize * m_cellSize;
// navMeshParams.maxTiles = 256; DtNavMeshParams navMeshParams = new DtNavMeshParams();
// navMeshParams.maxPolys = 16384; navMeshParams.orig = geom.GetMeshBoundsMin();
// navMeshParams.tileWidth = setting.tileSize * setting.cellSize;
// var navMesh = new DtNavMesh(navMeshParams, 6); navMeshParams.tileHeight = setting.tileSize * setting.cellSize;
// var comp = _compFactory.Get(cCompatibility); navMeshParams.maxTiles = 256; // ..
// var storageParams = new DtTileCacheStorageParams(order, cCompatibility); navMeshParams.maxPolys = 16384;
// var process = new TestTileCacheMeshProcess();
// DtTileCache tc = new DtTileCache(option, storageParams, navMesh, comp, process); var navMesh = new DtNavMesh(navMeshParams, 6);
// return tc; var comp = _compFactory.Create(cCompatibility ? 0 : 1);
return null; 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 namespace DotRecast.Recast.Toolset.Tools
{ {
public class OffMeshConnectionToolImpl : ISampleTool public class OffMeshConnectionToolImpl : IRcToolable
{ {
private Sample _sample;
private readonly OffMeshConnectionToolOption _option; private readonly OffMeshConnectionToolOption _option;
public OffMeshConnectionToolImpl() public OffMeshConnectionToolImpl()
@ -21,47 +20,31 @@ namespace DotRecast.Recast.Toolset.Tools
return "Create Off-Mesh Links"; return "Create Off-Mesh Links";
} }
public void SetSample(Sample sample)
{
_sample = sample;
}
public Sample GetSample()
{
return _sample;
}
public OffMeshConnectionToolOption GetOption() public OffMeshConnectionToolOption GetOption()
{ {
return _option; 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) if (null == geom)
return; return;
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP; int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP;
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_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 // Delete
// Find nearest link end-point // Find nearest link end-point
float nearestDist = float.MaxValue; float nearestDist = float.MaxValue;
DemoOffMeshConnection nearestConnection = null; DtOffMeshConnectionParam nearestConnection = null;
foreach (DemoOffMeshConnection offMeshCon in geom.GetOffMeshConnections()) foreach (DtOffMeshConnectionParam offMeshCon in geom.GetOffMeshConnections())
{ {
float d = Math.Min(RcVec3f.DistSqr(p, offMeshCon.verts, 0), RcVec3f.DistSqr(p, offMeshCon.verts, 3)); 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; nearestDist = d;
nearestConnection = offMeshCon; nearestConnection = offMeshCon;

View File

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

View File

@ -1,34 +1,20 @@
using System.Linq; using System.Linq;
using DotRecast.Core; using DotRecast.Core;
using DotRecast.Detour;
using DotRecast.Recast.Geom;
using DotRecast.Recast.Toolset.Builder; using DotRecast.Recast.Toolset.Builder;
namespace DotRecast.Recast.Toolset.Tools namespace DotRecast.Recast.Toolset.Tools
{ {
public class TileToolImpl : ISampleTool public class TileToolImpl : IRcToolable
{ {
private Sample _sample;
public string GetName() public string GetName()
{ {
return "Create Tiles"; 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) if (null == settings || null == geom || navMesh == null)
return; 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) if (null == settings || null == geom || navMesh == null)
return; return;
@ -73,21 +55,17 @@ namespace DotRecast.Recast.Toolset.Tools
{ {
for (int x = 0; x < tw; ++x) 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; tileBuildTicks = 0;
tileTriCount = 0; // ... tileTriCount = 0; // ...
tileMemUsage = 0; // ... tileMemUsage = 0; // ...
var settings = _sample.GetSettings();
var geom = _sample.GetInputGeom();
var navMesh = _sample.GetNavMesh();
var availableTileCount = navMesh.GetAvailableTileCount(); var availableTileCount = navMesh.GetAvailableTileCount();
if (0 >= availableTileCount) 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 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, var meshData = tb.BuildMeshData(geom, settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, RcImmutableArray.Create(result)
settings.cellSize, settings.cellHeight, settings.agentHeight, settings.agentRadius, settings.agentMaxClimb, RcImmutableArray.Create(result)
).FirstOrDefault(); ).FirstOrDefault();
if (null == meshData) if (null == meshData)
@ -144,12 +121,8 @@ namespace DotRecast.Recast.Toolset.Tools
return true; 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; tileBuildTicks = 0;
tileTriCount = 0; tileTriCount = 0;
tileMemUsage = 0; tileMemUsage = 0;
@ -165,15 +138,11 @@ namespace DotRecast.Recast.Toolset.Tools
int tx = (int)((pos.x - bmin[0]) / ts); int tx = (int)((pos.x - bmin[0]) / ts);
int ty = (int)((pos.z - bmin[2]) / 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) if (null == settings || null == geom || navMesh == null)
return false; return false;

View File

@ -19,19 +19,20 @@ freely, subject to the following restrictions:
*/ */
using DotRecast.Core; 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[] verts;
public readonly float radius; public readonly float radius;
public readonly bool bidir; public readonly bool bidir;
public readonly int area; public readonly int area;
public readonly int flags; 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 = new float[6];
verts[0] = start.x; verts[0] = start.x;

View File

@ -23,6 +23,7 @@ namespace DotRecast.Recast.Geom
{ {
public interface IConvexVolumeProvider public interface IConvexVolumeProvider
{ {
void AddConvexVolume(RcConvexVolume convexVolume);
IList<RcConvexVolume> ConvexVolumes(); 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. 3. This notice may not be removed or altered from any source distribution.
*/ */
using System;
using System.Collections.Generic; using System.Collections.Generic;
using DotRecast.Core; using DotRecast.Core;
@ -30,5 +31,11 @@ namespace DotRecast.Recast.Geom
RcVec3f GetMeshBoundsMax(); RcVec3f GetMeshBoundsMax();
IEnumerable<RcTriMesh> Meshes(); 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; public readonly float[] normals;
private RcVec3f bmin; private RcVec3f bmin;
private RcVec3f bmax; private RcVec3f bmax;
private readonly List<RcConvexVolume> volumes = new List<RcConvexVolume>(); private readonly List<RcConvexVolume> volumes = new List<RcConvexVolume>();
private readonly RcTriMesh _mesh; private readonly RcTriMesh _mesh;
@ -102,7 +103,11 @@ namespace DotRecast.Recast.Geom
vol.hmax = maxh; vol.hmax = maxh;
vol.verts = verts; vol.verts = verts;
vol.areaMod = areaMod; vol.areaMod = areaMod;
volumes.Add(vol); }
public void AddConvexVolume(RcConvexVolume convexVolume)
{
volumes.Add(convexVolume);
} }
public IEnumerable<RcTriMesh> Meshes() public IEnumerable<RcTriMesh> Meshes()
@ -110,6 +115,21 @@ namespace DotRecast.Recast.Geom
return RcImmutableArray.Create(_mesh); 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() public void CalculateNormals()
{ {
for (int i = 0; i < faces.Length; i += 3) for (int i = 0; i < faces.Length; i += 3)

View File

@ -59,9 +59,29 @@ namespace DotRecast.Recast.Geom
return RcImmutableArray.Create(_mesh); 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() public IList<RcConvexVolume> ConvexVolumes()
{ {
return RcImmutableArray<RcConvexVolume>.Empty; 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); return Build(builderCfg.tileX, builderCfg.tileZ, geom, cfg, solid, ctx);
} }
public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid, public RecastBuilderResult Build(int tileX, int tileZ, IConvexVolumeProvider geom, RcConfig cfg, RcHeightfield solid, RcTelemetry ctx)
RcTelemetry ctx)
{ {
FilterHeightfield(solid, cfg, ctx); FilterHeightfield(solid, cfg, ctx);
RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid); RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid);