< Summary

Information
Class: Trailblazer.Pathing.TraversalTransitionAnchor
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Transition/TraversalTransitionAnchor.cs
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 216
Line coverage: 100%
Branch coverage
95%
Covered branches: 21
Total branches: 22
Branch coverage: 95.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Position()100%22100%
Solid(...)100%11100%
Solid(...)100%11100%
Solid(...)100%11100%
Solid(...)100%11100%
Gas(...)100%11100%
Gas(...)100%11100%
Gas(...)100%11100%
Gas(...)100%11100%
Liquid(...)100%11100%
Liquid(...)100%11100%
Liquid(...)100%11100%
Liquid(...)100%11100%
get_IsVolumeMedium()100%22100%
TryGetVolumeMedium(...)100%44100%
.ctor(...)100%11100%
TryResolveVoxelIndex(...)100%11100%
TryResolveVoxelIndex(...)100%22100%
CreateFromPosition(...)100%22100%
Create(...)100%44100%
PointOverrideMatchesVoxel(...)50%22100%
GetVoxelWorldPosition(...)100%44100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Transition/TraversalTransitionAnchor.cs

#LineLine coverage
 1using FixedMathSharp;
 2using GridForge.Grids;
 3using GridForge.Spatial;
 4using System;
 5
 6namespace Trailblazer.Pathing;
 7
 8/// <summary>
 9/// Describes one endpoint of an authored traversal transition.
 10/// </summary>
 11[Serializable]
 12public readonly struct TraversalTransitionAnchor
 13{
 14    /// <summary>
 15    /// Identifies the traversal medium this anchor belongs to.
 16    /// </summary>
 17    public TraversalMedium Medium { get; }
 18
 19    /// <summary>
 20    /// The canonical voxel identity this anchor resolves through.
 21    /// </summary>
 22    public WorldVoxelIndex VoxelIndex { get; }
 23
 24    /// <summary>
 25    /// Indicates whether this anchor uses a world-space point override inside the resolved voxel.
 26    /// </summary>
 27    public bool HasPointOverride { get; }
 28
 29    /// <summary>
 30    /// The exact world-space point used for route steps when <see cref="HasPointOverride"/> is true.
 31    /// </summary>
 32    public Vector3d PointOverride { get; }
 33
 34    /// <summary>
 35    /// The effective world-space point used by planners.
 36    /// </summary>
 234537    public Vector3d Position => HasPointOverride
 234538        ? PointOverride
 234539        : GetVoxelWorldPosition(VoxelIndex);
 40
 41    /// <summary>
 42    /// Creates a solid anchor for the provided voxel index.
 43    /// </summary>
 44    public static TraversalTransitionAnchor Solid(WorldVoxelIndex voxelIndex) =>
 1745        Create(TraversalMedium.Solid, voxelIndex);
 46
 47    /// <summary>
 48    /// Creates a solid anchor for the provided voxel index with an explicit world-space point override.
 49    /// </summary>
 50    public static TraversalTransitionAnchor Solid(WorldVoxelIndex voxelIndex, Vector3d pointOverride) =>
 951        Create(TraversalMedium.Solid, voxelIndex, pointOverride, hasPointOverride: true);
 52
 53    /// <summary>
 54    /// Creates a solid anchor at the provided world position.
 55    /// </summary>
 56    public static TraversalTransitionAnchor Solid(Vector3d position) =>
 47557        CreateFromPosition(TraversalMedium.Solid, position);
 58
 59    /// <summary>
 60    /// Creates a solid anchor with an explicit world-space point override.
 61    /// </summary>
 62    public static TraversalTransitionAnchor Solid(Vector3d position, Vector3d pointOverride) =>
 663        CreateFromPosition(TraversalMedium.Solid, position, pointOverride, hasPointOverride: true);
 64
 65    /// <summary>
 66    /// Creates a gas anchor for the provided voxel index.
 67    /// </summary>
 68    public static TraversalTransitionAnchor Gas(WorldVoxelIndex voxelIndex) =>
 269        Create(TraversalMedium.Gas, voxelIndex);
 70
 71    /// <summary>
 72    /// Creates a gas anchor for the provided voxel index with an explicit world-space point override.
 73    /// </summary>
 74    public static TraversalTransitionAnchor Gas(WorldVoxelIndex voxelIndex, Vector3d pointOverride) =>
 175        Create(TraversalMedium.Gas, voxelIndex, pointOverride, hasPointOverride: true);
 76
 77    /// <summary>
 78    /// Creates a gas anchor at the provided world position.
 79    /// </summary>
 80    public static TraversalTransitionAnchor Gas(Vector3d position) =>
 2781        CreateFromPosition(TraversalMedium.Gas, position);
 82
 83    /// <summary>
 84    /// Creates a gas anchor with an explicit world-space point override.
 85    /// </summary>
 86    public static TraversalTransitionAnchor Gas(Vector3d position, Vector3d pointOverride) =>
 187        CreateFromPosition(TraversalMedium.Gas, position, pointOverride, hasPointOverride: true);
 88
 89    /// <summary>
 90    /// Creates a liquid anchor for the provided voxel index.
 91    /// </summary>
 92    public static TraversalTransitionAnchor Liquid(WorldVoxelIndex voxelIndex) =>
 193        Create(TraversalMedium.Liquid, voxelIndex);
 94
 95    /// <summary>
 96    /// Creates a liquid anchor for the provided voxel index with an explicit world-space point override.
 97    /// </summary>
 98    public static TraversalTransitionAnchor Liquid(WorldVoxelIndex voxelIndex, Vector3d pointOverride) =>
 199        Create(TraversalMedium.Liquid, voxelIndex, pointOverride, hasPointOverride: true);
 100
 101    /// <summary>
 102    /// Creates a liquid anchor at the provided world position.
 103    /// </summary>
 104    public static TraversalTransitionAnchor Liquid(Vector3d position) =>
 87105        CreateFromPosition(TraversalMedium.Liquid, position);
 106
 107    /// <summary>
 108    /// Creates a liquid anchor with an explicit world-space point override.
 109    /// </summary>
 110    public static TraversalTransitionAnchor Liquid(Vector3d position, Vector3d pointOverride) =>
 1111        CreateFromPosition(TraversalMedium.Liquid, position, pointOverride, hasPointOverride: true);
 112
 113    /// <summary>
 114    /// Returns true when this anchor belongs to any raw-volume traversal medium.
 115    /// </summary>
 3116    public bool IsVolumeMedium => Medium == TraversalMedium.Gas || Medium == TraversalMedium.Liquid;
 117
 118    /// <summary>
 119    /// Attempts to get the volume medium carried by this anchor.
 120    /// </summary>
 121    public bool TryGetVolumeMedium(out TraversalMedium volumeMedium)
 122    {
 4123        switch (Medium)
 124        {
 125            case TraversalMedium.Gas:
 1126                volumeMedium = TraversalMedium.Gas;
 1127                return true;
 128            case TraversalMedium.Liquid:
 2129                volumeMedium = TraversalMedium.Liquid;
 2130                return true;
 131            default:
 1132                volumeMedium = TraversalMedium.Unknown;
 1133                return false;
 134        }
 135    }
 136
 137    private TraversalTransitionAnchor(
 138        TraversalMedium medium,
 139        WorldVoxelIndex voxelIndex,
 140        Vector3d pointOverride = default,
 141        bool hasPointOverride = false)
 142    {
 624143        Medium = medium;
 624144        VoxelIndex = voxelIndex;
 624145        HasPointOverride = hasPointOverride;
 624146        PointOverride = pointOverride;
 624147    }
 148
 149    internal static bool TryResolveVoxelIndex(Vector3d position, out WorldVoxelIndex voxelIndex)
 150    {
 648151        return TryResolveVoxelIndex(PathManager.ActiveState.World, position, out voxelIndex);
 152    }
 153
 154    internal static bool TryResolveVoxelIndex(
 155        GridWorld world,
 156        Vector3d position,
 157        out WorldVoxelIndex voxelIndex)
 158    {
 652159        if (world.TryGetVoxel(position, out Voxel? voxel))
 160        {
 648161            voxelIndex = voxel!.WorldIndex;
 648162            return true;
 163        }
 164
 4165        voxelIndex = default;
 4166        return false;
 167    }
 168
 169    private static TraversalTransitionAnchor CreateFromPosition(
 170        TraversalMedium medium,
 171        Vector3d position,
 172        Vector3d pointOverride = default,
 173        bool hasPointOverride = false)
 174    {
 597175        if (!TryResolveVoxelIndex(position, out WorldVoxelIndex voxelIndex))
 176        {
 2177            throw new ArgumentException(
 2178                "Anchor position must resolve to a voxel in the active grid setup.",
 2179                nameof(position));
 180        }
 181
 595182        return Create(medium, voxelIndex, pointOverride, hasPointOverride);
 183    }
 184
 185    private static TraversalTransitionAnchor Create(
 186        TraversalMedium medium,
 187        WorldVoxelIndex voxelIndex,
 188        Vector3d pointOverride = default,
 189        bool hasPointOverride = false)
 190    {
 626191        if (hasPointOverride && !PointOverrideMatchesVoxel(voxelIndex, pointOverride))
 192        {
 2193            throw new ArgumentException(
 2194                "Point override must resolve to the same voxel as the anchor.",
 2195                nameof(pointOverride));
 196        }
 197
 624198        return new TraversalTransitionAnchor(medium, voxelIndex, pointOverride, hasPointOverride);
 199    }
 200
 201    private static bool PointOverrideMatchesVoxel(WorldVoxelIndex voxelIndex, Vector3d pointOverride)
 202    {
 19203        return TryResolveVoxelIndex(pointOverride, out WorldVoxelIndex pointOverrideVoxelIndex)
 19204            && pointOverrideVoxelIndex == voxelIndex;
 205    }
 206
 207    private static Vector3d GetVoxelWorldPosition(WorldVoxelIndex voxelIndex)
 208    {
 2337209        if (PathManager.ActiveState.World.TryGetGridAndVoxel(voxelIndex, out _, out Voxel? voxel)
 2337210            && voxel != null)
 2336211            return voxel.WorldPosition;
 212
 1213        throw new InvalidOperationException(
 1214            $"Transition anchor voxel {voxelIndex} is not available in the current grid setup.");
 215    }
 216}