diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtBoxCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtBoxCollider.cs index fd7b7c3..f8e5101 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtBoxCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtBoxCollider.cs @@ -63,7 +63,7 @@ namespace DotRecast.Detour.Dynamic.Colliders public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry) { - RecastFilledVolumeRasterization.RasterizeBox( + RcFilledVolumeRasterization.RasterizeBox( hf, center, halfEdges, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtCapsuleCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtCapsuleCollider.cs index 739e7ab..7bcfaad 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtCapsuleCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtCapsuleCollider.cs @@ -39,8 +39,7 @@ namespace DotRecast.Detour.Dynamic.Colliders public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry) { - RecastFilledVolumeRasterization.RasterizeCapsule(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), - telemetry); + RcFilledVolumeRasterization.RasterizeCapsule(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } private static float[] Bounds(RcVec3f start, RcVec3f end, float radius) diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtConvexTrimeshCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtConvexTrimeshCollider.cs index 44f8645..82bd9e5 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtConvexTrimeshCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtConvexTrimeshCollider.cs @@ -44,7 +44,7 @@ namespace DotRecast.Detour.Dynamic.Colliders public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry) { - RecastFilledVolumeRasterization.RasterizeConvex(hf, vertices, triangles, area, + RcFilledVolumeRasterization.RasterizeConvex(hf, vertices, triangles, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } } diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtCylinderCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtCylinderCollider.cs index 9cdbaf1..c477631 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtCylinderCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtCylinderCollider.cs @@ -39,7 +39,7 @@ namespace DotRecast.Detour.Dynamic.Colliders public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry) { - RecastFilledVolumeRasterization.RasterizeCylinder(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), + RcFilledVolumeRasterization.RasterizeCylinder(hf, start, end, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtSphereCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtSphereCollider.cs index 17ff831..2b7130c 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtSphereCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtSphereCollider.cs @@ -37,7 +37,7 @@ namespace DotRecast.Detour.Dynamic.Colliders public override void Rasterize(RcHeightfield hf, RcTelemetry telemetry) { - RecastFilledVolumeRasterization.RasterizeSphere(hf, center, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), + RcFilledVolumeRasterization.RasterizeSphere(hf, center, radius, area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } diff --git a/src/DotRecast.Detour.Dynamic/Colliders/DtTrimeshCollider.cs b/src/DotRecast.Detour.Dynamic/Colliders/DtTrimeshCollider.cs index ea07032..5e557c0 100644 --- a/src/DotRecast.Detour.Dynamic/Colliders/DtTrimeshCollider.cs +++ b/src/DotRecast.Detour.Dynamic/Colliders/DtTrimeshCollider.cs @@ -62,7 +62,7 @@ namespace DotRecast.Detour.Dynamic.Colliders { for (int i = 0; i < triangles.Length; i += 3) { - RecastRasterization.RasterizeTriangle(hf, vertices, triangles[i], triangles[i + 1], triangles[i + 2], area, + RcRasterizations.RasterizeTriangle(hf, vertices, triangles[i], triangles[i + 1], triangles[i + 2], area, (int)Math.Floor(flagMergeThreshold / hf.ch), telemetry); } } diff --git a/src/DotRecast.Detour.Dynamic/DtDynamicNavMesh.cs b/src/DotRecast.Detour.Dynamic/DtDynamicNavMesh.cs index 7999b2b..7aab6b3 100644 --- a/src/DotRecast.Detour.Dynamic/DtDynamicNavMesh.cs +++ b/src/DotRecast.Detour.Dynamic/DtDynamicNavMesh.cs @@ -33,7 +33,7 @@ namespace DotRecast.Detour.Dynamic { public const int MAX_VERTS_PER_POLY = 6; public readonly DtDynamicNavMeshConfig config; - private readonly RecastBuilder builder; + private readonly RcBuilder builder; private readonly Dictionary _tiles = new Dictionary(); private readonly RcTelemetry telemetry; private readonly DtNavMeshParams navMeshParams; @@ -57,7 +57,7 @@ namespace DotRecast.Detour.Dynamic config.buildDetailMesh = voxelFile.buildMeshDetail; config.detailSampleDistance = voxelFile.detailSampleDistance; config.detailSampleMaxError = voxelFile.detailSampleMaxError; - builder = new RecastBuilder(); + builder = new RcBuilder(); navMeshParams = new DtNavMeshParams(); navMeshParams.orig.x = voxelFile.bounds[0]; navMeshParams.orig.y = voxelFile.bounds[1]; @@ -254,7 +254,7 @@ namespace DotRecast.Detour.Dynamic return _tiles.Values.Select(t => t.voxelTile).ToList(); } - public List RecastResults() + public List RecastResults() { return _tiles.Values.Select(t => t.recastResult).ToList(); } diff --git a/src/DotRecast.Detour.Dynamic/DtDynamicTile.cs b/src/DotRecast.Detour.Dynamic/DtDynamicTile.cs index b911bca..e2448bc 100644 --- a/src/DotRecast.Detour.Dynamic/DtDynamicTile.cs +++ b/src/DotRecast.Detour.Dynamic/DtDynamicTile.cs @@ -33,7 +33,7 @@ namespace DotRecast.Detour.Dynamic { public readonly DtVoxelTile voxelTile; public DtDynamicTileCheckpoint checkpoint; - public RecastBuilderResult recastResult; + public RcBuilderResult recastResult; private DtMeshData meshData; private readonly ConcurrentDictionary colliders = new ConcurrentDictionary(); private bool dirty = true; @@ -44,12 +44,12 @@ namespace DotRecast.Detour.Dynamic this.voxelTile = voxelTile; } - public bool Build(RecastBuilder builder, DtDynamicNavMeshConfig config, RcTelemetry telemetry) + public bool Build(RcBuilder builder, DtDynamicNavMeshConfig config, RcTelemetry telemetry) { if (dirty) { RcHeightfield heightfield = BuildHeightfield(config, telemetry); - RecastBuilderResult r = BuildRecast(builder, config, voxelTile, heightfield, telemetry); + RcBuilderResult r = BuildRecast(builder, config, voxelTile, heightfield, telemetry); DtNavMeshCreateParams option = NavMeshCreateParams(voxelTile.tileX, voxelTile.tileZ, voxelTile.cellSize, voxelTile.cellHeight, config, r); meshData = DtNavMeshBuilder.CreateNavMeshData(option); @@ -86,7 +86,7 @@ namespace DotRecast.Detour.Dynamic return heightfield; } - private RecastBuilderResult BuildRecast(RecastBuilder builder, DtDynamicNavMeshConfig config, DtVoxelTile vt, + private RcBuilderResult BuildRecast(RcBuilder builder, DtDynamicNavMeshConfig config, DtVoxelTile vt, RcHeightfield heightfield, RcTelemetry telemetry) { RcConfig rcConfig = new RcConfig( @@ -100,7 +100,7 @@ namespace DotRecast.Detour.Dynamic Math.Min(DtDynamicNavMesh.MAX_VERTS_PER_POLY, config.vertsPerPoly), config.detailSampleDistance, config.detailSampleMaxError, true, true, true, null, true); - RecastBuilderResult r = builder.Build(vt.tileX, vt.tileZ, null, rcConfig, heightfield, telemetry); + RcBuilderResult r = builder.Build(vt.tileX, vt.tileZ, null, rcConfig, heightfield, telemetry); if (config.keepIntermediateResults) { recastResult = r; @@ -130,7 +130,7 @@ namespace DotRecast.Detour.Dynamic } private DtNavMeshCreateParams NavMeshCreateParams(int tilex, int tileZ, float cellSize, float cellHeight, - DtDynamicNavMeshConfig config, RecastBuilderResult rcResult) + DtDynamicNavMeshConfig config, RcBuilderResult rcResult) { RcPolyMesh m_pmesh = rcResult.GetMesh(); RcPolyMeshDetail m_dmesh = rcResult.GetMeshDetail(); diff --git a/src/DotRecast.Detour.Dynamic/Io/DtVoxelFile.cs b/src/DotRecast.Detour.Dynamic/Io/DtVoxelFile.cs index 505dc41..d2d9c81 100644 --- a/src/DotRecast.Detour.Dynamic/Io/DtVoxelFile.cs +++ b/src/DotRecast.Detour.Dynamic/Io/DtVoxelFile.cs @@ -77,7 +77,7 @@ namespace DotRecast.Detour.Dynamic.Io walkbableAreaMod, buildMeshDetail); } - public static DtVoxelFile From(RcConfig config, List results) + public static DtVoxelFile From(RcConfig config, List results) { DtVoxelFile f = new DtVoxelFile(); f.version = 1; @@ -106,7 +106,7 @@ namespace DotRecast.Detour.Dynamic.Io float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity }; - foreach (RecastBuilderResult r in results) + foreach (RcBuilderResult r in results) { f.tiles.Add(new DtVoxelTile(r.tileX, r.tileZ, r.GetSolidHeightfield())); f.bounds[0] = Math.Min(f.bounds[0], r.GetSolidHeightfield().bmin.x); diff --git a/src/DotRecast.Detour.Extras/Jumplink/AbstractGroundSampler.cs b/src/DotRecast.Detour.Extras/Jumplink/AbstractGroundSampler.cs index bc1d249..965fd97 100644 --- a/src/DotRecast.Detour.Extras/Jumplink/AbstractGroundSampler.cs +++ b/src/DotRecast.Detour.Extras/Jumplink/AbstractGroundSampler.cs @@ -1,7 +1,6 @@ using System; using DotRecast.Core; using DotRecast.Recast; -using static DotRecast.Core.RcMath; namespace DotRecast.Detour.Extras.Jumplink { @@ -22,7 +21,7 @@ namespace DotRecast.Detour.Extras.Jumplink } } - public abstract void Sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es); + public abstract void Sample(JumpLinkBuilderConfig acfg, RcBuilderResult result, EdgeSampler es); protected void SampleGroundSegment(ComputeNavMeshHeight heightFunc, GroundSegment seg, int nsamples) { diff --git a/src/DotRecast.Detour.Extras/Jumplink/IGroundSampler.cs b/src/DotRecast.Detour.Extras/Jumplink/IGroundSampler.cs index d82c206..3c69804 100644 --- a/src/DotRecast.Detour.Extras/Jumplink/IGroundSampler.cs +++ b/src/DotRecast.Detour.Extras/Jumplink/IGroundSampler.cs @@ -4,6 +4,6 @@ namespace DotRecast.Detour.Extras.Jumplink { public interface IGroundSampler { - void Sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es); + void Sample(JumpLinkBuilderConfig acfg, RcBuilderResult result, EdgeSampler es); } } \ No newline at end of file diff --git a/src/DotRecast.Detour.Extras/Jumplink/JumpLinkBuilder.cs b/src/DotRecast.Detour.Extras/Jumplink/JumpLinkBuilder.cs index f5ca751..fbe773e 100644 --- a/src/DotRecast.Detour.Extras/Jumplink/JumpLinkBuilder.cs +++ b/src/DotRecast.Detour.Extras/Jumplink/JumpLinkBuilder.cs @@ -15,9 +15,9 @@ namespace DotRecast.Detour.Extras.Jumplink private readonly JumpSegmentBuilder jumpSegmentBuilder = new JumpSegmentBuilder(); private readonly List edges; - private readonly IList results; + private readonly IList results; - public JumpLinkBuilder(IList results) + public JumpLinkBuilder(IList results) { this.results = results; edges = results.Select(r => edgeExtractor.ExtractEdges(r.GetMesh())).ToList(); @@ -38,7 +38,7 @@ namespace DotRecast.Detour.Extras.Jumplink return links; } - private List ProcessEdge(JumpLinkBuilderConfig acfg, RecastBuilderResult result, JumpLinkType type, JumpEdge edge) + private List ProcessEdge(JumpLinkBuilderConfig acfg, RcBuilderResult result, JumpLinkType type, JumpEdge edge) { EdgeSampler es = edgeSamplerFactory.Get(acfg, type, edge); groundSampler.Sample(acfg, result, es); diff --git a/src/DotRecast.Detour.Extras/Jumplink/NavMeshGroundSampler.cs b/src/DotRecast.Detour.Extras/Jumplink/NavMeshGroundSampler.cs index 18a8d7e..7f868bd 100644 --- a/src/DotRecast.Detour.Extras/Jumplink/NavMeshGroundSampler.cs +++ b/src/DotRecast.Detour.Extras/Jumplink/NavMeshGroundSampler.cs @@ -7,13 +7,13 @@ namespace DotRecast.Detour.Extras.Jumplink { class NavMeshGroundSampler : AbstractGroundSampler { - public override void Sample(JumpLinkBuilderConfig acfg, RecastBuilderResult result, EdgeSampler es) + public override void Sample(JumpLinkBuilderConfig acfg, RcBuilderResult result, EdgeSampler es) { DtNavMeshQuery navMeshQuery = CreateNavMesh(result, acfg.agentRadius, acfg.agentHeight, acfg.agentClimb); SampleGround(acfg, es, (RcVec3f pt, float heightRange, out float height) => GetNavMeshHeight(navMeshQuery, pt, acfg.cellSize, heightRange, out height)); } - private DtNavMeshQuery CreateNavMesh(RecastBuilderResult r, float agentRadius, float agentHeight, float agentClimb) + private DtNavMeshQuery CreateNavMesh(RcBuilderResult r, float agentRadius, float agentHeight, float agentClimb) { DtNavMeshCreateParams option = new DtNavMeshCreateParams(); option.verts = r.GetMesh().verts; diff --git a/src/DotRecast.Detour.TileCache/DtTileCacheLayerBuilder.cs b/src/DotRecast.Detour.TileCache/DtTileCacheLayerBuilder.cs index c5c5e2f..88686a0 100644 --- a/src/DotRecast.Detour.TileCache/DtTileCacheLayerBuilder.cs +++ b/src/DotRecast.Detour.TileCache/DtTileCacheLayerBuilder.cs @@ -86,10 +86,10 @@ namespace DotRecast.Detour.TileCache protected virtual RcHeightfieldLayerSet BuildHeightfieldLayerSet(IInputGeomProvider geom, RcConfig cfg, int tx, int ty) { - RecastBuilder rcBuilder = new RecastBuilder(); + RcBuilder rcBuilder = new RcBuilder(); RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RecastBuilderConfig builderCfg = new RecastBuilderConfig(cfg, bmin, bmax, tx, ty); + RcBuilderConfig builderCfg = new RcBuilderConfig(cfg, bmin, bmax, tx, ty); RcHeightfieldLayerSet lset = rcBuilder.BuildLayers(geom, builderCfg); return lset; } diff --git a/src/DotRecast.Recast.Demo/DemoSample.cs b/src/DotRecast.Recast.Demo/DemoSample.cs index dfcf183..ee62edf 100644 --- a/src/DotRecast.Recast.Demo/DemoSample.cs +++ b/src/DotRecast.Recast.Demo/DemoSample.cs @@ -32,10 +32,10 @@ namespace DotRecast.Recast.Demo private DtNavMesh _navMesh; private DtNavMeshQuery _navMeshQuery; private readonly RcNavMeshBuildSettings _settings; - private IList _recastResults; + private IList _recastResults; private bool _changed; - public DemoSample(DemoInputGeomProvider geom, IList recastResults, DtNavMesh navMesh) + public DemoSample(DemoInputGeomProvider geom, IList recastResults, DtNavMesh navMesh) { _geom = geom; _recastResults = recastResults; @@ -56,7 +56,7 @@ namespace DotRecast.Recast.Demo return _geom; } - public IList GetRecastResults() + public IList GetRecastResults() { return _recastResults; } @@ -86,7 +86,7 @@ namespace DotRecast.Recast.Demo _changed = changed; } - public void Update(DemoInputGeomProvider geom, IList recastResults, DtNavMesh navMesh) + public void Update(DemoInputGeomProvider geom, IList recastResults, DtNavMesh navMesh) { _geom = geom; _recastResults = recastResults; diff --git a/src/DotRecast.Recast.Demo/Draw/NavMeshRenderer.cs b/src/DotRecast.Recast.Demo/Draw/NavMeshRenderer.cs index f5522ec..8112cf8 100644 --- a/src/DotRecast.Recast.Demo/Draw/NavMeshRenderer.cs +++ b/src/DotRecast.Recast.Demo/Draw/NavMeshRenderer.cs @@ -23,6 +23,7 @@ using DotRecast.Core; using DotRecast.Detour; using DotRecast.Recast.Toolset.Builder; using DotRecast.Recast.Toolset.Geom; +using static DotRecast.Recast.RcCommons; namespace DotRecast.Recast.Demo.Draw; @@ -50,7 +51,7 @@ public class NavMeshRenderer DtNavMeshQuery navQuery = sample.GetNavMeshQuery(); DemoInputGeomProvider geom = sample.GetInputGeom(); - IList rcBuilderResults = sample.GetRecastResults(); + IList rcBuilderResults = sample.GetRecastResults(); DtNavMesh navMesh = sample.GetNavMesh(); var settings = sample.GetSettings(); _debugDraw.Fog(true); @@ -81,7 +82,7 @@ public class NavMeshRenderer int gw = 0, gh = 0; RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); + CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); int tw = (gw + settings.tileSize - 1) / settings.tileSize; int th = (gh + settings.tileSize - 1) / settings.tileSize; float s = settings.tileSize * settings.cellSize; @@ -120,7 +121,7 @@ public class NavMeshRenderer _debugDraw.DepthMask(true); - foreach (RecastBuilderResult rcBuilderResult in rcBuilderResults) + foreach (RcBuilderResult rcBuilderResult in rcBuilderResults) { if (rcBuilderResult.GetCompactHeightfield() != null && drawMode == DrawMode.DRAWMODE_COMPACT) { diff --git a/src/DotRecast.Recast.Demo/RecastDemo.cs b/src/DotRecast.Recast.Demo/RecastDemo.cs index 6de4e2d..8521ee9 100644 --- a/src/DotRecast.Recast.Demo/RecastDemo.cs +++ b/src/DotRecast.Recast.Demo/RecastDemo.cs @@ -324,7 +324,7 @@ public class RecastDemo : IRecastDemoChannel if (null != mesh) { - _sample.Update(_sample.GetInputGeom(), ImmutableArray.Empty, mesh); + _sample.Update(_sample.GetInputGeom(), ImmutableArray.Empty, mesh); toolset.SetEnabled(true); } } @@ -375,7 +375,7 @@ public class RecastDemo : IRecastDemoChannel _imgui = new ImGuiController(_gl, window, _input, imGuiFontConfig); DemoInputGeomProvider geom = LoadInputMesh("nav_test.obj"); - _sample = new DemoSample(geom, ImmutableArray.Empty, null); + _sample = new DemoSample(geom, ImmutableArray.Empty, null); settingsView = new RcSettingsView(this); settingsView.SetSample(_sample); @@ -454,7 +454,7 @@ public class RecastDemo : IRecastDemoChannel var settings = _sample.GetSettings(); RcVec3f bmin = _sample.GetInputGeom().GetMeshBoundsMin(); RcVec3f bmax = _sample.GetInputGeom().GetMeshBoundsMax(); - RcUtils.CalcGridSize(bmin, bmax, settings.cellSize, out var gw, out var gh); + RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out var gw, out var gh); settingsView.SetVoxels(gw, gh); settingsView.SetTiles(tileNavMeshBuilder.GetTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize)); settingsView.SetMaxTiles(tileNavMeshBuilder.GetMaxTiles(_sample.GetInputGeom(), settings.cellSize, settings.tileSize)); @@ -542,7 +542,7 @@ public class RecastDemo : IRecastDemoChannel } else if (0 < _sample.GetRecastResults().Count) { - foreach (RecastBuilderResult result in _sample.GetRecastResults()) + foreach (RcBuilderResult result in _sample.GetRecastResults()) { if (result.GetSolidHeightfield() != null) { @@ -662,7 +662,7 @@ public class RecastDemo : IRecastDemoChannel { var geom = LoadInputMesh(args.FilePath); - _sample.Update(geom, ImmutableArray.Empty, null); + _sample.Update(geom, ImmutableArray.Empty, null); } private void OnNavMeshBuildBegan(NavMeshBuildBeganEvent args) diff --git a/src/DotRecast.Recast.Toolset/Builder/DemoNavMeshBuilder.cs b/src/DotRecast.Recast.Toolset/Builder/DemoNavMeshBuilder.cs index 1b78aac..7cb6fe8 100644 --- a/src/DotRecast.Recast.Toolset/Builder/DemoNavMeshBuilder.cs +++ b/src/DotRecast.Recast.Toolset/Builder/DemoNavMeshBuilder.cs @@ -8,7 +8,7 @@ namespace DotRecast.Recast.Toolset.Builder { public static DtNavMeshCreateParams GetNavMeshCreateParams(IInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb, - RecastBuilderResult rcResult) + RcBuilderResult rcResult) { RcPolyMesh pmesh = rcResult.GetMesh(); RcPolyMeshDetail dmesh = rcResult.GetMeshDetail(); diff --git a/src/DotRecast.Recast.Toolset/Builder/NavMeshBuildResult.cs b/src/DotRecast.Recast.Toolset/Builder/NavMeshBuildResult.cs index 29acdee..6c93ad0 100644 --- a/src/DotRecast.Recast.Toolset/Builder/NavMeshBuildResult.cs +++ b/src/DotRecast.Recast.Toolset/Builder/NavMeshBuildResult.cs @@ -7,17 +7,17 @@ namespace DotRecast.Recast.Toolset.Builder public class NavMeshBuildResult { public readonly bool Success; - public readonly IList RecastBuilderResults; + public readonly IList RecastBuilderResults; public readonly DtNavMesh NavMesh; public NavMeshBuildResult() { Success = false; - RecastBuilderResults = Array.Empty(); + RecastBuilderResults = Array.Empty(); NavMesh = null; } - public NavMeshBuildResult(IList recastBuilderResults, DtNavMesh navMesh) + public NavMeshBuildResult(IList recastBuilderResults, DtNavMesh navMesh) { Success = true; RecastBuilderResults = recastBuilderResults; diff --git a/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs b/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs index 6ac153c..82b17b5 100644 --- a/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs +++ b/src/DotRecast.Recast.Toolset/Builder/SoloNavMeshBuilder.cs @@ -60,7 +60,7 @@ namespace DotRecast.Recast.Toolset.Builder filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans, SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true); - RecastBuilderResult rcResult = BuildRecastResult(geom, cfg); + RcBuilderResult rcResult = BuildRecastResult(geom, cfg); var meshData = BuildMeshData(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, rcResult); if (null == meshData) { @@ -76,17 +76,17 @@ namespace DotRecast.Recast.Toolset.Builder return new DtNavMesh(meshData, vertsPerPoly, 0); } - private RecastBuilderResult BuildRecastResult(DemoInputGeomProvider geom, RcConfig cfg) + private RcBuilderResult BuildRecastResult(DemoInputGeomProvider geom, RcConfig cfg) { - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); - RecastBuilder rcBuilder = new RecastBuilder(); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); + RcBuilder rcBuilder = new RcBuilder(); return rcBuilder.Build(geom, bcfg); } public DtMeshData BuildMeshData(DemoInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight, float agentRadius, float agentMaxClimb, - RecastBuilderResult result) + RcBuilderResult result) { DtNavMeshCreateParams option = DemoNavMeshBuilder .GetNavMeshCreateParams(geom, cellSize, cellHeight, agentHeight, agentRadius, agentMaxClimb, result); diff --git a/src/DotRecast.Recast.Toolset/Builder/TileNavMeshBuilder.cs b/src/DotRecast.Recast.Toolset/Builder/TileNavMeshBuilder.cs index 6445a61..f73fbc9 100644 --- a/src/DotRecast.Recast.Toolset/Builder/TileNavMeshBuilder.cs +++ b/src/DotRecast.Recast.Toolset/Builder/TileNavMeshBuilder.cs @@ -55,7 +55,7 @@ namespace DotRecast.Recast.Toolset.Builder float detailSampleDist, float detailSampleMaxError, bool filterLowHangingObstacles, bool filterLedgeSpans, bool filterWalkableLowHeightSpans) { - List results = BuildRecastResult( + List results = BuildRecastResult( geom, tileSize, partitionType, @@ -73,7 +73,7 @@ namespace DotRecast.Recast.Toolset.Builder return new NavMeshBuildResult(results, tileNavMesh); } - public List BuildRecastResult(IInputGeomProvider geom, + public List BuildRecastResult(IInputGeomProvider geom, int tileSize, RcPartition partitionType, float cellSize, float cellHeight, @@ -96,7 +96,7 @@ namespace DotRecast.Recast.Toolset.Builder detailSampleDist, detailSampleMaxError, filterLowHangingObstacles, filterLedgeSpans, filterWalkableLowHeightSpans, SampleAreaModifications.SAMPLE_AREAMOD_WALKABLE, true); - RecastBuilder rcBuilder = new RecastBuilder(); + RcBuilder rcBuilder = new RcBuilder(); return rcBuilder.BuildTiles(geom, cfg, Task.Factory); } @@ -117,11 +117,11 @@ namespace DotRecast.Recast.Toolset.Builder } public List BuildMeshData(IInputGeomProvider geom, float cellSize, float cellHeight, float agentHeight, - float agentRadius, float agentMaxClimb, IList results) + float agentRadius, float agentMaxClimb, IList results) { // Add tiles to nav mesh List meshData = new List(); - foreach (RecastBuilderResult result in results) + foreach (RcBuilderResult result in results) { int x = result.tileX; int z = result.tileZ; @@ -155,7 +155,7 @@ namespace DotRecast.Recast.Toolset.Builder private int GetTileBits(IInputGeomProvider geom, float cellSize, int tileSize) { - RcUtils.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh); + RcCommons.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh); int tw = (gw + tileSize - 1) / tileSize; int th = (gh + tileSize - 1) / tileSize; int tileBits = Math.Min(DtUtils.Ilog2(DtUtils.NextPow2(tw * th)), 14); @@ -164,7 +164,7 @@ namespace DotRecast.Recast.Toolset.Builder public int[] GetTiles(DemoInputGeomProvider geom, float cellSize, int tileSize) { - RcUtils.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh); + RcCommons.CalcGridSize(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), cellSize, out var gw, out var gh); int tw = (gw + tileSize - 1) / tileSize; int th = (gh + tileSize - 1) / tileSize; return new int[] { tw, th }; diff --git a/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs index 74c9987..e6f385a 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcConvexVolumeTool.cs @@ -80,7 +80,7 @@ namespace DotRecast.Recast.Toolset.Tools IList vols = geom.ConvexVolumes(); for (int i = 0; i < vols.Count; ++i) { - if (PolyUtils.PointInPoly(vols[i].verts, pos) && pos.y >= vols[i].hmin + if (RcAreas.PointInPoly(vols[i].verts, pos) && pos.y >= vols[i].hmin && pos.y <= vols[i].hmax) { nearestIndex = i; @@ -130,7 +130,7 @@ namespace DotRecast.Recast.Toolset.Tools if (polyOffset > 0.01f) { float[] offset = new float[verts.Length * 2]; - int noffset = PolyUtils.OffsetPoly(verts, hull.Count, polyOffset, offset, offset.Length); + int noffset = RcAreas.OffsetPoly(verts, hull.Count, polyOffset, offset, offset.Length); if (noffset > 0) { verts = RcArrayUtils.CopyOf(offset, 0, noffset * 3); diff --git a/src/DotRecast.Recast.Toolset/Tools/RcJumpLinkBuilderTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcJumpLinkBuilderTool.cs index 70fa86e..cbe1bf7 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcJumpLinkBuilderTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcJumpLinkBuilderTool.cs @@ -44,7 +44,7 @@ namespace DotRecast.Recast.Toolset.Tools return _links; } - public void Build(IInputGeomProvider geom, RcNavMeshBuildSettings settings, IList results, RcJumpLinkBuilderToolConfig cfg) + public void Build(IInputGeomProvider geom, RcNavMeshBuildSettings settings, IList results, RcJumpLinkBuilderToolConfig cfg) { if (_annotationBuilder == null) { diff --git a/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs index ec0e06d..592db77 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcObstacleTool.cs @@ -41,7 +41,7 @@ namespace DotRecast.Recast.Toolset.Tools // Init cache var bmin = geom.GetMeshBoundsMin(); var bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcGridSize(bmin, bmax, setting.cellSize, out var gw, out var gh); + RcCommons.CalcGridSize(bmin, bmax, setting.cellSize, out var gw, out var gh); int ts = setting.tileSize; int tw = (gw + ts - 1) / ts; int th = (gh + ts - 1) / ts; @@ -77,7 +77,7 @@ namespace DotRecast.Recast.Toolset.Tools _tc.BuildNavMeshTile(refs); } - return new NavMeshBuildResult(RcImmutableArray.Empty, _tc.GetNavMesh()); + return new NavMeshBuildResult(RcImmutableArray.Empty, _tc.GetNavMesh()); } public void ClearAllTempObstacles() diff --git a/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs b/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs index d6586f6..e811908 100644 --- a/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs +++ b/src/DotRecast.Recast.Toolset/Tools/RcTileTool.cs @@ -21,7 +21,7 @@ namespace DotRecast.Recast.Toolset.Tools var bmin = geom.GetMeshBoundsMin(); var bmax = geom.GetMeshBoundsMax(); int gw = 0, gh = 0; - RcUtils.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); + RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); int ts = settings.tileSize; int tw = (gw + ts - 1) / ts; @@ -45,7 +45,7 @@ namespace DotRecast.Recast.Toolset.Tools var bmin = geom.GetMeshBoundsMin(); var bmax = geom.GetMeshBoundsMax(); int gw = 0, gh = 0; - RcUtils.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); + RcCommons.CalcGridSize(bmin, bmax, settings.cellSize, out gw, out gh); int ts = settings.tileSize; int tw = (gw + ts - 1) / ts; @@ -91,7 +91,7 @@ namespace DotRecast.Recast.Toolset.Tools ); var beginTick = RcFrequency.Ticks; - var rb = new RecastBuilder(); + var rb = new RcBuilder(); var result = rb.BuildTile(geom, cfg, bmin, bmax, tx, ty, new RcAtomicInteger(0), 1); var tb = new TileNavMeshBuilder(); diff --git a/src/DotRecast.Recast/PolyUtils.cs b/src/DotRecast.Recast/PolyUtils.cs deleted file mode 100644 index 791c0d0..0000000 --- a/src/DotRecast.Recast/PolyUtils.cs +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright (c) 2009-2010 Mikko Mononen memon@inside.org -recast4j copyright (c) 2021 Piotr Piastucki piotr@jtilia.org -DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com - -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. -*/ - -using System; -using DotRecast.Core; - -namespace DotRecast.Recast -{ - public static class PolyUtils - { - // public static bool PointInPoly(float[] verts, RcVec3f p) - // { - // bool c = false; - // int i, j; - // for (i = 0, j = verts.Length - 3; i < verts.Length; j = i, i += 3) - // { - // int vi = i; - // int vj = j; - // if (((verts[vi + 2] > p.z) != (verts[vj + 2] > p.z)) - // && (p.x < (verts[vj] - verts[vi]) * (p.z - verts[vi + 2]) / (verts[vj + 2] - verts[vi + 2]) - // + verts[vi])) - // c = !c; - // } - // - // return c; - // } - - // TODO (graham): This is duplicated in the ConvexVolumeTool in RecastDemo - /// Checks if a point is contained within a polygon - /// - /// @param[in] numVerts Number of vertices in the polygon - /// @param[in] verts The polygon vertices - /// @param[in] point The point to check - /// @returns true if the point lies within the polygon, false otherwise. - public static bool PointInPoly(float[] verts, RcVec3f point) - { - bool inPoly = false; - for (int i = 0, j = verts.Length / 3 - 1; i < verts.Length / 3; j = i++) - { - RcVec3f vi = RcVec3f.Of(verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]); - RcVec3f vj = RcVec3f.Of(verts[j * 3], verts[j * 3 + 1], verts[j * 3 + 2]); - if (vi.z > point.z == vj.z > point.z) - { - continue; - } - - if (point.x >= (vj.x - vi.x) * (point.z - vi.z) / (vj.z - vi.z) + vi.x) - { - continue; - } - - inPoly = !inPoly; - } - - return inPoly; - } - - /// Expands a convex polygon along its vertex normals by the given offset amount. - /// Inserts extra vertices to bevel sharp corners. - /// - /// Helper function to offset convex polygons for rcMarkConvexPolyArea. - /// - /// @ingroup recast - /// - /// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p numVerts] - /// @param[in] numVerts The number of vertices in the polygon. - /// @param[in] offset How much to offset the polygon by. [Units: wu] - /// @param[out] outVerts The offset vertices (should hold up to 2 * @p numVerts) [Form: (x, y, z) * return value] - /// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. - /// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. - public static int OffsetPoly(float[] verts, int numVerts, float offset, float[] outVerts, int maxOutVerts) - { - // Defines the limit at which a miter becomes a bevel. - // Similar in behavior to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit - const float MITER_LIMIT = 1.20f; - - int numOutVerts = 0; - - for (int vertIndex = 0; vertIndex < numVerts; vertIndex++) - { - int vertIndexA = (vertIndex + numVerts - 1) % numVerts; - int vertIndexB = vertIndex; - int vertIndexC = (vertIndex + 1) % numVerts; - - RcVec3f vertA = RcVec3f.Of(verts, vertIndexA * 3); - RcVec3f vertB = RcVec3f.Of(verts, vertIndexB * 3); - RcVec3f vertC = RcVec3f.Of(verts, vertIndexC * 3); - - // From A to B on the x/z plane - RcVec3f prevSegmentDir = vertB.Subtract(vertA); - prevSegmentDir.y = 0; // Squash onto x/z plane - prevSegmentDir.SafeNormalize(); - - // From B to C on the x/z plane - RcVec3f currSegmentDir = vertC.Subtract(vertB); - currSegmentDir.y = 0; // Squash onto x/z plane - currSegmentDir.SafeNormalize(); - - // The y component of the cross product of the two normalized segment directions. - // The X and Z components of the cross product are both zero because the two - // segment direction vectors fall within the x/z plane. - float cross = currSegmentDir.x * prevSegmentDir.z - prevSegmentDir.x * currSegmentDir.z; - - // CCW perpendicular vector to AB. The segment normal. - float prevSegmentNormX = -prevSegmentDir.z; - float prevSegmentNormZ = prevSegmentDir.x; - - // CCW perpendicular vector to BC. The segment normal. - float currSegmentNormX = -currSegmentDir.z; - float currSegmentNormZ = currSegmentDir.x; - - // Average the two segment normals to get the proportional miter offset for B. - // This isn't normalized because it's defining the distance and direction the corner will need to be - // adjusted proportionally to the edge offsets to properly miter the adjoining edges. - float cornerMiterX = (prevSegmentNormX + currSegmentNormX) * 0.5f; - float cornerMiterZ = (prevSegmentNormZ + currSegmentNormZ) * 0.5f; - float cornerMiterSqMag = RcMath.Sqr(cornerMiterX) + RcMath.Sqr(cornerMiterZ); - - // If the magnitude of the segment normal average is less than about .69444, - // the corner is an acute enough angle that the result should be beveled. - bool bevel = cornerMiterSqMag * MITER_LIMIT * MITER_LIMIT < 1.0f; - - // Scale the corner miter so it's proportional to how much the corner should be offset compared to the edges. - if (cornerMiterSqMag > RcVec3f.EPSILON) - { - float scale = 1.0f / cornerMiterSqMag; - cornerMiterX *= scale; - cornerMiterZ *= scale; - } - - if (bevel && cross < 0.0f) // If the corner is convex and an acute enough angle, generate a bevel. - { - if (numOutVerts + 2 > maxOutVerts) - { - return 0; - } - - // Generate two bevel vertices at a distances from B proportional to the angle between the two segments. - // Move each bevel vertex out proportional to the given offset. - float d = (1.0f - (prevSegmentDir.x * currSegmentDir.x + prevSegmentDir.z * currSegmentDir.z)) * 0.5f; - - outVerts[numOutVerts * 3 + 0] = vertB.x + (-prevSegmentNormX + prevSegmentDir.x * d) * offset; - outVerts[numOutVerts * 3 + 1] = vertB.y; - outVerts[numOutVerts * 3 + 2] = vertB.z + (-prevSegmentNormZ + prevSegmentDir.z * d) * offset; - numOutVerts++; - - outVerts[numOutVerts * 3 + 0] = vertB.x + (-currSegmentNormX - currSegmentDir.x * d) * offset; - outVerts[numOutVerts * 3 + 1] = vertB.y; - outVerts[numOutVerts * 3 + 2] = vertB.z + (-currSegmentNormZ - currSegmentDir.z * d) * offset; - numOutVerts++; - } - else - { - if (numOutVerts + 1 > maxOutVerts) - { - return 0; - } - - // Move B along the miter direction by the specified offset. - outVerts[numOutVerts * 3 + 0] = vertB.x - cornerMiterX * offset; - outVerts[numOutVerts * 3 + 1] = vertB.y; - outVerts[numOutVerts * 3 + 2] = vertB.z - cornerMiterZ * offset; - numOutVerts++; - } - } - - return numOutVerts; - } - } -} \ No newline at end of file diff --git a/src/DotRecast.Recast/RecastArea.cs b/src/DotRecast.Recast/RcAreas.cs similarity index 71% rename from src/DotRecast.Recast/RecastArea.cs rename to src/DotRecast.Recast/RcAreas.cs index 4751bee..134297f 100644 --- a/src/DotRecast.Recast/RecastArea.cs +++ b/src/DotRecast.Recast/RcAreas.cs @@ -24,8 +24,9 @@ using DotRecast.Core; namespace DotRecast.Recast { using static RcConstants; + using static RcCommons; - public static class RecastArea + public static class RcAreas { /// Erodes the walkable area within the heightfield by the specified radius. /// @@ -72,15 +73,15 @@ namespace DotRecast.Recast int neighborCount = 0; for (int direction = 0; direction < 4; ++direction) { - int neighborConnection = RecastCommon.GetCon(span, direction); + int neighborConnection = GetCon(span, direction); if (neighborConnection == RC_NOT_CONNECTED) { break; } - int neighborX = x + RecastCommon.GetDirOffsetX(direction); - int neighborZ = z + RecastCommon.GetDirOffsetY(direction); - int neighborSpanIndex = compactHeightfield.cells[neighborX + neighborZ * zStride].index + RecastCommon.GetCon(span, direction); + int neighborX = x + GetDirOffsetX(direction); + int neighborZ = z + GetDirOffsetY(direction); + int neighborSpanIndex = compactHeightfield.cells[neighborX + neighborZ * zStride].index + GetCon(span, direction); if (compactHeightfield.areas[neighborSpanIndex] == RC_NULL_AREA) { break; @@ -112,12 +113,12 @@ namespace DotRecast.Recast { RcCompactSpan span = compactHeightfield.spans[spanIndex]; - if (RecastCommon.GetCon(span, 0) != RC_NOT_CONNECTED) + if (GetCon(span, 0) != RC_NOT_CONNECTED) { // (-1,0) - int aX = x + RecastCommon.GetDirOffsetX(0); - int aY = z + RecastCommon.GetDirOffsetY(0); - int aIndex = compactHeightfield.cells[aX + aY * xSize].index + RecastCommon.GetCon(span, 0); + int aX = x + GetDirOffsetX(0); + int aY = z + GetDirOffsetY(0); + int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 0); RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); if (newDistance < distanceToBoundary[spanIndex]) @@ -126,11 +127,11 @@ namespace DotRecast.Recast } // (-1,-1) - if (RecastCommon.GetCon(aSpan, 3) != RC_NOT_CONNECTED) + if (GetCon(aSpan, 3) != RC_NOT_CONNECTED) { - int bX = aX + RecastCommon.GetDirOffsetX(3); - int bY = aY + RecastCommon.GetDirOffsetY(3); - int bIndex = compactHeightfield.cells[bX + bY * xSize].index + RecastCommon.GetCon(aSpan, 3); + int bX = aX + GetDirOffsetX(3); + int bY = aY + GetDirOffsetY(3); + int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 3); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); if (newDistance < distanceToBoundary[spanIndex]) { @@ -139,12 +140,12 @@ namespace DotRecast.Recast } } - if (RecastCommon.GetCon(span, 3) != RC_NOT_CONNECTED) + if (GetCon(span, 3) != RC_NOT_CONNECTED) { // (0,-1) - int aX = x + RecastCommon.GetDirOffsetX(3); - int aY = z + RecastCommon.GetDirOffsetY(3); - int aIndex = compactHeightfield.cells[aX + aY * xSize].index + RecastCommon.GetCon(span, 3); + int aX = x + GetDirOffsetX(3); + int aY = z + GetDirOffsetY(3); + int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 3); RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); if (newDistance < distanceToBoundary[spanIndex]) @@ -153,11 +154,11 @@ namespace DotRecast.Recast } // (1,-1) - if (RecastCommon.GetCon(aSpan, 2) != RC_NOT_CONNECTED) + if (GetCon(aSpan, 2) != RC_NOT_CONNECTED) { - int bX = aX + RecastCommon.GetDirOffsetX(2); - int bY = aY + RecastCommon.GetDirOffsetY(2); - int bIndex = compactHeightfield.cells[bX + bY * xSize].index + RecastCommon.GetCon(aSpan, 2); + int bX = aX + GetDirOffsetX(2); + int bY = aY + GetDirOffsetY(2); + int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 2); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); if (newDistance < distanceToBoundary[spanIndex]) { @@ -180,12 +181,12 @@ namespace DotRecast.Recast { RcCompactSpan span = compactHeightfield.spans[i]; - if (RecastCommon.GetCon(span, 2) != RC_NOT_CONNECTED) + if (GetCon(span, 2) != RC_NOT_CONNECTED) { // (1,0) - int aX = x + RecastCommon.GetDirOffsetX(2); - int aY = z + RecastCommon.GetDirOffsetY(2); - int aIndex = compactHeightfield.cells[aX + aY * xSize].index + RecastCommon.GetCon(span, 2); + int aX = x + GetDirOffsetX(2); + int aY = z + GetDirOffsetY(2); + int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 2); RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); if (newDistance < distanceToBoundary[i]) @@ -194,11 +195,11 @@ namespace DotRecast.Recast } // (1,1) - if (RecastCommon.GetCon(aSpan, 1) != RC_NOT_CONNECTED) + if (GetCon(aSpan, 1) != RC_NOT_CONNECTED) { - int bX = aX + RecastCommon.GetDirOffsetX(1); - int bY = aY + RecastCommon.GetDirOffsetY(1); - int bIndex = compactHeightfield.cells[bX + bY * xSize].index + RecastCommon.GetCon(aSpan, 1); + int bX = aX + GetDirOffsetX(1); + int bY = aY + GetDirOffsetY(1); + int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 1); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); if (newDistance < distanceToBoundary[i]) { @@ -207,12 +208,12 @@ namespace DotRecast.Recast } } - if (RecastCommon.GetCon(span, 1) != RC_NOT_CONNECTED) + if (GetCon(span, 1) != RC_NOT_CONNECTED) { // (0,1) - int aX = x + RecastCommon.GetDirOffsetX(1); - int aY = z + RecastCommon.GetDirOffsetY(1); - int aIndex = compactHeightfield.cells[aX + aY * xSize].index + RecastCommon.GetCon(span, 1); + int aX = x + GetDirOffsetX(1); + int aY = z + GetDirOffsetY(1); + int aIndex = compactHeightfield.cells[aX + aY * xSize].index + GetCon(span, 1); RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; newDistance = Math.Min(distanceToBoundary[aIndex] + 2, 255); if (newDistance < distanceToBoundary[i]) @@ -221,11 +222,11 @@ namespace DotRecast.Recast } // (-1,1) - if (RecastCommon.GetCon(aSpan, 0) != RC_NOT_CONNECTED) + if (GetCon(aSpan, 0) != RC_NOT_CONNECTED) { - int bX = aX + RecastCommon.GetDirOffsetX(0); - int bY = aY + RecastCommon.GetDirOffsetY(0); - int bIndex = compactHeightfield.cells[bX + bY * xSize].index + RecastCommon.GetCon(aSpan, 0); + int bX = aX + GetDirOffsetX(0); + int bY = aY + GetDirOffsetY(0); + int bIndex = compactHeightfield.cells[bX + bY * xSize].index + GetCon(aSpan, 0); newDistance = Math.Min(distanceToBoundary[bIndex] + 3, 255); if (newDistance < distanceToBoundary[i]) { @@ -291,14 +292,14 @@ namespace DotRecast.Recast for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(span, dir) == RC_NOT_CONNECTED) + if (GetCon(span, dir) == RC_NOT_CONNECTED) { continue; } - int aX = x + RecastCommon.GetDirOffsetX(dir); - int aZ = z + RecastCommon.GetDirOffsetY(dir); - int aIndex = compactHeightfield.cells[aX + aZ * zStride].index + RecastCommon.GetCon(span, dir); + int aX = x + GetDirOffsetX(dir); + int aZ = z + GetDirOffsetY(dir); + int aIndex = compactHeightfield.cells[aX + aZ * zStride].index + GetCon(span, dir); if (compactHeightfield.areas[aIndex] != RC_NULL_AREA) { neighborAreas[dir * 2 + 0] = compactHeightfield.areas[aIndex]; @@ -306,12 +307,12 @@ namespace DotRecast.Recast RcCompactSpan aSpan = compactHeightfield.spans[aIndex]; int dir2 = (dir + 1) & 0x3; - int neighborConnection2 = RecastCommon.GetCon(aSpan, dir2); + int neighborConnection2 = GetCon(aSpan, dir2); if (neighborConnection2 != RC_NOT_CONNECTED) { - int bX = aX + RecastCommon.GetDirOffsetX(dir2); - int bZ = aZ + RecastCommon.GetDirOffsetY(dir2); - int bIndex = compactHeightfield.cells[bX + bZ * zStride].index + RecastCommon.GetCon(aSpan, dir2); + int bX = aX + GetDirOffsetX(dir2); + int bZ = aZ + GetDirOffsetY(dir2); + int bIndex = compactHeightfield.cells[bX + bZ * zStride].index + GetCon(aSpan, dir2); if (compactHeightfield.areas[bIndex] != RC_NULL_AREA) { neighborAreas[dir * 2 + 1] = compactHeightfield.areas[bIndex]; @@ -544,7 +545,7 @@ namespace DotRecast.Recast compactHeightfield.bmin.z + (z + 0.5f) * compactHeightfield.cs ); - if (PolyUtils.PointInPoly(verts, point)) + if (PointInPoly(verts, point)) { compactHeightfield.areas[spanIndex] = areaId.Apply(compactHeightfield.areas[spanIndex]); } @@ -677,5 +678,164 @@ namespace DotRecast.Recast } } } + + // public static bool PointInPoly(float[] verts, RcVec3f p) + // { + // bool c = false; + // int i, j; + // for (i = 0, j = verts.Length - 3; i < verts.Length; j = i, i += 3) + // { + // int vi = i; + // int vj = j; + // if (((verts[vi + 2] > p.z) != (verts[vj + 2] > p.z)) + // && (p.x < (verts[vj] - verts[vi]) * (p.z - verts[vi + 2]) / (verts[vj + 2] - verts[vi + 2]) + // + verts[vi])) + // c = !c; + // } + // + // return c; + // } + + // TODO (graham): This is duplicated in the ConvexVolumeTool in RecastDemo + /// Checks if a point is contained within a polygon + /// + /// @param[in] numVerts Number of vertices in the polygon + /// @param[in] verts The polygon vertices + /// @param[in] point The point to check + /// @returns true if the point lies within the polygon, false otherwise. + public static bool PointInPoly(float[] verts, RcVec3f point) + { + bool inPoly = false; + for (int i = 0, j = verts.Length / 3 - 1; i < verts.Length / 3; j = i++) + { + RcVec3f vi = RcVec3f.Of(verts[i * 3], verts[i * 3 + 1], verts[i * 3 + 2]); + RcVec3f vj = RcVec3f.Of(verts[j * 3], verts[j * 3 + 1], verts[j * 3 + 2]); + if (vi.z > point.z == vj.z > point.z) + { + continue; + } + + if (point.x >= (vj.x - vi.x) * (point.z - vi.z) / (vj.z - vi.z) + vi.x) + { + continue; + } + + inPoly = !inPoly; + } + + return inPoly; + } + + /// Expands a convex polygon along its vertex normals by the given offset amount. + /// Inserts extra vertices to bevel sharp corners. + /// + /// Helper function to offset convex polygons for rcMarkConvexPolyArea. + /// + /// @ingroup recast + /// + /// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p numVerts] + /// @param[in] numVerts The number of vertices in the polygon. + /// @param[in] offset How much to offset the polygon by. [Units: wu] + /// @param[out] outVerts The offset vertices (should hold up to 2 * @p numVerts) [Form: (x, y, z) * return value] + /// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts. + /// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts. + public static int OffsetPoly(float[] verts, int numVerts, float offset, float[] outVerts, int maxOutVerts) + { + // Defines the limit at which a miter becomes a bevel. + // Similar in behavior to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit + const float MITER_LIMIT = 1.20f; + + int numOutVerts = 0; + + for (int vertIndex = 0; vertIndex < numVerts; vertIndex++) + { + int vertIndexA = (vertIndex + numVerts - 1) % numVerts; + int vertIndexB = vertIndex; + int vertIndexC = (vertIndex + 1) % numVerts; + + RcVec3f vertA = RcVec3f.Of(verts, vertIndexA * 3); + RcVec3f vertB = RcVec3f.Of(verts, vertIndexB * 3); + RcVec3f vertC = RcVec3f.Of(verts, vertIndexC * 3); + + // From A to B on the x/z plane + RcVec3f prevSegmentDir = vertB.Subtract(vertA); + prevSegmentDir.y = 0; // Squash onto x/z plane + prevSegmentDir.SafeNormalize(); + + // From B to C on the x/z plane + RcVec3f currSegmentDir = vertC.Subtract(vertB); + currSegmentDir.y = 0; // Squash onto x/z plane + currSegmentDir.SafeNormalize(); + + // The y component of the cross product of the two normalized segment directions. + // The X and Z components of the cross product are both zero because the two + // segment direction vectors fall within the x/z plane. + float cross = currSegmentDir.x * prevSegmentDir.z - prevSegmentDir.x * currSegmentDir.z; + + // CCW perpendicular vector to AB. The segment normal. + float prevSegmentNormX = -prevSegmentDir.z; + float prevSegmentNormZ = prevSegmentDir.x; + + // CCW perpendicular vector to BC. The segment normal. + float currSegmentNormX = -currSegmentDir.z; + float currSegmentNormZ = currSegmentDir.x; + + // Average the two segment normals to get the proportional miter offset for B. + // This isn't normalized because it's defining the distance and direction the corner will need to be + // adjusted proportionally to the edge offsets to properly miter the adjoining edges. + float cornerMiterX = (prevSegmentNormX + currSegmentNormX) * 0.5f; + float cornerMiterZ = (prevSegmentNormZ + currSegmentNormZ) * 0.5f; + float cornerMiterSqMag = RcMath.Sqr(cornerMiterX) + RcMath.Sqr(cornerMiterZ); + + // If the magnitude of the segment normal average is less than about .69444, + // the corner is an acute enough angle that the result should be beveled. + bool bevel = cornerMiterSqMag * MITER_LIMIT * MITER_LIMIT < 1.0f; + + // Scale the corner miter so it's proportional to how much the corner should be offset compared to the edges. + if (cornerMiterSqMag > RcVec3f.EPSILON) + { + float scale = 1.0f / cornerMiterSqMag; + cornerMiterX *= scale; + cornerMiterZ *= scale; + } + + if (bevel && cross < 0.0f) // If the corner is convex and an acute enough angle, generate a bevel. + { + if (numOutVerts + 2 > maxOutVerts) + { + return 0; + } + + // Generate two bevel vertices at a distances from B proportional to the angle between the two segments. + // Move each bevel vertex out proportional to the given offset. + float d = (1.0f - (prevSegmentDir.x * currSegmentDir.x + prevSegmentDir.z * currSegmentDir.z)) * 0.5f; + + outVerts[numOutVerts * 3 + 0] = vertB.x + (-prevSegmentNormX + prevSegmentDir.x * d) * offset; + outVerts[numOutVerts * 3 + 1] = vertB.y; + outVerts[numOutVerts * 3 + 2] = vertB.z + (-prevSegmentNormZ + prevSegmentDir.z * d) * offset; + numOutVerts++; + + outVerts[numOutVerts * 3 + 0] = vertB.x + (-currSegmentNormX - currSegmentDir.x * d) * offset; + outVerts[numOutVerts * 3 + 1] = vertB.y; + outVerts[numOutVerts * 3 + 2] = vertB.z + (-currSegmentNormZ - currSegmentDir.z * d) * offset; + numOutVerts++; + } + else + { + if (numOutVerts + 1 > maxOutVerts) + { + return 0; + } + + // Move B along the miter direction by the specified offset. + outVerts[numOutVerts * 3 + 0] = vertB.x - cornerMiterX * offset; + outVerts[numOutVerts * 3 + 1] = vertB.y; + outVerts[numOutVerts * 3 + 2] = vertB.z - cornerMiterZ * offset; + numOutVerts++; + } + } + + return numOutVerts; + } } } \ No newline at end of file diff --git a/src/DotRecast.Recast/RecastBuilder.cs b/src/DotRecast.Recast/RcBuilder.cs similarity index 76% rename from src/DotRecast.Recast/RecastBuilder.cs rename to src/DotRecast.Recast/RcBuilder.cs index 88081f5..255d824 100644 --- a/src/DotRecast.Recast/RecastBuilder.cs +++ b/src/DotRecast.Recast/RcBuilder.cs @@ -27,26 +27,29 @@ using DotRecast.Recast.Geom; namespace DotRecast.Recast { - public class RecastBuilder + using static RcCommons; + using static RcAreas; + + public class RcBuilder { private readonly IRecastBuilderProgressListener progressListener; - public RecastBuilder() + public RcBuilder() { progressListener = null; } - public RecastBuilder(IRecastBuilderProgressListener progressListener) + public RcBuilder(IRecastBuilderProgressListener progressListener) { this.progressListener = progressListener; } - public List BuildTiles(IInputGeomProvider geom, RcConfig cfg, TaskFactory taskFactory) + public List BuildTiles(IInputGeomProvider geom, RcConfig cfg, TaskFactory taskFactory) { RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th); - List results = new List(); + CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th); + List results = new List(); if (null != taskFactory) { BuildMultiThreadAsync(geom, cfg, bmin, bmax, tw, th, results, taskFactory, default); @@ -60,11 +63,11 @@ namespace DotRecast.Recast } - public Task BuildTilesAsync(IInputGeomProvider geom, RcConfig cfg, int threads, List results, TaskFactory taskFactory, CancellationToken cancellationToken) + public Task BuildTilesAsync(IInputGeomProvider geom, RcConfig cfg, int threads, List results, TaskFactory taskFactory, CancellationToken cancellationToken) { RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th); + CalcTileCount(bmin, bmax, cfg.Cs, cfg.TileSizeX, cfg.TileSizeZ, out var tw, out var th); Task task; if (1 < threads) { @@ -79,7 +82,7 @@ namespace DotRecast.Recast } private Task BuildSingleThreadAsync(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, - int tw, int th, List results) + int tw, int th, List results) { RcAtomicInteger counter = new RcAtomicInteger(0); for (int y = 0; y < th; ++y) @@ -94,7 +97,7 @@ namespace DotRecast.Recast } private Task BuildMultiThreadAsync(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, - int tw, int th, List results, TaskFactory taskFactory, CancellationToken cancellationToken) + int tw, int th, List results, TaskFactory taskFactory, CancellationToken cancellationToken) { RcAtomicInteger counter = new RcAtomicInteger(0); CountdownEvent latch = new CountdownEvent(tw * th); @@ -113,7 +116,7 @@ namespace DotRecast.Recast try { - RecastBuilderResult tile = BuildTile(geom, cfg, bmin, bmax, tx, ty, counter, tw * th); + RcBuilderResult tile = BuildTile(geom, cfg, bmin, bmax, tx, ty, counter, tw * th); lock (results) { results.Add(tile); @@ -143,10 +146,10 @@ namespace DotRecast.Recast return Task.WhenAll(tasks.ToArray()); } - public RecastBuilderResult BuildTile(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tx, + public RcBuilderResult BuildTile(IInputGeomProvider geom, RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tx, int ty, RcAtomicInteger counter, int total) { - RecastBuilderResult result = Build(geom, new RecastBuilderConfig(cfg, bmin, bmax, tx, ty)); + RcBuilderResult result = Build(geom, new RcBuilderConfig(cfg, bmin, bmax, tx, ty)); if (progressListener != null) { progressListener.OnProgress(counter.IncrementAndGet(), total); @@ -155,18 +158,18 @@ namespace DotRecast.Recast return result; } - public RecastBuilderResult Build(IInputGeomProvider geom, RecastBuilderConfig builderCfg) + public RcBuilderResult Build(IInputGeomProvider geom, RcBuilderConfig builderCfg) { RcConfig cfg = builderCfg.cfg; RcTelemetry ctx = new RcTelemetry(); // // Step 1. Rasterize input polygon soup. // - RcHeightfield solid = RecastVoxelization.BuildSolidHeightfield(geom, builderCfg, ctx); + RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(geom, builderCfg, ctx); return Build(builderCfg.tileX, builderCfg.tileZ, geom, cfg, solid, ctx); } - public RecastBuilderResult Build(int tileX, int tileZ, IInputGeomProvider geom, RcConfig cfg, RcHeightfield solid, RcTelemetry ctx) + public RcBuilderResult Build(int tileX, int tileZ, IInputGeomProvider geom, RcConfig cfg, RcHeightfield solid, RcTelemetry ctx) { FilterHeightfield(solid, cfg, ctx); RcCompactHeightfield chf = BuildCompactHeightfield(geom, cfg, ctx, solid); @@ -213,20 +216,20 @@ namespace DotRecast.Recast { // Prepare for region partitioning, by calculating distance field // along the walkable surface. - RecastRegion.BuildDistanceField(ctx, chf); + RcRegions.BuildDistanceField(ctx, chf); // Partition the walkable surface into simple regions without holes. - RecastRegion.BuildRegions(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea); + RcRegions.BuildRegions(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea); } else if (cfg.Partition == RcPartitionType.MONOTONE.Value) { // Partition the walkable surface into simple regions without holes. // Monotone partitioning does not need distancefield. - RecastRegion.BuildRegionsMonotone(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea); + RcRegions.BuildRegionsMonotone(ctx, chf, cfg.MinRegionArea, cfg.MergeRegionArea); } else { // Partition the walkable surface into simple regions without holes. - RecastRegion.BuildLayerRegions(ctx, chf, cfg.MinRegionArea); + RcRegions.BuildLayerRegions(ctx, chf, cfg.MinRegionArea); } // @@ -234,23 +237,23 @@ namespace DotRecast.Recast // // Create contours. - RcContourSet cset = RecastContour.BuildContours(ctx, chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen, + RcContourSet cset = RcContours.BuildContours(ctx, chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen, RcConstants.RC_CONTOUR_TESS_WALL_EDGES); // // Step 6. Build polygons mesh from contours. // - RcPolyMesh pmesh = RecastMesh.BuildPolyMesh(ctx, cset, cfg.MaxVertsPerPoly); + RcPolyMesh pmesh = RcMeshs.BuildPolyMesh(ctx, cset, cfg.MaxVertsPerPoly); // // Step 7. Create detail mesh which allows to access approximate height // on each polygon. // RcPolyMeshDetail dmesh = cfg.BuildMeshDetail - ? RecastMeshDetail.BuildPolyMeshDetail(ctx, pmesh, chf, cfg.DetailSampleDist, cfg.DetailSampleMaxError) + ? RcMeshDetails.BuildPolyMeshDetail(ctx, pmesh, chf, cfg.DetailSampleDist, cfg.DetailSampleMaxError) : null; - return new RecastBuilderResult(tileX, tileZ, solid, chf, cset, pmesh, dmesh, ctx); + return new RcBuilderResult(tileX, tileZ, solid, chf, cset, pmesh, dmesh, ctx); } /* @@ -263,17 +266,17 @@ namespace DotRecast.Recast // as well as filter spans where the character cannot possibly stand. if (cfg.FilterLowHangingObstacles) { - RecastFilter.FilterLowHangingWalkableObstacles(ctx, cfg.WalkableClimb, solid); + RcFilters.FilterLowHangingWalkableObstacles(ctx, cfg.WalkableClimb, solid); } if (cfg.FilterLedgeSpans) { - RecastFilter.FilterLedgeSpans(ctx, cfg.WalkableHeight, cfg.WalkableClimb, solid); + RcFilters.FilterLedgeSpans(ctx, cfg.WalkableHeight, cfg.WalkableClimb, solid); } if (cfg.FilterWalkableLowHeightSpans) { - RecastFilter.FilterWalkableLowHeightSpans(ctx, cfg.WalkableHeight, solid); + RcFilters.FilterWalkableLowHeightSpans(ctx, cfg.WalkableHeight, solid); } } @@ -286,29 +289,29 @@ namespace DotRecast.Recast // Compact the heightfield so that it is faster to handle from now on. // This will result more cache coherent data as well as the neighbours // between walkable cells will be calculated. - RcCompactHeightfield chf = RecastCompact.BuildCompactHeightfield(ctx, cfg.WalkableHeight, cfg.WalkableClimb, solid); + RcCompactHeightfield chf = RcCompacts.BuildCompactHeightfield(ctx, cfg.WalkableHeight, cfg.WalkableClimb, solid); // Erode the walkable area by agent radius. - RecastArea.ErodeWalkableArea(ctx, cfg.WalkableRadius, chf); + ErodeWalkableArea(ctx, cfg.WalkableRadius, chf); // (Optional) Mark areas. if (geom != null) { foreach (RcConvexVolume vol in geom.ConvexVolumes()) { - RecastArea.MarkConvexPolyArea(ctx, vol.verts, vol.hmin, vol.hmax, vol.areaMod, chf); + MarkConvexPolyArea(ctx, vol.verts, vol.hmin, vol.hmax, vol.areaMod, chf); } } return chf; } - public RcHeightfieldLayerSet BuildLayers(IInputGeomProvider geom, RecastBuilderConfig builderCfg) + public RcHeightfieldLayerSet BuildLayers(IInputGeomProvider geom, RcBuilderConfig builderCfg) { RcTelemetry ctx = new RcTelemetry(); - RcHeightfield solid = RecastVoxelization.BuildSolidHeightfield(geom, builderCfg, ctx); + RcHeightfield solid = RcVoxelizations.BuildSolidHeightfield(geom, builderCfg, ctx); FilterHeightfield(solid, builderCfg.cfg, ctx); RcCompactHeightfield chf = BuildCompactHeightfield(geom, builderCfg.cfg, ctx, solid); - return RecastLayers.BuildHeightfieldLayers(ctx, chf, builderCfg.cfg.WalkableHeight); + return RcLayers.BuildHeightfieldLayers(ctx, chf, builderCfg.cfg.WalkableHeight); } } } \ No newline at end of file diff --git a/src/DotRecast.Recast/RecastBuilderConfig.cs b/src/DotRecast.Recast/RcBuilderConfig.cs similarity index 92% rename from src/DotRecast.Recast/RecastBuilderConfig.cs rename to src/DotRecast.Recast/RcBuilderConfig.cs index 0807faa..c92952a 100644 --- a/src/DotRecast.Recast/RecastBuilderConfig.cs +++ b/src/DotRecast.Recast/RcBuilderConfig.cs @@ -22,7 +22,7 @@ using DotRecast.Core; namespace DotRecast.Recast { - public class RecastBuilderConfig + public class RcBuilderConfig { public readonly RcConfig cfg; @@ -41,11 +41,11 @@ namespace DotRecast.Recast /** The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] **/ public readonly RcVec3f bmax = new RcVec3f(); - public RecastBuilderConfig(RcConfig cfg, RcVec3f bmin, RcVec3f bmax) : this(cfg, bmin, bmax, 0, 0) + public RcBuilderConfig(RcConfig cfg, RcVec3f bmin, RcVec3f bmax) : this(cfg, bmin, bmax, 0, 0) { } - public RecastBuilderConfig(RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tileX, int tileZ) + public RcBuilderConfig(RcConfig cfg, RcVec3f bmin, RcVec3f bmax, int tileX, int tileZ) { this.tileX = tileX; this.tileZ = tileZ; @@ -92,7 +92,7 @@ namespace DotRecast.Recast } else { - RcUtils.CalcGridSize(this.bmin, this.bmax, cfg.Cs, out width, out height); + RcCommons.CalcGridSize(this.bmin, this.bmax, cfg.Cs, out width, out height); } } } diff --git a/src/DotRecast.Recast/RecastBuilderResult.cs b/src/DotRecast.Recast/RcBuilderResult.cs similarity index 85% rename from src/DotRecast.Recast/RecastBuilderResult.cs rename to src/DotRecast.Recast/RcBuilderResult.cs index e9049cf..7a8264b 100644 --- a/src/DotRecast.Recast/RecastBuilderResult.cs +++ b/src/DotRecast.Recast/RcBuilderResult.cs @@ -2,7 +2,7 @@ namespace DotRecast.Recast { - public class RecastBuilderResult + public class RcBuilderResult { public readonly int tileX; public readonly int tileZ; @@ -14,7 +14,7 @@ namespace DotRecast.Recast private readonly RcHeightfield solid; private readonly RcTelemetry telemetry; - public RecastBuilderResult(int tileX, int tileZ, RcHeightfield solid, RcCompactHeightfield chf, RcContourSet cs, RcPolyMesh pmesh, RcPolyMeshDetail dmesh, RcTelemetry ctx) + public RcBuilderResult(int tileX, int tileZ, RcHeightfield solid, RcCompactHeightfield chf, RcContourSet cs, RcPolyMesh pmesh, RcPolyMeshDetail dmesh, RcTelemetry ctx) { this.tileX = tileX; this.tileZ = tileZ; diff --git a/src/DotRecast.Recast/RcUtils.cs b/src/DotRecast.Recast/RcCommons.cs similarity index 64% rename from src/DotRecast.Recast/RcUtils.cs rename to src/DotRecast.Recast/RcCommons.cs index 2954b1a..e965919 100644 --- a/src/DotRecast.Recast/RcUtils.cs +++ b/src/DotRecast.Recast/RcCommons.cs @@ -23,10 +23,61 @@ using DotRecast.Core; namespace DotRecast.Recast { - using static DotRecast.Recast.RcConstants; - - public static class RcUtils + using static RcConstants; + + public static class RcCommons { + private static readonly int[] DirOffsetX = { -1, 0, 1, 0, }; + private static readonly int[] DirOffsetY = { 0, 1, 0, -1 }; + private static readonly int[] DirForOffset = { 3, 0, -1, 2, 1 }; + + /// Sets the neighbor connection data for the specified direction. + /// @param[in] span The span to update. + /// @param[in] direction The direction to set. [Limits: 0 <= value < 4] + /// @param[in] neighborIndex The index of the neighbor span. + public static void SetCon(RcCompactSpan span, int direction, int neighborIndex) + { + int shift = direction * 6; + int con = span.con; + span.con = (con & ~(0x3f << shift)) | ((neighborIndex & 0x3f) << shift); + } + + /// Gets neighbor connection data for the specified direction. + /// @param[in] span The span to check. + /// @param[in] direction The direction to check. [Limits: 0 <= value < 4] + /// @return The neighbor connection data for the specified direction, or #RC_NOT_CONNECTED if there is no connection. + public static int GetCon(RcCompactSpan s, int dir) + { + int shift = dir * 6; + return (s.con >> shift) & 0x3f; + } + + /// Gets the standard width (x-axis) offset for the specified direction. + /// @param[in] direction The direction. [Limits: 0 <= value < 4] + /// @return The width offset to apply to the current cell position to move in the direction. + public static int GetDirOffsetX(int dir) + { + return DirOffsetX[dir & 0x03]; + } + + // TODO (graham): Rename this to rcGetDirOffsetZ + /// Gets the standard height (z-axis) offset for the specified direction. + /// @param[in] direction The direction. [Limits: 0 <= value < 4] + /// @return The height offset to apply to the current cell position to move in the direction. + public static int GetDirOffsetY(int dir) + { + return DirOffsetY[dir & 0x03]; + } + + /// Gets the direction for the specified offset. One of x and y should be 0. + /// @param[in] offsetX The x offset. [Limits: -1 <= value <= 1] + /// @param[in] offsetZ The z offset. [Limits: -1 <= value <= 1] + /// @return The direction that represents the offset. + public static int GetDirForOffset(int x, int y) + { + return DirForOffset[((y + 1) << 1) + x]; + } + public static void CalcBounds(float[] verts, int nv, float[] bmin, float[] bmax) { for (int i = 0; i < 3; i++) diff --git a/src/DotRecast.Recast/RecastCompact.cs b/src/DotRecast.Recast/RcCompacts.cs similarity index 95% rename from src/DotRecast.Recast/RecastCompact.cs rename to src/DotRecast.Recast/RcCompacts.cs index b7576a7..d192bcf 100644 --- a/src/DotRecast.Recast/RecastCompact.cs +++ b/src/DotRecast.Recast/RcCompacts.cs @@ -25,7 +25,9 @@ using static DotRecast.Recast.RcConstants; namespace DotRecast.Recast { - public static class RecastCompact + using static RcCommons; + + public static class RcCompacts { private const int MAX_LAYERS = RC_NOT_CONNECTED - 1; private const int MAX_HEIGHT = RcConstants.SPAN_MAX_HEIGHT; @@ -117,9 +119,9 @@ namespace DotRecast.Recast for (int dir = 0; dir < 4; ++dir) { - RecastCommon.SetCon(s, dir, RC_NOT_CONNECTED); - int nx = x + RecastCommon.GetDirOffsetX(dir); - int ny = y + RecastCommon.GetDirOffsetY(dir); + SetCon(s, dir, RC_NOT_CONNECTED); + int nx = x + GetDirOffsetX(dir); + int ny = y + GetDirOffsetY(dir); // First check that the neighbour cell is in bounds. if (nx < 0 || ny < 0 || nx >= w || ny >= h) continue; @@ -145,7 +147,7 @@ namespace DotRecast.Recast continue; } - RecastCommon.SetCon(s, dir, lidx); + SetCon(s, dir, lidx); break; } } diff --git a/src/DotRecast.Recast/RecastContour.cs b/src/DotRecast.Recast/RcContours.cs similarity index 93% rename from src/DotRecast.Recast/RecastContour.cs rename to src/DotRecast.Recast/RcContours.cs index 93eb4f7..0c7887b 100644 --- a/src/DotRecast.Recast/RecastContour.cs +++ b/src/DotRecast.Recast/RcContours.cs @@ -25,8 +25,9 @@ using DotRecast.Core; namespace DotRecast.Recast { using static RcConstants; + using static RcCommons; - public static class RecastContour + public static class RcContours { private static int GetCornerHeight(int x, int y, int i, int dir, RcCompactHeightfield chf, out bool isBorderVertex) { @@ -45,38 +46,38 @@ namespace DotRecast.Recast // border vertices which are in between two areas to be removed. regs[0] = chf.spans[i].reg | (chf.areas[i] << 16); - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); RcCompactSpan @as = chf.spans[ai]; ch = Math.Max(ch, @as.y); regs[1] = chf.spans[ai].reg | (chf.areas[ai] << 16); - if (RecastCommon.GetCon(@as, dirp) != RC_NOT_CONNECTED) + if (GetCon(@as, dirp) != RC_NOT_CONNECTED) { - int ax2 = ax + RecastCommon.GetDirOffsetX(dirp); - int ay2 = ay + RecastCommon.GetDirOffsetY(dirp); - int ai2 = chf.cells[ax2 + ay2 * chf.width].index + RecastCommon.GetCon(@as, dirp); + int ax2 = ax + GetDirOffsetX(dirp); + int ay2 = ay + GetDirOffsetY(dirp); + int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(@as, dirp); RcCompactSpan as2 = chf.spans[ai2]; ch = Math.Max(ch, as2.y); regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); } } - if (RecastCommon.GetCon(s, dirp) != RC_NOT_CONNECTED) + if (GetCon(s, dirp) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dirp); - int ay = y + RecastCommon.GetDirOffsetY(dirp); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(s, dirp); + int ax = x + GetDirOffsetX(dirp); + int ay = y + GetDirOffsetY(dirp); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dirp); RcCompactSpan @as = chf.spans[ai]; ch = Math.Max(ch, @as.y); regs[3] = chf.spans[ai].reg | (chf.areas[ai] << 16); - if (RecastCommon.GetCon(@as, dir) != RC_NOT_CONNECTED) + if (GetCon(@as, dir) != RC_NOT_CONNECTED) { - int ax2 = ax + RecastCommon.GetDirOffsetX(dir); - int ay2 = ay + RecastCommon.GetDirOffsetY(dir); - int ai2 = chf.cells[ax2 + ay2 * chf.width].index + RecastCommon.GetCon(@as, dir); + int ax2 = ax + GetDirOffsetX(dir); + int ay2 = ay + GetDirOffsetY(dir); + int ai2 = chf.cells[ax2 + ay2 * chf.width].index + GetCon(@as, dir); RcCompactSpan as2 = chf.spans[ai2]; ch = Math.Max(ch, as2.y); regs[2] = chf.spans[ai2].reg | (chf.areas[ai2] << 16); @@ -146,11 +147,11 @@ namespace DotRecast.Recast int r = 0; RcCompactSpan s = chf.spans[i]; - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); r = chf.spans[ai].reg; if (area != chf.areas[ai]) isAreaBorder = true; @@ -171,13 +172,13 @@ namespace DotRecast.Recast else { int ni = -1; - int nx = x + RecastCommon.GetDirOffsetX(dir); - int ny = y + RecastCommon.GetDirOffsetY(dir); + int nx = x + GetDirOffsetX(dir); + int ny = y + GetDirOffsetY(dir); RcCompactSpan s = chf.spans[i]; - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { RcCompactCell nc = chf.cells[nx + ny * chf.width]; - ni = nc.index + RecastCommon.GetCon(s, dir); + ni = nc.index + GetCon(s, dir); } if (ni == -1) @@ -475,7 +476,7 @@ namespace DotRecast.Recast d1 = 4; for (int k = 0; k < n; k++) { - int k1 = RecastMesh.Next(k, n); + int k1 = RcMeshs.Next(k, n); // Skip edges incident to i. if (i == k || i == k1) continue; @@ -489,11 +490,11 @@ namespace DotRecast.Recast p0 = 8; p1 = 12; - if (RecastMesh.VEqual(pverts, d0, p0) || RecastMesh.VEqual(pverts, d1, p0) || - RecastMesh.VEqual(pverts, d0, p1) || RecastMesh.VEqual(pverts, d1, p1)) + if (RcMeshs.VEqual(pverts, d0, p0) || RcMeshs.VEqual(pverts, d1, p0) || + RcMeshs.VEqual(pverts, d0, p1) || RcMeshs.VEqual(pverts, d1, p1)) continue; - if (RecastMesh.Intersect(pverts, d0, d1, p0, p1)) + if (RcMeshs.Intersect(pverts, d0, d1, p0, p1)) return true; } @@ -503,8 +504,8 @@ namespace DotRecast.Recast private static bool InCone(int i, int n, int[] verts, int pj, int[] vertpj) { int pi = i * 4; - int pi1 = RecastMesh.Next(i, n) * 4; - int pin1 = RecastMesh.Prev(i, n) * 4; + int pi1 = RcMeshs.Next(i, n) * 4; + int pin1 = RcMeshs.Prev(i, n) * 4; int[] pverts = new int[4 * 4]; for (int g = 0; g < 4; g++) { @@ -519,11 +520,11 @@ namespace DotRecast.Recast pin1 = 8; pj = 12; // If P[i] is a convex vertex [ i+1 left or on (i-1,i) ]. - if (RecastMesh.LeftOn(pverts, pin1, pi, pi1)) - return RecastMesh.Left(pverts, pi, pj, pin1) && RecastMesh.Left(pverts, pj, pi, pi1); + if (RcMeshs.LeftOn(pverts, pin1, pi, pi1)) + return RcMeshs.Left(pverts, pi, pj, pin1) && RcMeshs.Left(pverts, pj, pi, pi1); // Assume (i-1,i,i+1) not collinear. // else P[i] is reflex. - return !(RecastMesh.LeftOn(pverts, pi, pj, pi1) && RecastMesh.LeftOn(pverts, pj, pi, pin1)); + return !(RcMeshs.LeftOn(pverts, pi, pj, pi1) && RcMeshs.LeftOn(pverts, pj, pi, pin1)); } private static void RemoveDegenerateSegments(List simplified) @@ -533,7 +534,7 @@ namespace DotRecast.Recast int npts = simplified.Count / 4; for (int i = 0; i < npts; ++i) { - int ni = RecastMesh.Next(i, npts); + int ni = RcMeshs.Next(i, npts); // if (Vequal(&simplified[i*4], &simplified[ni*4])) if (simplified[i * 4] == simplified[ni * 4] @@ -766,11 +767,11 @@ namespace DotRecast.Recast for (int dir = 0; dir < 4; ++dir) { int r = 0; - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); r = chf.spans[ai].reg; } diff --git a/src/DotRecast.Recast/RecastFilledVolumeRasterization.cs b/src/DotRecast.Recast/RcFilledVolumeRasterization.cs similarity index 98% rename from src/DotRecast.Recast/RecastFilledVolumeRasterization.cs rename to src/DotRecast.Recast/RcFilledVolumeRasterization.cs index c867541..19dec00 100644 --- a/src/DotRecast.Recast/RecastFilledVolumeRasterization.cs +++ b/src/DotRecast.Recast/RcFilledVolumeRasterization.cs @@ -25,7 +25,7 @@ using static DotRecast.Recast.RcConstants; namespace DotRecast.Recast { - public static class RecastFilledVolumeRasterization + public static class RcFilledVolumeRasterization { private const float EPSILON = 0.00001f; private static readonly int[] BOX_EDGES = new[] { 0, 1, 0, 2, 0, 4, 1, 3, 1, 5, 2, 3, 2, 6, 3, 7, 4, 5, 4, 6, 5, 7, 6, 7 }; @@ -56,8 +56,7 @@ namespace DotRecast.Recast rectangle => IntersectCapsule(rectangle, start, end, axis, radius * radius)); } - public static void RasterizeCylinder(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr, - RcTelemetry ctx) + public static void RasterizeCylinder(RcHeightfield hf, RcVec3f start, RcVec3f end, float radius, int area, int flagMergeThr, RcTelemetry ctx) { using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CYLINDER); float[] bounds = @@ -71,8 +70,7 @@ namespace DotRecast.Recast rectangle => IntersectCylinder(rectangle, start, end, axis, radius * radius)); } - public static void RasterizeBox(RcHeightfield hf, RcVec3f center, RcVec3f[] halfEdges, int area, int flagMergeThr, - RcTelemetry ctx) + public static void RasterizeBox(RcHeightfield hf, RcVec3f center, RcVec3f[] halfEdges, int area, int flagMergeThr, RcTelemetry ctx) { using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_BOX); RcVec3f[] normals = @@ -122,8 +120,7 @@ namespace DotRecast.Recast RasterizationFilledShape(hf, bounds, area, flagMergeThr, rectangle => IntersectBox(rectangle, vertices, planes)); } - public static void RasterizeConvex(RcHeightfield hf, float[] vertices, int[] triangles, int area, int flagMergeThr, - RcTelemetry ctx) + public static void RasterizeConvex(RcHeightfield hf, float[] vertices, int[] triangles, int area, int flagMergeThr, RcTelemetry ctx) { using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_CONVEX); float[] bounds = new float[] { vertices[0], vertices[1], vertices[2], vertices[0], vertices[1], vertices[2] }; @@ -226,7 +223,7 @@ namespace DotRecast.Recast { int ismin = Clamp(smin, 0, SPAN_MAX_HEIGHT); int ismax = Clamp(smax, ismin + 1, SPAN_MAX_HEIGHT); - RecastRasterization.AddSpan(hf, x, z, ismin, ismax, area, flagMergeThr); + RcRasterizations.AddSpan(hf, x, z, ismin, ismax, area, flagMergeThr); } } } diff --git a/src/DotRecast.Recast/RecastFilter.cs b/src/DotRecast.Recast/RcFilters.cs similarity index 97% rename from src/DotRecast.Recast/RecastFilter.cs rename to src/DotRecast.Recast/RcFilters.cs index 1e48f1b..c1d6952 100644 --- a/src/DotRecast.Recast/RecastFilter.cs +++ b/src/DotRecast.Recast/RcFilters.cs @@ -24,8 +24,9 @@ using DotRecast.Core; namespace DotRecast.Recast { using static RcConstants; + using static RcCommons; - public static class RecastFilter + public static class RcFilters { /// @par /// @@ -113,8 +114,8 @@ namespace DotRecast.Recast for (int dir = 0; dir < 4; ++dir) { - int dx = x + RecastCommon.GetDirOffsetX(dir); - int dy = y + RecastCommon.GetDirOffsetY(dir); + int dx = x + GetDirOffsetX(dir); + int dy = y + GetDirOffsetY(dir); // Skip neighbours which are out of bounds. if (dx < 0 || dy < 0 || dx >= w || dy >= h) { diff --git a/src/DotRecast.Recast/RecastLayers.cs b/src/DotRecast.Recast/RcLayers.cs similarity index 99% rename from src/DotRecast.Recast/RecastLayers.cs rename to src/DotRecast.Recast/RcLayers.cs index b6bc27a..5637e96 100644 --- a/src/DotRecast.Recast/RecastLayers.cs +++ b/src/DotRecast.Recast/RcLayers.cs @@ -24,10 +24,10 @@ using DotRecast.Core; namespace DotRecast.Recast { - using static RecastCommon; using static RcConstants; + using static RcCommons; - public static class RecastLayers + public static class RcLayers { const int RC_MAX_LAYERS = RcConstants.RC_NOT_CONNECTED; const int RC_MAX_NEIS = 16; diff --git a/src/DotRecast.Recast/RecastMeshDetail.cs b/src/DotRecast.Recast/RcMeshDetails.cs similarity index 99% rename from src/DotRecast.Recast/RecastMeshDetail.cs rename to src/DotRecast.Recast/RcMeshDetails.cs index b8a3e3e..515e5b4 100644 --- a/src/DotRecast.Recast/RecastMeshDetail.cs +++ b/src/DotRecast.Recast/RcMeshDetails.cs @@ -22,12 +22,13 @@ using System; using System.Collections.Generic; using DotRecast.Core; using static DotRecast.Core.RcMath; -using static DotRecast.Recast.RecastCommon; using static DotRecast.Recast.RcConstants; namespace DotRecast.Recast { - public static class RecastMeshDetail + using static RcCommons; + + public static class RcMeshDetails { public const int MAX_VERTS = 127; public const int MAX_TRIS = 255; // Max tris for delaunay is 2n-2-k (n=num verts, k=num hull verts). @@ -764,8 +765,8 @@ namespace DotRecast.Recast } // segments on edges - int pi = RecastMesh.Prev(i, nhull); - int ni = RecastMesh.Next(i, nhull); + int pi = RcMeshs.Prev(i, nhull); + int ni = RcMeshs.Next(i, nhull); int pv = hull[pi] * 3; int cv = hull[i] * 3; int nv = hull[ni] * 3; @@ -789,11 +790,11 @@ namespace DotRecast.Recast // depending on which triangle has shorter perimeter. // This heuristic was chose empirically, since it seems // handle tessellated straight edges well. - while (RecastMesh.Next(left, nhull) != right) + while (RcMeshs.Next(left, nhull) != right) { // Check to see if se should advance left or right. - int nleft = RecastMesh.Next(left, nhull); - int nright = RecastMesh.Prev(right, nhull); + int nleft = RcMeshs.Next(left, nhull); + int nright = RcMeshs.Prev(right, nhull); int cvleft = hull[left] * 3; int nvleft = hull[nleft] * 3; diff --git a/src/DotRecast.Recast/RecastMesh.cs b/src/DotRecast.Recast/RcMeshs.cs similarity index 99% rename from src/DotRecast.Recast/RecastMesh.cs rename to src/DotRecast.Recast/RcMeshs.cs index 6e6710f..53e8e59 100644 --- a/src/DotRecast.Recast/RecastMesh.cs +++ b/src/DotRecast.Recast/RcMeshs.cs @@ -25,7 +25,7 @@ namespace DotRecast.Recast { using static RcConstants; - public static class RecastMesh + public static class RcMeshs { public const int MAX_MESH_VERTS_POLY = 0xffff; public const int VERTEX_BUCKET_COUNT = (1 << 12); diff --git a/src/DotRecast.Recast/RcPolyMeshRaycast.cs b/src/DotRecast.Recast/RcPolyMeshRaycast.cs index 51b3ae5..f959029 100644 --- a/src/DotRecast.Recast/RcPolyMeshRaycast.cs +++ b/src/DotRecast.Recast/RcPolyMeshRaycast.cs @@ -24,10 +24,10 @@ namespace DotRecast.Recast { public static class RcPolyMeshRaycast { - public static bool Raycast(IList results, RcVec3f src, RcVec3f dst, out float hitTime) + public static bool Raycast(IList results, RcVec3f src, RcVec3f dst, out float hitTime) { hitTime = 0.0f; - foreach (RecastBuilderResult result in results) + foreach (RcBuilderResult result in results) { if (result.GetMeshDetail() != null) { diff --git a/src/DotRecast.Recast/RecastRasterization.cs b/src/DotRecast.Recast/RcRasterizations.cs similarity index 99% rename from src/DotRecast.Recast/RecastRasterization.cs rename to src/DotRecast.Recast/RcRasterizations.cs index c38e5bc..f9a38be 100644 --- a/src/DotRecast.Recast/RecastRasterization.cs +++ b/src/DotRecast.Recast/RcRasterizations.cs @@ -25,7 +25,7 @@ using static DotRecast.Recast.RcConstants; namespace DotRecast.Recast { - public static class RecastRasterization + public static class RcRasterizations { /** * Check whether two bounding boxes overlap diff --git a/src/DotRecast.Recast/RecastRegion.cs b/src/DotRecast.Recast/RcRegions.cs similarity index 91% rename from src/DotRecast.Recast/RecastRegion.cs rename to src/DotRecast.Recast/RcRegions.cs index cb00d5e..2ccbcb3 100644 --- a/src/DotRecast.Recast/RecastRegion.cs +++ b/src/DotRecast.Recast/RcRegions.cs @@ -26,12 +26,12 @@ using DotRecast.Core; namespace DotRecast.Recast { using static RcConstants; + using static RcCommons; - public static class RecastRegion + public static class RcRegions { const int RC_NULL_NEI = 0xffff; - public static int CalculateDistanceField(RcCompactHeightfield chf, int[] src) { int maxDist; @@ -58,11 +58,11 @@ namespace DotRecast.Recast int nc = 0; for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); if (area == chf.areas[ai]) { nc++; @@ -88,12 +88,12 @@ namespace DotRecast.Recast { RcCompactSpan s = chf.spans[i]; - if (RecastCommon.GetCon(s, 0) != RC_NOT_CONNECTED) + if (GetCon(s, 0) != RC_NOT_CONNECTED) { // (-1,0) - int ax = x + RecastCommon.GetDirOffsetX(0); - int ay = y + RecastCommon.GetDirOffsetY(0); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 0); + int ax = x + GetDirOffsetX(0); + int ay = y + GetDirOffsetY(0); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); RcCompactSpan @as = chf.spans[ai]; if (src[ai] + 2 < src[i]) { @@ -101,11 +101,11 @@ namespace DotRecast.Recast } // (-1,-1) - if (RecastCommon.GetCon(@as, 3) != RC_NOT_CONNECTED) + if (GetCon(@as, 3) != RC_NOT_CONNECTED) { - int aax = ax + RecastCommon.GetDirOffsetX(3); - int aay = ay + RecastCommon.GetDirOffsetY(3); - int aai = chf.cells[aax + aay * w].index + RecastCommon.GetCon(@as, 3); + int aax = ax + GetDirOffsetX(3); + int aay = ay + GetDirOffsetY(3); + int aai = chf.cells[aax + aay * w].index + GetCon(@as, 3); if (src[aai] + 3 < src[i]) { src[i] = src[aai] + 3; @@ -113,12 +113,12 @@ namespace DotRecast.Recast } } - if (RecastCommon.GetCon(s, 3) != RC_NOT_CONNECTED) + if (GetCon(s, 3) != RC_NOT_CONNECTED) { // (0,-1) - int ax = x + RecastCommon.GetDirOffsetX(3); - int ay = y + RecastCommon.GetDirOffsetY(3); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 3); + int ax = x + GetDirOffsetX(3); + int ay = y + GetDirOffsetY(3); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 3); RcCompactSpan @as = chf.spans[ai]; if (src[ai] + 2 < src[i]) { @@ -126,11 +126,11 @@ namespace DotRecast.Recast } // (1,-1) - if (RecastCommon.GetCon(@as, 2) != RC_NOT_CONNECTED) + if (GetCon(@as, 2) != RC_NOT_CONNECTED) { - int aax = ax + RecastCommon.GetDirOffsetX(2); - int aay = ay + RecastCommon.GetDirOffsetY(2); - int aai = chf.cells[aax + aay * w].index + RecastCommon.GetCon(@as, 2); + int aax = ax + GetDirOffsetX(2); + int aay = ay + GetDirOffsetY(2); + int aai = chf.cells[aax + aay * w].index + GetCon(@as, 2); if (src[aai] + 3 < src[i]) { src[i] = src[aai] + 3; @@ -151,12 +151,12 @@ namespace DotRecast.Recast { RcCompactSpan s = chf.spans[i]; - if (RecastCommon.GetCon(s, 2) != RC_NOT_CONNECTED) + if (GetCon(s, 2) != RC_NOT_CONNECTED) { // (1,0) - int ax = x + RecastCommon.GetDirOffsetX(2); - int ay = y + RecastCommon.GetDirOffsetY(2); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 2); + int ax = x + GetDirOffsetX(2); + int ay = y + GetDirOffsetY(2); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 2); RcCompactSpan @as = chf.spans[ai]; if (src[ai] + 2 < src[i]) { @@ -164,11 +164,11 @@ namespace DotRecast.Recast } // (1,1) - if (RecastCommon.GetCon(@as, 1) != RC_NOT_CONNECTED) + if (GetCon(@as, 1) != RC_NOT_CONNECTED) { - int aax = ax + RecastCommon.GetDirOffsetX(1); - int aay = ay + RecastCommon.GetDirOffsetY(1); - int aai = chf.cells[aax + aay * w].index + RecastCommon.GetCon(@as, 1); + int aax = ax + GetDirOffsetX(1); + int aay = ay + GetDirOffsetY(1); + int aai = chf.cells[aax + aay * w].index + GetCon(@as, 1); if (src[aai] + 3 < src[i]) { src[i] = src[aai] + 3; @@ -176,12 +176,12 @@ namespace DotRecast.Recast } } - if (RecastCommon.GetCon(s, 1) != RC_NOT_CONNECTED) + if (GetCon(s, 1) != RC_NOT_CONNECTED) { // (0,1) - int ax = x + RecastCommon.GetDirOffsetX(1); - int ay = y + RecastCommon.GetDirOffsetY(1); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 1); + int ax = x + GetDirOffsetX(1); + int ay = y + GetDirOffsetY(1); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 1); RcCompactSpan @as = chf.spans[ai]; if (src[ai] + 2 < src[i]) { @@ -189,11 +189,11 @@ namespace DotRecast.Recast } // (-1,1) - if (RecastCommon.GetCon(@as, 0) != RC_NOT_CONNECTED) + if (GetCon(@as, 0) != RC_NOT_CONNECTED) { - int aax = ax + RecastCommon.GetDirOffsetX(0); - int aay = ay + RecastCommon.GetDirOffsetY(0); - int aai = chf.cells[aax + aay * w].index + RecastCommon.GetCon(@as, 0); + int aax = ax + GetDirOffsetX(0); + int aay = ay + GetDirOffsetY(0); + int aai = chf.cells[aax + aay * w].index + GetCon(@as, 0); if (src[aai] + 3 < src[i]) { src[i] = src[aai] + 3; @@ -239,20 +239,20 @@ namespace DotRecast.Recast int d = cd; for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); d += src[ai]; RcCompactSpan @as = chf.spans[ai]; int dir2 = (dir + 1) & 0x3; - if (RecastCommon.GetCon(@as, dir2) != RC_NOT_CONNECTED) + if (GetCon(@as, dir2) != RC_NOT_CONNECTED) { - int ax2 = ax + RecastCommon.GetDirOffsetX(dir2); - int ay2 = ay + RecastCommon.GetDirOffsetY(dir2); - int ai2 = chf.cells[ax2 + ay2 * w].index + RecastCommon.GetCon(@as, dir2); + int ax2 = ax + GetDirOffsetX(dir2); + int ay2 = ay + GetDirOffsetY(dir2); + int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(@as, dir2); d += src[ai2]; } else @@ -311,11 +311,11 @@ namespace DotRecast.Recast for (int dir = 0; dir < 4; ++dir) { // 8 connected - if (RecastCommon.GetCon(cs, dir) != RC_NOT_CONNECTED) + if (GetCon(cs, dir) != RC_NOT_CONNECTED) { - int ax = cx + RecastCommon.GetDirOffsetX(dir); - int ay = cy + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(cs, dir); + int ax = cx + GetDirOffsetX(dir); + int ay = cy + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(cs, dir); if (chf.areas[ai] != area) { continue; @@ -336,11 +336,11 @@ namespace DotRecast.Recast RcCompactSpan @as = chf.spans[ai]; int dir2 = (dir + 1) & 0x3; - if (RecastCommon.GetCon(@as, dir2) != RC_NOT_CONNECTED) + if (GetCon(@as, dir2) != RC_NOT_CONNECTED) { - int ax2 = ax + RecastCommon.GetDirOffsetX(dir2); - int ay2 = ay + RecastCommon.GetDirOffsetY(dir2); - int ai2 = chf.cells[ax2 + ay2 * w].index + RecastCommon.GetCon(@as, dir2); + int ax2 = ax + GetDirOffsetX(dir2); + int ay2 = ay + GetDirOffsetY(dir2); + int ai2 = chf.cells[ax2 + ay2 * w].index + GetCon(@as, dir2); if (chf.areas[ai2] != area) { continue; @@ -367,11 +367,11 @@ namespace DotRecast.Recast // Expand neighbours. for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(cs, dir) != RC_NOT_CONNECTED) + if (GetCon(cs, dir) != RC_NOT_CONNECTED) { - int ax = cx + RecastCommon.GetDirOffsetX(dir); - int ay = cy + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(cs, dir); + int ax = cx + GetDirOffsetX(dir); + int ay = cy + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(cs, dir); if (chf.areas[ai] != area) { continue; @@ -456,14 +456,14 @@ namespace DotRecast.Recast RcCompactSpan s = chf.spans[i]; for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(s, dir) == RC_NOT_CONNECTED) + if (GetCon(s, dir) == RC_NOT_CONNECTED) { continue; } - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); if (chf.areas[ai] != area) { continue; @@ -741,11 +741,11 @@ namespace DotRecast.Recast { RcCompactSpan s = chf.spans[i]; int r = 0; - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); r = srcReg[ai]; } @@ -765,11 +765,11 @@ namespace DotRecast.Recast RcCompactSpan ss = chf.spans[i]; int curReg = 0; - if (RecastCommon.GetCon(ss, dir) != RC_NOT_CONNECTED) + if (GetCon(ss, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(ss, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(ss, dir); curReg = srcReg[ai]; } @@ -784,11 +784,11 @@ namespace DotRecast.Recast { // Choose the edge corner int r = 0; - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * chf.width].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * chf.width].index + GetCon(s, dir); r = srcReg[ai]; } @@ -803,12 +803,12 @@ namespace DotRecast.Recast else { int ni = -1; - int nx = x + RecastCommon.GetDirOffsetX(dir); - int ny = y + RecastCommon.GetDirOffsetY(dir); - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + int nx = x + GetDirOffsetX(dir); + int ny = y + GetDirOffsetY(dir); + if (GetCon(s, dir) != RC_NOT_CONNECTED) { RcCompactCell nc = chf.cells[nx + ny * chf.width]; - ni = nc.index + RecastCommon.GetCon(s, dir); + ni = nc.index + GetCon(s, dir); } if (ni == -1) @@ -1215,11 +1215,11 @@ namespace DotRecast.Recast // Update neighbours for (int dir = 0; dir < 4; ++dir) { - if (RecastCommon.GetCon(s, dir) != RC_NOT_CONNECTED) + if (GetCon(s, dir) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(dir); - int ay = y + RecastCommon.GetDirOffsetY(dir); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, dir); + int ax = x + GetDirOffsetX(dir); + int ay = y + GetDirOffsetY(dir); + int ai = chf.cells[ax + ay * w].index + GetCon(s, dir); int rai = srcReg[ai]; if (rai > 0 && rai < nreg && rai != ri) { @@ -1543,11 +1543,11 @@ namespace DotRecast.Recast // -x int previd = 0; - if (RecastCommon.GetCon(s, 0) != RC_NOT_CONNECTED) + if (GetCon(s, 0) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(0); - int ay = y + RecastCommon.GetDirOffsetY(0); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 0); + int ax = x + GetDirOffsetX(0); + int ay = y + GetDirOffsetY(0); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) { previd = srcReg[ai]; @@ -1563,11 +1563,11 @@ namespace DotRecast.Recast } // -y - if (RecastCommon.GetCon(s, 3) != RC_NOT_CONNECTED) + if (GetCon(s, 3) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(3); - int ay = y + RecastCommon.GetDirOffsetY(3); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 3); + int ax = x + GetDirOffsetX(3); + int ay = y + GetDirOffsetY(3); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 3); if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) { int nr = srcReg[ai]; @@ -1843,11 +1843,11 @@ namespace DotRecast.Recast // -x int previd = 0; - if (RecastCommon.GetCon(s, 0) != RC_NOT_CONNECTED) + if (GetCon(s, 0) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(0); - int ay = y + RecastCommon.GetDirOffsetY(0); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 0); + int ax = x + GetDirOffsetX(0); + int ay = y + GetDirOffsetY(0); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 0); if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) { previd = srcReg[ai]; @@ -1863,11 +1863,11 @@ namespace DotRecast.Recast } // -y - if (RecastCommon.GetCon(s, 3) != RC_NOT_CONNECTED) + if (GetCon(s, 3) != RC_NOT_CONNECTED) { - int ax = x + RecastCommon.GetDirOffsetX(3); - int ay = y + RecastCommon.GetDirOffsetY(3); - int ai = chf.cells[ax + ay * w].index + RecastCommon.GetCon(s, 3); + int ax = x + GetDirOffsetX(3); + int ay = y + GetDirOffsetY(3); + int ai = chf.cells[ax + ay * w].index + GetCon(s, 3); if (srcReg[ai] != 0 && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai]) { int nr = srcReg[ai]; diff --git a/src/DotRecast.Recast/RecastVoxelization.cs b/src/DotRecast.Recast/RcVoxelizations.cs similarity index 81% rename from src/DotRecast.Recast/RecastVoxelization.cs rename to src/DotRecast.Recast/RcVoxelizations.cs index c7efcd6..5617ca1 100644 --- a/src/DotRecast.Recast/RecastVoxelization.cs +++ b/src/DotRecast.Recast/RcVoxelizations.cs @@ -23,9 +23,9 @@ using DotRecast.Recast.Geom; namespace DotRecast.Recast { - public static class RecastVoxelization + public static class RcVoxelizations { - public static RcHeightfield BuildSolidHeightfield(IInputGeomProvider geomProvider, RecastBuilderConfig builderCfg, RcTelemetry ctx) + public static RcHeightfield BuildSolidHeightfield(IInputGeomProvider geomProvider, RcBuilderConfig builderCfg, RcTelemetry ctx) { RcConfig cfg = builderCfg.cfg; @@ -58,16 +58,16 @@ namespace DotRecast.Recast { int[] tris = node.tris; int ntris = tris.Length / 3; - int[] m_triareas = RcUtils.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); - RecastRasterization.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx); + int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); + RcRasterizations.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx); } } else { int[] tris = geom.GetTris(); int ntris = tris.Length / 3; - int[] m_triareas = RcUtils.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); - RecastRasterization.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx); + int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); + RcRasterizations.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx); } } diff --git a/src/DotRecast.Recast/RecastCommon.cs b/src/DotRecast.Recast/RecastCommon.cs deleted file mode 100644 index 1da3138..0000000 --- a/src/DotRecast.Recast/RecastCommon.cs +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (c) 2009-2010 Mikko Mononen memon@inside.org -recast4j copyright (c) 2015-2019 Piotr Piastucki piotr@jtilia.org -DotRecast Copyright (c) 2023 Choi Ikpil ikpil@naver.com - -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. -*/ - -using System; - -namespace DotRecast.Recast -{ - public static class RecastCommon - { - private static readonly int[] DirOffsetX = { -1, 0, 1, 0, }; - private static readonly int[] DirOffsetY = { 0, 1, 0, -1 }; - private static readonly int[] DirForOffset = { 3, 0, -1, 2, 1 }; - - /// Sets the neighbor connection data for the specified direction. - /// @param[in] span The span to update. - /// @param[in] direction The direction to set. [Limits: 0 <= value < 4] - /// @param[in] neighborIndex The index of the neighbor span. - public static void SetCon(RcCompactSpan span, int direction, int neighborIndex) - { - int shift = direction * 6; - int con = span.con; - span.con = (con & ~(0x3f << shift)) | ((neighborIndex & 0x3f) << shift); - } - - /// Gets neighbor connection data for the specified direction. - /// @param[in] span The span to check. - /// @param[in] direction The direction to check. [Limits: 0 <= value < 4] - /// @return The neighbor connection data for the specified direction, or #RC_NOT_CONNECTED if there is no connection. - public static int GetCon(RcCompactSpan s, int dir) - { - int shift = dir * 6; - return (s.con >> shift) & 0x3f; - } - - /// Gets the standard width (x-axis) offset for the specified direction. - /// @param[in] direction The direction. [Limits: 0 <= value < 4] - /// @return The width offset to apply to the current cell position to move in the direction. - public static int GetDirOffsetX(int dir) - { - return DirOffsetX[dir & 0x03]; - } - - // TODO (graham): Rename this to rcGetDirOffsetZ - /// Gets the standard height (z-axis) offset for the specified direction. - /// @param[in] direction The direction. [Limits: 0 <= value < 4] - /// @return The height offset to apply to the current cell position to move in the direction. - public static int GetDirOffsetY(int dir) - { - return DirOffsetY[dir & 0x03]; - } - - /// Gets the direction for the specified offset. One of x and y should be 0. - /// @param[in] offsetX The x offset. [Limits: -1 <= value <= 1] - /// @param[in] offsetZ The z offset. [Limits: -1 <= value <= 1] - /// @return The direction that represents the offset. - public static int GetDirForOffset(int x, int y) - { - return DirForOffset[((y + 1) << 1) + x]; - } - } -} \ No newline at end of file diff --git a/test/DotRecast.Detour.Crowd.Test/RecastTestMeshBuilder.cs b/test/DotRecast.Detour.Crowd.Test/RecastTestMeshBuilder.cs index 1b97d5e..359391e 100644 --- a/test/DotRecast.Detour.Crowd.Test/RecastTestMeshBuilder.cs +++ b/test/DotRecast.Detour.Crowd.Test/RecastTestMeshBuilder.cs @@ -70,9 +70,9 @@ public class RecastTestMeshBuilder detailSampleDist, detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); - RecastBuilder rcBuilder = new RecastBuilder(); - RecastBuilderResult rcResult = rcBuilder.Build(geom, bcfg); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); + RcBuilder rcBuilder = new RcBuilder(); + RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg); RcPolyMesh m_pmesh = rcResult.GetMesh(); for (int i = 0; i < m_pmesh.npolys; ++i) { diff --git a/test/DotRecast.Detour.Test/Io/MeshSetReaderWriterTest.cs b/test/DotRecast.Detour.Test/Io/MeshSetReaderWriterTest.cs index 0e14f3b..87088cf 100644 --- a/test/DotRecast.Detour.Test/Io/MeshSetReaderWriterTest.cs +++ b/test/DotRecast.Detour.Test/Io/MeshSetReaderWriterTest.cs @@ -69,7 +69,7 @@ public class MeshSetReaderWriterTest RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcTileCount(bmin, bmax, m_cellSize, m_tileSize, m_tileSize, out var tw, out var th); + RcCommons.CalcTileCount(bmin, bmax, m_cellSize, m_tileSize, m_tileSize, out var tw, out var th); for (int y = 0; y < th; ++y) { for (int x = 0; x < tw; ++x) @@ -85,7 +85,7 @@ public class MeshSetReaderWriterTest m_detailSampleDist, m_detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, bmin, bmax, x, y); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, bmin, bmax, x, y); TestDetourBuilder db = new TestDetourBuilder(); DtMeshData data = db.Build(geom, bcfg, m_agentHeight, m_agentRadius, m_agentMaxClimb, x, y, true); if (data != null) diff --git a/test/DotRecast.Detour.Test/RecastTestMeshBuilder.cs b/test/DotRecast.Detour.Test/RecastTestMeshBuilder.cs index e1d455f..9978bc7 100644 --- a/test/DotRecast.Detour.Test/RecastTestMeshBuilder.cs +++ b/test/DotRecast.Detour.Test/RecastTestMeshBuilder.cs @@ -70,9 +70,9 @@ public class RecastTestMeshBuilder detailSampleDist, detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); - RecastBuilder rcBuilder = new RecastBuilder(); - RecastBuilderResult rcResult = rcBuilder.Build(geom, bcfg); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax()); + RcBuilder rcBuilder = new RcBuilder(); + RcBuilderResult rcResult = rcBuilder.Build(geom, bcfg); RcPolyMesh m_pmesh = rcResult.GetMesh(); for (int i = 0; i < m_pmesh.npolys; ++i) { diff --git a/test/DotRecast.Detour.Test/TestDetourBuilder.cs b/test/DotRecast.Detour.Test/TestDetourBuilder.cs index 8a50f65..0611b8e 100644 --- a/test/DotRecast.Detour.Test/TestDetourBuilder.cs +++ b/test/DotRecast.Detour.Test/TestDetourBuilder.cs @@ -23,11 +23,11 @@ namespace DotRecast.Detour.Test; public class TestDetourBuilder : DetourBuilder { - public DtMeshData Build(IInputGeomProvider geom, RecastBuilderConfig rcConfig, float agentHeight, float agentRadius, + public DtMeshData Build(IInputGeomProvider geom, RcBuilderConfig rcConfig, float agentHeight, float agentRadius, float agentMaxClimb, int x, int y, bool applyRecastDemoFlags) { - RecastBuilder rcBuilder = new RecastBuilder(); - RecastBuilderResult rcResult = rcBuilder.Build(geom, rcConfig); + RcBuilder rcBuilder = new RcBuilder(); + RcBuilderResult rcResult = rcBuilder.Build(geom, rcConfig); RcPolyMesh pmesh = rcResult.GetMesh(); if (applyRecastDemoFlags) diff --git a/test/DotRecast.Detour.Test/TestTiledNavMeshBuilder.cs b/test/DotRecast.Detour.Test/TestTiledNavMeshBuilder.cs index 5da4717..fed6d55 100644 --- a/test/DotRecast.Detour.Test/TestTiledNavMeshBuilder.cs +++ b/test/DotRecast.Detour.Test/TestTiledNavMeshBuilder.cs @@ -77,12 +77,12 @@ public class TestTiledNavMeshBuilder detailSampleDist, detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilder rcBuilder = new RecastBuilder(); - List rcResult = rcBuilder.BuildTiles(geom, cfg, null); + RcBuilder rcBuilder = new RcBuilder(); + List rcResult = rcBuilder.BuildTiles(geom, cfg, null); // Add tiles to nav mesh - foreach (RecastBuilderResult result in rcResult) + foreach (RcBuilderResult result in rcResult) { RcPolyMesh pmesh = result.GetMesh(); if (pmesh.npolys == 0) diff --git a/test/DotRecast.Detour.TileCache.Test/AbstractTileCacheTest.cs b/test/DotRecast.Detour.TileCache.Test/AbstractTileCacheTest.cs index 9266838..b714709 100644 --- a/test/DotRecast.Detour.TileCache.Test/AbstractTileCacheTest.cs +++ b/test/DotRecast.Detour.TileCache.Test/AbstractTileCacheTest.cs @@ -46,7 +46,7 @@ public class AbstractTileCacheTest public DtTileCache GetTileCache(IInputGeomProvider geom, RcByteOrder order, bool cCompatibility) { DtTileCacheParams option = new DtTileCacheParams(); - RcUtils.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th); + RcCommons.CalcTileCount(geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), m_cellSize, m_tileSize, m_tileSize, out var tw, out var th); option.ch = m_cellHeight; option.cs = m_cellSize; option.orig = geom.GetMeshBoundsMin(); diff --git a/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs b/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs index f56dc08..282eaa3 100644 --- a/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs +++ b/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs @@ -73,7 +73,7 @@ public class TestTileLayerBuilder : DtTileCacheLayerBuilder RcVec3f bmin = geom.GetMeshBoundsMin(); RcVec3f bmax = geom.GetMeshBoundsMax(); - RcUtils.CalcTileCount(bmin, bmax, CellSize, m_tileSize, m_tileSize, out tw, out th); + RcCommons.CalcTileCount(bmin, bmax, CellSize, m_tileSize, m_tileSize, out tw, out th); } public List Build(RcByteOrder order, bool cCompatibility, int threads) diff --git a/test/DotRecast.Recast.Test/RecastLayersTest.cs b/test/DotRecast.Recast.Test/RecastLayersTest.cs index dc986bf..ed1b2d1 100644 --- a/test/DotRecast.Recast.Test/RecastLayersTest.cs +++ b/test/DotRecast.Recast.Test/RecastLayersTest.cs @@ -146,7 +146,7 @@ public class RecastLayersTest private RcHeightfieldLayerSet Build(string filename, int x, int y) { IInputGeomProvider geom = ObjImporter.Load(RcResources.Load(filename)); - RecastBuilder builder = new RecastBuilder(); + RcBuilder builder = new RcBuilder(); RcConfig cfg = new RcConfig(true, m_tileSize, m_tileSize, RcConfig.CalcBorder(m_agentRadius, m_cellSize), RcPartitionType.OfValue(m_partitionType), @@ -158,7 +158,7 @@ public class RecastLayersTest m_detailSampleDist, m_detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), x, y); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), x, y); RcHeightfieldLayerSet lset = builder.BuildLayers(geom, bcfg); return lset; } diff --git a/test/DotRecast.Recast.Test/RecastSoloMeshTest.cs b/test/DotRecast.Recast.Test/RecastSoloMeshTest.cs index 6c2f6a8..41128c6 100644 --- a/test/DotRecast.Recast.Test/RecastSoloMeshTest.cs +++ b/test/DotRecast.Recast.Test/RecastSoloMeshTest.cs @@ -26,6 +26,7 @@ using NUnit.Framework; namespace DotRecast.Recast.Test; using static RcConstants; +using static RcAreas; [Parallelizable] public class RecastSoloMeshTest @@ -116,7 +117,7 @@ public class RecastSoloMeshTest m_detailSampleDist, m_detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, bmin, bmax); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, bmin, bmax); // // Step 2. Rasterize input polygon soup. @@ -138,8 +139,8 @@ public class RecastSoloMeshTest // Find triangles which are walkable based on their slope and rasterize them. // If your input data is multiple meshes, you can transform them here, calculate // the are type for each of the meshes and rasterize them. - int[] m_triareas = RcUtils.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); - RecastRasterization.RasterizeTriangles(m_solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, m_ctx); + int[] m_triareas = RcCommons.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod); + RcRasterizations.RasterizeTriangles(m_solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, m_ctx); } // @@ -149,9 +150,9 @@ public class RecastSoloMeshTest // Once all geometry is rasterized, we do initial pass of filtering to // remove unwanted overhangs caused by the conservative rasterization // as well as filter spans where the character cannot possibly stand. - RecastFilter.FilterLowHangingWalkableObstacles(m_ctx, cfg.WalkableClimb, m_solid); - RecastFilter.FilterLedgeSpans(m_ctx, cfg.WalkableHeight, cfg.WalkableClimb, m_solid); - RecastFilter.FilterWalkableLowHeightSpans(m_ctx, cfg.WalkableHeight, m_solid); + RcFilters.FilterLowHangingWalkableObstacles(m_ctx, cfg.WalkableClimb, m_solid); + RcFilters.FilterLedgeSpans(m_ctx, cfg.WalkableHeight, cfg.WalkableClimb, m_solid); + RcFilters.FilterWalkableLowHeightSpans(m_ctx, cfg.WalkableHeight, m_solid); // // Step 4. Partition walkable surface to simple regions. @@ -160,11 +161,10 @@ public class RecastSoloMeshTest // Compact the heightfield so that it is faster to handle from now on. // This will result more cache coherent data as well as the neighbours // between walkable cells will be calculated. - RcCompactHeightfield m_chf = RecastCompact.BuildCompactHeightfield(m_ctx, cfg.WalkableHeight, cfg.WalkableClimb, - m_solid); + RcCompactHeightfield m_chf = RcCompacts.BuildCompactHeightfield(m_ctx, cfg.WalkableHeight, cfg.WalkableClimb, m_solid); // Erode the walkable area by agent radius. - RecastArea.ErodeWalkableArea(m_ctx, cfg.WalkableRadius, m_chf); + ErodeWalkableArea(m_ctx, cfg.WalkableRadius, m_chf); // (Optional) Mark areas. /* @@ -216,20 +216,20 @@ public class RecastSoloMeshTest { // Prepare for region partitioning, by calculating distance field // along the walkable surface. - RecastRegion.BuildDistanceField(m_ctx, m_chf); + RcRegions.BuildDistanceField(m_ctx, m_chf); // Partition the walkable surface into simple regions without holes. - RecastRegion.BuildRegions(m_ctx, m_chf, cfg.MinRegionArea, cfg.MergeRegionArea); + RcRegions.BuildRegions(m_ctx, m_chf, cfg.MinRegionArea, cfg.MergeRegionArea); } else if (m_partitionType == RcPartition.MONOTONE) { // Partition the walkable surface into simple regions without holes. // Monotone partitioning does not need distancefield. - RecastRegion.BuildRegionsMonotone(m_ctx, m_chf, cfg.MinRegionArea, cfg.MergeRegionArea); + RcRegions.BuildRegionsMonotone(m_ctx, m_chf, cfg.MinRegionArea, cfg.MergeRegionArea); } else { // Partition the walkable surface into simple regions without holes. - RecastRegion.BuildLayerRegions(m_ctx, m_chf, cfg.MinRegionArea); + RcRegions.BuildLayerRegions(m_ctx, m_chf, cfg.MinRegionArea); } Assert.That(m_chf.maxDistance, Is.EqualTo(expDistance), "maxDistance"); @@ -239,7 +239,7 @@ public class RecastSoloMeshTest // // Create contours. - RcContourSet m_cset = RecastContour.BuildContours(m_ctx, m_chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen, + RcContourSet m_cset = RcContours.BuildContours(m_ctx, m_chf, cfg.MaxSimplificationError, cfg.MaxEdgeLen, RcConstants.RC_CONTOUR_TESS_WALL_EDGES); Assert.That(m_cset.conts.Count, Is.EqualTo(expContours), "Contours"); @@ -248,7 +248,7 @@ public class RecastSoloMeshTest // // Build polygon navmesh from the contours. - RcPolyMesh m_pmesh = RecastMesh.BuildPolyMesh(m_ctx, m_cset, cfg.MaxVertsPerPoly); + RcPolyMesh m_pmesh = RcMeshs.BuildPolyMesh(m_ctx, m_cset, cfg.MaxVertsPerPoly); Assert.That(m_pmesh.nverts, Is.EqualTo(expVerts), "Mesh Verts"); Assert.That(m_pmesh.npolys, Is.EqualTo(expPolys), "Mesh Polys"); @@ -257,7 +257,7 @@ public class RecastSoloMeshTest // on each polygon. // - RcPolyMeshDetail m_dmesh = RecastMeshDetail.BuildPolyMeshDetail(m_ctx, m_pmesh, m_chf, cfg.DetailSampleDist, + RcPolyMeshDetail m_dmesh = RcMeshDetails.BuildPolyMeshDetail(m_ctx, m_pmesh, m_chf, cfg.DetailSampleDist, cfg.DetailSampleMaxError); Assert.That(m_dmesh.nmeshes, Is.EqualTo(expDetMeshes), "Mesh Detail Meshes"); Assert.That(m_dmesh.nverts, Is.EqualTo(expDetVerts), "Mesh Detail Verts"); diff --git a/test/DotRecast.Recast.Test/RecastTest.cs b/test/DotRecast.Recast.Test/RecastTest.cs index 921f112..bddd08d 100644 --- a/test/DotRecast.Recast.Test/RecastTest.cs +++ b/test/DotRecast.Recast.Test/RecastTest.cs @@ -39,18 +39,18 @@ public class RecastTest RcTelemetry ctx = new RcTelemetry(); { int[] areas = { 42 }; - RcUtils.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas); + RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, unwalkable_tri, nt, areas); Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Sets area ID of unwalkable triangle to RC_NULL_AREA"); } { int[] areas = { 42 }; - RcUtils.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas); + RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas); Assert.That(areas[0], Is.EqualTo(42), "Does not modify walkable triangle aread ID's"); } { int[] areas = { 42 }; walkableSlopeAngle = 0; - RcUtils.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas); + RcCommons.ClearUnwalkableTriangles(ctx, walkableSlopeAngle, verts, nv, walkable_tri, nt, areas); Assert.That(areas[0], Is.EqualTo(RC_NULL_AREA), "Slopes equal to the max slope are considered unwalkable."); } } diff --git a/test/DotRecast.Recast.Test/RecastTileMeshTest.cs b/test/DotRecast.Recast.Test/RecastTileMeshTest.cs index 3d80208..95084da 100644 --- a/test/DotRecast.Recast.Test/RecastTileMeshTest.cs +++ b/test/DotRecast.Recast.Test/RecastTileMeshTest.cs @@ -59,7 +59,7 @@ public class RecastTileMeshTest public void TestBuild(string filename) { IInputGeomProvider geom = ObjImporter.Load(RcResources.Load(filename)); - RecastBuilder builder = new RecastBuilder(); + RcBuilder builder = new RcBuilder(); RcConfig cfg = new RcConfig( true, m_tileSize, m_tileSize, RcConfig.CalcBorder(m_agentRadius, m_cellSize), m_partitionType, @@ -71,27 +71,27 @@ public class RecastTileMeshTest m_detailSampleDist, m_detailSampleMaxError, true, true, true, SampleAreaModifications.SAMPLE_AREAMOD_GROUND, true); - RecastBuilderConfig bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 7, 8); - RecastBuilderResult rcResult = builder.Build(geom, bcfg); + RcBuilderConfig bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 7, 8); + RcBuilderResult rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(1)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(5)); - bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 6, 9); + bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 6, 9); rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(7)); - bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 9); + bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 9); rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(2)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(9)); - bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 4, 3); + bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 4, 3); rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(3)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(6)); - bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 8); + bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 2, 8); rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(5)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(17)); - bcfg = new RecastBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 0, 8); + bcfg = new RcBuilderConfig(cfg, geom.GetMeshBoundsMin(), geom.GetMeshBoundsMax(), 0, 8); rcResult = builder.Build(geom, bcfg); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(6)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(15)); @@ -101,7 +101,7 @@ public class RecastTileMeshTest public void TestPerformance() { IInputGeomProvider geom = ObjImporter.Load(RcResources.Load("dungeon.obj")); - RecastBuilder builder = new RecastBuilder(); + RcBuilder builder = new RcBuilder(); RcConfig cfg = new RcConfig( true, m_tileSize, m_tileSize, RcConfig.CalcBorder(m_agentRadius, m_cellSize), @@ -137,14 +137,14 @@ public class RecastTileMeshTest Console.WriteLine(" Time MT : " + (t3 - t2) / TimeSpan.TicksPerMillisecond); } - private void Build(IInputGeomProvider geom, RecastBuilder builder, RcConfig cfg, int threads, bool validate) + private void Build(IInputGeomProvider geom, RcBuilder builder, RcConfig cfg, int threads, bool validate) { CancellationTokenSource cts = new CancellationTokenSource(); - List tiles = new(); + List tiles = new(); var task = builder.BuildTilesAsync(geom, cfg, threads, tiles, Task.Factory, cts.Token); if (validate) { - RecastBuilderResult rcResult = GetTile(tiles, 7, 8); + RcBuilderResult rcResult = GetTile(tiles, 7, 8); Assert.That(rcResult.GetMesh().npolys, Is.EqualTo(1)); Assert.That(rcResult.GetMesh().nverts, Is.EqualTo(5)); rcResult = GetTile(tiles, 6, 9); @@ -175,7 +175,7 @@ public class RecastTileMeshTest } } - private RecastBuilderResult GetTile(List tiles, int x, int z) + private RcBuilderResult GetTile(List tiles, int x, int z) { return tiles.FirstOrDefault(tile => tile.tileX == x && tile.tileZ == z); }