completed JumpLinkBuilderTool

This commit is contained in:
ikpil 2023-03-26 13:51:30 +09:00
parent 5c4f9411a3
commit 706364c30e
8 changed files with 113 additions and 128 deletions

View File

@ -19,13 +19,9 @@ namespace DotRecast.Detour.Extras.Jumplink
} }
} }
public void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es) public abstract void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es);
{
throw new NotImplementedException();
}
protected void sampleGroundSegment(Func<float[], float, Tuple<bool, float>> heightFunc, GroundSegment seg, protected void sampleGroundSegment(Func<float[], float, Tuple<bool, float>> heightFunc, GroundSegment seg, int nsamples)
int nsamples)
{ {
seg.gsamples = new GroundSample[nsamples]; seg.gsamples = new GroundSample[nsamples];

View File

@ -7,15 +7,15 @@ namespace DotRecast.Detour.Extras.Jumplink
public EdgeSampler get(JumpLinkBuilderConfig acfg, JumpLinkType type, Edge edge) public EdgeSampler get(JumpLinkBuilderConfig acfg, JumpLinkType type, Edge edge)
{ {
EdgeSampler es = null; EdgeSampler es = null;
switch (type) switch (type.Bit)
{ {
case JumpLinkType.EDGE_JUMP: case JumpLinkType.EDGE_JUMP_BIT:
es = initEdgeJumpSampler(acfg, edge); es = initEdgeJumpSampler(acfg, edge);
break; break;
case JumpLinkType.EDGE_CLIMB_DOWN: case JumpLinkType.EDGE_CLIMB_DOWN_BIT:
es = initClimbDownSampler(acfg, edge); es = initClimbDownSampler(acfg, edge);
break; break;
case JumpLinkType.EDGE_JUMP_OVER: case JumpLinkType.EDGE_JUMP_OVER_BIT:
default: default:
throw new ArgumentException("Unsupported jump type " + type); throw new ArgumentException("Unsupported jump type " + type);
} }

View File

@ -16,9 +16,9 @@ namespace DotRecast.Detour.Extras.Jumplink
private readonly JumpSegmentBuilder jumpSegmentBuilder = new JumpSegmentBuilder(); private readonly JumpSegmentBuilder jumpSegmentBuilder = new JumpSegmentBuilder();
private readonly List<Edge[]> edges; private readonly List<Edge[]> edges;
private readonly List<RecastBuilderResult> results; private readonly IList<RecastBuilderResult> results;
public JumpLinkBuilder(List<RecastBuilderResult> results) public JumpLinkBuilder(IList<RecastBuilderResult> results)
{ {
this.results = results; this.results = results;
edges = results.Select(r => edgeExtractor.extractEdges(r.getMesh())).ToList(); edges = results.Select(r => edgeExtractor.extractEdges(r.getMesh())).ToList();

View File

@ -1,9 +1,20 @@
namespace DotRecast.Detour.Extras.Jumplink namespace DotRecast.Detour.Extras.Jumplink
{ {
public enum JumpLinkType public class JumpLinkType
{ {
EDGE_JUMP, public const int EDGE_JUMP_BIT = 1 << 0;
EDGE_CLIMB_DOWN, public const int EDGE_CLIMB_DOWN_BIT = 1 << 1;
EDGE_JUMP_OVER public const int EDGE_JUMP_OVER_BIT = 1 << 2;
public static readonly JumpLinkType EDGE_JUMP = new JumpLinkType(EDGE_JUMP_BIT);
public static readonly JumpLinkType EDGE_CLIMB_DOWN = new JumpLinkType(EDGE_CLIMB_DOWN_BIT);
public static readonly JumpLinkType EDGE_JUMP_OVER = new JumpLinkType(EDGE_JUMP_OVER_BIT);
public int Bit { get; }
private JumpLinkType(int bit)
{
Bit = bit;
}
} }
} }

View File

@ -22,7 +22,7 @@ namespace DotRecast.Detour.Extras.Jumplink
} }
} }
public void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es) public override void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es)
{ {
NavMeshQuery navMeshQuery = createNavMesh(result, acfg.agentRadius, acfg.agentHeight, acfg.agentClimb); NavMeshQuery navMeshQuery = createNavMesh(result, acfg.agentRadius, acfg.agentHeight, acfg.agentClimb);
sampleGround(acfg, es, (pt, h) => getNavMeshHeight(navMeshQuery, pt, acfg.cellSize, h)); sampleGround(acfg, es, (pt, h) => getNavMeshHeight(navMeshQuery, pt, acfg.cellSize, h));

View File

@ -512,7 +512,6 @@ public class RecastDemo
cameraPos[1] += (float)((_moveUp - _moveDown) * keySpeed * dt); cameraPos[1] += (float)((_moveUp - _moveDown) * keySpeed * dt);
long time = Stopwatch.GetTimestamp(); long time = Stopwatch.GetTimestamp();
// float dt = (time - prevFrameTime) / TimeSpan.TicksPerMillisecond;
prevFrameTime = time; prevFrameTime = time;
// Update sample simulation. // Update sample simulation.

View File

@ -17,6 +17,8 @@ freely, subject to the following restrictions:
*/ */
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using DotRecast.Core;
using Silk.NET.Windowing; using Silk.NET.Windowing;
using DotRecast.Detour.Extras.Jumplink; using DotRecast.Detour.Extras.Jumplink;
using DotRecast.Recast.Demo.Builder; using DotRecast.Recast.Demo.Builder;
@ -324,128 +326,105 @@ public class JumpLinkBuilderTool : Tool
public override void layout() public override void layout()
{ {
// if (!sample.getRecastResults().isEmpty()) { if (0 >= sample.getRecastResults().Count)
// return;
// nk_layout_row_dynamic(ctx, 18, 1);
ImGui.Text("Options"); ImGui.Text("Options");
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.Separator();
ImGui.SliderFloat("Ground Tolerance", ref option.groundTolerance, 0f, 2f, "%.2f"); ImGui.SliderFloat("Ground Tolerance", ref option.groundTolerance, 0f, 2f, "%.2f");
// nk_layout_row_dynamic(ctx, 5, 1); ImGui.NewLine();
// nk_spacing(ctx, 1);
//
// nk_layout_row_dynamic(ctx, 18, 1);
ImGui.Text("Climb Down"); ImGui.Text("Climb Down");
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.Separator();
ImGui.SliderFloat("Distance", ref option.climbDownDistance, 0f, 5f, "%.2f"); ImGui.SliderFloat("Distance", ref option.climbDownDistance, 0f, 5f, "%.2f");
// nk_layout_row_dynamic(ctx, 20, 1);
ImGui.SliderFloat("Min Cliff Height", ref option.climbDownMinHeight, 0f, 10f, "%.2f"); ImGui.SliderFloat("Min Cliff Height", ref option.climbDownMinHeight, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 20, 1);
ImGui.SliderFloat("Max Cliff Height", ref option.climbDownMaxHeight, 0f, 10f, "%.2f"); ImGui.SliderFloat("Max Cliff Height", ref option.climbDownMaxHeight, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 5, 1); ImGui.NewLine();
// nk_spacing(ctx, 1);
//
// nk_layout_row_dynamic(ctx, 18, 1);
ImGui.Text("Jump Down"); ImGui.Text("Jump Down");
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.Separator();
ImGui.SliderFloat("Max Distance", ref option.edgeJumpEndDistance, 0f, 10f, "%.2f"); ImGui.SliderFloat("Max Distance", ref option.edgeJumpEndDistance, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 20, 1);
ImGui.SliderFloat("Jump Height", ref option.edgeJumpHeight, 0f, 10f, "%.2f"); ImGui.SliderFloat("Jump Height", ref option.edgeJumpHeight, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 20, 1);
ImGui.SliderFloat("Max Jump Down", ref option.edgeJumpDownMaxHeight, 0f, 10f, "%.2f"); ImGui.SliderFloat("Max Jump Down", ref option.edgeJumpDownMaxHeight, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 20, 1);
ImGui.SliderFloat("Max Jump Up", ref option.edgeJumpUpMaxHeight, 0f, 10f, "%.2f"); ImGui.SliderFloat("Max Jump Up", ref option.edgeJumpUpMaxHeight, 0f, 10f, "%.2f");
// nk_layout_row_dynamic(ctx, 5, 1); ImGui.NewLine();
// nk_spacing(ctx, 1);
// nk_layout_row_dynamic(ctx, 18, 1);
ImGui.Text("Mode"); ImGui.Text("Mode");
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.Separator();
//int buildTypes = 0; //int buildTypes = 0;
// buildTypes |= nk_option_text(ctx, "Climb Down", ImGui.CheckboxFlags("Climb Down", ref option.buildTypes, JumpLinkType.EDGE_CLIMB_DOWN.Bit);
// (option.buildTypes & (1 << JumpLinkType.EDGE_CLIMB_DOWN.ordinal())) != 0) ImGui.CheckboxFlags("Edge Jump", ref option.buildTypes, JumpLinkType.EDGE_JUMP.Bit);
// ? (1 << JumpLinkType.EDGE_CLIMB_DOWN.ordinal())
// : 0;
// nk_layout_row_dynamic(ctx, 20, 1);
// buildTypes |= nk_option_text(ctx, "Edge Jump",
// (option.buildTypes & (1 << JumpLinkType.EDGE_JUMP.ordinal())) != 0)
// ? (1 << JumpLinkType.EDGE_JUMP.ordinal())
// : 0;
//option.buildTypes = buildTypes; //option.buildTypes = buildTypes;
// bool build = false; bool build = false;
// bool buildOffMeshConnections = false; bool buildOffMeshConnections = false;
// if (nk_button_text(ctx, "Build")) { if (ImGui.Button("Build"))
// build = true; {
// } build = true;
// if (nk_button_text(ctx, "Build Off-Mesh Links")) { }
// buildOffMeshConnections = true;
// } if (ImGui.Button("Build Off-Mesh Links"))
// if (build || buildOffMeshConnections) { {
// if (annotationBuilder == null) { buildOffMeshConnections = true;
// if (sample != null && !sample.getRecastResults().isEmpty()) { }
// annotationBuilder = new JumpLinkBuilder(sample.getRecastResults());
// } if (build || buildOffMeshConnections)
// } {
// links.clear(); if (annotationBuilder == null)
// if (annotationBuilder != null) { {
// float cellSize = sample.getSettingsUI().getCellSize(); if (sample != null && 0 < sample.getRecastResults().Count)
// float agentHeight = sample.getSettingsUI().getAgentHeight(); {
// float agentRadius = sample.getSettingsUI().getAgentRadius(); annotationBuilder = new JumpLinkBuilder(sample.getRecastResults());
// float agentClimb = sample.getSettingsUI().getAgentMaxClimb(); }
// float cellHeight = sample.getSettingsUI().getCellHeight(); }
// if ((buildTypes & (1 << JumpLinkType.EDGE_CLIMB_DOWN.ordinal())) != 0) {
// JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, links.Clear();
// agentHeight, agentClimb, option.groundTolerance[0], -agentRadius * 0.2f, if (annotationBuilder != null)
// cellSize + 2 * agentRadius + option.climbDownDistance[0], {
// -option.climbDownMaxHeight[0], -option.climbDownMinHeight[0], 0); float cellSize = sample.getSettingsUI().getCellSize();
// links.addAll(annotationBuilder.build(config, JumpLinkType.EDGE_CLIMB_DOWN)); float agentHeight = sample.getSettingsUI().getAgentHeight();
// } float agentRadius = sample.getSettingsUI().getAgentRadius();
// if ((buildTypes & (1 << JumpLinkType.EDGE_JUMP.ordinal())) != 0) { float agentClimb = sample.getSettingsUI().getAgentMaxClimb();
// JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius, float cellHeight = sample.getSettingsUI().getCellHeight();
// agentHeight, agentClimb, option.groundTolerance[0], -agentRadius * 0.2f, if ((option.buildTypes & JumpLinkType.EDGE_CLIMB_DOWN.Bit) != 0)
// option.edgeJumpEndDistance[0], -option.edgeJumpDownMaxHeight[0], {
// option.edgeJumpUpMaxHeight[0], option.edgeJumpHeight[0]); JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius,
// links.addAll(annotationBuilder.build(config, JumpLinkType.EDGE_JUMP)); agentHeight, agentClimb, option.groundTolerance, -agentRadius * 0.2f,
// } cellSize + 2 * agentRadius + option.climbDownDistance,
// if (buildOffMeshConnections) { -option.climbDownMaxHeight, -option.climbDownMinHeight, 0);
// DemoInputGeomProvider geom = sample.getInputGeom(); links.AddRange(annotationBuilder.build(config, JumpLinkType.EDGE_CLIMB_DOWN));
// if (geom != null) { }
// int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP_AUTO;
// geom.removeOffMeshConnections(c => c.area == area); if ((option.buildTypes & JumpLinkType.EDGE_JUMP.Bit) != 0)
// links.forEach(l => addOffMeshLink(l, geom, agentRadius)); {
// } JumpLinkBuilderConfig config = new JumpLinkBuilderConfig(cellSize, cellHeight, agentRadius,
// } agentHeight, agentClimb, option.groundTolerance, -agentRadius * 0.2f,
// } option.edgeJumpEndDistance, -option.edgeJumpDownMaxHeight,
// } option.edgeJumpUpMaxHeight, option.edgeJumpHeight);
// nk_spacing(ctx, 1); links.AddRange(annotationBuilder.build(config, JumpLinkType.EDGE_JUMP));
// nk_layout_row_dynamic(ctx, 18, 1); }
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));
}
}
}
}
ImGui.Text("Debug Draw Options"); ImGui.Text("Debug Draw Options");
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.Separator();
//int newFlags = 0; //int newFlags = 0;
// newFlags |= nk_option_text(ctx, "Walkable Border", ImGui.CheckboxFlags("Walkable Border", ref option.flags, JumpLinkBuilderToolParams.DRAW_WALKABLE_BORDER);
// (params.flags & JumpLinkBuilderToolParams.DRAW_WALKABLE_BORDER) != 0) ImGui.CheckboxFlags("Selected Edge", ref option.flags, JumpLinkBuilderToolParams.DRAW_SELECTED_EDGE);
// ? JumpLinkBuilderToolParams.DRAW_WALKABLE_BORDER ImGui.CheckboxFlags("Anim Trajectory", ref option.flags, JumpLinkBuilderToolParams.DRAW_ANIM_TRAJECTORY);
// : 0; ImGui.CheckboxFlags("Land Samples", ref option.flags, JumpLinkBuilderToolParams.DRAW_LAND_SAMPLES);
// nk_layout_row_dynamic(ctx, 20, 1); ImGui.CheckboxFlags("All Annotations", ref option.flags, JumpLinkBuilderToolParams.DRAW_ANNOTATIONS);
// newFlags |= nk_option_text(ctx, "Selected Edge", //option.flags = newFlags;
// (params.flags & JumpLinkBuilderToolParams.DRAW_SELECTED_EDGE) != 0)
// ? JumpLinkBuilderToolParams.DRAW_SELECTED_EDGE
// : 0;
// nk_layout_row_dynamic(ctx, 20, 1);
// newFlags |= nk_option_text(ctx, "Anim Trajectory",
// (params.flags & JumpLinkBuilderToolParams.DRAW_ANIM_TRAJECTORY) != 0)
// ? JumpLinkBuilderToolParams.DRAW_ANIM_TRAJECTORY
// : 0;
// nk_layout_row_dynamic(ctx, 20, 1);
// newFlags |= nk_option_text(ctx, "Land Samples",
// (params.flags & JumpLinkBuilderToolParams.DRAW_LAND_SAMPLES) != 0)
// ? JumpLinkBuilderToolParams.DRAW_LAND_SAMPLES
// : 0;
// nk_layout_row_dynamic(ctx, 20, 1);
// newFlags |= nk_option_text(ctx, "All Annotations",
// (params.flags & JumpLinkBuilderToolParams.DRAW_ANNOTATIONS) != 0)
// ? JumpLinkBuilderToolParams.DRAW_ANNOTATIONS
// : 0;
// params.flags = newFlags;
// }
} }
private void addOffMeshLink(JumpLink link, DemoInputGeomProvider geom, float agentRadius) private void addOffMeshLink(JumpLink link, DemoInputGeomProvider geom, float agentRadius)

View File

@ -39,5 +39,5 @@ public class JumpLinkBuilderToolParams
public float edgeJumpHeight = 0.4f; public float edgeJumpHeight = 0.4f;
public float edgeJumpDownMaxHeight = 2.5f; public float edgeJumpDownMaxHeight = 2.5f;
public float edgeJumpUpMaxHeight = 0.3f; public float edgeJumpUpMaxHeight = 0.3f;
public int buildTypes = (1 << (int)JumpLinkType.EDGE_CLIMB_DOWN) | (1 << (int)JumpLinkType.EDGE_JUMP); public int buildTypes = (1 << JumpLinkType.EDGE_CLIMB_DOWN.Bit) | (1 << JumpLinkType.EDGE_JUMP.Bit);
} }