separated various build configuration values in the sample view

This commit is contained in:
ikpil 2023-06-11 16:04:21 +09:00
parent 5e1d4cd02a
commit 869c1e7b98
10 changed files with 296 additions and 335 deletions

View File

@ -29,22 +29,20 @@ namespace DotRecast.Recast.Demo.Draw;
public class NavMeshRenderer
{
private readonly RecastDebugDraw debugDraw;
private readonly int navMeshDrawFlags = RecastDebugDraw.DRAWNAVMESH_OFFMESHCONS
| RecastDebugDraw.DRAWNAVMESH_CLOSEDLIST;
private readonly RecastDebugDraw _debugDraw;
private readonly int _navMeshDrawFlags = RecastDebugDraw.DRAWNAVMESH_OFFMESHCONS | RecastDebugDraw.DRAWNAVMESH_CLOSEDLIST;
public NavMeshRenderer(RecastDebugDraw debugDraw)
{
this.debugDraw = debugDraw;
_debugDraw = debugDraw;
}
public RecastDebugDraw GetDebugDraw()
{
return debugDraw;
return _debugDraw;
}
public void Render(Sample sample)
public void Render(Sample sample, DrawMode drawMode)
{
if (sample == null)
{
@ -55,139 +53,140 @@ public class NavMeshRenderer
DemoInputGeomProvider geom = sample.GetInputGeom();
IList<RecastBuilderResult> rcBuilderResults = sample.GetRecastResults();
DtNavMesh navMesh = sample.GetNavMesh();
RcSettingsView rcSettingsView = sample.GetSettingsUI();
debugDraw.Fog(true);
debugDraw.DepthMask(true);
var drawMode = rcSettingsView.GetDrawMode();
var settings = sample.GetSettings();
_debugDraw.Fog(true);
_debugDraw.DepthMask(true);
float texScale = 1.0f / (rcSettingsView.GetCellSize() * 10.0f);
float m_agentMaxSlope = rcSettingsView.GetAgentMaxSlope();
float texScale = 1.0f / (settings.cellSize * 10.0f);
float agentMaxSlope = settings.agentMaxSlope;
if (drawMode != DrawMode.DRAWMODE_NAVMESH_TRANS)
{
// Draw mesh
if (geom != null)
{
debugDraw.DebugDrawTriMeshSlope(geom.vertices, geom.faces, geom.normals, m_agentMaxSlope, texScale);
_debugDraw.DebugDrawTriMeshSlope(geom.vertices, geom.faces, geom.normals, agentMaxSlope, texScale);
DrawOffMeshConnections(geom, false);
}
}
debugDraw.Fog(false);
debugDraw.DepthMask(false);
_debugDraw.Fog(false);
_debugDraw.DepthMask(false);
if (geom != null)
{
DrawGeomBounds(geom);
}
if (navMesh != null && navQuery != null
&& (drawMode == DrawMode.DRAWMODE_NAVMESH || drawMode == DrawMode.DRAWMODE_NAVMESH_TRANS
|| drawMode == DrawMode.DRAWMODE_NAVMESH_BVTREE || drawMode == DrawMode.DRAWMODE_NAVMESH_NODES
&& (drawMode == DrawMode.DRAWMODE_NAVMESH
|| drawMode == DrawMode.DRAWMODE_NAVMESH_TRANS
|| drawMode == DrawMode.DRAWMODE_NAVMESH_BVTREE
|| drawMode == DrawMode.DRAWMODE_NAVMESH_NODES
|| drawMode == DrawMode.DRAWMODE_NAVMESH_INVIS
|| drawMode == DrawMode.DRAWMODE_NAVMESH_PORTALS))
{
if (drawMode != DrawMode.DRAWMODE_NAVMESH_INVIS)
{
debugDraw.DebugDrawNavMeshWithClosedList(navMesh, navQuery, navMeshDrawFlags);
_debugDraw.DebugDrawNavMeshWithClosedList(navMesh, navQuery, _navMeshDrawFlags);
}
if (drawMode == DrawMode.DRAWMODE_NAVMESH_BVTREE)
{
debugDraw.DebugDrawNavMeshBVTree(navMesh);
_debugDraw.DebugDrawNavMeshBVTree(navMesh);
}
if (drawMode == DrawMode.DRAWMODE_NAVMESH_PORTALS)
{
debugDraw.DebugDrawNavMeshPortals(navMesh);
_debugDraw.DebugDrawNavMeshPortals(navMesh);
}
if (drawMode == DrawMode.DRAWMODE_NAVMESH_NODES)
{
debugDraw.DebugDrawNavMeshNodes(navQuery);
debugDraw.DebugDrawNavMeshPolysWithFlags(navMesh, SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED,
_debugDraw.DebugDrawNavMeshNodes(navQuery);
_debugDraw.DebugDrawNavMeshPolysWithFlags(navMesh, SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED,
DebugDraw.DuRGBA(0, 0, 0, 128));
}
}
debugDraw.DepthMask(true);
_debugDraw.DepthMask(true);
foreach (RecastBuilderResult rcBuilderResult in rcBuilderResults)
{
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT)
{
debugDraw.DebugDrawCompactHeightfieldSolid(rcBuilderResult.GetCompactHeightfield());
_debugDraw.DebugDrawCompactHeightfieldSolid(rcBuilderResult.GetCompactHeightfield());
}
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT_DISTANCE)
{
debugDraw.DebugDrawCompactHeightfieldDistance(rcBuilderResult.GetCompactHeightfield());
_debugDraw.DebugDrawCompactHeightfieldDistance(rcBuilderResult.GetCompactHeightfield());
}
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT_REGIONS)
{
debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
}
if (rcBuilderResult.GetSolidHeightfield() != null && drawMode == DrawMode.DRAWMODE_VOXELS)
{
debugDraw.Fog(true);
debugDraw.DebugDrawHeightfieldSolid(rcBuilderResult.GetSolidHeightfield());
debugDraw.Fog(false);
_debugDraw.Fog(true);
_debugDraw.DebugDrawHeightfieldSolid(rcBuilderResult.GetSolidHeightfield());
_debugDraw.Fog(false);
}
if (rcBuilderResult.GetSolidHeightfield() != null && drawMode == DrawMode.DRAWMODE_VOXELS_WALKABLE)
{
debugDraw.Fog(true);
debugDraw.DebugDrawHeightfieldWalkable(rcBuilderResult.GetSolidHeightfield());
debugDraw.Fog(false);
_debugDraw.Fog(true);
_debugDraw.DebugDrawHeightfieldWalkable(rcBuilderResult.GetSolidHeightfield());
_debugDraw.Fog(false);
}
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_RAW_CONTOURS)
{
debugDraw.DepthMask(false);
debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 1f);
debugDraw.DepthMask(true);
_debugDraw.DepthMask(false);
_debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 1f);
_debugDraw.DepthMask(true);
}
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_BOTH_CONTOURS)
{
debugDraw.DepthMask(false);
debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 0.5f);
debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
debugDraw.DepthMask(true);
_debugDraw.DepthMask(false);
_debugDraw.DebugDrawRawContours(rcBuilderResult.GetContourSet(), 0.5f);
_debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
_debugDraw.DepthMask(true);
}
if (rcBuilderResult.GetContourSet() != null && drawMode == DrawMode.DRAWMODE_CONTOURS)
{
debugDraw.DepthMask(false);
debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
debugDraw.DepthMask(true);
_debugDraw.DepthMask(false);
_debugDraw.DebugDrawContours(rcBuilderResult.GetContourSet());
_debugDraw.DepthMask(true);
}
if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_REGION_CONNECTIONS)
{
debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
debugDraw.DepthMask(false);
_debugDraw.DebugDrawCompactHeightfieldRegions(rcBuilderResult.GetCompactHeightfield());
_debugDraw.DepthMask(false);
if (rcBuilderResult.GetContourSet() != null)
{
debugDraw.DebugDrawRegionConnections(rcBuilderResult.GetContourSet());
_debugDraw.DebugDrawRegionConnections(rcBuilderResult.GetContourSet());
}
debugDraw.DepthMask(true);
_debugDraw.DepthMask(true);
}
if (rcBuilderResult.GetMesh() != null && drawMode == DrawMode.DRAWMODE_POLYMESH)
{
debugDraw.DepthMask(false);
debugDraw.DebugDrawPolyMesh(rcBuilderResult.GetMesh());
debugDraw.DepthMask(true);
_debugDraw.DepthMask(false);
_debugDraw.DebugDrawPolyMesh(rcBuilderResult.GetMesh());
_debugDraw.DepthMask(true);
}
if (rcBuilderResult.GetMeshDetail() != null && drawMode == DrawMode.DRAWMODE_POLYMESH_DETAIL)
{
debugDraw.DepthMask(false);
debugDraw.DebugDrawPolyMeshDetail(rcBuilderResult.GetMeshDetail());
debugDraw.DepthMask(true);
_debugDraw.DepthMask(false);
_debugDraw.DebugDrawPolyMeshDetail(rcBuilderResult.GetMeshDetail());
_debugDraw.DepthMask(true);
}
}
@ -202,48 +201,48 @@ public class NavMeshRenderer
// Draw bounds
RcVec3f bmin = geom.GetMeshBoundsMin();
RcVec3f bmax = geom.GetMeshBoundsMax();
debugDraw.DebugDrawBoxWire(bmin.x, bmin.y, bmin.z, bmax.x, bmax.y, bmax.z,
_debugDraw.DebugDrawBoxWire(bmin.x, bmin.y, bmin.z, bmax.x, bmax.y, bmax.z,
DebugDraw.DuRGBA(255, 255, 255, 128), 1.0f);
debugDraw.Begin(DebugDrawPrimitives.POINTS, 5.0f);
debugDraw.Vertex(bmin.x, bmin.y, bmin.z, DebugDraw.DuRGBA(255, 255, 255, 128));
debugDraw.End();
_debugDraw.Begin(DebugDrawPrimitives.POINTS, 5.0f);
_debugDraw.Vertex(bmin.x, bmin.y, bmin.z, DebugDraw.DuRGBA(255, 255, 255, 128));
_debugDraw.End();
}
public void DrawOffMeshConnections(DemoInputGeomProvider geom, bool hilight)
{
int conColor = DebugDraw.DuRGBA(192, 0, 128, 192);
int baseColor = DebugDraw.DuRGBA(0, 0, 0, 64);
debugDraw.DepthMask(false);
_debugDraw.DepthMask(false);
debugDraw.Begin(DebugDrawPrimitives.LINES, 2.0f);
_debugDraw.Begin(DebugDrawPrimitives.LINES, 2.0f);
foreach (DemoOffMeshConnection con in geom.GetOffMeshConnections())
{
float[] v = con.verts;
debugDraw.Vertex(v[0], v[1], v[2], baseColor);
debugDraw.Vertex(v[0], v[1] + 0.2f, v[2], baseColor);
_debugDraw.Vertex(v[0], v[1], v[2], baseColor);
_debugDraw.Vertex(v[0], v[1] + 0.2f, v[2], baseColor);
debugDraw.Vertex(v[3], v[4], v[5], baseColor);
debugDraw.Vertex(v[3], v[4] + 0.2f, v[5], baseColor);
_debugDraw.Vertex(v[3], v[4], v[5], baseColor);
_debugDraw.Vertex(v[3], v[4] + 0.2f, v[5], baseColor);
debugDraw.AppendCircle(v[0], v[1] + 0.1f, v[2], con.radius, baseColor);
debugDraw.AppendCircle(v[3], v[4] + 0.1f, v[5], con.radius, baseColor);
_debugDraw.AppendCircle(v[0], v[1] + 0.1f, v[2], con.radius, baseColor);
_debugDraw.AppendCircle(v[3], v[4] + 0.1f, v[5], con.radius, baseColor);
if (hilight)
{
debugDraw.AppendArc(v[0], v[1], v[2], v[3], v[4], v[5], 0.25f, con.bidir ? 0.6f : 0.0f, 0.6f, conColor);
_debugDraw.AppendArc(v[0], v[1], v[2], v[3], v[4], v[5], 0.25f, con.bidir ? 0.6f : 0.0f, 0.6f, conColor);
}
}
debugDraw.End();
_debugDraw.End();
debugDraw.DepthMask(true);
_debugDraw.DepthMask(true);
}
void DrawConvexVolumes(DemoInputGeomProvider geom)
{
debugDraw.DepthMask(false);
_debugDraw.DepthMask(false);
debugDraw.Begin(DebugDrawPrimitives.TRIS);
_debugDraw.Begin(DebugDrawPrimitives.TRIS);
foreach (ConvexVolume vol in geom.ConvexVolumes())
{
@ -253,23 +252,23 @@ public class NavMeshRenderer
var va = RcVec3f.Of(vol.verts[k], vol.verts[k + 1], vol.verts[k + 2]);
var vb = RcVec3f.Of(vol.verts[j], vol.verts[j + 1], vol.verts[j + 2]);
debugDraw.Vertex(vol.verts[0], vol.hmax, vol.verts[2], col);
debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
debugDraw.Vertex(va.x, vol.hmax, va.z, col);
_debugDraw.Vertex(vol.verts[0], vol.hmax, vol.verts[2], col);
_debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
_debugDraw.Vertex(va.x, vol.hmax, va.z, col);
debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
debugDraw.Vertex(va.x, vol.hmax, va.z, col);
debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
_debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(va.x, vol.hmax, va.z, col);
_debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
debugDraw.Vertex(vb.x, vol.hmin, vb.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
_debugDraw.Vertex(vb.x, vol.hmin, vb.z, DebugDraw.DuDarkenCol(col));
}
}
debugDraw.End();
_debugDraw.End();
debugDraw.Begin(DebugDrawPrimitives.LINES, 2.0f);
_debugDraw.Begin(DebugDrawPrimitives.LINES, 2.0f);
foreach (ConvexVolume vol in geom.ConvexVolumes())
{
int col = DebugDraw.DuTransCol(DebugDraw.AreaToCol(vol.areaMod.GetMaskedValue()), 220);
@ -277,31 +276,31 @@ public class NavMeshRenderer
{
var va = RcVec3f.Of(vol.verts[k], vol.verts[k + 1], vol.verts[k + 2]);
var vb = RcVec3f.Of(vol.verts[j], vol.verts[j + 1], vol.verts[j + 2]);
debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
debugDraw.Vertex(vb.x, vol.hmin, vb.z, DebugDraw.DuDarkenCol(col));
debugDraw.Vertex(va.x, vol.hmax, va.z, col);
debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
debugDraw.Vertex(va.x, vol.hmax, va.z, col);
_debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(vb.x, vol.hmin, vb.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(va.x, vol.hmax, va.z, col);
_debugDraw.Vertex(vb.x, vol.hmax, vb.z, col);
_debugDraw.Vertex(va.x, vol.hmin, va.z, DebugDraw.DuDarkenCol(col));
_debugDraw.Vertex(va.x, vol.hmax, va.z, col);
}
}
debugDraw.End();
_debugDraw.End();
debugDraw.Begin(DebugDrawPrimitives.POINTS, 3.0f);
_debugDraw.Begin(DebugDrawPrimitives.POINTS, 3.0f);
foreach (ConvexVolume vol in geom.ConvexVolumes())
{
int col = DebugDraw.DuDarkenCol(DebugDraw.DuTransCol(DebugDraw.AreaToCol(vol.areaMod.GetMaskedValue()), 220));
for (int j = 0; j < vol.verts.Length; j += 3)
{
debugDraw.Vertex(vol.verts[j + 0], vol.verts[j + 1] + 0.1f, vol.verts[j + 2], col);
debugDraw.Vertex(vol.verts[j + 0], vol.hmin, vol.verts[j + 2], col);
debugDraw.Vertex(vol.verts[j + 0], vol.hmax, vol.verts[j + 2], col);
_debugDraw.Vertex(vol.verts[j + 0], vol.verts[j + 1] + 0.1f, vol.verts[j + 2], col);
_debugDraw.Vertex(vol.verts[j + 0], vol.hmin, vol.verts[j + 2], col);
_debugDraw.Vertex(vol.verts[j + 0], vol.hmax, vol.verts[j + 2], col);
}
}
debugDraw.End();
_debugDraw.End();
debugDraw.DepthMask(true);
_debugDraw.DepthMask(true);
}
}

View File

@ -109,7 +109,7 @@ public class RecastDemo
private bool markerPositionSet;
private RcVec3f markerPosition = new RcVec3f();
private RcToolsetView toolsetView;
private RcToolsetView toolset;
private RcSettingsView settingsView;
private RcLogView logView;
@ -301,7 +301,7 @@ public class RecastDemo
{
DemoInputGeomProvider geom = DemoObjImporter.Load(stream);
sample = new Sample(geom, ImmutableArray<RecastBuilderResult>.Empty, null, settingsView, dd);
toolsetView.SetEnabled(true);
toolset.SetEnabled(true);
return geom;
}
@ -325,7 +325,7 @@ public class RecastDemo
if (mesh != null)
{
//sample = new Sample(null, ImmutableArray<RecastBuilderResult>.Empty, mesh, settingsUI, dd);
toolsetView.SetEnabled(true);
toolset.SetEnabled(true);
}
}
@ -369,7 +369,7 @@ public class RecastDemo
_imgui = new ImGuiController(_gl, window, _input);
settingsView = new RcSettingsView();
toolsetView = new RcToolsetView(
toolset = new RcToolsetView(
new TestNavmeshTool(),
new OffMeshConnectionTool(),
new ConvexVolumeTool(),
@ -379,7 +379,7 @@ public class RecastDemo
);
logView = new RcLogView();
_canvas = new RcCanvas(window, settingsView, toolsetView, logView);
_canvas = new RcCanvas(window, settingsView, toolset, logView);
var vendor = _gl.GetStringS(GLEnum.Vendor);
var version = _gl.GetStringS(GLEnum.Version);
@ -430,13 +430,14 @@ public class RecastDemo
*/
if (sample.GetInputGeom() != null)
{
var settings = settingsView.GetSettings();
RcVec3f bmin = sample.GetInputGeom().GetMeshBoundsMin();
RcVec3f bmax = sample.GetInputGeom().GetMeshBoundsMax();
Recast.CalcGridSize(bmin, bmax, settingsView.GetCellSize(), out var gw, out var gh);
Recast.CalcGridSize(bmin, bmax, settings.cellSize, out var gw, out var gh);
settingsView.SetVoxels(gw, gh);
settingsView.SetTiles(tileNavMeshBuilder.GetTiles(sample.GetInputGeom(), settingsView.GetCellSize(), settingsView.GetTileSize()));
settingsView.SetMaxTiles(tileNavMeshBuilder.GetMaxTiles(sample.GetInputGeom(), settingsView.GetCellSize(), settingsView.GetTileSize()));
settingsView.SetMaxPolys(tileNavMeshBuilder.GetMaxPolysPerTile(sample.GetInputGeom(), settingsView.GetCellSize(), settingsView.GetTileSize()));
settingsView.SetTiles(tileNavMeshBuilder.GetTiles(sample.GetInputGeom(), settings.cellSize, settings.tileSize));
settingsView.SetMaxTiles(tileNavMeshBuilder.GetMaxTiles(sample.GetInputGeom(), settings.cellSize, settings.tileSize));
settingsView.SetMaxPolys(tileNavMeshBuilder.GetMaxPolysPerTile(sample.GetInputGeom(), settings.cellSize, settings.tileSize));
}
UpdateKeyboard((float)dt);
@ -475,7 +476,7 @@ public class RecastDemo
timeAcc -= DELTA_TIME;
if (simIter < 5 && sample != null)
{
toolsetView.HandleUpdate(DELTA_TIME);
toolset.HandleUpdate(DELTA_TIME);
}
simIter++;
@ -515,47 +516,84 @@ public class RecastDemo
{
if (!building)
{
float m_cellSize = settingsView.GetCellSize();
float m_cellHeight = settingsView.GetCellHeight();
float m_agentHeight = settingsView.GetAgentHeight();
float m_agentRadius = settingsView.GetAgentRadius();
float m_agentMaxClimb = settingsView.GetAgentMaxClimb();
float m_agentMaxSlope = settingsView.GetAgentMaxSlope();
int m_regionMinSize = settingsView.GetMinRegionSize();
int m_regionMergeSize = settingsView.GetMergedRegionSize();
float m_edgeMaxLen = settingsView.GetEdgeMaxLen();
float m_edgeMaxError = settingsView.GetEdgeMaxError();
int m_vertsPerPoly = settingsView.GetVertsPerPoly();
float m_detailSampleDist = settingsView.GetDetailSampleDist();
float m_detailSampleMaxError = settingsView.GetDetailSampleMaxError();
int m_tileSize = settingsView.GetTileSize();
var settings = settingsView.GetSettings();
var partitioning = settings.partitioning;
var cellSize = settings.cellSize;
var cellHeight = settings.cellHeight;
var agentHeight = settings.agentHeight;
var agentRadius = settings.agentRadius;
var agentMaxClimb = settings.agentMaxClimb;
var agentMaxSlope = settings.agentMaxSlope;
var regionMinSize = settings.minRegionSize;
var regionMergeSize = settings.mergedRegionSize;
var edgeMaxLen = settings.edgeMaxLen;
var edgeMaxError = settings.edgeMaxError;
var vertsPerPoly = settings.vertsPerPoly;
var detailSampleDist = settings.detailSampleDist;
var detailSampleMaxError = settings.detailSampleMaxError;
var filterLowHangingObstacles = settings.filterLowHangingObstacles;
var filterLedgeSpans = settings.filterLedgeSpans;
var filterWalkableLowHeightSpans = settings.filterWalkableLowHeightSpans;
var tileSize = settings.tileSize;
long t = RcFrequency.Ticks;
Logger.Information($"build");
Tuple<IList<RecastBuilderResult>, DtNavMesh> buildResult;
if (settingsView.IsTiled())
if (settings.tiled)
{
buildResult = tileNavMeshBuilder.Build(sample.GetInputGeom(), settingsView.GetPartitioning(), m_cellSize,
m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize,
m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist,
m_detailSampleMaxError, settingsView.IsFilterLowHangingObstacles(), settingsView.IsFilterLedgeSpans(),
settingsView.IsFilterWalkableLowHeightSpans(), m_tileSize);
buildResult = tileNavMeshBuilder.Build(
sample.GetInputGeom(),
partitioning,
cellSize,
cellHeight,
agentHeight,
agentRadius,
agentMaxClimb,
agentMaxSlope,
regionMinSize,
regionMergeSize,
edgeMaxLen,
edgeMaxError,
vertsPerPoly,
detailSampleDist,
detailSampleMaxError,
filterLowHangingObstacles,
filterLedgeSpans,
filterWalkableLowHeightSpans,
tileSize
);
}
else
{
buildResult = soloNavMeshBuilder.Build(sample.GetInputGeom(), settingsView.GetPartitioning(), m_cellSize,
m_cellHeight, m_agentHeight, m_agentRadius, m_agentMaxClimb, m_agentMaxSlope, m_regionMinSize,
m_regionMergeSize, m_edgeMaxLen, m_edgeMaxError, m_vertsPerPoly, m_detailSampleDist,
m_detailSampleMaxError, settingsView.IsFilterLowHangingObstacles(), settingsView.IsFilterLedgeSpans(),
settingsView.IsFilterWalkableLowHeightSpans());
buildResult = soloNavMeshBuilder.Build(
sample.GetInputGeom(),
partitioning,
cellSize,
cellHeight,
agentHeight,
agentRadius,
agentMaxClimb,
agentMaxSlope,
regionMinSize,
regionMergeSize,
edgeMaxLen,
edgeMaxError,
vertsPerPoly,
detailSampleDist,
detailSampleMaxError,
filterLowHangingObstacles,
filterLedgeSpans,
filterWalkableLowHeightSpans
);
}
sample.Update(sample.GetInputGeom(), buildResult.Item1, buildResult.Item2);
sample.SetChanged(false);
settingsView.SetBuildTime((RcFrequency.Ticks - t) / TimeSpan.TicksPerMillisecond);
//settingsUI.SetBuildTelemetry(buildResult.Item1.Select(x => x.GetTelemetry()).ToList());
toolsetView.SetSample(sample);
toolset.SetSample(sample);
Logger.Information($"build times");
Logger.Information($"-----------------------------------------");
@ -602,7 +640,7 @@ public class RecastDemo
}
RcVec3f rayDir = RcVec3f.Of(rayEnd.x - rayStart.x, rayEnd.y - rayStart.y, rayEnd.z - rayStart.z);
IRcTool rayTool = toolsetView.GetTool();
IRcTool rayTool = toolset.GetTool();
rayDir.Normalize();
if (rayTool != null)
{
@ -704,7 +742,7 @@ public class RecastDemo
}
sample.SetChanged(false);
toolsetView.SetSample(sample);
toolset.SetSample(sample);
}
@ -726,8 +764,9 @@ public class RecastDemo
modelviewMatrix = dd.ViewMatrix(cameraPos, cameraEulers);
dd.Fog(camr * 0.1f, camr * 1.25f);
renderer.Render(sample);
IRcTool tool = toolsetView.GetTool();
renderer.Render(sample, settingsView.GetDrawMode());
IRcTool tool = toolset.GetTool();
if (tool != null)
{
tool.HandleRender(renderer);

View File

@ -24,75 +24,76 @@ using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.DemoTool.Geom;
using DotRecast.Recast.Demo.UI;
using DotRecast.Recast.DemoTool;
namespace DotRecast.Recast.Demo;
public class Sample
{
private DemoInputGeomProvider inputGeom;
private DtNavMesh navMesh;
private DtNavMeshQuery navMeshQuery;
private readonly RcSettingsView _settingsView;
private IList<RecastBuilderResult> recastResults;
private bool changed;
private DemoInputGeomProvider _inputGeom;
private DtNavMesh _navMesh;
private DtNavMeshQuery _navMeshQuery;
private readonly RcSettings _settings;
private IList<RecastBuilderResult> _recastResults;
private bool _changed;
public Sample(DemoInputGeomProvider inputGeom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh,
RcSettingsView settingsView, RecastDebugDraw debugDraw)
{
this.inputGeom = inputGeom;
this.recastResults = recastResults;
this.navMesh = navMesh;
_settingsView = settingsView;
_inputGeom = inputGeom;
_recastResults = recastResults;
_navMesh = navMesh;
_settings = settingsView.GetSettings();
SetQuery(navMesh);
changed = true;
_changed = true;
}
private void SetQuery(DtNavMesh navMesh)
{
navMeshQuery = navMesh != null ? new DtNavMeshQuery(navMesh) : null;
_navMeshQuery = navMesh != null ? new DtNavMeshQuery(navMesh) : null;
}
public DemoInputGeomProvider GetInputGeom()
{
return inputGeom;
return _inputGeom;
}
public IList<RecastBuilderResult> GetRecastResults()
{
return recastResults;
return _recastResults;
}
public DtNavMesh GetNavMesh()
{
return navMesh;
return _navMesh;
}
public RcSettingsView GetSettingsUI()
public RcSettings GetSettings()
{
return _settingsView;
return _settings;
}
public DtNavMeshQuery GetNavMeshQuery()
{
return navMeshQuery;
return _navMeshQuery;
}
public bool IsChanged()
{
return changed;
return _changed;
}
public void SetChanged(bool changed)
{
this.changed = changed;
_changed = changed;
}
public void Update(DemoInputGeomProvider geom, IList<RecastBuilderResult> recastResults, DtNavMesh navMesh)
{
inputGeom = geom;
this.recastResults = recastResults;
this.navMesh = navMesh;
_inputGeom = geom;
_recastResults = recastResults;
_navMesh = navMesh;
SetQuery(navMesh);
changed = true;
_changed = true;
}
}

View File

@ -69,7 +69,7 @@ public class CrowdTool : IRcTool
{
m_nav = nav;
DtCrowdConfig config = new DtCrowdConfig(sample.GetSettingsUI().GetAgentRadius());
DtCrowdConfig config = new DtCrowdConfig(sample.GetSettings().agentRadius);
crowd = new DtCrowd(config, nav, __ => new DtQueryDefaultFilter(SampleAreaModifications.SAMPLE_POLYFLAGS_ALL,
SampleAreaModifications.SAMPLE_POLYFLAGS_DISABLED, new float[] { 1f, 10f, 1f, 1f, 2f, 1.5f }));
@ -107,7 +107,7 @@ public class CrowdTool : IRcTool
crowd.SetObstacleAvoidanceParams(3, option);
profilingTool.Setup(sample.GetSettingsUI().GetAgentRadius(), m_nav);
profilingTool.Setup(sample.GetSettings().agentRadius, m_nav);
}
}
@ -210,8 +210,8 @@ public class CrowdTool : IRcTool
private DtCrowdAgentParams GetAgentParams()
{
DtCrowdAgentParams ap = new DtCrowdAgentParams();
ap.radius = sample.GetSettingsUI().GetAgentRadius();
ap.height = sample.GetSettingsUI().GetAgentHeight();
ap.radius = sample.GetSettings().agentRadius;
ap.height = sample.GetSettings().agentHeight;
ap.maxAcceleration = 8.0f;
ap.maxSpeed = 3.5f;
ap.collisionQueryRange = ap.radius * 12.0f;
@ -319,7 +319,7 @@ public class CrowdTool : IRcTool
}
RecastDebugDraw dd = renderer.GetDebugDraw();
float rad = sample.GetSettingsUI().GetAgentRadius();
float rad = sample.GetSettings().agentRadius;
DtNavMesh nav = sample.GetNavMesh();
if (nav == null || crowd == null)
return;

View File

@ -431,9 +431,9 @@ public class DynamicUpdateTool : IRcTool
private void DrawAgent(RecastDebugDraw dd, RcVec3f pos, int col)
{
float r = sample.GetSettingsUI().GetAgentRadius();
float h = sample.GetSettingsUI().GetAgentHeight();
float c = sample.GetSettingsUI().GetAgentMaxClimb();
float r = sample.GetSettings().agentRadius;
float h = sample.GetSettings().agentHeight;
float c = sample.GetSettings().agentMaxClimb;
dd.DepthMask(false);
// 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);

View File

@ -378,11 +378,13 @@ public class JumpLinkBuilderTool : IRcTool
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();
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,

View File

@ -57,7 +57,7 @@ public class OffMeshConnectionTool : IRcTool
foreach (DemoOffMeshConnection offMeshCon in geom.GetOffMeshConnections())
{
float d = Math.Min(RcVec3f.DistSqr(p, offMeshCon.verts, 0), RcVec3f.DistSqr(p, offMeshCon.verts, 3));
if (d < nearestDist && Math.Sqrt(d) < sample.GetSettingsUI().GetAgentRadius())
if (d < nearestDist && Math.Sqrt(d) < sample.GetSettings().agentRadius)
{
nearestDist = d;
nearestConnection = offMeshCon;
@ -81,7 +81,7 @@ public class OffMeshConnectionTool : IRcTool
{
int area = SampleAreaModifications.SAMPLE_POLYAREA_TYPE_JUMP;
int flags = SampleAreaModifications.SAMPLE_POLYFLAGS_JUMP;
geom.AddOffMeshConnection(hitPos, p, sample.GetSettingsUI().GetAgentRadius(), 0 == bidir, area, flags);
geom.AddOffMeshConnection(hitPos, p, sample.GetSettings().agentRadius, 0 == bidir, area, flags);
hitPosSet = false;
}
}
@ -95,7 +95,7 @@ public class OffMeshConnectionTool : IRcTool
}
RecastDebugDraw dd = renderer.GetDebugDraw();
float s = sample.GetSettingsUI().GetAgentRadius();
float s = sample.GetSettings().agentRadius;
if (hitPosSet)
{

View File

@ -439,7 +439,7 @@ public class TestNavmeshTool : IRcTool
{
float nx = (m_epos.z - m_spos.z) * 0.25f;
float nz = -(m_epos.x - m_spos.x) * 0.25f;
float agentHeight = m_sample != null ? m_sample.GetSettingsUI().GetAgentHeight() : 0;
float agentHeight = m_sample != null ? m_sample.GetSettings().agentHeight : 0;
m_queryPoly[0] = m_spos.x + nx * 1.2f;
m_queryPoly[1] = m_spos.y + agentHeight / 2;
@ -469,7 +469,7 @@ public class TestNavmeshTool : IRcTool
{
if (m_sposSet && m_startRef != 0)
{
m_neighbourhoodRadius = m_sample.GetSettingsUI().GetAgentRadius() * 20.0f;
m_neighbourhoodRadius = m_sample.GetSettings().agentRadius * 20.0f;
Result<FindLocalNeighbourhoodResult> result = m_navQuery.FindLocalNeighbourhood(m_startRef, m_spos,
m_neighbourhoodRadius, m_filter);
if (result.Succeeded())
@ -516,9 +516,9 @@ public class TestNavmeshTool : IRcTool
int endCol = DuRGBA(51, 102, 0, 129);
int pathCol = DuRGBA(0, 0, 0, 64);
float agentRadius = m_sample.GetSettingsUI().GetAgentRadius();
float agentHeight = m_sample.GetSettingsUI().GetAgentHeight();
float agentClimb = m_sample.GetSettingsUI().GetAgentMaxClimb();
float agentRadius = m_sample.GetSettings().agentRadius;
float agentHeight = m_sample.GetSettings().agentHeight;
float agentClimb = m_sample.GetSettings().agentMaxClimb;
if (m_sposSet)
{
@ -927,9 +927,9 @@ public class TestNavmeshTool : IRcTool
private void DrawAgent(RecastDebugDraw dd, RcVec3f pos, int col)
{
float r = m_sample.GetSettingsUI().GetAgentRadius();
float h = m_sample.GetSettingsUI().GetAgentHeight();
float c = m_sample.GetSettingsUI().GetAgentMaxClimb();
float r = m_sample.GetSettings().agentRadius;
float h = m_sample.GetSettings().agentHeight;
float c = m_sample.GetSettings().agentMaxClimb;
dd.DepthMask(false);
// 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);

View File

@ -23,45 +23,16 @@ using System.Linq;
using System.Numerics;
using DotRecast.Core;
using DotRecast.Recast.Demo.Draw;
using DotRecast.Recast.DemoTool;
using ImGuiNET;
namespace DotRecast.Recast.Demo.UI;
public class RcSettingsView : IRcView
{
private float cellSize = 0.3f;
private float cellHeight = 0.2f;
private float agentHeight = 2.0f;
private float agentRadius = 0.6f;
private float agentMaxClimb = 0.9f;
private float agentMaxSlope = 45f;
private int minRegionSize = 8;
private int mergedRegionSize = 20;
private int partitioningIdx = 0;
private PartitionType partitioning = PartitionType.WATERSHED;
private bool filterLowHangingObstacles = true;
private bool filterLedgeSpans = true;
private bool filterWalkableLowHeightSpans = true;
private float edgeMaxLen = 12f;
private float edgeMaxError = 1.3f;
private int vertsPerPoly = 6;
private float detailSampleDist = 6f;
private float detailSampleMaxError = 1f;
private bool tiled = false;
private int tileSize = 32;
// public readonly NkColor white = NkColor.Create();
// public readonly NkColor background = NkColor.Create();
// public readonly NkColor transparent = NkColor.Create();
private bool buildTriggered;
private long buildTime;
private readonly int[] voxels = new int[2];
private readonly int[] tiles = new int[2];
private int maxTiles;
@ -76,16 +47,26 @@ public class RcSettingsView : IRcView
private bool _mouseInside;
public bool IsMouseInside() => _mouseInside;
private readonly RcSettings _settings;
private RcCanvas _canvas;
public RcSettingsView()
{
_settings = new();
}
public void Bind(RcCanvas canvas)
{
_canvas = canvas;
}
public RcSettings GetSettings()
{
return _settings;
}
public void Update(double dt)
{
}
public void Draw(double dt)
@ -131,63 +112,62 @@ public class RcSettingsView : IRcView
ImGui.Text("Rasterization");
ImGui.Separator();
ImGui.SliderFloat("Cell Size", ref cellSize, 0.01f, 1f, "%.2f");
ImGui.SliderFloat("Cell Height", ref cellHeight, 0.01f, 1f, "%.2f");
ImGui.SliderFloat("Cell Size", ref _settings.cellSize, 0.01f, 1f, "%.2f");
ImGui.SliderFloat("Cell Height", ref _settings.cellHeight, 0.01f, 1f, "%.2f");
ImGui.Text($"Voxels {voxels[0]} x {voxels[1]}");
ImGui.NewLine();
ImGui.Text("Agent");
ImGui.Separator();
ImGui.SliderFloat("Height", ref agentHeight, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Radius", ref agentRadius, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Max Climb", ref agentMaxClimb, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Max Slope", ref agentMaxSlope, 1f, 90f, "%.0f");
ImGui.SliderFloat("Height", ref _settings.agentHeight, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Radius", ref _settings.agentRadius, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Max Climb", ref _settings.agentMaxClimb, 0.1f, 5f, "%.1f");
ImGui.SliderFloat("Max Slope", ref _settings.agentMaxSlope, 1f, 90f, "%.0f");
ImGui.NewLine();
ImGui.Text("Region");
ImGui.Separator();
ImGui.SliderInt("Min Region Size", ref minRegionSize, 1, 150);
ImGui.SliderInt("Merged Region Size", ref mergedRegionSize, 1, 150);
ImGui.SliderInt("Min Region Size", ref _settings.minRegionSize, 1, 150);
ImGui.SliderInt("Merged Region Size", ref _settings.mergedRegionSize, 1, 150);
ImGui.NewLine();
ImGui.Text("Partitioning");
ImGui.Separator();
PartitionType.Values.ForEach(partition =>
{
var label = partition.Name.Substring(0, 1).ToUpper()
+ partition.Name.Substring(1).ToLower();
ImGui.RadioButton(label, ref partitioningIdx, partition.Idx);
var label = partition.Name.Substring(0, 1).ToUpper() + partition.Name.Substring(1).ToLower();
ImGui.RadioButton(label, ref _settings.partitioningIdx, partition.Idx);
});
ImGui.NewLine();
ImGui.Text("Filtering");
ImGui.Separator();
ImGui.Checkbox("Low Hanging Obstacles", ref filterLowHangingObstacles);
ImGui.Checkbox("Ledge Spans", ref filterLedgeSpans);
ImGui.Checkbox("Walkable Low Height Spans", ref filterWalkableLowHeightSpans);
ImGui.Checkbox("Low Hanging Obstacles", ref _settings.filterLowHangingObstacles);
ImGui.Checkbox("Ledge Spans", ref _settings.filterLedgeSpans);
ImGui.Checkbox("Walkable Low Height Spans", ref _settings.filterWalkableLowHeightSpans);
ImGui.NewLine();
ImGui.Text("Polygonization");
ImGui.Separator();
ImGui.SliderFloat("Max Edge Length", ref edgeMaxLen, 0f, 50f, "%.1f");
ImGui.SliderFloat("Max Edge Error", ref edgeMaxError, 0.1f, 3f, "%.1f");
ImGui.SliderInt("Vert Per Poly", ref vertsPerPoly, 3, 12);
ImGui.SliderFloat("Max Edge Length", ref _settings.edgeMaxLen, 0f, 50f, "%.1f");
ImGui.SliderFloat("Max Edge Error", ref _settings.edgeMaxError, 0.1f, 3f, "%.1f");
ImGui.SliderInt("Vert Per Poly", ref _settings.vertsPerPoly, 3, 12);
ImGui.NewLine();
ImGui.Text("Detail Mesh");
ImGui.Separator();
ImGui.SliderFloat("Sample Distance", ref detailSampleDist, 0f, 16f, "%.1f");
ImGui.SliderFloat("Max Sample Error", ref detailSampleMaxError, 0f, 16f, "%.1f");
ImGui.SliderFloat("Sample Distance", ref _settings.detailSampleDist, 0f, 16f, "%.1f");
ImGui.SliderFloat("Max Sample Error", ref _settings.detailSampleMaxError, 0f, 16f, "%.1f");
ImGui.NewLine();
ImGui.Text("Tiling");
ImGui.Separator();
ImGui.Checkbox("Enable", ref tiled);
if (tiled)
ImGui.Checkbox("Enable", ref _settings.tiled);
if (_settings.tiled)
{
if (0 < (tileSize % 16))
tileSize = tileSize + (16 - (tileSize % 16));
ImGui.SliderInt("Tile Size", ref tileSize, 16, 1024);
if (0 < (_settings.tileSize % 16))
_settings.tileSize = _settings.tileSize + (16 - (_settings.tileSize % 16));
ImGui.SliderInt("Tile Size", ref _settings.tileSize, 16, 1024);
ImGui.Text($"Tiles {tiles[0]} x {tiles[1]}");
ImGui.Text($"Max Tiles {maxTiles}");
@ -230,70 +210,12 @@ public class RcSettingsView : IRcView
ImGui.End();
}
public float GetCellSize()
{
return cellSize;
}
public float GetCellHeight()
{
return cellHeight;
}
public float GetAgentHeight()
{
return agentHeight;
}
public float GetAgentRadius()
{
return agentRadius;
}
public float GetAgentMaxClimb()
{
return agentMaxClimb;
}
public float GetAgentMaxSlope()
{
return agentMaxSlope;
}
public int GetMinRegionSize()
{
return minRegionSize;
}
public int GetMergedRegionSize()
{
return mergedRegionSize;
}
public PartitionType GetPartitioning()
{
return partitioning;
}
public bool IsBuildTriggered()
{
return buildTriggered;
}
public bool IsFilterLowHangingObstacles()
{
return filterLowHangingObstacles;
}
public bool IsFilterLedgeSpans()
{
return filterLedgeSpans;
}
public bool IsFilterWalkableLowHeightSpans()
{
return filterWalkableLowHeightSpans;
}
public void SetBuildTime(long buildTime)
{
@ -305,47 +227,12 @@ public class RcSettingsView : IRcView
return DrawMode.Values[drawMode];
}
public float GetEdgeMaxLen()
{
return edgeMaxLen;
}
public float GetEdgeMaxError()
{
return edgeMaxError;
}
public int GetVertsPerPoly()
{
return vertsPerPoly;
}
public float GetDetailSampleDist()
{
return detailSampleDist;
}
public float GetDetailSampleMaxError()
{
return detailSampleMaxError;
}
public void SetVoxels(int gw, int gh)
{
voxels[0] = gw;
voxels[1] = gh;
}
public bool IsTiled()
{
return tiled;
}
public int GetTileSize()
{
return tileSize;
}
public void SetTiles(int[] tiles)
{
this.tiles[0] = tiles[0];

View File

@ -0,0 +1,33 @@
namespace DotRecast.Recast.DemoTool
{
public class RcSettings
{
public float cellSize = 0.3f;
public float cellHeight = 0.2f;
public float agentHeight = 2.0f;
public float agentRadius = 0.6f;
public float agentMaxClimb = 0.9f;
public float agentMaxSlope = 45f;
public int minRegionSize = 8;
public int mergedRegionSize = 20;
public int partitioningIdx = 0;
public PartitionType partitioning = PartitionType.WATERSHED;
public bool filterLowHangingObstacles = true;
public bool filterLedgeSpans = true;
public bool filterWalkableLowHeightSpans = true;
public float edgeMaxLen = 12f;
public float edgeMaxError = 1.3f;
public int vertsPerPoly = 6;
public float detailSampleDist = 6f;
public float detailSampleMaxError = 1f;
public bool tiled = false;
public int tileSize = 32;
}
}