remove Result<Tuple<DtMeshTile, DtPoly>>

This commit is contained in:
ikpil 2023-06-11 01:15:44 +09:00
parent a0877d3dc6
commit 34e04f010e
7 changed files with 72 additions and 99 deletions

View File

@ -211,30 +211,41 @@ namespace DotRecast.Detour
ty = (int)Math.Floor((pos.z - m_orig.z) / m_tileHeight); ty = (int)Math.Floor((pos.z - m_orig.z) / m_tileHeight);
} }
public Result<Tuple<DtMeshTile, DtPoly>> GetTileAndPolyByRef(long refs) /// Gets the tile and polygon for the specified polygon reference.
/// @param[in] ref The reference for the a polygon.
/// @param[out] tile The tile containing the polygon.
/// @param[out] poly The polygon.
/// @return The status flags for the operation.
public DtStatus GetTileAndPolyByRef(long refs, out DtMeshTile tile, out DtPoly poly)
{ {
tile = null;
poly = null;
if (refs == 0) if (refs == 0)
{ {
return Results.InvalidParam<Tuple<DtMeshTile, DtPoly>>("ref = 0"); return DtStatus.DT_FAILURE;
} }
DecodePolyId(refs, out var salt, out var it, out var ip); DecodePolyId(refs, out var salt, out var it, out var ip);
if (it >= m_maxTiles) if (it >= m_maxTiles)
{ {
return Results.InvalidParam<Tuple<DtMeshTile, DtPoly>>("tile > m_maxTiles"); 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.header == null)
{ {
return Results.InvalidParam<Tuple<DtMeshTile, DtPoly>>("Invalid salt or header"); return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
if (ip >= m_tiles[it].data.header.polyCount) if (ip >= m_tiles[it].data.header.polyCount)
{ {
return Results.InvalidParam<Tuple<DtMeshTile, DtPoly>>("poly > polyCount"); return DtStatus.DT_FAILURE | DtStatus.DT_INVALID_PARAM;
} }
return Results.Success(Tuple.Create(m_tiles[it], m_tiles[it].data.polys[ip])); tile = m_tiles[it];
poly = m_tiles[it].data.polys[ip];
return DtStatus.DT_SUCCSESS;
} }
/// @par /// @par

View File

@ -466,14 +466,12 @@ namespace DotRecast.Detour
/// @returns The status flags for the query. /// @returns The status flags for the query.
public Result<RcVec3f> ClosestPointOnPolyBoundary(long refs, RcVec3f pos) public Result<RcVec3f> ClosestPointOnPolyBoundary(long refs, RcVec3f pos)
{ {
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(refs); var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return Results.Of<RcVec3f>(tileAndPoly.status, tileAndPoly.message); return Results.Of<RcVec3f>(status, "");
} }
DtMeshTile tile = tileAndPoly.result.Item1;
DtPoly poly = tileAndPoly.result.Item2;
if (tile == null) if (tile == null)
{ {
return Results.InvalidParam<RcVec3f>("Invalid tile"); return Results.InvalidParam<RcVec3f>("Invalid tile");
@ -533,15 +531,12 @@ namespace DotRecast.Detour
/// @returns The status flags for the query. /// @returns The status flags for the query.
public Result<float> GetPolyHeight(long refs, RcVec3f pos) public Result<float> GetPolyHeight(long refs, RcVec3f pos)
{ {
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(refs); var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return Results.Of<float>(tileAndPoly.status, tileAndPoly.message); return Results.Of<float>(status, "");
} }
DtMeshTile tile = tileAndPoly.result.Item1;
DtPoly poly = tileAndPoly.result.Item2;
if (!RcVec3f.IsFinite2D(pos)) if (!RcVec3f.IsFinite2D(pos))
{ {
return Results.InvalidParam<float>(); return Results.InvalidParam<float>();
@ -1136,16 +1131,14 @@ namespace DotRecast.Detour
// The API input has been cheked already, skip checking internal // The API input has been cheked already, skip checking internal
// data. // data.
long bestRef = bestNode.id; long bestRef = bestNode.id;
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(bestRef); var status = m_nav.GetTileAndPolyByRef(bestRef, out var bestTile, out var bestPoly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
m_query.status = DtStatus.DT_FAILURE; m_query.status = DtStatus.DT_FAILURE;
// The polygon has disappeared during the sliced query, fail. // The polygon has disappeared during the sliced query, fail.
return Results.Of(m_query.status, iter); return Results.Of(m_query.status, iter);
} }
DtMeshTile bestTile = tileAndPoly.result.Item1;
DtPoly bestPoly = tileAndPoly.result.Item2;
// Get parent and grand parent poly and tile. // Get parent and grand parent poly and tile.
long parentRef = 0, grandpaRef = 0; long parentRef = 0, grandpaRef = 0;
DtMeshTile parentTile = null; DtMeshTile parentTile = null;
@ -1164,8 +1157,8 @@ namespace DotRecast.Detour
if (parentRef != 0) if (parentRef != 0)
{ {
bool invalidParent = false; bool invalidParent = false;
tileAndPoly = m_nav.GetTileAndPolyByRef(parentRef); status = m_nav.GetTileAndPolyByRef(parentRef, out parentTile, out parentPoly);
invalidParent = tileAndPoly.Failed(); invalidParent = status.Failed();
if (invalidParent || (grandpaRef != 0 && !m_nav.IsValidPolyRef(grandpaRef))) if (invalidParent || (grandpaRef != 0 && !m_nav.IsValidPolyRef(grandpaRef)))
{ {
// The polygon has disappeared during the sliced query, // The polygon has disappeared during the sliced query,
@ -1173,9 +1166,6 @@ namespace DotRecast.Detour
m_query.status = DtStatus.DT_FAILURE; m_query.status = DtStatus.DT_FAILURE;
return Results.Of(m_query.status, iter); return Results.Of(m_query.status, iter);
} }
parentTile = tileAndPoly.result.Item1;
parentPoly = tileAndPoly.result.Item2;
} }
// decide whether to test raycast to previous nodes // decide whether to test raycast to previous nodes
@ -1464,25 +1454,19 @@ namespace DotRecast.Detour
{ {
// Calculate portal // Calculate portal
long from = path[i]; long from = path[i];
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(from); var status = m_nav.GetTileAndPolyByRef(from, out var fromTile, out var fromPoly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return DtStatus.DT_FAILURE; return DtStatus.DT_FAILURE;
} }
DtMeshTile fromTile = tileAndPoly.result.Item1;
DtPoly fromPoly = tileAndPoly.result.Item2;
long to = path[i + 1]; long to = path[i + 1];
tileAndPoly = m_nav.GetTileAndPolyByRef(to); status = m_nav.GetTileAndPolyByRef(to, out var toTile, out var toPoly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return DtStatus.DT_FAILURE; return DtStatus.DT_FAILURE;
} }
DtMeshTile toTile = tileAndPoly.result.Item1;
DtPoly toPoly = tileAndPoly.result.Item2;
Result<PortalResult> portals = GetPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, 0, 0); Result<PortalResult> portals = GetPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, 0, 0);
if (portals.Failed()) if (portals.Failed())
{ {
@ -1969,26 +1953,20 @@ namespace DotRecast.Detour
protected Result<PortalResult> GetPortalPoints(long from, long to) protected Result<PortalResult> GetPortalPoints(long from, long to)
{ {
Result<Tuple<DtMeshTile, DtPoly>> tileAndPolyResult = m_nav.GetTileAndPolyByRef(from); var status = m_nav.GetTileAndPolyByRef(from, out var fromTile, out var fromPoly);
if (tileAndPolyResult.Failed()) if (status.Failed())
{ {
return Results.Of<PortalResult>(tileAndPolyResult.status, tileAndPolyResult.message); return Results.Of<PortalResult>(status, "");
} }
Tuple<DtMeshTile, DtPoly> tileAndPoly = tileAndPolyResult.result;
DtMeshTile fromTile = tileAndPoly.Item1;
DtPoly fromPoly = tileAndPoly.Item2;
int fromType = fromPoly.GetPolyType(); int fromType = fromPoly.GetPolyType();
tileAndPolyResult = m_nav.GetTileAndPolyByRef(to); status = m_nav.GetTileAndPolyByRef(to, out var toTile, out var toPoly);
if (tileAndPolyResult.Failed()) if (status.Failed())
{ {
return Results.Of<PortalResult>(tileAndPolyResult.status, tileAndPolyResult.message); return Results.Of<PortalResult>(status, "");
} }
tileAndPoly = tileAndPolyResult.result;
DtMeshTile toTile = tileAndPoly.Item1;
DtPoly toPoly = tileAndPoly.Item2;
int toType = toPoly.GetPolyType(); int toType = toPoly.GetPolyType();
return GetPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, fromType, toType); return GetPortalPoints(from, fromPoly, fromTile, to, toPoly, toTile, fromType, toType);
@ -3000,10 +2978,10 @@ namespace DotRecast.Detour
/// @returns The status flags for the query. /// @returns The status flags for the query.
public Result<GetPolyWallSegmentsResult> GetPolyWallSegments(long refs, bool storePortals, IDtQueryFilter filter) public Result<GetPolyWallSegmentsResult> GetPolyWallSegments(long refs, bool storePortals, IDtQueryFilter filter)
{ {
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(refs); var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return Results.Of<GetPolyWallSegmentsResult>(tileAndPoly.status, tileAndPoly.message); return Results.Of<GetPolyWallSegmentsResult>(status, "");
} }
if (null == filter) if (null == filter)
@ -3011,9 +2989,6 @@ namespace DotRecast.Detour
return Results.InvalidParam<GetPolyWallSegmentsResult>(); return Results.InvalidParam<GetPolyWallSegmentsResult>();
} }
DtMeshTile tile = tileAndPoly.result.Item1;
DtPoly poly = tileAndPoly.result.Item2;
List<long> segmentRefs = new List<long>(); List<long> segmentRefs = new List<long>();
List<SegmentVert> segmentVerts = new List<SegmentVert>(); List<SegmentVert> segmentVerts = new List<SegmentVert>();
List<DtSegInterval> ints = new List<DtSegInterval>(16); List<DtSegInterval> ints = new List<DtSegInterval>(16);
@ -3338,15 +3313,14 @@ namespace DotRecast.Detour
/// @param[in] filter The filter to apply. /// @param[in] filter The filter to apply.
public bool IsValidPolyRef(long refs, IDtQueryFilter filter) public bool IsValidPolyRef(long refs, IDtQueryFilter filter)
{ {
Result<Tuple<DtMeshTile, DtPoly>> tileAndPolyResult = m_nav.GetTileAndPolyByRef(refs); var status = m_nav.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPolyResult.Failed()) if (status.Failed())
{ {
return false; return false;
} }
Tuple<DtMeshTile, DtPoly> tileAndPoly = tileAndPolyResult.result;
// If cannot pass filter, assume flags has changed and boundary is invalid. // If cannot pass filter, assume flags has changed and boundary is invalid.
if (!filter.PassFilter(refs, tileAndPoly.Item1, tileAndPoly.Item2)) if (!filter.PassFilter(refs, tile, poly))
{ {
return false; return false;
} }

View File

@ -264,16 +264,14 @@ namespace DotRecast.Detour
// The API input has been cheked already, skip checking internal // The API input has been cheked already, skip checking internal
// data. // data.
long bestRef = bestNode.id; long bestRef = bestNode.id;
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = m_nav.GetTileAndPolyByRef(bestRef); var status = m_nav.GetTileAndPolyByRef(bestRef, out var bestTile, out var bestPoly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
m_query.status = DtStatus.DT_FAILURE; m_query.status = DtStatus.DT_FAILURE;
// The polygon has disappeared during the sliced query, fail. // The polygon has disappeared during the sliced query, fail.
return Results.Of(m_query.status, iter); return Results.Of(m_query.status, iter);
} }
DtMeshTile bestTile = tileAndPoly.result.Item1;
DtPoly bestPoly = tileAndPoly.result.Item2;
// Get parent and grand parent poly and tile. // Get parent and grand parent poly and tile.
long parentRef = 0, grandpaRef = 0; long parentRef = 0, grandpaRef = 0;
DtMeshTile parentTile = null; DtMeshTile parentTile = null;
@ -292,8 +290,8 @@ namespace DotRecast.Detour
if (parentRef != 0) if (parentRef != 0)
{ {
bool invalidParent = false; bool invalidParent = false;
tileAndPoly = m_nav.GetTileAndPolyByRef(parentRef); status = m_nav.GetTileAndPolyByRef(parentRef, out parentTile, out parentPoly);
invalidParent = tileAndPoly.Failed(); invalidParent = status.Failed();
if (invalidParent || (grandpaRef != 0 && !m_nav.IsValidPolyRef(grandpaRef))) if (invalidParent || (grandpaRef != 0 && !m_nav.IsValidPolyRef(grandpaRef)))
{ {
// The polygon has disappeared during the sliced query, // The polygon has disappeared during the sliced query,
@ -301,9 +299,6 @@ namespace DotRecast.Detour
m_query.status = DtStatus.DT_FAILURE; m_query.status = DtStatus.DT_FAILURE;
return Results.Of(m_query.status, iter); return Results.Of(m_query.status, iter);
} }
parentTile = tileAndPoly.result.Item1;
parentPoly = tileAndPoly.result.Item2;
} }
// decide whether to test raycast to previous nodes // decide whether to test raycast to previous nodes

View File

@ -153,14 +153,12 @@ namespace DotRecast.Detour
// Get connected polygons // Get connected polygons
List<long> neis = new List<long>(); List<long> neis = new List<long>();
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = navQuery.GetAttachedNavMesh().GetTileAndPolyByRef(path[0]); var status = navQuery.GetAttachedNavMesh().GetTileAndPolyByRef(path[0], out var tile, out var poly);
if (tileAndPoly.Failed()) if (status.Failed())
{ {
return path; return path;
} }
DtMeshTile tile = tileAndPoly.result.Item1;
DtPoly poly = tileAndPoly.result.Item2;
for (int k = tile.polyLinks[poly.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next) for (int k = tile.polyLinks[poly.index]; k != DtNavMesh.DT_NULL_LINK; k = tile.links[k].next)
{ {
@ -198,4 +196,4 @@ namespace DotRecast.Detour
return path; return path;
} }
} }
} }

View File

@ -1281,16 +1281,12 @@ public class RecastDebugDraw : DebugDraw
return; return;
} }
Result<Tuple<DtMeshTile, DtPoly>> tileAndPolyResult = mesh.GetTileAndPolyByRef(refs); var status = mesh.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPolyResult.Failed()) if (status.Failed())
{ {
return; return;
} }
Tuple<DtMeshTile, DtPoly> tileAndPoly = tileAndPolyResult.result;
DtMeshTile tile = tileAndPoly.Item1;
DtPoly poly = tileAndPoly.Item2;
DepthMask(false); DepthMask(false);
int c = DuTransCol(col, 64); int c = DuTransCol(col, 64);
@ -1406,4 +1402,4 @@ public class RecastDebugDraw : DebugDraw
End(); End();
} }
} }

View File

@ -951,11 +951,9 @@ public class TestNavmeshTool : ITool
{ {
RcVec3f center = RcVec3f.Zero; RcVec3f center = RcVec3f.Zero;
Result<Tuple<DtMeshTile, DtPoly>> tileAndPoly = navMesh.GetTileAndPolyByRef(refs); var status = navMesh.GetTileAndPolyByRef(refs, out var tile, out var poly);
if (tileAndPoly.Succeeded()) if (status.Succeeded())
{ {
DtMeshTile tile = tileAndPoly.result.Item1;
DtPoly poly = tileAndPoly.result.Item2;
for (int i = 0; i < poly.vertCount; ++i) for (int i = 0; i < poly.vertCount; ++i)
{ {
int v = poly.verts[i] * 3; int v = poly.verts[i] * 3;

View File

@ -37,16 +37,17 @@ public class RandomPointTest : AbstractDetourTest
{ {
var status = query.FindRandomPoint(filter, f, out var randomRef, out var randomPt); var status = query.FindRandomPoint(filter, f, out var randomRef, out var randomPt);
Assert.That(status.Succeeded(), Is.True); Assert.That(status.Succeeded(), Is.True);
Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(randomRef).result;
status = navmesh.GetTileAndPolyByRef(randomRef, out var tile, out var poly);
float[] bmin = new float[2]; float[] bmin = new float[2];
float[] bmax = new float[2]; float[] bmax = new float[2];
for (int j = 0; j < tileAndPoly.Item2.vertCount; j++) for (int j = 0; j < poly.vertCount; j++)
{ {
int v = tileAndPoly.Item2.verts[j] * 3; int v = poly.verts[j] * 3;
bmin[0] = j == 0 ? tileAndPoly.Item1.data.verts[v] : Math.Min(bmin[0], tileAndPoly.Item1.data.verts[v]); bmin[0] = j == 0 ? tile.data.verts[v] : Math.Min(bmin[0], tile.data.verts[v]);
bmax[0] = j == 0 ? tileAndPoly.Item1.data.verts[v] : Math.Max(bmax[0], tileAndPoly.Item1.data.verts[v]); bmax[0] = j == 0 ? tile.data.verts[v] : Math.Max(bmax[0], tile.data.verts[v]);
bmin[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Min(bmin[1], tileAndPoly.Item1.data.verts[v + 2]); bmin[1] = j == 0 ? tile.data.verts[v + 2] : Math.Min(bmin[1], tile.data.verts[v + 2]);
bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]); bmax[1] = j == 0 ? tile.data.verts[v + 2] : Math.Max(bmax[1], tile.data.verts[v + 2]);
} }
Assert.That(randomPt.x >= bmin[0], Is.True); Assert.That(randomPt.x >= bmin[0], Is.True);
@ -69,18 +70,18 @@ public class RandomPointTest : AbstractDetourTest
randomRef = nextRandomRef; randomRef = nextRandomRef;
randomPt = nextRandomPt; randomPt = nextRandomPt;
Tuple<DtMeshTile, DtPoly> tileAndPoly = navmesh.GetTileAndPolyByRef(randomRef).result; status = navmesh.GetTileAndPolyByRef(randomRef, out var tile, out var poly);
float[] bmin = new float[2]; float[] bmin = new float[2];
float[] bmax = new float[2]; float[] bmax = new float[2];
for (int j = 0; j < tileAndPoly.Item2.vertCount; j++) for (int j = 0; j < poly.vertCount; j++)
{ {
int v = tileAndPoly.Item2.verts[j] * 3; int v = poly.verts[j] * 3;
bmin[0] = j == 0 ? tileAndPoly.Item1.data.verts[v] : Math.Min(bmin[0], tileAndPoly.Item1.data.verts[v]); bmin[0] = j == 0 ? tile.data.verts[v] : Math.Min(bmin[0], tile.data.verts[v]);
bmax[0] = j == 0 ? tileAndPoly.Item1.data.verts[v] : Math.Max(bmax[0], tileAndPoly.Item1.data.verts[v]); bmax[0] = j == 0 ? tile.data.verts[v] : Math.Max(bmax[0], tile.data.verts[v]);
bmin[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Min(bmin[1], tileAndPoly.Item1.data.verts[v + 2]); bmin[1] = j == 0 ? tile.data.verts[v + 2] : Math.Min(bmin[1], tile.data.verts[v + 2]);
bmax[1] = j == 0 ? tileAndPoly.Item1.data.verts[v + 2] : Math.Max(bmax[1], tileAndPoly.Item1.data.verts[v + 2]); bmax[1] = j == 0 ? tile.data.verts[v + 2] : Math.Max(bmax[1], tile.data.verts[v + 2]);
} }
Assert.That(randomPt.x >= bmin[0], Is.True); Assert.That(randomPt.x >= bmin[0], Is.True);