diff --git a/src/DotRecast.Recast.Demo/RecastDemo.cs b/src/DotRecast.Recast.Demo/RecastDemo.cs index 5f89248..670ff20 100644 --- a/src/DotRecast.Recast.Demo/RecastDemo.cs +++ b/src/DotRecast.Recast.Demo/RecastDemo.cs @@ -386,7 +386,8 @@ public class RecastDemo : IRecastDemoChannel new ObstacleSampleTool(), new OffMeshConnectionSampleTool(), new ConvexVolumeSampleTool(), - new CrowdSampleTool(), + new CrowdampleTool(), + new CrowdProfilingSampleTool(), new JumpLinkBuilderSampleTool(), new DynamicUpdateSampleTool() ); diff --git a/src/DotRecast.Recast.Demo/Tools/CrowdProfilingTool.cs b/src/DotRecast.Recast.Demo/Tools/CrowdProfilingSampleTool.cs similarity index 74% rename from src/DotRecast.Recast.Demo/Tools/CrowdProfilingTool.cs rename to src/DotRecast.Recast.Demo/Tools/CrowdProfilingSampleTool.cs index 341bf8d..80e5241 100644 --- a/src/DotRecast.Recast.Demo/Tools/CrowdProfilingTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/CrowdProfilingSampleTool.cs @@ -28,13 +28,21 @@ 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; namespace DotRecast.Recast.Demo.Tools; -public class CrowdProfilingTool +public class CrowdProfilingSampleTool : ISampleTool { - private readonly Func agentParamsSupplier; + private static readonly ILogger Logger = Log.ForContext(); + + private DemoSample _sample; + private DtNavMesh m_nav; + + private readonly CrowdToolParams toolParams = new CrowdToolParams(); + private RcCrowdProfilingTool _tool; + private int expandSimOptions = 1; private int expandCrowdOptions = 1; private int agents = 1000; @@ -52,13 +60,113 @@ public class CrowdProfilingTool private readonly List _polyPoints = new(); private long crowdUpdateTime; - public CrowdProfilingTool(Func agentParamsSupplier) + public CrowdProfilingSampleTool() { - this.agentParamsSupplier = agentParamsSupplier; + _tool = new(); + } + + public void SetSample(DemoSample sample) + { + _sample = sample; + } + + public void OnSampleChanged() + { + var geom = _sample.GetInputGeom(); + var settings = _sample.GetSettings(); + var navMesh = _sample.GetNavMesh(); + + if (navMesh != null && m_nav != navMesh) + { + m_nav = navMesh; + Setup(settings.agentRadius, m_nav); + } + } + + private DtCrowdAgentParams GetAgentParams() + { + var settings = _sample.GetSettings(); + + DtCrowdAgentParams ap = new DtCrowdAgentParams(); + 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(); + ap.obstacleAvoidanceType = toolParams.m_obstacleAvoidanceType; + ap.separationWeight = toolParams.m_separationWeight; + return ap; + } + + + private int GetUpdateFlags() + { + int updateFlags = 0; + if (toolParams.m_anticipateTurns) + { + updateFlags |= DtCrowdAgentParams.DT_CROWD_ANTICIPATE_TURNS; + } + + if (toolParams.m_optimizeVis) + { + updateFlags |= DtCrowdAgentParams.DT_CROWD_OPTIMIZE_VIS; + } + + if (toolParams.m_optimizeTopo) + { + updateFlags |= DtCrowdAgentParams.DT_CROWD_OPTIMIZE_TOPO; + } + + if (toolParams.m_obstacleAvoidance) + { + updateFlags |= DtCrowdAgentParams.DT_CROWD_OBSTACLE_AVOIDANCE; + } + + if (toolParams.m_separation) + { + updateFlags |= DtCrowdAgentParams.DT_CROWD_SEPARATION; + } + + return updateFlags; + } + + + public IRcToolable GetTool() + { + return _tool; } public void Layout() { + ImGui.Text("Options"); + ImGui.Separator(); + bool m_optimizeVis = toolParams.m_optimizeVis; + bool m_optimizeTopo = toolParams.m_optimizeTopo; + bool m_anticipateTurns = toolParams.m_anticipateTurns; + bool m_obstacleAvoidance = toolParams.m_obstacleAvoidance; + bool m_separation = toolParams.m_separation; + int m_obstacleAvoidanceType = toolParams.m_obstacleAvoidanceType; + float m_separationWeight = toolParams.m_separationWeight; + ImGui.Checkbox("Optimize Visibility", ref toolParams.m_optimizeVis); + ImGui.Checkbox("Optimize Topology", ref toolParams.m_optimizeTopo); + ImGui.Checkbox("Anticipate Turns", ref toolParams.m_anticipateTurns); + ImGui.Checkbox("Obstacle Avoidance", ref toolParams.m_obstacleAvoidance); + ImGui.SliderInt("Avoidance Quality", ref toolParams.m_obstacleAvoidanceType, 0, 3); + ImGui.Checkbox("Separation", ref toolParams.m_separation); + ImGui.SliderFloat("Separation Weight", ref toolParams.m_separationWeight, 0f, 20f, "%.2f"); + ImGui.NewLine(); + + if (m_optimizeVis != toolParams.m_optimizeVis || m_optimizeTopo != toolParams.m_optimizeTopo + || m_anticipateTurns != toolParams.m_anticipateTurns || m_obstacleAvoidance != toolParams.m_obstacleAvoidance + || m_separation != toolParams.m_separation + || m_obstacleAvoidanceType != toolParams.m_obstacleAvoidanceType + || m_separationWeight != toolParams.m_separationWeight) + { + UpdateAgentParams(); + } + ImGui.Text("Simulation Options"); ImGui.Separator(); ImGui.SliderInt("Agents", ref agents, 0, 10000); @@ -80,6 +188,16 @@ public class CrowdProfilingTool StartProfiling(); } + if (m_optimizeVis != toolParams.m_optimizeVis || m_optimizeTopo != toolParams.m_optimizeTopo + || m_anticipateTurns != toolParams.m_anticipateTurns || m_obstacleAvoidance != toolParams.m_obstacleAvoidance + || m_separation != toolParams.m_separation + || m_obstacleAvoidanceType != toolParams.m_obstacleAvoidanceType + || m_separationWeight != toolParams.m_separationWeight) + { + UpdateAgentParams(); + } + + ImGui.Text("Times"); ImGui.Separator(); if (crowd != null) @@ -96,6 +214,11 @@ public class CrowdProfilingTool } } + public void HandleClick(RcVec3f s, RcVec3f p, bool shift) + { + //throw new NotImplementedException(); + } + private DtStatus GetMobPosition(DtNavMeshQuery navquery, IDtQueryFilter filter, out RcVec3f randomPt) { return navquery.FindRandomPoint(filter, rnd, out var randomRef, out randomPt); @@ -395,15 +518,26 @@ public class CrowdProfilingTool dd.DepthMask(true); } + public void HandleUpdate(float dt) + { + Update(dt); + } + + public void HandleClickRay(RcVec3f start, RcVec3f direction, bool shift) + { + //throw new NotImplementedException(); + } + private DtCrowdAgent AddAgent(RcVec3f p, CrowdAgentType type) { - DtCrowdAgentParams ap = agentParamsSupplier.Invoke(); + DtCrowdAgentParams ap = GetAgentParams(); ap.userData = new CrowdAgentData(type, p); return crowd.AddAgent(p, ap); } - public void UpdateAgentParams(int updateFlags, int obstacleAvoidanceType, float separationWeight) + private void UpdateAgentParams() { + int updateFlags = GetUpdateFlags(); if (crowd != null) { foreach (DtCrowdAgent ag in crowd.GetActiveAgents()) @@ -418,8 +552,8 @@ public class CrowdProfilingTool option.queryFilterType = ag.option.queryFilterType; option.userData = ag.option.userData; option.updateFlags = updateFlags; - option.obstacleAvoidanceType = obstacleAvoidanceType; - option.separationWeight = separationWeight; + option.obstacleAvoidanceType = toolParams.m_obstacleAvoidanceType; + option.separationWeight = toolParams.m_separationWeight; crowd.UpdateAgentParameters(ag, option); } } diff --git a/src/DotRecast.Recast.Demo/Tools/CrowdSampleTool.cs b/src/DotRecast.Recast.Demo/Tools/CrowdampleTool.cs similarity index 93% rename from src/DotRecast.Recast.Demo/Tools/CrowdSampleTool.cs rename to src/DotRecast.Recast.Demo/Tools/CrowdampleTool.cs index ba5113f..077388d 100644 --- a/src/DotRecast.Recast.Demo/Tools/CrowdSampleTool.cs +++ b/src/DotRecast.Recast.Demo/Tools/CrowdampleTool.cs @@ -35,16 +35,15 @@ using static DotRecast.Recast.Demo.Draw.DebugDrawPrimitives; namespace DotRecast.Recast.Demo.Tools; -public class CrowdSampleTool : ISampleTool +public class CrowdampleTool : ISampleTool { - private static readonly ILogger Logger = Log.ForContext(); + private static readonly ILogger Logger = Log.ForContext(); private DemoSample _sample; private readonly RcCrowdTool _tool; private readonly CrowdToolParams toolParams = new CrowdToolParams(); private DtNavMesh m_nav; private DtCrowd crowd; - private readonly CrowdProfilingTool profilingTool; private readonly DtCrowdAgentDebugInfo m_agentDebug = new DtCrowdAgentDebugInfo(); private readonly Dictionary m_trails = new(); @@ -54,10 +53,9 @@ public class CrowdSampleTool : ISampleTool private int m_modeIdx = CrowdToolMode.CREATE.Idx; private long crowdUpdateTime; - public CrowdSampleTool() + public CrowdampleTool() { m_agentDebug.vod = new DtObstacleAvoidanceDebugData(2048); - profilingTool = new CrowdProfilingTool(GetAgentParams); _tool = new(); } @@ -118,18 +116,11 @@ public class CrowdSampleTool : ISampleTool option.adaptiveDepth = 3; crowd.SetObstacleAvoidanceParams(3, option); - - profilingTool.Setup(settings.agentRadius, m_nav); } } public void HandleClick(RcVec3f s, RcVec3f p, bool shift) { - if (m_mode == CrowdToolMode.PROFILING) - { - return; - } - if (crowd == null) { return; @@ -326,12 +317,6 @@ public class CrowdSampleTool : ISampleTool public void HandleRender(NavMeshRenderer renderer) { - if (m_mode == CrowdToolMode.PROFILING) - { - profilingTool.HandleRender(renderer); - return; - } - RecastDebugDraw dd = renderer.GetDebugDraw(); var settings = _sample.GetSettings(); float rad = settings.agentRadius; @@ -639,14 +624,9 @@ public class CrowdSampleTool : ISampleTool private void UpdateTick(float dt) { - if (m_mode == CrowdToolMode.PROFILING) - { - profilingTool.Update(dt); - return; - } - if (crowd == null) return; + DtNavMesh nav = _sample.GetNavMesh(); if (nav == null) return; @@ -686,7 +666,6 @@ public class CrowdSampleTool : ISampleTool ImGui.RadioButton(CrowdToolMode.MOVE_TARGET.Label, ref m_modeIdx, CrowdToolMode.MOVE_TARGET.Idx); ImGui.RadioButton(CrowdToolMode.SELECT.Label, ref m_modeIdx, CrowdToolMode.SELECT.Idx); ImGui.RadioButton(CrowdToolMode.TOGGLE_POLYS.Label, ref m_modeIdx, CrowdToolMode.TOGGLE_POLYS.Idx); - ImGui.RadioButton(CrowdToolMode.PROFILING.Label, ref m_modeIdx, CrowdToolMode.PROFILING.Idx); ImGui.NewLine(); if (previousToolMode.Idx != m_modeIdx) @@ -722,29 +701,21 @@ public class CrowdSampleTool : ISampleTool } - if (m_mode == CrowdToolMode.PROFILING) - { - profilingTool.Layout(); - } + ImGui.Text("Selected Debug Draw"); + ImGui.Separator(); + ImGui.Checkbox("Show Corners", ref toolParams.m_showCorners); + ImGui.Checkbox("Show Collision Segs", ref toolParams.m_showCollisionSegments); + ImGui.Checkbox("Show Path", ref toolParams.m_showPath); + ImGui.Checkbox("Show VO", ref toolParams.m_showVO); + ImGui.Checkbox("Show Path Optimization", ref toolParams.m_showOpt); + ImGui.Checkbox("Show Neighbours", ref toolParams.m_showNeis); + ImGui.NewLine(); - if (m_mode != CrowdToolMode.PROFILING) - { - ImGui.Text("Selected Debug Draw"); - ImGui.Separator(); - ImGui.Checkbox("Show Corners", ref toolParams.m_showCorners); - ImGui.Checkbox("Show Collision Segs", ref toolParams.m_showCollisionSegments); - ImGui.Checkbox("Show Path", ref toolParams.m_showPath); - ImGui.Checkbox("Show VO", ref toolParams.m_showVO); - ImGui.Checkbox("Show Path Optimization", ref toolParams.m_showOpt); - ImGui.Checkbox("Show Neighbours", ref toolParams.m_showNeis); - ImGui.NewLine(); - - ImGui.Text("Debug Draw"); - ImGui.Separator(); - ImGui.Checkbox("Show Proximity Grid", ref toolParams.m_showGrid); - ImGui.Checkbox("Show Nodes", ref toolParams.m_showNodes); - ImGui.Text($"Update Time: {crowdUpdateTime} ms"); - } + ImGui.Text("Debug Draw"); + ImGui.Separator(); + ImGui.Checkbox("Show Proximity Grid", ref toolParams.m_showGrid); + ImGui.Checkbox("Show Nodes", ref toolParams.m_showNodes); + ImGui.Text($"Update Time: {crowdUpdateTime} ms"); } private void UpdateAgentParams() @@ -755,7 +726,6 @@ public class CrowdSampleTool : ISampleTool } int updateFlags = GetUpdateFlags(); - profilingTool.UpdateAgentParams(updateFlags, toolParams.m_obstacleAvoidanceType, toolParams.m_separationWeight); foreach (DtCrowdAgent ag in crowd.GetActiveAgents()) { DtCrowdAgentParams option = new DtCrowdAgentParams(); diff --git a/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs b/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs index f5bd0b8..1ebced8 100644 --- a/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs +++ b/src/DotRecast.Recast.Toolset/Tools/CrowdToolMode.cs @@ -8,14 +8,12 @@ namespace DotRecast.Recast.Toolset.Tools public static readonly CrowdToolMode MOVE_TARGET = new CrowdToolMode(1, "Move Target"); public static readonly CrowdToolMode SELECT = new CrowdToolMode(2, "Select Agent"); public static readonly CrowdToolMode TOGGLE_POLYS = new CrowdToolMode(3, "Toggle Polys"); - public static readonly CrowdToolMode PROFILING = new CrowdToolMode(4, "Profiling"); public static readonly RcImmutableArray Values = RcImmutableArray.Create( CREATE, MOVE_TARGET, SELECT, - TOGGLE_POLYS, - PROFILING + TOGGLE_POLYS ); public int Idx { get; } diff --git a/src/DotRecast.Recast.Toolset/Tools/CrowdToolParams.cs b/src/DotRecast.Recast.Toolset/Tools/CrowdToolParams.cs index b3ca402..649902f 100644 --- a/src/DotRecast.Recast.Toolset/Tools/CrowdToolParams.cs +++ b/src/DotRecast.Recast.Toolset/Tools/CrowdToolParams.cs @@ -1,21 +1,3 @@ -/* -recast4j copyright (c) 2020-2021 Piotr Piastucki piotr@jtilia.org - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. -*/ - namespace DotRecast.Recast.Toolset.Tools { public class CrowdToolParams diff --git a/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs index 1cc96aa..7a2f8e7 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs @@ -9,7 +9,7 @@ namespace DotRecast.Recast.Toolset.Tools { public string GetName() { - return "Create Convex Volumes"; + return "Convex Volumes"; } public RcConvexVolume RemoveByPos(IInputGeomProvider geom, RcVec3f pos) diff --git a/src/DotRecast.Recast.Toolset/Tools/RcCrowdProfilingTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcCrowdProfilingTool.cs new file mode 100644 index 0000000..52ada9f --- /dev/null +++ b/src/DotRecast.Recast.Toolset/Tools/RcCrowdProfilingTool.cs @@ -0,0 +1,10 @@ +namespace DotRecast.Recast.Toolset.Tools +{ + public class RcCrowdProfilingTool : IRcToolable + { + public string GetName() + { + return "Crowd Profiling"; + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Recast.Toolset/Tools/RcCrowdTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcCrowdTool.cs index b63efb7..45d1aaa 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcCrowdTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcCrowdTool.cs @@ -4,7 +4,7 @@ { public string GetName() { - return "Create Crowd"; + return "Crowd Control"; } } } \ No newline at end of file diff --git a/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs index 4495ab7..5931f74 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs @@ -25,7 +25,7 @@ namespace DotRecast.Recast.Toolset.Tools public string GetName() { - return "Create Temp Obstacles"; + return "Temp Obstacles"; } public NavMeshBuildResult Build(IInputGeomProvider geom, RcNavMeshBuildSettings setting, RcByteOrder order, bool cCompatibility) diff --git a/src/DotRecast.Recast.Toolset/Tools/RcOffMeshConnectionTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcOffMeshConnectionTool.cs index b0234ac..a3b31df 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcOffMeshConnectionTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcOffMeshConnectionTool.cs @@ -16,7 +16,7 @@ namespace DotRecast.Recast.Toolset.Tools public string GetName() { - return "Create Off-Mesh Links"; + return "Off-Mesh Links"; } public RcOffMeshConnectionToolOption GetOption() diff --git a/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs index 75e601a..d6586f6 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs @@ -10,7 +10,7 @@ namespace DotRecast.Recast.Toolset.Tools { public string GetName() { - return "Create Tiles"; + return "Tiles"; } public void RemoveAllTiles(IInputGeomProvider geom, RcNavMeshBuildSettings settings, DtNavMesh navMesh)