diff --git a/Runtime/DotRecast.Core/Numerics/RcVec2f.cs b/Runtime/DotRecast.Core/Numerics/RcVec2f.cs index 8d0e4a9..e90b3e3 100644 --- a/Runtime/DotRecast.Core/Numerics/RcVec2f.cs +++ b/Runtime/DotRecast.Core/Numerics/RcVec2f.cs @@ -8,7 +8,7 @@ public struct RcVec2f public float X; public float Y; - public static RcVec2f Zero { get; } = new RcVec2f { X = 0, Y = 0 }; + public static readonly RcVec2f Zero = new RcVec2f { X = 0, Y = 0 }; public RcVec2f(float x, float y) { diff --git a/Runtime/DotRecast.Core/Numerics/RcVec3f.cs b/Runtime/DotRecast.Core/Numerics/RcVec3f.cs index 95f29d9..5e8d86a 100644 --- a/Runtime/DotRecast.Core/Numerics/RcVec3f.cs +++ b/Runtime/DotRecast.Core/Numerics/RcVec3f.cs @@ -27,11 +27,11 @@ public struct RcVec3f public float Y; public float Z; - public static RcVec3f Zero { get; } = new RcVec3f(0.0f, 0.0f, 0.0f); - public static RcVec3f One { get; } = new RcVec3f(1.0f); - public static RcVec3f UnitX { get; } = new RcVec3f(1.0f, 0.0f, 0.0f); - public static RcVec3f UnitY { get; } = new RcVec3f(0.0f, 1.0f, 0.0f); - public static RcVec3f UnitZ { get; } = new RcVec3f(0.0f, 0.0f, 1.0f); + public static readonly RcVec3f Zero = new RcVec3f(0.0f, 0.0f, 0.0f); + public static readonly RcVec3f One = new RcVec3f(1.0f); + public static readonly RcVec3f UnitX = new RcVec3f(1.0f, 0.0f, 0.0f); + public static readonly RcVec3f UnitY = new RcVec3f(0.0f, 1.0f, 0.0f); + public static readonly RcVec3f UnitZ = new RcVec3f(0.0f, 0.0f, 1.0f); [MethodImpl(MethodImplOptions.AggressiveInlining)] public RcVec3f(float x, float y, float z) diff --git a/Runtime/DotRecast.Detour.Extras/Jumplink/JumpLinkType.cs b/Runtime/DotRecast.Detour.Extras/Jumplink/JumpLinkType.cs index 38a4764..817d3d9 100644 --- a/Runtime/DotRecast.Detour.Extras/Jumplink/JumpLinkType.cs +++ b/Runtime/DotRecast.Detour.Extras/Jumplink/JumpLinkType.cs @@ -10,7 +10,7 @@ public class JumpLinkType public static readonly JumpLinkType EDGE_CLIMB_DOWN = new JumpLinkType(EDGE_CLIMB_DOWN_BIT); public static readonly JumpLinkType EDGE_JUMP_OVER = new JumpLinkType(EDGE_JUMP_OVER_BIT); - public int Bit { get; } + public readonly int Bit; private JumpLinkType(int bit) { diff --git a/Runtime/DotRecast.Detour/DtNavMesh.cs b/Runtime/DotRecast.Detour/DtNavMesh.cs index 2f2e494..740f0a4 100644 --- a/Runtime/DotRecast.Detour/DtNavMesh.cs +++ b/Runtime/DotRecast.Detour/DtNavMesh.cs @@ -43,7 +43,7 @@ public class DtNavMesh /** A version number used to detect compatibility of navigation tile states. */ public const int DT_NAVMESH_STATE_VERSION = 1; - + public const int DT_SALT_BITS = 16; public const int DT_TILE_BITS = 28; public const int DT_POLY_BITS = 20; @@ -284,7 +284,7 @@ public DtStatus GetTileAndPolyByRef(long refs, out DtMeshTile tile, out DtPoly p return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } - if (m_tiles[it].salt != salt || m_tiles[it].data.header == null) + if (m_tiles[it].salt != salt || m_tiles[it].data == null || m_tiles[it].data.header == null) { return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM; } diff --git a/Runtime/DotRecast.Recast.Toolset/Tools/RcCrowdToolMode.cs b/Runtime/DotRecast.Recast.Toolset/Tools/RcCrowdToolMode.cs index 69a5328..65f9440 100644 --- a/Runtime/DotRecast.Recast.Toolset/Tools/RcCrowdToolMode.cs +++ b/Runtime/DotRecast.Recast.Toolset/Tools/RcCrowdToolMode.cs @@ -16,8 +16,8 @@ public class RcCrowdToolMode TOGGLE_POLYS ); - public int Idx { get; } - public string Label { get; } + public readonly int Idx; + public readonly string Label; private RcCrowdToolMode(int idx, string label) { diff --git a/Runtime/DotRecast.Recast.Toolset/Tools/RcDynamicUpdateToolMode.cs b/Runtime/DotRecast.Recast.Toolset/Tools/RcDynamicUpdateToolMode.cs index 9a12183..a7125d5 100644 --- a/Runtime/DotRecast.Recast.Toolset/Tools/RcDynamicUpdateToolMode.cs +++ b/Runtime/DotRecast.Recast.Toolset/Tools/RcDynamicUpdateToolMode.cs @@ -12,8 +12,8 @@ public class RcDynamicUpdateToolMode BUILD, COLLIDERS, RAYCAST ); - public int Idx { get; } - public string Label { get; } + public readonly int Idx; + public readonly string Label; private RcDynamicUpdateToolMode(int idx, string label) { diff --git a/Runtime/DotRecast.Recast.Toolset/Tools/RcTestNavmeshToolMode.cs b/Runtime/DotRecast.Recast.Toolset/Tools/RcTestNavmeshToolMode.cs index 2c60a4e..64159a9 100644 --- a/Runtime/DotRecast.Recast.Toolset/Tools/RcTestNavmeshToolMode.cs +++ b/Runtime/DotRecast.Recast.Toolset/Tools/RcTestNavmeshToolMode.cs @@ -27,8 +27,8 @@ public class RcTestNavmeshToolMode ); - public int Idx { get; } - public string Label { get; } + public readonly int Idx; + public readonly string Label; private RcTestNavmeshToolMode(int idx, string label) { diff --git a/Runtime/DotRecast.Recast/RcFilters.cs b/Runtime/DotRecast.Recast/RcFilters.cs index c04be82..fb0ce1f 100644 --- a/Runtime/DotRecast.Recast/RcFilters.cs +++ b/Runtime/DotRecast.Recast/RcFilters.cs @@ -84,70 +84,79 @@ public static void FilterLowHangingWalkableObstacles(RcTelemetry ctx, int walkab /// A span is a ledge if: RcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb /// /// @see rcHeightfield, rcConfig - public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield solid) + public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int walkableClimb, RcHeightfield heightfield) { using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_FILTER_BORDER); - int w = solid.width; - int h = solid.height; + int xSize = heightfield.width; + int zSize = heightfield.height; // Mark border spans. - for (int y = 0; y < h; ++y) + for (int z = 0; z < zSize; ++z) { - for (int x = 0; x < w; ++x) + for (int x = 0; x < xSize; ++x) { - for (RcSpan s = solid.spans[x + y * w]; s != null; s = s.next) + for (RcSpan span = heightfield.spans[x + z * xSize]; span != null; span = span.next) { // Skip non walkable spans. - if (s.area == RC_NULL_AREA) + if (span.area == RC_NULL_AREA) + { continue; + } - int bot = (s.smax); - int top = s.next != null ? s.next.smin : SPAN_MAX_HEIGHT; + int bot = (span.smax); + int top = span.next != null ? span.next.smin : SPAN_MAX_HEIGHT; // Find neighbours minimum height. - int minh = SPAN_MAX_HEIGHT; + int minNeighborHeight = SPAN_MAX_HEIGHT; // Min and max height of accessible neighbours. - int asmin = s.smax; - int asmax = s.smax; + int accessibleNeighborMinHeight = span.smax; + int accessibleNeighborMaxHeight = span.smax; - for (int dir = 0; dir < 4; ++dir) + for (int direction = 0; direction < 4; ++direction) { - int dx = x + GetDirOffsetX(dir); - int dy = y + GetDirOffsetY(dir); + int dx = x + GetDirOffsetX(direction); + int dz = z + GetDirOffsetY(direction); // Skip neighbours which are out of bounds. - if (dx < 0 || dy < 0 || dx >= w || dy >= h) + if (dx < 0 || dz < 0 || dx >= xSize || dz >= zSize) { - minh = Math.Min(minh, -walkableClimb - bot); - continue; + minNeighborHeight = (-walkableClimb - 1); + break; } // From minus infinity to the first span. - RcSpan ns = solid.spans[dx + dy * w]; - int nbot = -walkableClimb; - int ntop = ns != null ? ns.smin : SPAN_MAX_HEIGHT; + RcSpan neighborSpan = heightfield.spans[dx + dz * xSize]; + int neighborTop = neighborSpan != null ? neighborSpan.smin : SPAN_MAX_HEIGHT; + // Skip neightbour if the gap between the spans is too small. - if (Math.Min(top, ntop) - Math.Max(bot, nbot) > walkableHeight) - minh = Math.Min(minh, nbot - bot); + if (Math.Min(top, neighborTop) - bot >= walkableHeight) + { + minNeighborHeight = (-walkableClimb - 1); + break; + } // Rest of the spans. - for (ns = solid.spans[dx + dy * w]; ns != null; ns = ns.next) + for (neighborSpan = heightfield.spans[dx + dz * xSize]; neighborSpan != null; neighborSpan = neighborSpan.next) { - nbot = ns.smax; - ntop = ns.next != null ? ns.next.smin : SPAN_MAX_HEIGHT; + int neighborBot = neighborSpan.smax; + neighborTop = neighborSpan.next != null ? neighborSpan.next.smin : SPAN_MAX_HEIGHT; + // Skip neightbour if the gap between the spans is too small. - if (Math.Min(top, ntop) - Math.Max(bot, nbot) > walkableHeight) + if (Math.Min(top, neighborTop) - Math.Max(bot, neighborBot) >= walkableHeight) { - minh = Math.Min(minh, nbot - bot); + int accessibleNeighbourHeight = neighborBot - bot; + minNeighborHeight = Math.Min(minNeighborHeight, accessibleNeighbourHeight); - // Find min/max accessible neighbour height. - if (MathF.Abs(nbot - bot) <= walkableClimb) + // Find min/max accessible neighbour height. + if (MathF.Abs(accessibleNeighbourHeight) <= walkableClimb) + { + if (neighborBot < accessibleNeighborMinHeight) accessibleNeighborMinHeight = neighborBot; + if (neighborBot > accessibleNeighborMaxHeight) accessibleNeighborMaxHeight = neighborBot; + } + else if (accessibleNeighbourHeight < -walkableClimb) { - if (nbot < asmin) - asmin = nbot; - if (nbot > asmax) - asmax = nbot; + break; } } } @@ -155,14 +164,16 @@ public static void FilterLedgeSpans(RcTelemetry ctx, int walkableHeight, int wal // The current span is close to a ledge if the drop to any // neighbour span is less than the walkableClimb. - if (minh < -walkableClimb) - s.area = RC_NULL_AREA; + if (minNeighborHeight < -walkableClimb) + { + span.area = RC_NULL_AREA; + } // If the difference between all neighbours is too large, // we are at steep slope, mark the span as ledge. - if ((asmax - asmin) > walkableClimb) + if ((accessibleNeighborMaxHeight - accessibleNeighborMinHeight) > walkableClimb) { - s.area = RC_NULL_AREA; + span.area = RC_NULL_AREA; } } } diff --git a/package.json b/package.json index 89c6eef..58e4f21 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.ikpil.unirecast", "displayName": "UniRecast", - "version": "0.0.5", + "version": "0.0.6", "unity": "2019.3", "description": "navigation mesh toolset for Unity3D using DotRecast", "license": "MIT", @@ -21,8 +21,7 @@ }, "repository": { "url": "https://github.com/ikpil/UniRecast.git", - "type": "git", - "revision": "20bf43272e9a453cb080f2864185ee0396bf36e3" + "type": "git" }, "samples": [ {