Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions sources/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
<!-- Runtime dependencies -->
<ItemGroup>
<PackageVersion Include="BepuPhysics" Version="2.5.0-beta.25" />
<PackageVersion Include="DotRecast.Core" Version="2024.1.1" />
<PackageVersion Include="DotRecast.Detour" Version="2024.2.1" />
<PackageVersion Include="DotRecast.Recast" Version="2024.2.1" />
<PackageVersion Include="DotRecast.Recast.Toolset" Version="2024.3.1" />
<PackageVersion Include="DotRecast.Core" Version="2025.2.1" />
<PackageVersion Include="DotRecast.Detour" Version="2025.2.1" />
<PackageVersion Include="DotRecast.Recast" Version="2025.2.1" />
<PackageVersion Include="DotRecast.Recast.Toolset" Version="2025.2.1" />
<PackageVersion Include="FFmpeg.AutoGen" Version="3.4.0.2" />
<PackageVersion Include="K4os.Compression.LZ4.Legacy" Version="1.3.6" />
<PackageVersion Include="Microsoft.Management.Infrastructure" Version="3.0.0-preview.4" />
Expand Down Expand Up @@ -148,4 +148,4 @@
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" PrivateAssets="all" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public NavmeshBuildCommand(string url, AssetItem assetItem, NavigationMeshAsset
asset = value;
assetUrl = url;

Version = 1; // Removed separate debug model stored in the navigation mesh
Version = 2;
}

protected override void ComputeParameterHash(BinarySerializationWriter writer)
Expand Down
32 changes: 18 additions & 14 deletions sources/engine/Stride.Navigation/DtMeshDataSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System.Diagnostics;
using DotRecast.Core.Numerics;
using DotRecast.Detour;
using Stride.Core.Serialization;
Expand Down Expand Up @@ -40,14 +41,14 @@ internal void WriteDtMeshBvTree(DtBVNode[] dataBvTree)
if (isNull)
continue;

for (int i = 0; i < 3; i++)
{
stream.Write(t.bmin[i]);
}
for (int i = 0; i < 3; i++)
{
stream.Write(t.bmax[i]);
}
stream.Write(t.bmin.X);
stream.Write(t.bmin.Y);
stream.Write(t.bmin.Z);

stream.Write(t.bmax.X);
stream.Write(t.bmax.Y);
stream.Write(t.bmax.Z);

stream.Write(t.i);
}
}
Expand Down Expand Up @@ -173,10 +174,13 @@ internal DtBVNode[] ReadDtMeshBvTree()
continue;
}
var node = new DtBVNode();
for (int j = 0; j < 3; j++)
node.bmin[j] = stream.Read<int>();
for (int j = 0; j < 3; j++)
node.bmax[j] = stream.Read<int>();
node.bmin.X = stream.Read<int>();
node.bmin.Y = stream.Read<int>();
node.bmin.Z = stream.Read<int>();

node.bmax.X = stream.Read<int>();
node.bmax.Y = stream.Read<int>();
node.bmax.Z = stream.Read<int>();
node.i = stream.Read<int>();

arr[i] = node;
Expand Down Expand Up @@ -207,7 +211,7 @@ internal DtPolyDetail[] ReadDtMeshDetailMeshes()
int count = stream.Read<int>();
var arr = new DtPolyDetail[count];
for (int i = 0; i < count; i++)
arr[i] = new DtPolyDetail(stream.Read<int>(),stream.Read<int>(),stream.Read<int>(),stream.Read<int>());
arr[i] = new DtPolyDetail(stream.Read<int>(),stream.Read<int>(),stream.Read<byte>(),stream.Read<byte>());
return arr;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public async Task<NavigationMeshBuildResult> Rebuild()
});
await result;

FinilizeRebuild(result);
FinalizeRebuild(result);

return result.Result;
}
Expand All @@ -191,7 +191,7 @@ internal void InitializeSettingsFromNavigationSettings(NavigationSettings naviga
pendingRebuild = true;
}

private void FinilizeRebuild(Task<NavigationMeshBuildResult> resultTask)
private void FinalizeRebuild(Task<NavigationMeshBuildResult> resultTask)
{
var result = resultTask.Result;
if (result.Success)
Expand Down
60 changes: 38 additions & 22 deletions sources/engine/Stride.Navigation/InternalNavigationMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using DotRecast.Core.Numerics;
using DotRecast.Detour;
using Stride.Core.Mathematics;
Expand Down Expand Up @@ -40,7 +42,8 @@ public InternalNavigationMesh(float cellTileSize)
meshParams.maxPolys = 1 << polyBits;

// Initialize the query object
navMesh = new DtNavMesh(meshParams, 2048);
navMesh = new DtNavMesh();
navMesh.Init(meshParams, 2048);
navQuery = new DtNavMeshQuery(navMesh);
}

Expand All @@ -51,7 +54,7 @@ public bool LoadTile(DtMeshData navData)
if (navData == null)
return false;

long tileRef = navMesh.AddTile(navData, 0, 0);
var status = navMesh.AddTile(navData, 0, 0, out long tileRef);
return tileRef != 0;
}

Expand All @@ -62,29 +65,44 @@ public bool RemoveTile(Point coord)
return status != 0;
}

public void DoPathFindQuery(PathFindQuery query, ref PathFindResult result)
public bool DoPathFindQuery(PathFindQuery query, ref Span<DtStraightPath> result)
{
// Reset result
result.PathFound = false;

// Find the starting polygons and point on it to start from
DtQueryDefaultFilter filter = new DtQueryDefaultFilter();
DtStatus status = navQuery.FindNearestPoly(query.Source.ToDotRecastVector(), query.FindNearestPolyExtent.ToDotRecastVector(), filter, out long startPoly, out RcVec3f startPoint, out _);
if (status.Failed())
return;
return false;
status = navQuery.FindNearestPoly(query.Target.ToDotRecastVector(), query.FindNearestPolyExtent.ToDotRecastVector(), filter, out long endPoly, out RcVec3f endPoint, out _);
if (status.Failed())
return;

List<long> polys = new(query.MaxPathPoints);
status = navQuery.FindPath(startPoly, endPoly, startPoint, endPoint, filter, ref polys, DtFindPathOption.NoOption);
if (status.Failed() || status.IsPartial())
return;
return false;


var rented = query.MaxPathPoints < 32 ? null : System.Buffers.ArrayPool<long>.Shared.Rent(query.MaxPathPoints);
var polysSpan = rented is null ? stackalloc long[query.MaxPathPoints] : rented.AsSpan()[..query.MaxPathPoints];

navQuery.FindPath(startPoly, endPoly, startPoint, endPoint, filter, polysSpan, out var pathCount, polysSpan.Length);

if (0 < pathCount)
{
// In case of partial path, make sure the end point is clamped to the last polygon.
var endPosition = new RcVec3f(endPoint.X, endPoint.Y, endPoint.Z);
if (polysSpan[pathCount - 1] != endPoly)
{
status = navQuery.ClosestPointOnPoly(polysSpan[pathCount - 1], endPoint, out var closest, out var _);
if (status.Succeeded())
{
endPosition = closest;
}
}

navQuery.FindStraightPath(startPoint, endPosition, polysSpan, pathCount, result, out var straightPathCount, query.MaxPathPoints, 0);
result = result[..straightPathCount];
}

status = navQuery.FindStraightPath(startPoint, endPoint, polys, ref result.PathPoints, query.MaxPathPoints, 0);
if (status.Failed())
return;
result.PathFound = true;
if (rented is not null)
System.Buffers.ArrayPool<long>.Shared.Return(rented);

return 0 < pathCount;
}

public void DoRaycastQuery(RaycastQuery query, out NavigationRaycastResult result)
Expand All @@ -96,12 +114,10 @@ public void DoRaycastQuery(RaycastQuery query, out NavigationRaycastResult resul
DtStatus status = navQuery.FindNearestPoly(query.Source.ToDotRecastVector(), query.FindNearestPolyExtent.ToDotRecastVector(), filter, out long startPoly, out _, out _);
if (status.Failed())
return;
List<long> polys = new (query.MaxPathPoints);

long[] polys = new long[query.MaxPathPoints];
var normal = result.Normal.ToDotRecastVector();
status = navQuery.Raycast(startPoly, query.Source.ToDotRecastVector(),
query.Target.ToDotRecastVector(), filter,
out float t, out normal, ref polys);
status = navQuery.Raycast(startPoly, query.Source.ToDotRecastVector(), query.Target.ToDotRecastVector(), filter, out float t, out normal, polys, out var pathCount, query.MaxPathPoints);
result.Normal = new(normal.X, normal.Y, normal.Z);

if (status.Failed())
Expand Down
6 changes: 0 additions & 6 deletions sources/engine/Stride.Navigation/Navigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ internal struct PathFindQuery
public Vector3 FindNearestPolyExtent;
public int MaxPathPoints;
}

internal struct PathFindResult
{
public bool PathFound;
public List<DtStraightPath> PathPoints;
}

internal struct BuildSettings
{
Expand Down
6 changes: 3 additions & 3 deletions sources/engine/Stride.Navigation/NavigationBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

using System;
Expand Down Expand Up @@ -96,7 +96,7 @@ public GeneratedData BuildNavmesh(ref Vector3[] vertices, ref int[] indices)
}

// Find walkable triangles and rasterize into heightfield
triAreas = RcCommons.MarkWalkableTriangles(context, buildSettings.AgentMaxSlope, verts, indices, numTriangles, new RcAreaModification(RcAreaModification.RC_AREA_FLAGS_MASK));
triAreas = RcRecast.MarkWalkableTriangles(context, buildSettings.AgentMaxSlope, verts, indices, numTriangles, new RcAreaModification(RcAreaModification.RC_AREA_FLAGS_MASK));
RcRasterizations.RasterizeTriangles(context, verts, indices, triAreas, numTriangles, solid, walkableClimb);

// Filter walkable surfaces.
Expand Down Expand Up @@ -129,7 +129,7 @@ public GeneratedData BuildNavmesh(ref Vector3[] vertices, ref int[] indices)
// Update poly flags from areas.
for (int i = 0; i < polyMesh.npolys; ++i)
{
if (polyMesh.areas[i] == RcConstants.RC_WALKABLE_AREA)
if (polyMesh.areas[i] == RcRecast.RC_WALKABLE_AREA)
polyMesh.areas[i] = 0;

if (polyMesh.areas[i] == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,23 @@ public bool TryFindPath(Vector3 start, Vector3 end, ICollection<Vector3> path, N
query.Target = end;
query.MaxPathPoints = querySettings.MaxPathPoints;
query.FindNearestPolyExtent = querySettings.FindNearestPolyExtent;
PathFindResult queryResult = default;

queryResult.PathPoints = new List<DtStraightPath>(querySettings.MaxPathPoints);
navmesh.DoPathFindQuery(query, ref queryResult);
if (!queryResult.PathFound)
return false;

for (int i = 0; i < queryResult.PathPoints.Count; i++)
var rented = querySettings.MaxPathPoints < 32 ? null : System.Buffers.ArrayPool<DtStraightPath>.Shared.Rent(querySettings.MaxPathPoints);
var workingSpan = rented is null ? stackalloc DtStraightPath[querySettings.MaxPathPoints] : rented.AsSpan()[..querySettings.MaxPathPoints];

bool validPath = navmesh.DoPathFindQuery(query, ref workingSpan);
if (validPath)
{
path.Add(queryResult.PathPoints[i].pos.ToStrideVector());
for (int i = 0; i < workingSpan.Length; i++)
{
path.Add(workingSpan[i].pos.ToStrideVector());
}
}
return true;

if (rented is not null)
System.Buffers.ArrayPool<DtStraightPath>.Shared.Return(rented);

return validPath;
}
}
}
1 change: 1 addition & 0 deletions sources/engine/Stride.Navigation/Stride.Navigation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DotRecast.Core" />
<PackageReference Include="DotRecast.Detour" />
<PackageReference Include="DotRecast.Recast" />
</ItemGroup>
Expand Down
Loading