diff --git a/src/DotRecast.Core/IntersectResult.cs b/src/DotRecast.Core/IntersectResult.cs new file mode 100644 index 0000000..1bf8ba4 --- /dev/null +++ b/src/DotRecast.Core/IntersectResult.cs @@ -0,0 +1,11 @@ +namespace DotRecast.Core +{ + public class IntersectResult + { + public bool intersects; + public float tmin; + public float tmax = 1f; + public int segMin = -1; + public int segMax = -1; + } +} \ No newline at end of file diff --git a/src/DotRecast.Core/RecastMath.cs b/src/DotRecast.Core/RecastMath.cs index 4f96b57..a162577 100644 --- a/src/DotRecast.Core/RecastMath.cs +++ b/src/DotRecast.Core/RecastMath.cs @@ -810,14 +810,7 @@ namespace DotRecast.Core return r; } - public class IntersectResult - { - public bool intersects; - public float tmin; - public float tmax = 1f; - public int segMin = -1; - public int segMax = -1; - } + public static IntersectResult IntersectSegmentPoly2D(Vector3f p0, Vector3f p1, float[] verts, int nverts) { diff --git a/src/DotRecast.Detour.Crowd/Crowd.cs b/src/DotRecast.Detour.Crowd/Crowd.cs index 5a8272e..ee14e57 100644 --- a/src/DotRecast.Detour.Crowd/Crowd.cs +++ b/src/DotRecast.Detour.Crowd/Crowd.cs @@ -901,7 +901,7 @@ namespace DotRecast.Detour.Crowd _telemetry.Stop("buildNeighbours"); } - + private List GetNeighbours(Vector3f pos, float height, float range, CrowdAgent skip, ProximityGrid grid) { @@ -1373,23 +1373,5 @@ namespace DotRecast.Detour.Crowd { return Clamp((t - t0) / (t1 - t0), 0.0f, 1.0f); } - - /// Provides neighbor data for agents managed by the crowd. - /// @ingroup crowd - /// @see dtCrowdAgent::neis, dtCrowd - public class CrowdNeighbour - { - public readonly CrowdAgent agent; - - /// < The index of the neighbor in the crowd. - public readonly float dist; - - /// < The distance between the current agent and the neighbor. - public CrowdNeighbour(CrowdAgent agent, float dist) - { - this.agent = agent; - this.dist = dist; - } - }; } } \ No newline at end of file diff --git a/src/DotRecast.Detour.Crowd/CrowdAgent.cs b/src/DotRecast.Detour.Crowd/CrowdAgent.cs index de44f62..8635926 100644 --- a/src/DotRecast.Detour.Crowd/CrowdAgent.cs +++ b/src/DotRecast.Detour.Crowd/CrowdAgent.cs @@ -73,7 +73,7 @@ namespace DotRecast.Detour.Crowd public float topologyOptTime; /// The known neighbors of the agent. - public List neis = new List(); + public List neis = new List(); /// The desired speed. public float desiredSpeed; diff --git a/src/DotRecast.Detour.Crowd/CrowdNeighbour.cs b/src/DotRecast.Detour.Crowd/CrowdNeighbour.cs new file mode 100644 index 0000000..33411f6 --- /dev/null +++ b/src/DotRecast.Detour.Crowd/CrowdNeighbour.cs @@ -0,0 +1,20 @@ +namespace DotRecast.Detour.Crowd +{ + /// Provides neighbor data for agents managed by the crowd. + /// @ingroup crowd + /// @see dtCrowdAgent::neis, dtCrowd + public class CrowdNeighbour + { + public readonly CrowdAgent agent; + + /// < The index of the neighbor in the crowd. + public readonly float dist; + + /// < The distance between the current agent and the neighbor. + public CrowdNeighbour(CrowdAgent agent, float dist) + { + this.agent = agent; + this.dist = dist; + } + }; +} \ No newline at end of file diff --git a/src/DotRecast.Detour.Crowd/ObstacleAvoidanceQuery.cs b/src/DotRecast.Detour.Crowd/ObstacleAvoidanceQuery.cs index 3b2224a..3f853cc 100644 --- a/src/DotRecast.Detour.Crowd/ObstacleAvoidanceQuery.cs +++ b/src/DotRecast.Detour.Crowd/ObstacleAvoidanceQuery.cs @@ -33,38 +33,6 @@ namespace DotRecast.Detour.Crowd /// < Max numver of adaptive divs. public const int DT_MAX_PATTERN_RINGS = 4; - /// < Max number of adaptive rings. - public class ObstacleCircle - { - /** Position of the obstacle */ - public Vector3f p = new Vector3f(); - - /** Velocity of the obstacle */ - public Vector3f vel = new Vector3f(); - - /** Velocity of the obstacle */ - public Vector3f dvel = new Vector3f(); - - /** Radius of the obstacle */ - public float rad; - - /** Use for side selection during sampling. */ - public Vector3f dp = new Vector3f(); - - /** Use for side selection during sampling. */ - public Vector3f np = new Vector3f(); - } - - public class ObstacleSegment - { - /** End points of the obstacle segment */ - public Vector3f p = new Vector3f(); - - /** End points of the obstacle segment */ - public Vector3f q = new Vector3f(); - - public bool touch; - } private ObstacleAvoidanceParams m_params; private float m_invHorizTime; @@ -214,16 +182,16 @@ namespace DotRecast.Detour.Crowd float d = VPerp2D(u, v); if (Math.Abs(d) < 1e-6f) return new IsectRaySegResult(false, 0f); - + d = 1.0f / d; float t = VPerp2D(v, w) * d; if (t < 0 || t > 1) return new IsectRaySegResult(false, 0f); - + float s = VPerp2D(u, w) * d; if (s < 0 || s > 1) return new IsectRaySegResult(false, 0f); - + return new IsectRaySegResult(true, t); } @@ -316,7 +284,7 @@ namespace DotRecast.Detour.Crowd var ires = IsectRaySeg(pos, vcand, seg.p, seg.q); if (!ires.result) continue; - + htmin = ires.htmin; } diff --git a/src/DotRecast.Detour.Crowd/ObstacleCircle.cs b/src/DotRecast.Detour.Crowd/ObstacleCircle.cs new file mode 100644 index 0000000..4d9ed7e --- /dev/null +++ b/src/DotRecast.Detour.Crowd/ObstacleCircle.cs @@ -0,0 +1,26 @@ +using DotRecast.Core; + +namespace DotRecast.Detour.Crowd +{ + /// < Max number of adaptive rings. + public class ObstacleCircle + { + /** Position of the obstacle */ + public Vector3f p = new Vector3f(); + + /** Velocity of the obstacle */ + public Vector3f vel = new Vector3f(); + + /** Velocity of the obstacle */ + public Vector3f dvel = new Vector3f(); + + /** Radius of the obstacle */ + public float rad; + + /** Use for side selection during sampling. */ + public Vector3f dp = new Vector3f(); + + /** Use for side selection during sampling. */ + public Vector3f np = new Vector3f(); + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour.Crowd/ObstacleSegment.cs b/src/DotRecast.Detour.Crowd/ObstacleSegment.cs new file mode 100644 index 0000000..d256c10 --- /dev/null +++ b/src/DotRecast.Detour.Crowd/ObstacleSegment.cs @@ -0,0 +1,15 @@ +using DotRecast.Core; + +namespace DotRecast.Detour.Crowd +{ + public class ObstacleSegment + { + /** End points of the obstacle segment */ + public Vector3f p = new Vector3f(); + + /** End points of the obstacle segment */ + public Vector3f q = new Vector3f(); + + public bool touch; + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour/IPolygonByCircleConstraint.cs b/src/DotRecast.Detour/IPolygonByCircleConstraint.cs index 1e79d9f..6b1a152 100644 --- a/src/DotRecast.Detour/IPolygonByCircleConstraint.cs +++ b/src/DotRecast.Detour/IPolygonByCircleConstraint.cs @@ -21,7 +21,6 @@ using DotRecast.Core; namespace DotRecast.Detour { - using static DotRecast.Core.RecastMath; public interface IPolygonByCircleConstraint { @@ -36,77 +35,5 @@ namespace DotRecast.Detour { return new StrictPolygonByCircleConstraint(); } - - public class NoOpPolygonByCircleConstraint : IPolygonByCircleConstraint - { - public float[] Aply(float[] polyVerts, Vector3f circleCenter, float radius) - { - return polyVerts; - } - } - - /** - * Calculate the intersection between a polygon and a circle. A dodecagon is used as an approximation of the circle. - */ - public class StrictPolygonByCircleConstraint : IPolygonByCircleConstraint - { - private const int CIRCLE_SEGMENTS = 12; - private static float[] unitCircle; - - public float[] Aply(float[] verts, Vector3f center, float radius) - { - float radiusSqr = radius * radius; - int outsideVertex = -1; - for (int pv = 0; pv < verts.Length; pv += 3) - { - if (VDist2DSqr(center, verts, pv) > radiusSqr) - { - outsideVertex = pv; - break; - } - } - - if (outsideVertex == -1) - { - // polygon inside circle - return verts; - } - - float[] qCircle = Circle(center, radius); - float[] intersection = ConvexConvexIntersection.Intersect(verts, qCircle); - if (intersection == null && PointInPolygon(center, verts, verts.Length / 3)) - { - // circle inside polygon - return qCircle; - } - - return intersection; - } - - private float[] Circle(Vector3f center, float radius) - { - if (unitCircle == null) - { - unitCircle = new float[CIRCLE_SEGMENTS * 3]; - for (int i = 0; i < CIRCLE_SEGMENTS; i++) - { - double a = i * Math.PI * 2 / CIRCLE_SEGMENTS; - unitCircle[3 * i] = (float)Math.Cos(a); - unitCircle[3 * i + 1] = 0; - unitCircle[3 * i + 2] = (float)-Math.Sin(a); - } - } - - float[] circle = new float[12 * 3]; - for (int i = 0; i < CIRCLE_SEGMENTS * 3; i += 3) - { - circle[i] = unitCircle[i] * radius + center.x; - circle[i + 1] = center.y; - circle[i + 2] = unitCircle[i + 2] * radius + center.z; - } - - return circle; - } - } } } \ No newline at end of file diff --git a/src/DotRecast.Detour/NavMeshQuery.cs b/src/DotRecast.Detour/NavMeshQuery.cs index 39c55a8..8195983 100644 --- a/src/DotRecast.Detour/NavMeshQuery.cs +++ b/src/DotRecast.Detour/NavMeshQuery.cs @@ -2993,18 +2993,6 @@ namespace DotRecast.Detour return Results.Success(new FindLocalNeighbourhoodResult(resultRef, resultParent)); } - public class SegInterval - { - public long refs; - public int tmin, tmax; - - public SegInterval(long refs, int tmin, int tmax) - { - this.refs = refs; - this.tmin = tmin; - this.tmax = tmax; - } - } protected void InsertInterval(List ints, int tmin, int tmax, long refs) { diff --git a/src/DotRecast.Detour/NoOpPolygonByCircleConstraint.cs b/src/DotRecast.Detour/NoOpPolygonByCircleConstraint.cs new file mode 100644 index 0000000..b951200 --- /dev/null +++ b/src/DotRecast.Detour/NoOpPolygonByCircleConstraint.cs @@ -0,0 +1,12 @@ +using DotRecast.Core; + +namespace DotRecast.Detour +{ + public class NoOpPolygonByCircleConstraint : IPolygonByCircleConstraint + { + public float[] Aply(float[] polyVerts, Vector3f circleCenter, float radius) + { + return polyVerts; + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour/SegInterval.cs b/src/DotRecast.Detour/SegInterval.cs new file mode 100644 index 0000000..45d176d --- /dev/null +++ b/src/DotRecast.Detour/SegInterval.cs @@ -0,0 +1,16 @@ +namespace DotRecast.Detour +{ + public class SegInterval + { + public long refs; + public int tmin; + public int tmax; + + public SegInterval(long refs, int tmin, int tmax) + { + this.refs = refs; + this.tmin = tmin; + this.tmax = tmax; + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Detour/StrictPolygonByCircleConstraint.cs b/src/DotRecast.Detour/StrictPolygonByCircleConstraint.cs new file mode 100644 index 0000000..ce39637 --- /dev/null +++ b/src/DotRecast.Detour/StrictPolygonByCircleConstraint.cs @@ -0,0 +1,71 @@ +using System; +using DotRecast.Core; + +namespace DotRecast.Detour +{ + using static DotRecast.Core.RecastMath; + + /** + * Calculate the intersection between a polygon and a circle. A dodecagon is used as an approximation of the circle. + */ + public class StrictPolygonByCircleConstraint : IPolygonByCircleConstraint + { + private const int CIRCLE_SEGMENTS = 12; + private static float[] unitCircle; + + public float[] Aply(float[] verts, Vector3f center, float radius) + { + float radiusSqr = radius * radius; + int outsideVertex = -1; + for (int pv = 0; pv < verts.Length; pv += 3) + { + if (VDist2DSqr(center, verts, pv) > radiusSqr) + { + outsideVertex = pv; + break; + } + } + + if (outsideVertex == -1) + { + // polygon inside circle + return verts; + } + + float[] qCircle = Circle(center, radius); + float[] intersection = ConvexConvexIntersection.Intersect(verts, qCircle); + if (intersection == null && PointInPolygon(center, verts, verts.Length / 3)) + { + // circle inside polygon + return qCircle; + } + + return intersection; + } + + private float[] Circle(Vector3f center, float radius) + { + if (unitCircle == null) + { + unitCircle = new float[CIRCLE_SEGMENTS * 3]; + for (int i = 0; i < CIRCLE_SEGMENTS; i++) + { + double a = i * Math.PI * 2 / CIRCLE_SEGMENTS; + unitCircle[3 * i] = (float)Math.Cos(a); + unitCircle[3 * i + 1] = 0; + unitCircle[3 * i + 2] = (float)-Math.Sin(a); + } + } + + float[] circle = new float[12 * 3]; + for (int i = 0; i < CIRCLE_SEGMENTS * 3; i += 3) + { + circle[i] = unitCircle[i] * radius + center.x; + circle[i + 1] = center.y; + circle[i + 2] = unitCircle[i + 2] * radius + center.z; + } + + return circle; + } + } +} \ No newline at end of file diff --git a/src/DotRecast.Recast/HeightfieldLayer.cs b/src/DotRecast.Recast/HeightfieldLayer.cs new file mode 100644 index 0000000..e771709 --- /dev/null +++ b/src/DotRecast.Recast/HeightfieldLayer.cs @@ -0,0 +1,53 @@ +using DotRecast.Core; + +namespace DotRecast.Recast +{ + /// Represents a heightfield layer within a layer set. + /// @see rcHeightfieldLayerSet + public class HeightfieldLayer + { + public Vector3f bmin = new Vector3f(); + + /// < The minimum bounds in world space. [(x, y, z)] + public Vector3f bmax = new Vector3f(); + + /// < The maximum bounds in world space. [(x, y, z)] + public float cs; + + /// < The size of each cell. (On the xz-plane.) + public float ch; + + /// < The height of each cell. (The minimum increment along the y-axis.) + public int width; + + /// < The width of the heightfield. (Along the x-axis in cell units.) + public int height; + + /// < The height of the heightfield. (Along the z-axis in cell units.) + public int minx; + + /// < The minimum x-bounds of usable data. + public int maxx; + + /// < The maximum x-bounds of usable data. + public int miny; + + /// < The minimum y-bounds of usable data. (Along the z-axis.) + public int maxy; + + /// < The maximum y-bounds of usable data. (Along the z-axis.) + public int hmin; + + /// < The minimum height bounds of usable data. (Along the y-axis.) + public int hmax; + + /// < The maximum height bounds of usable data. (Along the y-axis.) + public int[] heights; + + /// < The heightfield. [Size: width * height] + public int[] areas; + + /// < Area ids. [Size: Same as #heights] + public int[] cons; /// < Packed neighbor connection information. [Size: Same as #heights] + } +} \ No newline at end of file diff --git a/src/DotRecast.Recast/HeightfieldLayerSet.cs b/src/DotRecast.Recast/HeightfieldLayerSet.cs index d1d58ae..435b57b 100644 --- a/src/DotRecast.Recast/HeightfieldLayerSet.cs +++ b/src/DotRecast.Recast/HeightfieldLayerSet.cs @@ -27,55 +27,6 @@ namespace DotRecast.Recast /// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet public class HeightfieldLayerSet { - /// Represents a heightfield layer within a layer set. - /// @see rcHeightfieldLayerSet - public class HeightfieldLayer - { - public Vector3f bmin = new Vector3f(); - - /// < The minimum bounds in world space. [(x, y, z)] - public Vector3f bmax = new Vector3f(); - - /// < The maximum bounds in world space. [(x, y, z)] - public float cs; - - /// < The size of each cell. (On the xz-plane.) - public float ch; - - /// < The height of each cell. (The minimum increment along the y-axis.) - public int width; - - /// < The width of the heightfield. (Along the x-axis in cell units.) - public int height; - - /// < The height of the heightfield. (Along the z-axis in cell units.) - public int minx; - - /// < The minimum x-bounds of usable data. - public int maxx; - - /// < The maximum x-bounds of usable data. - public int miny; - - /// < The minimum y-bounds of usable data. (Along the z-axis.) - public int maxy; - - /// < The maximum y-bounds of usable data. (Along the z-axis.) - public int hmin; - - /// < The minimum height bounds of usable data. (Along the y-axis.) - public int hmax; - - /// < The maximum height bounds of usable data. (Along the y-axis.) - public int[] heights; - - /// < The heightfield. [Size: width * height] - public int[] areas; - - /// < Area ids. [Size: Same as #heights] - public int[] cons; /// < Packed neighbor connection information. [Size: Same as #heights] - } - public HeightfieldLayer[] layers; /// < The layers in the set. [Size: #nlayers] } } \ No newline at end of file diff --git a/src/DotRecast.Recast/ObjImporter.cs b/src/DotRecast.Recast/ObjImporter.cs index 958cebe..2401a19 100644 --- a/src/DotRecast.Recast/ObjImporter.cs +++ b/src/DotRecast.Recast/ObjImporter.cs @@ -25,12 +25,6 @@ namespace DotRecast.Recast { public static class ObjImporter { - public class ObjImporterContext - { - public List vertexPositions = new List(); - public List meshFaces = new List(); - } - public static IInputGeomProvider Load(byte[] chunck) { var context = LoadContext(chunck); @@ -136,4 +130,4 @@ namespace DotRecast.Recast return posi; } } -} +} \ No newline at end of file diff --git a/src/DotRecast.Recast/ObjImporterContext.cs b/src/DotRecast.Recast/ObjImporterContext.cs new file mode 100644 index 0000000..e6cab53 --- /dev/null +++ b/src/DotRecast.Recast/ObjImporterContext.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace DotRecast.Recast +{ + public class ObjImporterContext + { + public List vertexPositions = new List(); + public List meshFaces = new List(); + } +} \ No newline at end of file diff --git a/src/DotRecast.Recast/RecastLayers.cs b/src/DotRecast.Recast/RecastLayers.cs index b8abb4e..6706306 100644 --- a/src/DotRecast.Recast/RecastLayers.cs +++ b/src/DotRecast.Recast/RecastLayers.cs @@ -418,10 +418,10 @@ namespace DotRecast.Recast bmax.z -= borderSize * chf.cs; HeightfieldLayerSet lset = new HeightfieldLayerSet(); - lset.layers = new HeightfieldLayerSet.HeightfieldLayer[layerId]; + lset.layers = new HeightfieldLayer[layerId]; for (int i = 0; i < lset.layers.Length; i++) { - lset.layers[i] = new HeightfieldLayerSet.HeightfieldLayer(); + lset.layers[i] = new HeightfieldLayer(); } // Store layers. @@ -429,7 +429,7 @@ namespace DotRecast.Recast { int curId = i; - HeightfieldLayerSet.HeightfieldLayer layer = lset.layers[i]; + HeightfieldLayer layer = lset.layers[i]; int gridSize = lw * lh; diff --git a/test/DotRecast.Detour.Test/PolygonByCircleConstraintTest.cs b/test/DotRecast.Detour.Test/PolygonByCircleConstraintTest.cs index 8e1d8e4..6f70f8f 100644 --- a/test/DotRecast.Detour.Test/PolygonByCircleConstraintTest.cs +++ b/test/DotRecast.Detour.Test/PolygonByCircleConstraintTest.cs @@ -24,7 +24,7 @@ namespace DotRecast.Detour.Test; [Parallelizable] public class PolygonByCircleConstraintTest { - private readonly IPolygonByCircleConstraint constraint = new IPolygonByCircleConstraint.StrictPolygonByCircleConstraint(); + private readonly IPolygonByCircleConstraint constraint = new StrictPolygonByCircleConstraint(); [Test] public void ShouldHandlePolygonFullyInsideCircle() diff --git a/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs b/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs index 19b3be0..83e3e42 100644 --- a/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs +++ b/test/DotRecast.Detour.TileCache.Test/TestTileLayerBuilder.cs @@ -87,7 +87,7 @@ public class TestTileLayerBuilder : AbstractTileLayersBuilder TileCacheBuilder builder = new TileCacheBuilder(); for (int i = 0; i < lset.layers.Length; ++i) { - HeightfieldLayerSet.HeightfieldLayer layer = lset.layers[i]; + HeightfieldLayer layer = lset.layers[i]; // Store header TileCacheLayerHeader header = new TileCacheLayerHeader();