diff --git a/src/DotRecast.Detour/PathUtils.cs b/src/DotRecast.Detour/PathUtils.cs index 0a9f400..d6479ce 100644 --- a/src/DotRecast.Detour/PathUtils.cs +++ b/src/DotRecast.Detour/PathUtils.cs @@ -123,7 +123,7 @@ namespace DotRecast.Detour // If any of the neighbour polygons is within the next few polygons // in the path, short cut to that polygon directly. - int maxLookAhead = 6; + const int maxLookAhead = 6; int cut = 0; for (int i = Math.Min(maxLookAhead, path.Count) - 1; i > 1 && cut == 0; i--) { diff --git a/src/DotRecast.Recast.Demo/Tools/JumpLinkBuilderTool.cs b/src/DotRecast.Recast.Demo/Tools/JumpLinkBuilderTool.cs index fc77115..b120d9a 100644 --- a/src/DotRecast.Recast.Demo/Tools/JumpLinkBuilderTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/JumpLinkBuilderTool.cs @@ -33,11 +33,6 @@ namespace DotRecast.Recast.Demo.Tools; public class JumpLinkBuilderTool : IRcTool { private readonly JumpLinkBuilderToolImpl _impl; - private readonly List links = new(); - private JumpLinkBuilder annotationBuilder; - private readonly int selEdge = -1; - private readonly JumpLinkBuilderToolParams option = new JumpLinkBuilderToolParams(); - public JumpLinkBuilderTool() { @@ -51,7 +46,7 @@ public class JumpLinkBuilderTool : IRcTool public void OnSampleChanged() { - annotationBuilder = null; + _impl.Clear(); } public void HandleClick(RcVec3f s, RcVec3f p, bool shift) @@ -65,10 +60,15 @@ public class JumpLinkBuilderTool : IRcTool RecastDebugDraw dd = renderer.GetDebugDraw(); dd.DepthMask(false); - if ((option.flags & JumpLinkBuilderToolParams.DRAW_WALKABLE_BORDER) != 0) + var option = _impl.GetOption(); + var annotationBuilder = _impl.GetAnnotationBuilder(); + + if ((option.flags & JumpLinkBuilderToolOptions.DRAW_WALKABLE_BORDER) != 0) { if (annotationBuilder != null) { + var selEdge = _impl.GetSelEdge(); + foreach (JumpEdge[] edges in annotationBuilder.GetEdges()) { dd.Begin(LINES, 3.0f); @@ -121,10 +121,10 @@ public class JumpLinkBuilderTool : IRcTool } } - if ((option.flags & JumpLinkBuilderToolParams.DRAW_ANNOTATIONS) != 0) + if ((option.flags & JumpLinkBuilderToolOptions.DRAW_ANNOTATIONS) != 0) { dd.Begin(QUADS); - foreach (JumpLink link in links) + foreach (JumpLink link in _impl.GetLinks()) { for (int j = 0; j < link.nspine - 1; ++j) { @@ -141,7 +141,7 @@ public class JumpLinkBuilderTool : IRcTool dd.End(); dd.Begin(LINES, 3.0f); - foreach (JumpLink link in links) + foreach (JumpLink link in _impl.GetLinks()) { for (int j = 0; j < link.nspine - 1; ++j) { @@ -170,9 +170,9 @@ public class JumpLinkBuilderTool : IRcTool if (annotationBuilder != null) { - foreach (JumpLink link in links) + foreach (JumpLink link in _impl.GetLinks()) { - if ((option.flags & JumpLinkBuilderToolParams.DRAW_ANIM_TRAJECTORY) != 0) + if ((option.flags & JumpLinkBuilderToolOptions.DRAW_ANIM_TRAJECTORY) != 0) { float r = link.start.height; @@ -238,7 +238,7 @@ public class JumpLinkBuilderTool : IRcTool dd.End(); } - if ((option.flags & JumpLinkBuilderToolParams.DRAW_LAND_SAMPLES) != 0) + if ((option.flags & JumpLinkBuilderToolOptions.DRAW_LAND_SAMPLES) != 0) { dd.Begin(POINTS, 8.0f); for (int i = 0; i < link.start.gsamples.Length; ++i) @@ -338,6 +338,8 @@ public class JumpLinkBuilderTool : IRcTool if (0 >= _impl.GetSample().GetRecastResults().Count) return; + var option = _impl.GetOption(); + ImGui.Text("Options"); ImGui.Separator(); ImGui.SliderFloat("Ground Tolerance", ref option.groundTolerance, 0f, 2f, "%.2f"); @@ -378,83 +380,20 @@ public class JumpLinkBuilderTool : IRcTool if (build || buildOffMeshConnections) { - if (annotationBuilder == null) - { - if (_impl.GetSample() != null && 0 < _impl.GetSample().GetRecastResults().Count) - { - annotationBuilder = new JumpLinkBuilder(_impl.GetSample().GetRecastResults()); - } - } - - links.Clear(); - if (annotationBuilder != null) - { - var settings = _impl.GetSample().GetSettings(); - float cellSize = settings.cellSize; - float agentHeight = settings.agentHeight; - float agentRadius = settings.agentRadius; - float agentClimb = settings.agentMaxClimb; - float cellHeight = settings.cellHeight; - - if ((option.buildTypes & JumpLinkType.EDGE_CLIMB_DOWN.Bit) != 0) - { - JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, - agentHeight, agentClimb, option.groundTolerance, -agentRadius * 0.2f, - cellSize + 2 * agentRadius + option.climbDownDistance, - -option.climbDownMaxHeight, -option.climbDownMinHeight, 0); - links.AddRange(annotationBuilder.Build(config, JumpLinkType.EDGE_CLIMB_DOWN)); - } - - if ((option.buildTypes & JumpLinkType.EDGE_JUMP.Bit) != 0) - { - JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, - agentHeight, agentClimb, option.groundTolerance, -agentRadius * 0.2f, - option.edgeJumpEndDistance, -option.edgeJumpDownMaxHeight, - option.edgeJumpUpMaxHeight, option.edgeJumpHeight); - links.AddRange(annotationBuilder.Build(config, JumpLinkType.EDGE_JUMP)); - } - - if (buildOffMeshConnections) - { - DemoInputGeomProvider geom = _impl.GetSample().GetInputGeom(); - if (geom != null) - { - int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO; - geom.RemoveOffMeshConnections(c => c.area == area); - links.ForEach(l => AddOffMeshLink(l, geom, agentRadius)); - } - } - } + _impl.Build(buildOffMeshConnections); } ImGui.Text("Debug Draw Options"); ImGui.Separator(); //int newFlags = 0; - ImGui.CheckboxFlags("Walkable Border", ref option.flags, JumpLinkBuilderToolParams.DRAW_WALKABLE_BORDER); - ImGui.CheckboxFlags("Selected Edge", ref option.flags, JumpLinkBuilderToolParams.DRAW_SELECTED_EDGE); - ImGui.CheckboxFlags("Anim Trajectory", ref option.flags, JumpLinkBuilderToolParams.DRAW_ANIM_TRAJECTORY); - ImGui.CheckboxFlags("Land Samples", ref option.flags, JumpLinkBuilderToolParams.DRAW_LAND_SAMPLES); - ImGui.CheckboxFlags("All Annotations", ref option.flags, JumpLinkBuilderToolParams.DRAW_ANNOTATIONS); + ImGui.CheckboxFlags("Walkable Border", ref option.flags, JumpLinkBuilderToolOptions.DRAW_WALKABLE_BORDER); + ImGui.CheckboxFlags("Selected Edge", ref option.flags, JumpLinkBuilderToolOptions.DRAW_SELECTED_EDGE); + ImGui.CheckboxFlags("Anim Trajectory", ref option.flags, JumpLinkBuilderToolOptions.DRAW_ANIM_TRAJECTORY); + ImGui.CheckboxFlags("Land Samples", ref option.flags, JumpLinkBuilderToolOptions.DRAW_LAND_SAMPLES); + ImGui.CheckboxFlags("All Annotations", ref option.flags, JumpLinkBuilderToolOptions.DRAW_ANNOTATIONS); //option.flags = newFlags; } - private void AddOffMeshLink(JumpLink link, DemoInputGeomProvider geom, float agentRadius) - { - int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO; - int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP; - RcVec3f prev = new RcVec3f(); - for (int i = 0; i < link.startSamples.Length; i++) - { - RcVec3f p = link.startSamples[i].p; - RcVec3f q = link.endSamples[i].p; - if (i == 0 || RcVec3f.Dist2D(prev, p) > agentRadius) - { - geom.AddOffMeshConnection(p, q, agentRadius, false, area, flags); - prev = p; - } - } - } - public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift) { diff --git a/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolImpl.cs b/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolImpl.cs index 3a2a346..df7e67d 100644 --- a/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolImpl.cs +++ b/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolImpl.cs @@ -1,13 +1,32 @@ -namespace DotRecast.Recast.DemoTool.Tools +using System.Collections.Generic; +using DotRecast.Core; +using DotRecast.Detour.Extras.Jumplink; +using DotRecast.Recast.DemoTool.Builder; +using DotRecast.Recast.DemoTool.Geom; + +namespace DotRecast.Recast.DemoTool.Tools { public class JumpLinkBuilderToolImpl : ISampleTool { + private Sample _sample; + + private readonly List _links; + private JumpLinkBuilder _annotationBuilder; + private readonly int _selEdge = -1; + private readonly JumpLinkBuilderToolOptions _option; + + public JumpLinkBuilderToolImpl() + { + _links = new List(); + _option = new JumpLinkBuilderToolOptions(); + } + + public string GetName() { return "Annotation Builder"; } - - private Sample _sample; + public void SetSample(Sample sample) { _sample = sample; @@ -18,5 +37,97 @@ return _sample; } + public void Clear() + { + _annotationBuilder = null; + } + + public JumpLinkBuilderToolOptions GetOption() + { + return _option; + } + + public JumpLinkBuilder GetAnnotationBuilder() + { + return _annotationBuilder; + } + + public int GetSelEdge() + { + return _selEdge; + } + + public List GetLinks() + { + return _links; + } + + public void Build(bool buildOffMeshConnections) + { + if (_annotationBuilder == null) + { + if (_sample != null && 0 < _sample.GetRecastResults().Count) + { + _annotationBuilder = new JumpLinkBuilder(_sample.GetRecastResults()); + } + } + + _links.Clear(); + if (_annotationBuilder != null) + { + var settings = _sample.GetSettings(); + float cellSize = settings.cellSize; + float agentHeight = settings.agentHeight; + float agentRadius = settings.agentRadius; + float agentClimb = settings.agentMaxClimb; + float cellHeight = settings.cellHeight; + + if ((_option.buildTypes & JumpLinkType.EDGE_CLIMB_DOWN.Bit) != 0) + { + JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, + agentHeight, agentClimb, _option.groundTolerance, -agentRadius * 0.2f, + cellSize + 2 * agentRadius + _option.climbDownDistance, + -_option.climbDownMaxHeight, -_option.climbDownMinHeight, 0); + _links.AddRange(_annotationBuilder.Build(config, JumpLinkType.EDGE_CLIMB_DOWN)); + } + + if ((_option.buildTypes & JumpLinkType.EDGE_JUMP.Bit) != 0) + { + JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, + agentHeight, agentClimb, _option.groundTolerance, -agentRadius * 0.2f, + _option.edgeJumpEndDistance, -_option.edgeJumpDownMaxHeight, + _option.edgeJumpUpMaxHeight, _option.edgeJumpHeight); + _links.AddRange(_annotationBuilder.Build(config, JumpLinkType.EDGE_JUMP)); + } + + if (buildOffMeshConnections) + { + DemoInputGeomProvider geom = _sample.GetInputGeom(); + if (geom != null) + { + int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO; + geom.RemoveOffMeshConnections(c => c.area == area); + _links.ForEach(l => AddOffMeshLink(l, geom, agentRadius)); + } + } + } + } + + private void AddOffMeshLink(JumpLink link, DemoInputGeomProvider geom, float agentRadius) + { + int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO; + int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP; + RcVec3f prev = new RcVec3f(); + for (int i = 0; i < link.startSamples.Length; i++) + { + RcVec3f p = link.startSamples[i].p; + RcVec3f q = link.endSamples[i].p; + if (i == 0 || RcVec3f.Dist2D(prev, p) > agentRadius) + { + geom.AddOffMeshConnection(p, q, agentRadius, false, area, flags); + prev = p; + } + } + } } } \ No newline at end of file diff --git a/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolParams.cs b/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolOptions.cs similarity index 97% rename from src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolParams.cs rename to src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolOptions.cs index 78e0e78..149dfd2 100644 --- a/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolParams.cs +++ b/src/DotRecast.Recast.DemoTool/Tools/JumpLinkBuilderToolOptions.cs @@ -20,7 +20,7 @@ using DotRecast.Detour.Extras.Jumplink; namespace DotRecast.Recast.DemoTool.Tools { - public class JumpLinkBuilderToolParams + public class JumpLinkBuilderToolOptions { public const int DRAW_WALKABLE_SURFACE = 1 << 0; public const int DRAW_WALKABLE_BORDER = 1 << 1;