< Summary

Information
Class: Trailblazer.Pathing.NavigationRayWork
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Ray/NavigationRayWork.cs
Line coverage
100%
Covered lines: 1035
Uncovered lines: 0
Coverable lines: 1035
Total lines: 1627
Line coverage: 100%
Branch coverage
100%
Covered branches: 458
Total branches: 458
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Medium()100%11100%
Begin(...)100%11100%
Reset()100%11100%
Advance(...)100%11100%
Advance(...)100%11100%
AdvanceCore(...)100%1414100%
Trace(...)100%1212100%
ResolveTraceStatus(...)100%1515100%
MapIntervals(...)100%2020100%
EvaluateChain(...)100%6464100%
FinishDestinationSuffix(...)100%1616100%
Expand(...)100%5252100%
ExpandVolume(...)100%1010100%
FindVolumeTarget(...)100%1414100%
EvaluateExplicitEdge(...)100%3636100%
MapExplicitStatus(...)100%22100%
IsExplicitFirstLegValid(...)100%66100%
IsEarlierContinuation(...)100%44100%
CompareAlongRay(...)100%11100%
CompareAlongRay(...)100%66100%
FindMapped(...)100%1010100%
ContainsParameter(...)100%22100%
ResolvePortalTargetOrdinal(...)100%44100%
IsExplicitPortalProgressValid(...)100%44100%
ShouldAcceptContinuation(...)100%11100%
ApplyContinuation(...)100%44100%
FindTarget(...)100%11100%
CanSeed(...)100%2424100%
MatchesSeedConstraint(...)100%44100%
AllowsEdge(...)100%1212100%
CanFinish(...)100%1818100%
CertifyVolumeSegment(...)100%11100%
MapVolumeStatus(...)100%55100%
IsTraceIntervalCurrent(...)100%11100%
ShouldAdvanceFarthestExit(...)100%22100%
IsPermittedFinalTarget(...)100%1414100%
IsPageDependencyCurrent(...)100%22100%
ResolveVolumeTraversalStatus(...)100%66100%
MapTraversalAdvanceStatus(...)100%66100%
GetEndpointAllowance(...)100%1212100%
TryGetIncomingPortal(...)100%88100%
IsSemanticCostNeutral(...)100%44100%
GetAddress(...)100%11100%
IsSemanticCostNeutral(...)100%22100%
TryRecordDependencyNode(...)100%22100%
FinishSuccess(...)100%22100%
FinishBlocked()100%22100%
AreDependenciesCurrent()100%1616100%
TryConsumeLookup(...)100%22100%
TryConsumeConnectionLeg(...)100%22100%
TryConsumePortal(...)100%66100%
TryConsumePrism(...)100%66100%
Finish(...)100%22100%
ReleaseExplicitConnectionReferences()100%44100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Ray/NavigationRayWork.cs

#LineLine coverage
 1//=======================================================================
 2// NavigationRayWork.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using System;
 9using FixedMathSharp;
 10using FixedMathSharp.Geometry;
 11using GridForge.Grids;
 12using GridForge.Grids.Topology;
 13using GridForge.Utility;
 14
 15namespace Trailblazer.Pathing;
 16
 17/// <summary>Evaluates one bounded straight segment through the immutable navigation graph.</summary>
 18internal sealed class NavigationRayWork
 19{
 20    private readonly NavigationRayWorkspace _workspace;
 21    private NavigationRayRequest _request;
 22    private TraversalEvaluator _evaluator;
 23    private ulong _worldChangeSequence;
 24    private bool _meterBlocked;
 25    private bool _begun;
 26
 1722627    internal NavigationRayWork(NavigationRayWorkspace workspace)
 28    {
 1722629        SwiftThrowHelper.ThrowIfNull(workspace, nameof(workspace));
 1722630        _workspace = workspace;
 1722631        Status = NavigationRayStatus.Pending;
 1722632    }
 33
 34    internal NavigationRayStatus Status { get; private set; }
 35
 36    internal NavigationRayResult Result { get; private set; }
 37
 1493338    private TraversalMedium Medium => _request.Medium;
 39
 40    internal void Begin(in NavigationRayRequest request)
 41    {
 195542        Reset();
 195543        _request = request;
 195544        _evaluator = new TraversalEvaluator(
 195545            request.ExpectedGraph,
 195546            request.Profile,
 195547            request.AreaPolicy,
 195548            request.Medium);
 195549        Result = default;
 195550        Status = NavigationRayStatus.Pending;
 195551        _worldChangeSequence = 0;
 195552        _meterBlocked = false;
 195553        _begun = true;
 195554    }
 55
 56    internal void Reset()
 57    {
 749458        ReleaseExplicitConnectionReferences();
 749459        _workspace.Reset();
 749460        _request = default;
 749461        _evaluator = default;
 749462        Result = default;
 749463        Status = NavigationRayStatus.Pending;
 749464        _worldChangeSequence = 0;
 749465        _meterBlocked = false;
 749466        _begun = false;
 749467    }
 68
 69    internal NavigationRayStatus Advance(NavigationWorkMeter meter)
 70    {
 132771        SwiftThrowHelper.ThrowIfNull(meter, nameof(meter));
 132772        GuideSampleWorkMeter unused = default;
 132773        return AdvanceCore(meter, ref unused, useGuideMeter: false);
 74    }
 75
 76    internal NavigationRayStatus Advance(ref GuideSampleWorkMeter meter) =>
 62477        AdvanceCore(null, ref meter, useGuideMeter: true);
 78
 79    private NavigationRayStatus AdvanceCore(
 80        NavigationWorkMeter? queryMeter,
 81        ref GuideSampleWorkMeter guideMeter,
 82        bool useGuideMeter)
 83    {
 195184        if (!_begun || Status != NavigationRayStatus.Pending)
 285            return Status;
 194986        if (useGuideMeter
 194987            && Medium is TraversalMedium.Gas or TraversalMedium.Liquid)
 88        {
 189            return Finish(NavigationRayStatus.Blocked);
 90        }
 91
 194892        NavigationRayStatus traceStatus = Trace(
 194893            queryMeter,
 194894            ref guideMeter,
 194895            useGuideMeter);
 194896        if (traceStatus != NavigationRayStatus.Pending)
 9197            return Finish(traceStatus);
 185798        NavigationRayStatus mapStatus = MapIntervals(
 185799            queryMeter,
 1857100            ref guideMeter,
 1857101            useGuideMeter);
 1857102        if (mapStatus != NavigationRayStatus.Pending)
 24103            return Finish(mapStatus);
 1833104        return EvaluateChain(queryMeter, ref guideMeter, useGuideMeter);
 105    }
 106
 107    private NavigationRayStatus Trace(
 108        NavigationWorkMeter? queryMeter,
 109        ref GuideSampleWorkMeter guideMeter,
 110        bool useGuideMeter)
 111    {
 1954112        int gridLimit = useGuideMeter
 1954113            ? _workspace.MapCapacity
 1954114            : Math.Min(_workspace.MapCapacity, queryMeter!.RemainingLookupProbes);
 1954115        int addressLimit = useGuideMeter
 1954116            ? _workspace.CoveredAddressCapacity
 1954117            : Math.Min(
 1954118                _workspace.CoveredAddressCapacity,
 1954119                queryMeter!.RemainingCoveredVoxelIntervals);
 1954120        int outputLimit = Math.Min(
 1954121            _workspace.TraceIntervalCapacity,
 1954122            useGuideMeter
 1954123                ? guideMeter.GetTraceIntervalAllowance()
 1954124                : queryMeter!.RemainingTraceIntervals);
 1954125        long candidateWorkLimit = useGuideMeter
 1954126            ? guideMeter.GetCurrentNodeLookupAllowance()
 1954127            : queryMeter!.RemainingGridCandidateWork;
 1954128        ulong before = _request.World.ChangeSequence;
 1954129        GridTraceIntervalReport report = GridTracer.TraceIntervalsInto(
 1954130            _request.World,
 1954131            _request.Start,
 1954132            _request.End,
 1954133            _workspace.TraceIntervals,
 1954134            _workspace.TraceScratch,
 1954135            gridLimit,
 1954136            addressLimit,
 1954137            outputLimit,
 1954138            candidateWorkLimit);
 1954139        ulong after = _request.World.ChangeSequence;
 140
 1954141        int traceIntervals = report.Status == GridTraceIntervalStatus.OutputLimitExceeded
 1954142            ? outputLimit
 1954143            : report.IntervalCount;
 1954144        if (useGuideMeter)
 145        {
 623146            guideMeter.TryConsumeCurrentNodeLookupProbes(
 623147                checked(report.GridCandidateCount + report.AddressCandidateCount));
 623148            guideMeter.TryConsumeTraceIntervals(traceIntervals);
 149        }
 150        else
 151        {
 1331152            queryMeter!.TryConsumeLookupProbes(report.GridCandidateCount);
 1331153            queryMeter.TryConsumeCoveredVoxelIntervals(report.AddressCandidateCount);
 1331154            queryMeter.TryConsumeTraceIntervals(traceIntervals);
 155        }
 1954156        _worldChangeSequence = after;
 1954157        return ResolveTraceStatus(
 1954158            before,
 1954159            after,
 1954160            report.Status,
 1954161            gridLimit,
 1954162            _workspace.MapCapacity,
 1954163            addressLimit,
 1954164            _workspace.CoveredAddressCapacity,
 1954165            outputLimit,
 1954166            _workspace.TraceIntervalCapacity);
 167    }
 168
 169    internal static NavigationRayStatus ResolveTraceStatus(
 170        ulong worldSequenceBefore,
 171        ulong worldSequenceAfter,
 172        GridTraceIntervalStatus status,
 173        int gridLimit,
 174        int mapCapacity,
 175        int addressLimit,
 176        int coveredAddressCapacity,
 177        int outputLimit,
 178        int traceIntervalCapacity)
 179    {
 1964180        if (worldSequenceBefore != worldSequenceAfter)
 1181            return NavigationRayStatus.Stale;
 1963182        return status switch
 1963183        {
 1864184            GridTraceIntervalStatus.Complete => NavigationRayStatus.Pending,
 2185            GridTraceIntervalStatus.UnrepresentableGeometry => NavigationRayStatus.CostOverflow,
 1963186            GridTraceIntervalStatus.GridCandidateLimitExceeded =>
 5187                gridLimit < mapCapacity
 5188                    ? NavigationRayStatus.BudgetExceeded
 5189                    : NavigationRayStatus.CapacityExceeded,
 1963190            GridTraceIntervalStatus.AddressCandidateLimitExceeded =>
 63191                addressLimit < coveredAddressCapacity
 63192                    ? NavigationRayStatus.BudgetExceeded
 63193                    : NavigationRayStatus.CapacityExceeded,
 1963194            GridTraceIntervalStatus.CandidateWorkLimitExceeded =>
 12195                NavigationRayStatus.BudgetExceeded,
 17196            _ => outputLimit < traceIntervalCapacity
 17197                ? NavigationRayStatus.BudgetExceeded
 17198                : NavigationRayStatus.CapacityExceeded
 1963199        };
 200    }
 201
 202    private NavigationRayStatus MapIntervals(
 203        NavigationWorkMeter? queryMeter,
 204        ref GuideSampleWorkMeter guideMeter,
 205        bool useGuideMeter)
 206    {
 1863207        NavigationWorldGraph graph = _request.ExpectedGraph;
 1863208        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 18116209        for (int ordinal = 0; ordinal < _workspace.TraceIntervals.Count; ordinal++)
 210        {
 7219211            ref NavigationRayChainRecord record = ref records[ordinal];
 7219212            record = default;
 7219213            record.PredecessorOrdinal = -1;
 7219214            record.RootOrdinal = -1;
 7219215            GridTraceInterval interval = _workspace.TraceIntervals[ordinal];
 7219216            if (!TryConsumeLookup(
 7219217                    queryMeter,
 7219218                    ref guideMeter,
 7219219                    useGuideMeter,
 7219220                    1))
 12221                return NavigationRayStatus.BudgetExceeded;
 7207222            if (!graph.TryGetMapId(interval.ConfigurationKey, out string mapId))
 223                continue;
 7202224            bool hasInstance = graph.TryGetMap(
 7202225                mapId,
 7202226                out NavigationMapInstance instance);
 227            System.Diagnostics.Debug.Assert(
 228                hasInstance,
 229                "the immutable configuration index and map directory are built and replaced together");
 7202230            if (!IsTraceIntervalCurrent(
 7202231                    instance.GridIdentity.Matches(
 7202232                        interval.Cell.WorldSpawnToken,
 7202233                        interval.Cell.GridIndex,
 7202234                        interval.Cell.GridSpawnToken),
 7202235                    instance.GridIdentity.ConfigurationKey == interval.ConfigurationKey,
 7202236                    instance.GridLastChangeSequence == interval.GridLastChangeSequence))
 237            {
 4238                return NavigationRayStatus.Stale;
 239            }
 7198240            if (!interval.IsPhysicallyPresent)
 241                continue;
 242
 6881243            var address = new NavigationCellAddress(mapId, interval.Cell.VoxelIndex);
 6881244            if (!graph.TryGetNodeRef(address, out NavigationNodeRef node))
 245                continue;
 5312246            if (!_workspace.Dependencies.TryRecordPage(
 5312247                    mapId,
 5312248                    node.CellSlot / NavigationSemanticPage.SlotCount))
 249            {
 5250                return NavigationRayStatus.CapacityExceeded;
 251            }
 5307252            if (!graph.TryGetSurfaceComponent(
 5307253                    address,
 5307254                    Medium,
 5307255                    out NavigationSurfaceComponentKey component,
 5307256                    out _))
 257            {
 258                continue;
 259            }
 5302260            if (!_workspace.Dependencies.TryRecordComponent(component))
 3261                return NavigationRayStatus.CapacityExceeded;
 5299262            if (!_evaluator.TryGetPassableNodeState(node, out _))
 263                continue;
 264
 5293265            record.Node = node;
 5293266            record.State = NavigationRayChainRecordState.Unreached;
 5293267            record.IsSemanticCostNeutral = true;
 268        }
 1839269        return NavigationRayStatus.Pending;
 270    }
 271
 272    private NavigationRayStatus EvaluateChain(
 273        NavigationWorkMeter? queryMeter,
 274        ref GuideSampleWorkMeter guideMeter,
 275        bool useGuideMeter)
 276    {
 1839277        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 1839278        int count = _workspace.TraceIntervals.Count;
 1839279        NavigationSurfaceComponentKey finishComponent = default;
 1839280        if (_request.ChainConstraint.Kind
 1839281                == NavigationRayChainConstraintKind.FinishAddress
 1839282            && !_request.ExpectedGraph.TryGetSurfaceComponent(
 1839283                _request.ChainConstraint.TargetAddress,
 1839284                Medium,
 1839285                out finishComponent,
 1839286                out _))
 287        {
 1288            return Finish(NavigationRayStatus.Stale);
 289        }
 1838290        bool permitsStartPrefix = _request.EndpointAllowance
 1838291            == NavigationRayEndpointAllowance.StartPrefix;
 1838292        bool permitsDestinationSuffix = _request.EndpointAllowance
 1838293            == NavigationRayEndpointAllowance.DestinationSuffix;
 1838294        Fixed64 firstSeedParameter = Fixed64.MaxValue;
 1838295        if (permitsStartPrefix)
 296        {
 2992297            for (int ordinal = 0; ordinal < count; ordinal++)
 298            {
 1048299                if (records[ordinal].State == NavigationRayChainRecordState.Unreached
 1048300                    && MatchesSeedConstraint(ordinal, finishComponent)
 1048301                    && _workspace.TraceIntervals[ordinal].TEnter < firstSeedParameter)
 302                {
 443303                    firstSeedParameter = _workspace.TraceIntervals[ordinal].TEnter;
 304                }
 305            }
 448306            NavigationRayChainConstraintKind constraintKind =
 448307                _request.ChainConstraint.Kind;
 448308            if (constraintKind is NavigationRayChainConstraintKind.SourceAddress
 448309                    or NavigationRayChainConstraintKind.SelectedEdge)
 310            {
 2736311                for (int ordinal = 0; ordinal < count; ordinal++)
 312                {
 968313                    if (records[ordinal].State == NavigationRayChainRecordState.Unreached
 968314                        && _workspace.TraceIntervals[ordinal].TEnter < firstSeedParameter)
 315                    {
 17316                        return FinishBlocked();
 317                    }
 318                }
 319            }
 320        }
 17872321        for (int ordinal = 0; ordinal < count; ordinal++)
 322        {
 7119323            GridTraceInterval interval = _workspace.TraceIntervals[ordinal];
 7119324            ref NavigationRayChainRecord record = ref records[ordinal];
 7119325            NavigationRayStatus seedStatus = NavigationRayStatus.Pending;
 7119326            if (record.State != NavigationRayChainRecordState.Unreached
 7119327                || (permitsStartPrefix
 7119328                    ? interval.TEnter != firstSeedParameter
 7119329                    : interval.TEnter > Fixed64.Zero || interval.TExit < Fixed64.Zero)
 7119330                || !CanSeed(
 7119331                    ordinal,
 7119332                    finishComponent,
 7119333                    queryMeter,
 7119334                    ref guideMeter,
 7119335                    useGuideMeter,
 7119336                    out seedStatus))
 337            {
 5307338                if (_meterBlocked)
 3339                    return Finish(NavigationRayStatus.BudgetExceeded);
 5304340                if (seedStatus != NavigationRayStatus.Pending)
 1341                    return Finish(seedStatus);
 342                continue;
 343            }
 1812344            record.RootOrdinal = ordinal;
 1812345            record.ArrivalParameter = Fixed64.Zero;
 1812346            record.TraversalCost = Fixed64.Zero;
 1812347            record.IsSemanticCostNeutral = true;
 1812348            record.State = NavigationRayChainRecordState.Ready;
 349        }
 350
 351        bool progressed;
 352        do
 353        {
 1880354            progressed = false;
 14320355            for (int ordinal = 0; ordinal < count; ordinal++)
 356            {
 7031357                ref NavigationRayChainRecord record = ref records[ordinal];
 7031358                if (record.State != NavigationRayChainRecordState.Ready)
 359                    continue;
 4906360                NavigationRayStatus finishStatus = NavigationRayStatus.Pending;
 4906361                if (!permitsDestinationSuffix
 4906362                    && CanFinish(
 4906363                        ordinal,
 4906364                        queryMeter,
 4906365                        ref guideMeter,
 4906366                        useGuideMeter,
 4906367                        out finishStatus))
 1708368                    return FinishSuccess(ordinal);
 3198369                if (_meterBlocked)
 4370                    return Finish(NavigationRayStatus.BudgetExceeded);
 3194371                if (finishStatus != NavigationRayStatus.Pending)
 3372                    return Finish(finishStatus);
 373
 3191374                record.State = NavigationRayChainRecordState.Expanded;
 3191375                progressed = true;
 3191376                NavigationRayChainConstraintKind constraintKind =
 3191377                    _request.ChainConstraint.Kind;
 3191378                if (constraintKind == NavigationRayChainConstraintKind.SourceAddress
 3191379                    || (constraintKind == NavigationRayChainConstraintKind.SelectedEdge
 3191380                        && record.PredecessorOrdinal >= 0))
 381                {
 382                    continue;
 383                }
 384
 3179385                NavigationRayStatus expansion = Expand(
 3179386                    ordinal,
 3179387                    queryMeter,
 3179388                    ref guideMeter,
 3179389                    useGuideMeter);
 3179390                if (expansion != NavigationRayStatus.Pending)
 36391                    return Finish(expansion);
 392            }
 393        }
 129394        while (progressed);
 395
 66396        if (permitsDestinationSuffix)
 15397            return FinishDestinationSuffix(queryMeter, ref guideMeter, useGuideMeter);
 51398        return FinishBlocked();
 399    }
 400
 401    private NavigationRayStatus FinishDestinationSuffix(
 402        NavigationWorkMeter? queryMeter,
 403        ref GuideSampleWorkMeter guideMeter,
 404        bool useGuideMeter)
 405    {
 15406        Fixed64 farthestExit = Fixed64.MinValue;
 15407        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 15408        int count = _workspace.TraceIntervals.Count;
 100409        for (int ordinal = 0; ordinal < count; ordinal++)
 410        {
 35411            if (ShouldAdvanceFarthestExit(
 35412                    records[ordinal].State,
 35413                    _workspace.TraceIntervals[ordinal].TExit,
 35414                    farthestExit))
 415            {
 23416                farthestExit = _workspace.TraceIntervals[ordinal].TExit;
 417            }
 418        }
 56419        for (int ordinal = 0; ordinal < count; ordinal++)
 420        {
 27421            if (records[ordinal].State != NavigationRayChainRecordState.Expanded
 27422                || _workspace.TraceIntervals[ordinal].TExit != farthestExit)
 423            {
 424                continue;
 425            }
 15426            if (CanFinish(
 15427                    ordinal,
 15428                    queryMeter,
 15429                    ref guideMeter,
 15430                    useGuideMeter,
 15431                    out NavigationRayStatus finishStatus))
 12432                return FinishSuccess(ordinal);
 3433            if (_meterBlocked)
 1434                return Finish(NavigationRayStatus.BudgetExceeded);
 2435            if (finishStatus != NavigationRayStatus.Pending)
 1436                return Finish(finishStatus);
 437        }
 1438        return FinishBlocked();
 439    }
 440
 441    private NavigationRayStatus Expand(
 442        int sourceOrdinal,
 443        NavigationWorkMeter? queryMeter,
 444        ref GuideSampleWorkMeter guideMeter,
 445        bool useGuideMeter)
 446    {
 3179447        if (!useGuideMeter
 3179448            && Medium is TraversalMedium.Gas or TraversalMedium.Liquid)
 449        {
 271450            return ExpandVolume(sourceOrdinal, queryMeter!);
 451        }
 452
 2908453        NavigationWorldGraph graph = _request.ExpectedGraph;
 2908454        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 2908455        ref NavigationRayChainRecord sourceRecord = ref records[sourceOrdinal];
 2908456        if (!TryGetIncomingPortal(
 2908457                sourceOrdinal,
 2908458                queryMeter,
 2908459                ref guideMeter,
 2908460                useGuideMeter,
 2908461                out GridNavigationPortal incomingPortal))
 462        {
 2463            return NavigationRayStatus.BudgetExceeded;
 464        }
 2906465        graph.TryGetNodeAddress(
 2906466            sourceRecord.Node,
 2906467            out NavigationCellAddress sourceAddress);
 2906468        graph.TryGetSeamPrism(sourceAddress, out GridCellPrism sourcePrism);
 469
 2906470        NavigationSurfaceEdgeEnumerator edges = graph.EnumerateSurfaceEdges(sourceRecord.Node);
 2906471        int edgeSteps = int.MaxValue;
 2845472        while (true)
 473        {
 10952474            NavigationSurfaceEdgeAdvanceStatus advance = useGuideMeter
 10952475                ? edges.AdvanceOne(ref guideMeter, ref edgeSteps)
 10952476                : edges.AdvanceOne(queryMeter, ref edgeSteps);
 10952477            if (advance == NavigationSurfaceEdgeAdvanceStatus.Blocked)
 12478                return NavigationRayStatus.BudgetExceeded;
 10940479            if (advance == NavigationSurfaceEdgeAdvanceStatus.Pending)
 480                continue;
 8038481            if (advance == NavigationSurfaceEdgeAdvanceStatus.Complete)
 2877482                return NavigationRayStatus.Pending;
 483
 5161484            NavigationGraphEdge edge = edges.Current;
 5161485            int edgeOrdinal = edges.CurrentOrdinal;
 5161486            if (!AllowsEdge(sourceAddress, edge.Target, edgeOrdinal))
 487                continue;
 488            Fixed64 edgeCost;
 489            int targetOrdinal;
 490            Fixed64 targetParameter;
 5139491            NavigationExplicitConnectionRecord incomingExplicit = null!;
 5139492            if (edge.Kind == NavigationGraphEdgeKind.Explicit)
 493            {
 35494                NavigationRayStatus explicitStatus = EvaluateExplicitEdge(
 35495                    sourceOrdinal,
 35496                    sourceRecord.Node,
 35497                    edge,
 35498                    incomingPortal,
 35499                    queryMeter,
 35500                    ref guideMeter,
 35501                    useGuideMeter,
 35502                    out edgeCost,
 35503                    out targetOrdinal,
 35504                    out targetParameter);
 35505                if (explicitStatus == NavigationRayStatus.BudgetExceeded
 35506                    || explicitStatus == NavigationRayStatus.CostOverflow
 35507                    || explicitStatus == NavigationRayStatus.CapacityExceeded
 35508                    || explicitStatus == NavigationRayStatus.Stale)
 509                {
 5510                    return explicitStatus;
 511                }
 30512                if (explicitStatus != NavigationRayStatus.Success)
 513                {
 514                    continue;
 515                }
 19516                incomingExplicit = edge.ExplicitConnection;
 517            }
 518            else
 519            {
 5104520                TraversalEvaluationStatus evaluation = _evaluator.EvaluateEdge(
 5104521                    sourceRecord.Node,
 5104522                    edge,
 5104523                    out TraversalEdgeEvidence evidence);
 5104524                edgeCost = evidence.Cost;
 5104525                if (evaluation == TraversalEvaluationStatus.CostOverflow)
 1526                    return NavigationRayStatus.CostOverflow;
 5103527                if (evaluation != TraversalEvaluationStatus.Passable)
 528                    continue;
 5102529                if (!TryConsumePortal(queryMeter, ref guideMeter, useGuideMeter)
 5102530                    || !GridCellGeometry.TryGetNavigationPortalTraversalParameters(
 5102531                        evidence.SourcePrism,
 5102532                        evidence.TargetPrism,
 5102533                        evidence.Portal,
 5102534                        _request.Start,
 5102535                        _request.End,
 5102536                        _request.Profile.Shape.Radius,
 5102537                        _request.Profile.Shape.Height,
 5102538                        out Fixed64 sourceParameter,
 5102539                        out targetParameter))
 540                {
 2268541                    if (_meterBlocked)
 6542                        return NavigationRayStatus.BudgetExceeded;
 543                    continue;
 544                }
 2834545                GridTraceInterval sourceInterval = _workspace.TraceIntervals[sourceOrdinal];
 2834546                targetOrdinal = ResolvePortalTargetOrdinal(
 2834547                    sourceParameter,
 2834548                    sourceRecord.ArrivalParameter,
 2834549                    sourceInterval.TEnter,
 2834550                    sourceInterval.TExit,
 2834551                    FindTarget(edge.Target, targetParameter));
 2834552                if (targetOrdinal < 0)
 553                    continue;
 2832554                Vector3d sourcePoint = Vector3d.Lerp(
 2832555                    _request.Start,
 2832556                    _request.End,
 2832557                    sourceRecord.ArrivalParameter);
 2832558                Vector3d portalPoint = Vector3d.Lerp(
 2832559                    _request.Start,
 2832560                    _request.End,
 2832561                    sourceParameter);
 562                System.Diagnostics.Debug.Assert(
 563                    sourceRecord.IncomingExplicitConnection == null
 564                    || new FixedSegment(sourcePoint, portalPoint).Contains(
 565                        sourceRecord.IncomingExplicitConnection.Definition.ExitAnchor),
 566                    "a successful explicit exit lies on the traced ray inside the convex source prism and therefore on i
 2832567                if (!TryConsumePrism(queryMeter, ref guideMeter, useGuideMeter)
 2832568                    || !GridCellGeometry.IsNavigationBodySegmentValid(
 2832569                        sourcePrism,
 2832570                        sourcePoint,
 2832571                        portalPoint,
 2832572                        _request.Profile.Shape.Radius,
 2832573                        _request.Profile.Shape.Height,
 2832574                        incomingPortal,
 2832575                        evidence.Portal,
 2832576                        GetEndpointAllowance(
 2832577                            sourceOrdinal,
 2832578                            sourceRecord,
 2832579                            isFinalSegment: false)))
 580                {
 5581                    if (_meterBlocked)
 4582                        return NavigationRayStatus.BudgetExceeded;
 583                    continue;
 584                }
 585            }
 2846586            if (!Fixed64.TryAdd(
 2846587                    sourceRecord.TraversalCost,
 2846588                    edgeCost,
 2846589                    out Fixed64 traversalCost))
 590            {
 1591                return NavigationRayStatus.CostOverflow;
 592            }
 593
 2845594            ref NavigationRayChainRecord targetRecord = ref records[targetOrdinal];
 2845595            bool isEarlierContinuation = IsEarlierContinuation(
 2845596                    targetRecord,
 2845597                    targetParameter,
 2845598                    incomingExplicit);
 2845599            ApplyContinuation(
 2845600                ref targetRecord,
 2845601                candidatePassable: true,
 2845602                isEarlierContinuation,
 2845603                sourceOrdinal,
 2845604                sourceRecord.RootOrdinal,
 2845605                targetParameter,
 2845606                traversalCost,
 2845607                incomingExplicit,
 2845608                sourceRecord.IsSemanticCostNeutral && IsSemanticCostNeutral(edge));
 609        }
 610    }
 611
 612    private NavigationRayStatus ExpandVolume(
 613        int sourceOrdinal,
 614        NavigationWorkMeter meter)
 615    {
 271616        NavigationWorldGraph graph = _request.ExpectedGraph;
 271617        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 271618        ref NavigationRayChainRecord sourceRecord = ref records[sourceOrdinal];
 271619        var source = new NavigationMediumStateRef(sourceRecord.Node, Medium);
 271620        var edges = new NavigationTraversalEdgeEnumerator(
 271621            _request.World,
 271622            graph,
 271623            source,
 271624            _request.Profile,
 271625            _request.AreaPolicy,
 271626            _workspace,
 271627            allowTransitions: false,
 271628            emittedSurfaceOrdinal: -1);
 271629        var segmentEvaluator = new NavigationVolumeEdgeEvaluator(
 271630            _request.World,
 271631            graph,
 271632            _request.Profile,
 271633            _request.AreaPolicy,
 271634            Medium,
 271635            _workspace);
 271636        int edgeSteps = int.MaxValue;
 271637        int connectionSteps = int.MaxValue;
 270638        while (true)
 639        {
 1022640            NavigationTraversalEdgeAdvanceStatus advance = edges.AdvanceOne(
 1022641                meter,
 1022642                _workspace.Dependencies,
 1022643                ref edgeSteps,
 1022644                ref connectionSteps);
 645            System.Diagnostics.Debug.Assert(
 646                advance != NavigationTraversalEdgeAdvanceStatus.Blocked,
 647                "volume-ray enumeration uses an unbounded local edge-step allowance");
 1022648            if (advance != NavigationTraversalEdgeAdvanceStatus.Edge)
 270649                return MapTraversalAdvanceStatus(advance);
 650            System.Diagnostics.Debug.Assert(
 651                advance == NavigationTraversalEdgeAdvanceStatus.Edge
 652                && edges.CurrentKind == NavigationTraversalEdgeKind.Volume
 653                && edges.CurrentTarget.Medium == Medium,
 654                "a transition-disabled volume enumerator emits only same-medium volume edges");
 752655            if (!AllowsEdge(
 752656                    GetAddress(sourceRecord.Node),
 752657                    edges.CurrentTarget.Node,
 752658                    edges.CurrentOrdinal))
 659            {
 660                continue;
 661            }
 662
 519663            int targetOrdinal = FindVolumeTarget(
 519664                sourceOrdinal,
 519665                edges.CurrentTarget.Node,
 519666                edges.CurrentVolumeIsShortcut,
 519667                out Fixed64 targetParameter);
 519668            if (targetOrdinal < 0)
 669                continue;
 271670            Vector3d sourcePoint = Vector3d.Lerp(
 271671                _request.Start,
 271672                _request.End,
 271673                sourceRecord.ArrivalParameter);
 271674            Vector3d targetPoint = Vector3d.Lerp(
 271675                _request.Start,
 271676                _request.End,
 271677                targetParameter);
 271678            NavigationTraversalEvaluationStatus segmentStatus =
 271679                segmentEvaluator.CertifyRaySegment(
 271680                    source,
 271681                    edges.CurrentTarget,
 271682                    sourcePoint,
 271683                    targetPoint,
 271684                    meter,
 271685                    _workspace.Dependencies);
 271686            NavigationRayStatus terminalStatus = ResolveVolumeTraversalStatus(
 271687                segmentStatus,
 271688                sourceRecord.TraversalCost,
 271689                edges.CurrentCost,
 271690                out Fixed64 traversalCost);
 271691            if (terminalStatus != NavigationRayStatus.Pending)
 1692                return terminalStatus;
 693
 270694            ref NavigationRayChainRecord targetRecord = ref records[targetOrdinal];
 270695            bool isEarlierContinuation = IsEarlierContinuation(
 270696                targetRecord,
 270697                targetParameter,
 270698                null!);
 270699            ApplyContinuation(
 270700                ref targetRecord,
 270701                segmentStatus == NavigationTraversalEvaluationStatus.Passable,
 270702                isEarlierContinuation,
 270703                sourceOrdinal,
 270704                sourceRecord.RootOrdinal,
 270705                targetParameter,
 270706                traversalCost,
 270707                null!,
 270708                sourceRecord.IsSemanticCostNeutral
 270709                    && IsSemanticCostNeutral(edges.CurrentTarget.Node));
 710        }
 711    }
 712
 713    private int FindVolumeTarget(
 714        int sourceOrdinal,
 715        NavigationNodeRef target,
 716        bool isShortcut,
 717        out Fixed64 targetParameter)
 718    {
 519719        NavigationWorldGraph graph = _request.ExpectedGraph;
 519720        NavigationRayChainRecord sourceRecord = _workspace.ChainRecords[sourceOrdinal];
 519721        if (!isShortcut)
 722        {
 258723            graph.TryGetNodeAddress(
 258724                sourceRecord.Node,
 258725                out NavigationCellAddress sourceAddress);
 258726            graph.TryGetNodeAddress(target, out NavigationCellAddress targetAddress);
 258727            graph.TryGetSeamPrism(sourceAddress, out GridCellPrism sourcePrism);
 258728            graph.TryGetSeamPrism(targetAddress, out GridCellPrism targetPrism);
 258729            GridCellGeometry.TryCreateNavigationPortal(
 258730                sourcePrism,
 258731                targetPrism,
 258732                out GridNavigationPortal portal);
 258733            if (GridCellGeometry.TryGetNavigationPortalTraversalParameters(
 258734                    sourcePrism,
 258735                    targetPrism,
 258736                    portal,
 258737                    _request.Start,
 258738                    _request.End,
 258739                    _request.Profile.Shape.Radius,
 258740                    _request.Profile.Shape.Height,
 258741                    out Fixed64 sourceParameter,
 258742                    out targetParameter))
 743            {
 165744                GridTraceInterval sourceInterval =
 165745                    _workspace.TraceIntervals[sourceOrdinal];
 165746                return ResolvePortalTargetOrdinal(
 165747                    sourceParameter,
 165748                    sourceRecord.ArrivalParameter,
 165749                    sourceInterval.TEnter,
 165750                    sourceInterval.TExit,
 165751                    FindTarget(target, targetParameter));
 752            }
 753        }
 2082754        for (int ordinal = 0; ordinal < _workspace.TraceIntervals.Count; ordinal++)
 755        {
 793756            ref NavigationRayChainRecord targetRecord =
 793757                ref _workspace.ChainRecords[ordinal];
 793758            if (targetRecord.State == NavigationRayChainRecordState.Unavailable
 793759                || !targetRecord.Node.Equals(target))
 760            {
 761                continue;
 762            }
 113763            GridTraceInterval interval = _workspace.TraceIntervals[ordinal];
 113764            targetParameter = interval.TEnter < sourceRecord.ArrivalParameter
 113765                ? sourceRecord.ArrivalParameter
 113766                : interval.TEnter;
 113767            if (targetParameter <= interval.TExit)
 106768                return ordinal;
 769        }
 248770        targetParameter = default;
 248771        return -1;
 772    }
 773
 774    private NavigationRayStatus EvaluateExplicitEdge(
 775        int sourceOrdinal,
 776        NavigationNodeRef source,
 777        in NavigationGraphEdge edge,
 778        in GridNavigationPortal incomingPortal,
 779        NavigationWorkMeter? queryMeter,
 780        ref GuideSampleWorkMeter guideMeter,
 781        bool useGuideMeter,
 782        out Fixed64 cost,
 783        out int targetOrdinal,
 784        out Fixed64 targetParameter)
 785    {
 35786        cost = Fixed64.Zero;
 35787        targetOrdinal = -1;
 35788        targetParameter = default;
 35789        TraversalExplicitEdgeStatus status = _evaluator.BeginExplicitEdge(
 35790            source,
 35791            edge,
 35792            out TraversalExplicitEdgeWork work);
 35793        if (status != TraversalExplicitEdgeStatus.Pending)
 1794            return MapExplicitStatus(status);
 795
 34796        NavigationExplicitConnectionRecord record = edge.ExplicitConnection;
 34797        NavigationConnection connection = record.Definition;
 34798        var path = new FixedSegment(_request.Start, _request.End);
 34799        bool geometryPassable = path.Contains(connection.EntryAnchor)
 34800            && path.Contains(connection.ExitAnchor);
 34801        int currentOrdinal = sourceOrdinal;
 34802        Fixed64 currentParameter =
 34803            _workspace.ChainRecords[sourceOrdinal].ArrivalParameter;
 34804        GridNavigationPortal currentIncoming = incomingPortal;
 34805        int portalOrdinal = 0;
 86806        while (status == TraversalExplicitEdgeStatus.Pending)
 807        {
 56808            if (!TryConsumeConnectionLeg(
 56809                    queryMeter,
 56810                    ref guideMeter,
 56811                    useGuideMeter))
 1812                return NavigationRayStatus.BudgetExceeded;
 55813            status = _evaluator.AdvanceExplicitEdge(
 55814                ref work,
 55815                out TraversalEdgeEvidence evidence);
 55816            if (status == TraversalExplicitEdgeStatus.CostOverflow)
 1817                return MapExplicitStatus(status);
 818            System.Diagnostics.Debug.Assert(
 819                evidence.DependencyNode.IsValid,
 820                "every advanced explicit corridor leg identifies its immutable dependency node");
 54821            if (!TryRecordDependencyNode(evidence.DependencyNode))
 1822                return NavigationRayStatus.CapacityExceeded;
 53823            if (status == TraversalExplicitEdgeStatus.Impassable)
 1824                return NavigationRayStatus.Blocked;
 825
 52826            cost = evidence.Cost;
 52827            if (!geometryPassable)
 828                continue;
 39829            if (!TryConsumePortal(queryMeter, ref guideMeter, useGuideMeter))
 830            {
 1831                geometryPassable = false;
 1832                continue;
 833            }
 38834            bool hasPortalParameters =
 38835                GridCellGeometry.TryGetNavigationPortalTraversalParameters(
 38836                    evidence.SourcePrism,
 38837                    evidence.TargetPrism,
 38838                    evidence.Portal,
 38839                    _request.Start,
 38840                    _request.End,
 38841                    _request.Profile.Shape.Radius,
 38842                    _request.Profile.Shape.Height,
 38843                    out Fixed64 sourceParameter,
 38844                    out Fixed64 nextParameter);
 38845            GridTraceInterval currentInterval =
 38846                _workspace.TraceIntervals[currentOrdinal];
 38847            if (!IsExplicitPortalProgressValid(
 38848                    hasPortalParameters,
 38849                    sourceParameter,
 38850                    currentParameter,
 38851                    currentInterval.TEnter,
 38852                    currentInterval.TExit))
 853            {
 1854                geometryPassable = false;
 1855                continue;
 856            }
 37857            int nextOrdinal = FindMapped(
 37858                _workspace,
 37859                evidence.DependencyNode,
 37860                nextParameter);
 37861            if (nextOrdinal < 0)
 862            {
 1863                geometryPassable = false;
 1864                continue;
 865            }
 36866            Vector3d currentPoint = Vector3d.Lerp(
 36867                _request.Start,
 36868                _request.End,
 36869                currentParameter);
 36870            Vector3d outgoingPoint = Vector3d.Lerp(
 36871                _request.Start,
 36872                _request.End,
 36873                sourceParameter);
 36874            if (portalOrdinal == 0)
 875            {
 23876                var firstLeg = new FixedSegment(currentPoint, outgoingPoint);
 23877                NavigationExplicitConnectionRecord prior =
 23878                    _workspace.ChainRecords[sourceOrdinal].IncomingExplicitConnection;
 23879                if (!IsExplicitFirstLegValid(
 23880                        firstLeg,
 23881                        connection.EntryAnchor,
 23882                        prior,
 23883                        _request.Start,
 23884                        _request.End))
 885                {
 1886                    geometryPassable = false;
 1887                    continue;
 888                }
 889            }
 35890            if (!TryConsumePrism(queryMeter, ref guideMeter, useGuideMeter))
 891            {
 1892                geometryPassable = false;
 1893                continue;
 894            }
 34895            if (!GridCellGeometry.IsNavigationBodySegmentValid(
 34896                    evidence.SourcePrism,
 34897                    currentPoint,
 34898                    outgoingPoint,
 34899                    _request.Profile.Shape.Radius,
 34900                    _request.Profile.Shape.Height,
 34901                    currentIncoming,
 34902                    evidence.Portal,
 34903                    portalOrdinal == 0
 34904                        ? GetEndpointAllowance(
 34905                            sourceOrdinal,
 34906                            _workspace.ChainRecords[sourceOrdinal],
 34907                            isFinalSegment: false)
 34908                        : GridNavigationBodySegmentEndpointAllowance.None))
 909            {
 1910                geometryPassable = false;
 1911                continue;
 912            }
 913
 33914            currentOrdinal = nextOrdinal;
 33915            currentParameter = nextParameter;
 33916            currentIncoming = evidence.Portal;
 33917            portalOrdinal++;
 918        }
 919
 30920        if (_meterBlocked)
 2921            return NavigationRayStatus.BudgetExceeded;
 28922        if (!geometryPassable)
 9923            return NavigationRayStatus.Blocked;
 924        System.Diagnostics.Debug.Assert(
 925            _workspace.ChainRecords[currentOrdinal].Node.Equals(edge.Target)
 926            && _workspace.ChainRecords[currentOrdinal].State
 927                != NavigationRayChainRecordState.Unavailable,
 928            "a successful explicit replay ends on the final passable dependency node mapped by FindMapped");
 19929        targetOrdinal = currentOrdinal;
 19930        targetParameter = currentParameter;
 19931        return NavigationRayStatus.Success;
 932    }
 933
 934    private static NavigationRayStatus MapExplicitStatus(
 935        TraversalExplicitEdgeStatus status) =>
 2936        status == TraversalExplicitEdgeStatus.CostOverflow
 2937            ? NavigationRayStatus.CostOverflow
 2938            : NavigationRayStatus.Blocked;
 939
 940    internal static bool IsExplicitFirstLegValid(
 941        in FixedSegment firstLeg,
 942        Vector3d entryAnchor,
 943        NavigationExplicitConnectionRecord prior,
 944        Vector3d rayStart,
 945        Vector3d rayEnd)
 946    {
 28947        if (!firstLeg.Contains(entryAnchor))
 1948            return false;
 27949        if (prior == null)
 18950            return true;
 9951        Vector3d priorExit = prior.Definition.ExitAnchor;
 9952        return firstLeg.Contains(priorExit)
 9953            && CompareAlongRay(rayStart, rayEnd, priorExit, entryAnchor) <= 0;
 954    }
 955
 956    private bool IsEarlierContinuation(
 957        in NavigationRayChainRecord current,
 958        Fixed64 candidateArrivalParameter,
 959        NavigationExplicitConnectionRecord candidateExplicit)
 960    {
 3115961        Vector3d candidate = candidateExplicit != null
 3115962            ? candidateExplicit.Definition.ExitAnchor
 3115963            : Vector3d.Lerp(
 3115964                _request.Start,
 3115965                _request.End,
 3115966                candidateArrivalParameter);
 3115967        Vector3d prior = current.IncomingExplicitConnection != null
 3115968            ? current.IncomingExplicitConnection.Definition.ExitAnchor
 3115969            : Vector3d.Lerp(
 3115970                _request.Start,
 3115971                _request.End,
 3115972                current.ArrivalParameter);
 3115973        return CompareAlongRay(candidate, prior) < 0;
 974    }
 975
 976    private int CompareAlongRay(Vector3d first, Vector3d second)
 3115977        => CompareAlongRay(_request.Start, _request.End, first, second);
 978
 979    private static int CompareAlongRay(
 980        Vector3d rayStart,
 981        Vector3d rayEnd,
 982        Vector3d first,
 983        Vector3d second)
 984    {
 3123985        if (rayEnd.X != rayStart.X)
 986        {
 2963987            return rayEnd.X > rayStart.X
 2963988                ? first.X.CompareTo(second.X)
 2963989                : second.X.CompareTo(first.X);
 990        }
 160991        return rayEnd.Z > rayStart.Z
 160992            ? first.Z.CompareTo(second.Z)
 160993            : second.Z.CompareTo(first.Z);
 994    }
 995
 996    internal static int FindMapped(
 997        NavigationRayWorkspace workspace,
 998        NavigationNodeRef target,
 999        Fixed64 parameter)
 1000    {
 219181001        for (int ordinal = 0; ordinal < workspace.TraceIntervals.Count; ordinal++)
 1002        {
 109561003            GridTraceInterval interval = workspace.TraceIntervals[ordinal];
 109561004            if (interval.TEnter > parameter)
 1005                break;
 109551006            ref NavigationRayChainRecord record = ref workspace.ChainRecords[ordinal];
 109551007            if (record.State != NavigationRayChainRecordState.Unavailable
 109551008                && record.Node.Equals(target)
 109551009                && interval.TExit >= parameter)
 1010            {
 30341011                return ordinal;
 1012            }
 1013        }
 41014        return -1;
 1015    }
 1016
 1017    internal static bool ContainsParameter(
 1018        Fixed64 enter,
 1019        Fixed64 exit,
 30481020        Fixed64 parameter) => enter <= parameter && exit >= parameter;
 1021
 1022    internal static int ResolvePortalTargetOrdinal(
 1023        Fixed64 sourceParameter,
 1024        Fixed64 arrivalParameter,
 1025        Fixed64 intervalEnter,
 1026        Fixed64 intervalExit,
 1027        int targetOrdinal) =>
 30041028        sourceParameter >= arrivalParameter
 30041029        && ContainsParameter(intervalEnter, intervalExit, sourceParameter)
 30041030            ? targetOrdinal
 30041031            : -1;
 1032
 1033    internal static bool IsExplicitPortalProgressValid(
 1034        bool hasPortalParameters,
 1035        Fixed64 sourceParameter,
 1036        Fixed64 currentParameter,
 1037        Fixed64 intervalEnter,
 1038        Fixed64 intervalExit) =>
 431039        hasPortalParameters
 431040        && sourceParameter >= currentParameter
 431041        && ContainsParameter(intervalEnter, intervalExit, sourceParameter);
 1042
 1043    internal static bool ShouldAcceptContinuation(
 1044        NavigationRayChainRecordState currentState,
 1045        bool candidateIsEarlier) =>
 31211046        currentState == NavigationRayChainRecordState.Unreached
 31211047        || candidateIsEarlier;
 1048
 1049    internal static void ApplyContinuation(
 1050        ref NavigationRayChainRecord target,
 1051        bool candidatePassable,
 1052        bool candidateIsEarlier,
 1053        int predecessorOrdinal,
 1054        int rootOrdinal,
 1055        Fixed64 arrivalParameter,
 1056        Fixed64 traversalCost,
 1057        NavigationExplicitConnectionRecord incomingExplicitConnection,
 1058        bool isSemanticCostNeutral)
 1059    {
 31191060        if (!candidatePassable
 31191061            || !ShouldAcceptContinuation(target.State, candidateIsEarlier))
 1062        {
 81063            return;
 1064        }
 31111065        target.PredecessorOrdinal = predecessorOrdinal;
 31111066        target.RootOrdinal = rootOrdinal;
 31111067        target.ArrivalParameter = arrivalParameter;
 31111068        target.TraversalCost = traversalCost;
 31111069        target.IncomingExplicitConnection = incomingExplicitConnection;
 31111070        target.IsSemanticCostNeutral = isSemanticCostNeutral;
 31111071        target.State = NavigationRayChainRecordState.Ready;
 31111072    }
 1073
 1074    private int FindTarget(NavigationNodeRef target, Fixed64 parameter) =>
 29991075        FindMapped(_workspace, target, parameter);
 1076
 1077    private bool CanSeed(
 1078        int ordinal,
 1079        NavigationSurfaceComponentKey finishComponent,
 1080        NavigationWorkMeter? queryMeter,
 1081        ref GuideSampleWorkMeter guideMeter,
 1082        bool useGuideMeter,
 1083        out NavigationRayStatus terminalStatus)
 1084    {
 18481085        terminalStatus = NavigationRayStatus.Pending;
 18481086        NavigationNodeRef node = _workspace.ChainRecords[ordinal].Node;
 18481087        NavigationRayChainConstraint constraint = _request.ChainConstraint;
 1088        NavigationCellAddress address;
 18481089        if (constraint.Kind == NavigationRayChainConstraintKind.FinishAddress
 18481090            && !MatchesSeedConstraint(ordinal, finishComponent))
 1091        {
 171092            return false;
 1093        }
 18311094        if (constraint.Kind is NavigationRayChainConstraintKind.Unrestricted
 18311095            or NavigationRayChainConstraintKind.FinishAddress)
 1096        {
 13521097            if (_request.EndpointAllowance == NavigationRayEndpointAllowance.StartPrefix)
 311098                return true;
 13211099            _request.ExpectedGraph.TryGetNodeAddress(node, out address);
 1100        }
 1101        else
 1102        {
 4791103            _request.ExpectedGraph.TryGetNodeAddress(node, out address);
 4791104            if (address != constraint.SourceAddress)
 1105            {
 91106                return false;
 1107            }
 4701108            if (_request.EndpointAllowance == NavigationRayEndpointAllowance.StartPrefix)
 4001109                return true;
 1110        }
 13911111        if (!useGuideMeter
 13911112            && Medium is TraversalMedium.Gas or TraversalMedium.Liquid)
 1113        {
 1841114            var state = new NavigationMediumStateRef(node, Medium);
 1841115            return CertifyVolumeSegment(
 1841116                state,
 1841117                state,
 1841118                _request.Start,
 1841119                _request.Start,
 1841120                queryMeter!,
 1841121                out terminalStatus);
 1122        }
 12071123        _request.ExpectedGraph.TryGetSeamPrism(address, out GridCellPrism prism);
 12071124        return TryConsumePrism(queryMeter, ref guideMeter, useGuideMeter)
 12071125            && GridCellGeometry.IsNavigationBodySegmentValid(
 12071126                prism,
 12071127                _request.Start,
 12071128                _request.Start,
 12071129                _request.Profile.Shape.Radius,
 12071130                _request.Profile.Shape.Height,
 12071131                default,
 12071132                default,
 12071133                GridNavigationBodySegmentEndpointAllowance.None);
 1134    }
 1135
 1136    private bool MatchesSeedConstraint(
 1137        int ordinal,
 1138        NavigationSurfaceComponentKey finishComponent)
 1139    {
 7901140        NavigationRayChainConstraint constraint = _request.ChainConstraint;
 7901141        if (constraint.Kind == NavigationRayChainConstraintKind.Unrestricted)
 31142            return true;
 7871143        if (constraint.Kind == NavigationRayChainConstraintKind.FinishAddress)
 1144        {
 961145            _request.ExpectedGraph.TryGetNodeAddress(
 961146                _workspace.ChainRecords[ordinal].Node,
 961147                out NavigationCellAddress seedAddress);
 961148            _request.ExpectedGraph.TryGetSurfaceComponent(
 961149                seedAddress,
 961150                Medium,
 961151                out NavigationSurfaceComponentKey actual,
 961152                out _);
 961153            return actual.Equals(finishComponent);
 1154        }
 6911155        _request.ExpectedGraph.TryGetNodeAddress(
 6911156            _workspace.ChainRecords[ordinal].Node,
 6911157            out NavigationCellAddress address);
 6911158        return address == constraint.SourceAddress;
 1159    }
 1160
 1161    private bool AllowsEdge(
 1162        NavigationCellAddress source,
 1163        NavigationNodeRef targetNode,
 1164        int edgeOrdinal)
 1165    {
 59131166        NavigationRayChainConstraint constraint = _request.ChainConstraint;
 59131167        if (constraint.Kind is NavigationRayChainConstraintKind.Unrestricted
 59131168            or NavigationRayChainConstraintKind.SeedAddress
 59131169            or NavigationRayChainConstraintKind.FinishAddress)
 55491170            return true;
 3641171        return constraint.Kind == NavigationRayChainConstraintKind.SelectedEdge
 3641172            && source == constraint.SourceAddress
 3641173            && edgeOrdinal == constraint.EdgeOrdinal
 3641174            && GetAddress(targetNode) == constraint.TargetAddress;
 1175    }
 1176
 1177    private bool CanFinish(
 1178        int ordinal,
 1179        NavigationWorkMeter? queryMeter,
 1180        ref GuideSampleWorkMeter guideMeter,
 1181        bool useGuideMeter,
 1182        out NavigationRayStatus terminalStatus)
 1183    {
 48971184        terminalStatus = NavigationRayStatus.Pending;
 48971185        GridTraceInterval interval = _workspace.TraceIntervals[ordinal];
 48971186        ref NavigationRayChainRecord record = ref _workspace.ChainRecords[ordinal];
 48971187        bool permitsDestinationSuffix = _request.EndpointAllowance
 48971188            == NavigationRayEndpointAllowance.DestinationSuffix;
 48971189        _request.ExpectedGraph.TryGetNodeAddress(
 48971190            record.Node,
 48971191            out NavigationCellAddress address);
 48971192        if (!IsPermittedFinalTarget(
 48971193                permitsDestinationSuffix,
 48971194                interval.TEnter,
 48971195                interval.TExit,
 48971196                _request.ChainConstraint.Kind,
 48971197                address,
 48971198                _request.ChainConstraint.TargetAddress,
 48971199                record.PredecessorOrdinal))
 1200        {
 31541201            return false;
 1202        }
 17431203        Vector3d arrival = Vector3d.Lerp(
 17431204            _request.Start,
 17431205            _request.End,
 17431206            record.ArrivalParameter);
 1207        // EvaluateExplicitEdge certifies this exact arrival-to-end suffix before
 1208        // publishing an incoming explicit continuation into a chain record.
 17431209        if (!useGuideMeter
 17431210            && Medium is TraversalMedium.Gas or TraversalMedium.Liquid)
 1211        {
 2711212            _request.ExpectedGraph.TryGetSeamPrism(
 2711213                address,
 2711214                out GridCellPrism targetPrism);
 2711215            if (record.PredecessorOrdinal >= 0
 2711216                && TryGetIncomingPortal(
 2711217                    ordinal,
 2711218                    queryMeter,
 2711219                    ref guideMeter,
 2711220                    useGuideMeter,
 2711221                    out GridNavigationPortal volumeIncoming)
 2711222                && GridCellGeometry.IsNavigationBodySegmentValid(
 2711223                    targetPrism,
 2711224                    arrival,
 2711225                    _request.End,
 2711226                    _request.Profile.Shape.Radius,
 2711227                    _request.Profile.Shape.Height,
 2711228                    volumeIncoming,
 2711229                    default,
 2711230                    GetEndpointAllowance(ordinal, record, isFinalSegment: true)))
 1231            {
 1551232                return true;
 1233            }
 1161234            var state = new NavigationMediumStateRef(record.Node, Medium);
 1161235            return CertifyVolumeSegment(
 1161236                state,
 1161237                state,
 1161238                arrival,
 1161239                _request.End,
 1161240                queryMeter!,
 1161241                out terminalStatus);
 1242        }
 14721243        _request.ExpectedGraph.TryGetSeamPrism(address, out GridCellPrism prism);
 14721244        return TryGetIncomingPortal(
 14721245                ordinal,
 14721246                queryMeter,
 14721247                ref guideMeter,
 14721248                useGuideMeter,
 14721249                out GridNavigationPortal incomingPortal)
 14721250            && TryConsumePrism(queryMeter, ref guideMeter, useGuideMeter)
 14721251            && GridCellGeometry.IsNavigationBodySegmentValid(
 14721252                prism,
 14721253                arrival,
 14721254                _request.End,
 14721255                _request.Profile.Shape.Radius,
 14721256                _request.Profile.Shape.Height,
 14721257                incomingPortal,
 14721258                default,
 14721259                GetEndpointAllowance(ordinal, record, isFinalSegment: true));
 1260    }
 1261
 1262    private bool CertifyVolumeSegment(
 1263        NavigationMediumStateRef source,
 1264        NavigationMediumStateRef target,
 1265        Vector3d sourceFoot,
 1266        Vector3d targetFoot,
 1267        NavigationWorkMeter meter,
 1268        out NavigationRayStatus terminalStatus)
 1269    {
 3001270        var evaluator = new NavigationVolumeEdgeEvaluator(
 3001271            _request.World,
 3001272            _request.ExpectedGraph,
 3001273            _request.Profile,
 3001274            _request.AreaPolicy,
 3001275            Medium,
 3001276            _workspace);
 3001277        NavigationTraversalEvaluationStatus status = evaluator.CertifyRaySegment(
 3001278            source,
 3001279            target,
 3001280            sourceFoot,
 3001281            targetFoot,
 3001282            meter,
 3001283            _workspace.Dependencies);
 3001284        terminalStatus = MapVolumeStatus(status);
 3001285        return status == NavigationTraversalEvaluationStatus.Passable;
 1286    }
 1287
 1288    internal static NavigationRayStatus MapVolumeStatus(
 5841289        NavigationTraversalEvaluationStatus status) => status switch
 5841290    {
 5841291        NavigationTraversalEvaluationStatus.BudgetExceeded =>
 71292            NavigationRayStatus.BudgetExceeded,
 5841293        NavigationTraversalEvaluationStatus.CapacityExceeded =>
 21294            NavigationRayStatus.CapacityExceeded,
 5841295        NavigationTraversalEvaluationStatus.CostOverflow =>
 21296            NavigationRayStatus.CostOverflow,
 21297        NavigationTraversalEvaluationStatus.Stale => NavigationRayStatus.Stale,
 5711298        _ => NavigationRayStatus.Pending
 5841299    };
 1300
 1301    internal static bool IsTraceIntervalCurrent(
 1302        bool identityMatches,
 1303        bool configurationMatches,
 1304        bool sequenceMatches) =>
 72061305        identityMatches
 72061306        && configurationMatches
 72061307        && sequenceMatches;
 1308
 1309    internal static bool ShouldAdvanceFarthestExit(
 1310        NavigationRayChainRecordState state,
 1311        Fixed64 candidateExit,
 1312        Fixed64 farthestExit) =>
 391313        state == NavigationRayChainRecordState.Expanded
 391314        && candidateExit > farthestExit;
 1315
 1316    internal static bool IsPermittedFinalTarget(
 1317        bool permitsDestinationSuffix,
 1318        Fixed64 intervalEnter,
 1319        Fixed64 intervalExit,
 1320        NavigationRayChainConstraintKind constraintKind,
 1321        NavigationCellAddress actualAddress,
 1322        NavigationCellAddress targetAddress,
 1323        int predecessorOrdinal)
 1324    {
 1325        System.Diagnostics.Debug.Assert(
 1326            intervalEnter <= Fixed64.One,
 1327            "trace intervals are normalized to the closed segment parameter range");
 49051328        if (!permitsDestinationSuffix && intervalExit < Fixed64.One)
 1329        {
 31521330            return false;
 1331        }
 17531332        if (constraintKind == NavigationRayChainConstraintKind.FinishAddress
 17531333            && actualAddress != targetAddress)
 1334        {
 21335            return false;
 1336        }
 17511337        if (constraintKind == NavigationRayChainConstraintKind.SelectedEdge
 17511338            && (predecessorOrdinal < 0 || actualAddress != targetAddress))
 1339        {
 41340            return false;
 1341        }
 17471342        return true;
 1343    }
 1344
 1345    internal static bool IsPageDependencyCurrent(
 1346        bool found,
 1347        GraphPageDependency expected,
 1348        GraphPageDependency current) =>
 18531349        found && expected.Equals(current);
 1350
 1351    internal static NavigationRayStatus ResolveVolumeTraversalStatus(
 1352        NavigationTraversalEvaluationStatus segmentStatus,
 1353        Fixed64 sourceTraversalCost,
 1354        Fixed64 edgeCost,
 1355        out Fixed64 traversalCost)
 1356    {
 2781357        traversalCost = default;
 2781358        NavigationRayStatus status = MapVolumeStatus(segmentStatus);
 2781359        if (status != NavigationRayStatus.Pending
 2781360            || segmentStatus != NavigationTraversalEvaluationStatus.Passable)
 1361        {
 51362            return status;
 1363        }
 2731364        return Fixed64.TryAdd(sourceTraversalCost, edgeCost, out traversalCost)
 2731365            ? NavigationRayStatus.Pending
 2731366            : NavigationRayStatus.CostOverflow;
 1367    }
 1368
 1369    internal static NavigationRayStatus MapTraversalAdvanceStatus(
 2781370        NavigationTraversalEdgeAdvanceStatus status) => status switch
 2781371    {
 11372        NavigationTraversalEdgeAdvanceStatus.Blocked => NavigationRayStatus.Blocked,
 2781373        NavigationTraversalEdgeAdvanceStatus.BudgetExceeded =>
 31374            NavigationRayStatus.BudgetExceeded,
 2781375        NavigationTraversalEdgeAdvanceStatus.CapacityExceeded =>
 21376            NavigationRayStatus.CapacityExceeded,
 2781377        NavigationTraversalEdgeAdvanceStatus.CostOverflow =>
 21378            NavigationRayStatus.CostOverflow,
 11379        NavigationTraversalEdgeAdvanceStatus.Stale => NavigationRayStatus.Stale,
 2691380        _ => NavigationRayStatus.Pending
 2781381    };
 1382
 1383    private GridNavigationBodySegmentEndpointAllowance GetEndpointAllowance(
 1384        int ordinal,
 1385        in NavigationRayChainRecord record,
 1386        bool isFinalSegment)
 1387    {
 45661388        if (record.PredecessorOrdinal < 0
 45661389            && _request.EndpointAllowance == NavigationRayEndpointAllowance.StartPrefix
 45661390            && _workspace.TraceIntervals[ordinal].TEnter > Fixed64.Zero)
 1391        {
 2961392            return GridNavigationBodySegmentEndpointAllowance.StartFootprintEdge;
 1393        }
 42701394        return isFinalSegment
 42701395            && _request.EndpointAllowance
 42701396                == NavigationRayEndpointAllowance.DestinationSuffix
 42701397            && _workspace.TraceIntervals[ordinal].TExit < Fixed64.One
 42701398            ? GridNavigationBodySegmentEndpointAllowance.EndFootprintEdge
 42701399            : GridNavigationBodySegmentEndpointAllowance.None;
 1400    }
 1401
 1402    private bool TryGetIncomingPortal(
 1403        int ordinal,
 1404        NavigationWorkMeter? queryMeter,
 1405        ref GuideSampleWorkMeter guideMeter,
 1406        bool useGuideMeter,
 1407        out GridNavigationPortal portal)
 1408    {
 46301409        ref NavigationRayChainRecord record = ref _workspace.ChainRecords[ordinal];
 46301410        if (record.PredecessorOrdinal < 0)
 1411        {
 15401412            portal = default;
 15401413            return true;
 1414        }
 30901415        if (record.IncomingExplicitConnection != null)
 1416        {
 181417            if (!TryConsumePortal(queryMeter, ref guideMeter, useGuideMeter))
 1418            {
 11419                portal = default;
 11420                return false;
 1421            }
 171422            var portals = record.IncomingExplicitConnection.NavigationPortals;
 171423            portal = portals[portals.Count - 1];
 171424            return true;
 1425        }
 30721426        NavigationRayChainRecord predecessor =
 30721427            _workspace.ChainRecords[record.PredecessorOrdinal];
 30721428        NavigationWorldGraph graph = _request.ExpectedGraph;
 30721429        if (!TryConsumePortal(queryMeter, ref guideMeter, useGuideMeter))
 1430        {
 31431            portal = default;
 31432            return false;
 1433        }
 30691434        graph.TryGetNodeAddress(predecessor.Node, out NavigationCellAddress source);
 30691435        graph.TryGetNodeAddress(record.Node, out NavigationCellAddress target);
 30691436        graph.TryGetSeamPrism(source, out GridCellPrism sourcePrism);
 30691437        graph.TryGetSeamPrism(target, out GridCellPrism targetPrism);
 30691438        GridCellGeometry.TryCreateNavigationPortal(sourcePrism, targetPrism, out portal);
 30691439        return true;
 1440    }
 1441
 1442    private bool IsSemanticCostNeutral(in NavigationGraphEdge edge)
 1443    {
 28421444        return IsSemanticCostNeutral(edge.Target)
 28421445            && (edge.Kind != NavigationGraphEdgeKind.Explicit
 28421446                || edge.ExplicitConnection.Definition.AdditionalCost == Fixed64.Zero);
 1447    }
 1448
 1449    private NavigationCellAddress GetAddress(NavigationNodeRef node)
 1450    {
 8621451        _request.ExpectedGraph.TryGetNodeAddress(node, out NavigationCellAddress address);
 8621452        return address;
 1453    }
 1454
 1455    private bool IsSemanticCostNeutral(NavigationNodeRef target)
 1456    {
 31101457        _request.ExpectedGraph.TryGetNodeState(
 31101458            target,
 31101459            Medium,
 31101460            out NavigationNodeState state);
 31101461        _request.AreaPolicy.TryGetRule(state.Cell.Area, out NavigationAreaRule rule);
 31101462        return state.Cell.EnterCost == Fixed64.Zero
 31101463            && rule.AdditionalEnterCost == Fixed64.Zero;
 1464    }
 1465
 1466    private bool TryRecordDependencyNode(NavigationNodeRef node)
 1467    {
 541468        NavigationWorldGraph graph = _request.ExpectedGraph;
 541469        graph.TryGetNodeAddress(node, out NavigationCellAddress address);
 541470        if (!_workspace.Dependencies.TryRecordPage(
 541471                address.MapId,
 541472                node.CellSlot / NavigationSemanticPage.SlotCount))
 1473        {
 11474            return false;
 1475        }
 531476        graph.TryGetSurfaceComponent(
 531477            address,
 531478            Medium,
 531479            out NavigationSurfaceComponentKey component,
 531480            out _);
 531481        return _workspace.Dependencies.TryRecordComponent(component);
 1482    }
 1483
 1484    private NavigationRayStatus FinishSuccess(int ordinal)
 1485    {
 17201486        NavigationRayChainRecord record = _workspace.ChainRecords[ordinal];
 17201487        NavigationRayChainRecord root = _workspace.ChainRecords[record.RootOrdinal];
 17201488        _request.ExpectedGraph.TryGetNodeAddress(
 17201489            root.Node,
 17201490            out NavigationCellAddress start);
 17201491        _request.ExpectedGraph.TryGetNodeAddress(
 17201492            record.Node,
 17201493            out NavigationCellAddress end);
 17201494        if (!AreDependenciesCurrent())
 1495        {
 71496            return Finish(NavigationRayStatus.Stale);
 1497        }
 17131498        Result = new NavigationRayResult(
 17131499            NavigationRayStatus.Success,
 17131500            start,
 17131501            end,
 17131502            record.TraversalCost,
 17131503            record.IsSemanticCostNeutral);
 17131504        return Finish(NavigationRayStatus.Success, preserveResult: true);
 1505    }
 1506
 1507    private NavigationRayStatus FinishBlocked() =>
 691508        AreDependenciesCurrent()
 691509            ? Finish(NavigationRayStatus.Blocked)
 691510            : Finish(NavigationRayStatus.Stale);
 1511
 1512    private bool AreDependenciesCurrent()
 1513    {
 17891514        if (_request.World.ChangeSequence != _worldChangeSequence)
 31515            return false;
 17861516        NavigationWorldGraph expected = _request.ExpectedGraph;
 17861517        NavigationWorldGraph current = _request.Store.Current;
 17861518        if (!current.AreaCatalog.TryGet(
 17861519                _request.AreaPolicy.Key,
 17861520                out NavigationAreaPolicy currentPolicy)
 17861521            || !currentPolicy.ContentEquals(_request.AreaPolicy))
 1522        {
 41523            return false;
 1524        }
 17821525        NavigationDependencyWorkspace dependencies = _workspace.Dependencies;
 71801526        for (int i = 0; i < dependencies.ComponentCount; i++)
 1527        {
 18091528            NavigationSurfaceComponentKey key = dependencies.Components[i];
 18091529            expected.TryGetComponentDependency(key, out GraphComponentDependency prior);
 18091530            if (!current.TryGetComponentDependency(key, out GraphComponentDependency next)
 18091531                || !prior.Equals(next))
 1532            {
 11533                return false;
 1534            }
 1535        }
 72601536        for (int i = 0; i < dependencies.PageCount; i++)
 1537        {
 18501538            GraphPageDependencyAddress address = dependencies.Pages[i];
 18501539            expected.TryGetPageDependency(address, out GraphPageDependency prior);
 18501540            bool found = current.TryGetPageDependency(
 18501541                address,
 18501542                out GraphPageDependency next);
 18501543            if (!IsPageDependencyCurrent(found, prior, next))
 1544            {
 11545                return false;
 1546            }
 1547        }
 17801548        return _request.World.ChangeSequence == _worldChangeSequence;
 1549    }
 1550
 1551    private bool TryConsumeLookup(
 1552        NavigationWorkMeter? queryMeter,
 1553        ref GuideSampleWorkMeter guideMeter,
 1554        bool useGuideMeter,
 1555        int count)
 1556    {
 72191557        bool consumed = useGuideMeter
 72191558            ? guideMeter.TryConsumeCurrentNodeLookupProbes(count)
 72191559            : queryMeter!.TryConsumeLookupProbes(count);
 72191560        _meterBlocked |= !consumed;
 72191561        return consumed;
 1562    }
 1563
 1564    private bool TryConsumeConnectionLeg(
 1565        NavigationWorkMeter? queryMeter,
 1566        ref GuideSampleWorkMeter guideMeter,
 1567        bool useGuideMeter)
 1568    {
 561569        bool consumed = useGuideMeter
 561570            ? guideMeter.TryConsumeCursorLegScans(1)
 561571            : queryMeter!.TryConsumeConnectionLegs(1);
 561572        _meterBlocked |= !consumed;
 561573        return consumed;
 1574    }
 1575
 1576    private bool TryConsumePortal(
 1577        NavigationWorkMeter? queryMeter,
 1578        ref GuideSampleWorkMeter guideMeter,
 1579        bool useGuideMeter)
 1580    {
 82311581        bool consumed = useGuideMeter
 82311582            ? guideMeter.TryConsumePortalChecks(1)
 82311583            : queryMeter == null
 82311584                || !queryMeter.IsGuideSampleBridge
 82311585                || queryMeter.TryConsumeGuidePortalChecks(1);
 82311586        _meterBlocked |= !consumed;
 82311587        return consumed;
 1588    }
 1589
 1590    private bool TryConsumePrism(
 1591        NavigationWorkMeter? queryMeter,
 1592        ref GuideSampleWorkMeter guideMeter,
 1593        bool useGuideMeter)
 1594    {
 55441595        bool consumed = useGuideMeter
 55441596            ? guideMeter.TryConsumePrismChecks(1)
 55441597            : queryMeter == null
 55441598                || !queryMeter.IsGuideSampleBridge
 55441599                || queryMeter.TryConsumeGuidePrismChecks(1);
 55441600        _meterBlocked |= !consumed;
 55441601        return consumed;
 1602    }
 1603
 1604    private NavigationRayStatus Finish(
 1605        NavigationRayStatus status,
 1606        bool preserveResult = false)
 1607    {
 19551608        Status = status;
 19551609        if (!preserveResult)
 2421610            Result = new NavigationRayResult(status, default, default, default, false);
 19551611        ReleaseExplicitConnectionReferences();
 19551612        _request = default;
 19551613        _evaluator = default;
 19551614        _begun = false;
 19551615        return status;
 1616    }
 1617
 1618    private void ReleaseExplicitConnectionReferences()
 1619    {
 94491620        NavigationRayChainRecord[] records = _workspace.ChainRecords;
 470981621        for (int ordinal = 0; ordinal < _workspace.TraceIntervals.Count; ordinal++)
 1622        {
 141001623            if (records[ordinal].IncomingExplicitConnection != null)
 181624                records[ordinal].IncomingExplicitConnection = null!;
 1625        }
 94491626    }
 1627}

Methods/Properties

.ctor(Trailblazer.Pathing.NavigationRayWorkspace)
get_Medium()
Begin(Trailblazer.Pathing.NavigationRayRequest&)
Reset()
Advance(Trailblazer.Pathing.NavigationWorkMeter)
Advance(Trailblazer.Pathing.GuideSampleWorkMeter&)
AdvanceCore(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
Trace(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
ResolveTraceStatus(System.UInt64,System.UInt64,GridForge.Grids.GridTraceIntervalStatus,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)
MapIntervals(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
EvaluateChain(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
FinishDestinationSuffix(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
Expand(System.Int32,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
ExpandVolume(System.Int32,Trailblazer.Pathing.NavigationWorkMeter)
FindVolumeTarget(System.Int32,Trailblazer.Pathing.NavigationNodeRef,System.Boolean,FixedMathSharp.Fixed64&)
EvaluateExplicitEdge(System.Int32,Trailblazer.Pathing.NavigationNodeRef,Trailblazer.Pathing.NavigationGraphEdge&,GridForge.Grids.Topology.GridNavigationPortal&,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean,FixedMathSharp.Fixed64&,System.Int32&,FixedMathSharp.Fixed64&)
MapExplicitStatus(Trailblazer.Pathing.TraversalExplicitEdgeStatus)
IsExplicitFirstLegValid(FixedMathSharp.Geometry.FixedSegment&,FixedMathSharp.Vector3d,Trailblazer.Pathing.NavigationExplicitConnectionRecord,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
IsEarlierContinuation(Trailblazer.Pathing.NavigationRayChainRecord&,FixedMathSharp.Fixed64,Trailblazer.Pathing.NavigationExplicitConnectionRecord)
CompareAlongRay(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
CompareAlongRay(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
FindMapped(Trailblazer.Pathing.NavigationRayWorkspace,Trailblazer.Pathing.NavigationNodeRef,FixedMathSharp.Fixed64)
ContainsParameter(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
ResolvePortalTargetOrdinal(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.Int32)
IsExplicitPortalProgressValid(System.Boolean,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
ShouldAcceptContinuation(Trailblazer.Pathing.NavigationRayChainRecordState,System.Boolean)
ApplyContinuation(Trailblazer.Pathing.NavigationRayChainRecord&,System.Boolean,System.Boolean,System.Int32,System.Int32,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Trailblazer.Pathing.NavigationExplicitConnectionRecord,System.Boolean)
FindTarget(Trailblazer.Pathing.NavigationNodeRef,FixedMathSharp.Fixed64)
CanSeed(System.Int32,Trailblazer.Pathing.NavigationSurfaceComponentKey,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean,Trailblazer.Pathing.NavigationRayStatus&)
MatchesSeedConstraint(System.Int32,Trailblazer.Pathing.NavigationSurfaceComponentKey)
AllowsEdge(Trailblazer.Pathing.NavigationCellAddress,Trailblazer.Pathing.NavigationNodeRef,System.Int32)
CanFinish(System.Int32,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean,Trailblazer.Pathing.NavigationRayStatus&)
CertifyVolumeSegment(Trailblazer.Pathing.NavigationMediumStateRef,Trailblazer.Pathing.NavigationMediumStateRef,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.NavigationRayStatus&)
MapVolumeStatus(Trailblazer.Pathing.NavigationTraversalEvaluationStatus)
IsTraceIntervalCurrent(System.Boolean,System.Boolean,System.Boolean)
ShouldAdvanceFarthestExit(Trailblazer.Pathing.NavigationRayChainRecordState,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
IsPermittedFinalTarget(System.Boolean,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Trailblazer.Pathing.NavigationRayChainConstraintKind,Trailblazer.Pathing.NavigationCellAddress,Trailblazer.Pathing.NavigationCellAddress,System.Int32)
IsPageDependencyCurrent(System.Boolean,Trailblazer.Pathing.GraphPageDependency,Trailblazer.Pathing.GraphPageDependency)
ResolveVolumeTraversalStatus(Trailblazer.Pathing.NavigationTraversalEvaluationStatus,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64&)
MapTraversalAdvanceStatus(Trailblazer.Pathing.NavigationTraversalEdgeAdvanceStatus)
GetEndpointAllowance(System.Int32,Trailblazer.Pathing.NavigationRayChainRecord&,System.Boolean)
TryGetIncomingPortal(System.Int32,Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean,GridForge.Grids.Topology.GridNavigationPortal&)
IsSemanticCostNeutral(Trailblazer.Pathing.NavigationGraphEdge&)
GetAddress(Trailblazer.Pathing.NavigationNodeRef)
IsSemanticCostNeutral(Trailblazer.Pathing.NavigationNodeRef)
TryRecordDependencyNode(Trailblazer.Pathing.NavigationNodeRef)
FinishSuccess(System.Int32)
FinishBlocked()
AreDependenciesCurrent()
TryConsumeLookup(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean,System.Int32)
TryConsumeConnectionLeg(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
TryConsumePortal(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
TryConsumePrism(Trailblazer.Pathing.NavigationWorkMeter,Trailblazer.Pathing.GuideSampleWorkMeter&,System.Boolean)
Finish(Trailblazer.Pathing.NavigationRayStatus,System.Boolean)
ReleaseExplicitConnectionReferences()