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)
{
throw new NotImplementedException();
}
public abstract void sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es);
protected void sampleGroundSegment(Func<float[], float, Tuple<bool, float>> heightFunc, GroundSegment seg,
int nsamples)
protected void sampleGroundSegment(Func<float[], float, Tuple<bool, float>> heightFunc, GroundSegment seg, int 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)
{
EdgeSampler es = null;
switch (type)
switch (type.Bit)
{
case JumpLinkType.EDGE_JUMP:
case JumpLinkType.EDGE_JUMP_BIT:
es = initEdgeJumpSampler(acfg, edge);
break;
case JumpLinkType.EDGE_CLIMB_DOWN:
case JumpLinkType.EDGE_CLIMB_DOWN_BIT:
es = initClimbDownSampler(acfg, edge);
break;
case JumpLinkType.EDGE_JUMP_OVER:
case JumpLinkType.EDGE_JUMP_OVER_BIT:
default:
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 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;
edges = results.Select(r => edgeExtractor.extractEdges(r.getMesh())).ToList();

View File

@ -1,9 +1,20 @@
namespace DotRecast.Detour.Extras.Jumplink
{
public enum JumpLinkType
public class JumpLinkType
{
EDGE_JUMP,
EDGE_CLIMB_DOWN,
EDGE_JUMP_OVER
public const int EDGE_JUMP_BIT = 1 << 0;
public const int EDGE_CLIMB_DOWN_BIT = 1 << 1;
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);
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);
long time = Stopwatch.GetTimestamp();
// float dt = (time - prevFrameTime) / TimeSpan.TicksPerMillisecond;
prevFrameTime = time;
// Update sample simulation.

View File

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