< Summary

Information
Class: GridForge.Utility.GridTracer
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Utility/GridTracer.cs
Line coverage
98%
Covered lines: 581
Uncovered lines: 6
Coverable lines: 587
Total lines: 1402
Line coverage: 98.9%
Branch coverage
95%
Covered branches: 196
Total branches: 206
Branch coverage: 95.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
TraceLine(...)100%44100%
TraceLine(...)100%11100%
GetCoveredVoxels(...)100%44100%
GetCoveredVoxels(...)100%11100%
GetCoveredVoxelsInto(...)100%44100%
GetCoveredVoxelsInto(...)100%11100%
GetCoveredVoxelsInto(...)75%44100%
GetCoveredVoxelsInto(...)100%11100%
GetCoveredScanCells(...)100%44100%
GetCoveredScanCells(...)100%11100%
GetCoveredScanCellsInto(...)100%44100%
GetCoveredScanCellsInto(...)100%11100%
GetCoveredScanCellsInto(...)100%44100%
GetCoveredScanCellsInto(...)100%11100%
AddCoveredScanCellsTo(...)100%11100%
AddCoveredScanCellsTo(...)100%11100%
AddCoveredVoxelsTo(...)100%11100%
AddCoveredVoxelsTo(...)100%11100%
AddCoveredVoxelsCore(...)100%66100%
AddCoveredVoxelsForSpatialCell(...)87.5%8891.66%
AddCoveredScanCellsCore(...)100%66100%
AddCoveredScanCellsForSpatialCell(...)100%88100%
AddCoveredScanCellsForGrid(...)100%44100%
TraceLineIterator()100%22100%
<>m__Finally1()100%11100%
AddTraceLineVoxelsToMapping(...)100%88100%
CreateTraceLinePlan(...)100%11100%
CalculateTraceSteps(...)100%11100%
CreateTraceEndpoint(...)100%11100%
SelectTraceCoordinate(...)100%22100%
CreatePaddedOrderedBounds(...)100%1010100%
ExpandOrderedBounds(...)100%22100%
TryGetCoveredScanCellRange(...)100%22100%
AddTraceLineVoxelsForCell(...)100%1010100%
AddTraceLineGridVoxels(...)100%1010100%
AddHexTraceLineGridVoxels(...)100%66100%
CreateHexTraceEndpoints(...)100%11100%
CalculateHexTraceSteps(...)100%11100%
InterpolateHexTraceIndex(...)100%11100%
Interpolate(...)100%11100%
TryClipTraceSegmentToGrid(...)70%1010100%
ClipTraceSegmentAxis(...)100%1010100%
ShouldIncludeHexTraceEndIndex(...)75%44100%
InterpolateTraceSegment(...)100%11100%
InterpolateTraceAxis(...)100%66100%
AddTraceVoxelByPosition(...)100%44100%
AddTraceVoxelByIndex(...)100%44100%
AddTraceLineEndVoxel(...)62.5%19844.44%
ReleaseGridVoxelMapping(...)100%22100%
GetCoveredVoxelsIterator()100%22100%
<>m__Finally1()100%11100%
AddCoveredVoxelsToMapping(...)100%88100%
AddCoveredVoxelsForCell(...)100%88100%
AddCoveredGridVoxels(...)100%44100%
AddCoveredHexGridVoxels(...)92.85%1414100%
AddCoveredHexScanCellsForGrid(...)100%22100%
IsHexVoxelCenterInHorizontalCoverage(...)100%66100%
GetCoveredScanCellsIterator()100%22100%
<>m__Finally1()100%11100%

File(s)

/home/runner/work/GridForge/GridForge/src/GridForge/Utility/GridTracer.cs

#LineLine coverage
 1//=======================================================================
 2// GridTracer.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 FixedMathSharp;
 9using GridForge.Grids;
 10using GridForge.Grids.Topology;
 11using GridForge.Spatial;
 12using SwiftCollections;
 13using SwiftCollections.Pool;
 14using SwiftCollections.Utility;
 15using System.Collections.Generic;
 16using System.Runtime.CompilerServices;
 17
 18namespace GridForge.Utility;
 19
 20/// <summary>
 21/// Provides utilities for tracing lines or bounding areas in a grid, aligning them to grid voxels.
 22/// Uses fixed-point calculations to ensure deterministic and accurate grid traversal.
 23/// </summary>
 24public static class GridTracer
 25{
 26    private readonly struct TraceLinePlan
 27    {
 28        public readonly Vector3d TraceStart;
 29        public readonly Fixed64 Steps;
 30        public readonly Fixed64 StepX;
 31        public readonly Fixed64 StepY;
 32        public readonly Fixed64 StepZ;
 33
 34        public TraceLinePlan(
 35            Vector3d traceStart,
 36            Fixed64 steps,
 37            Fixed64 stepX,
 38            Fixed64 stepY,
 39            Fixed64 stepZ)
 40        {
 1941            TraceStart = traceStart;
 1942            Steps = steps;
 1943            StepX = stepX;
 1944            StepY = stepY;
 1945            StepZ = stepZ;
 1946        }
 47    }
 48
 49    /// <summary>
 50    /// Traces a 3D line between two points in the supplied world.
 51    /// The traced points are returned as grid voxels.
 52    /// </summary>
 53    /// <remarks>
 54    /// Uses a fractional step algorithm inspired by Bresenham’s line algorithm.
 55    /// This implementation leverages fixed-point math to maintain precision across a deterministic grid.
 56    /// </remarks>
 57    /// <param name="world">The world whose grids should be traced.</param>
 58    /// <param name="start">Starting position in world space.</param>
 59    /// <param name="end">Ending position in world space.</param>
 60    /// <param name="padding">Value applied to the start/end positions before snapping.</param>
 61    /// <param name="includeEnd">Whether to include the end voxel in the traced line.</param>
 62    /// <returns>A collection of <see cref="GridVoxelSet"/> objects representing the traced path.</returns>
 63    public static IEnumerable<GridVoxelSet> TraceLine(
 64        GridWorld world,
 65        Vector3d start,
 66        Vector3d end,
 67        Fixed64? padding = null,
 68        bool includeEnd = true)
 69    {
 2870        if (world == null || !world.IsActive)
 271            return System.Array.Empty<GridVoxelSet>();
 72
 2673        return TraceLineIterator(world, start, end, padding, includeEnd);
 74    }
 75
 76    /// <summary>
 77    /// Traces a 2D XZ-plane line between two points in the supplied world, snapping them to grid coordinates.
 78    /// </summary>
 79    /// <remarks>
 80    /// This method maps <see cref="Vector2d.X"/> to world X, <see cref="Vector2d.Y"/> to world Z,
 81    /// and <paramref name="layerY"/> to world Y. The default layer is world Y = 0.
 82    /// </remarks>
 83    /// <param name="world">The world whose grids should be traced.</param>
 84    /// <param name="start">Starting XZ-plane position in world space.</param>
 85    /// <param name="end">Ending XZ-plane position in world space.</param>
 86    /// <param name="padding">Value applied to the start/end positions before snapping.</param>
 87    /// <param name="includeEnd">Whether to include the end voxel in the traced line.</param>
 88    /// <param name="layerY">The world Y layer to trace. Defaults to zero.</param>
 89    /// <returns>A collection of <see cref="GridVoxelSet"/> objects representing the traced path.</returns>
 90    public static IEnumerable<GridVoxelSet> TraceLine(
 91        GridWorld world,
 92        Vector2d start,
 93        Vector2d end,
 94        Fixed64? padding = null,
 95        bool includeEnd = true,
 96        Fixed64 layerY = default)
 97    {
 398        Vector3d start3D = GridPlane2d.ToWorld(start, layerY);
 399        Vector3d end3D = GridPlane2d.ToWorld(end, layerY);
 100
 3101        return TraceLine(world, start3D, end3D, padding, includeEnd);
 102    }
 103
 104    /// <summary>
 105    /// Retrieves all grid voxels covered by the given bounding area in the supplied world.
 106    /// </summary>
 107    public static IEnumerable<GridVoxelSet> GetCoveredVoxels(
 108        GridWorld world,
 109        Vector3d boundsMin,
 110        Vector3d boundsMax,
 111        Fixed64? padding = null)
 112    {
 187113        if (world == null || !world.IsActive)
 2114            return System.Array.Empty<GridVoxelSet>();
 115
 185116        return GetCoveredVoxelsIterator(world, boundsMin, boundsMax, padding);
 117    }
 118
 119    /// <summary>
 120    /// Retrieves all grid voxels covered by the given XZ-plane bounding area on the supplied world Y layer.
 121    /// </summary>
 122    /// <param name="world">The world whose grids should be queried.</param>
 123    /// <param name="boundsMin">The 2D minimum corner whose X component maps to world X and Y component maps to world Z.
 124    /// <param name="boundsMax">The 2D maximum corner whose X component maps to world X and Y component maps to world Z.
 125    /// <param name="layerY">The world Y layer to cover. Defaults to zero.</param>
 126    /// <param name="padding">Value applied to the min/max bounds before snapping.</param>
 127    /// <returns>A collection of <see cref="GridVoxelSet"/> objects representing the covered voxels.</returns>
 128    public static IEnumerable<GridVoxelSet> GetCoveredVoxels(
 129        GridWorld world,
 130        Vector2d boundsMin,
 131        Vector2d boundsMax,
 132        Fixed64 layerY = default,
 133        Fixed64? padding = null)
 134    {
 3135        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 3136        return GetCoveredVoxels(world, min, max, padding);
 137    }
 138
 139    /// <summary>
 140    /// Clears and fills caller-owned storage with voxels covered by the supplied bounding area.
 141    /// </summary>
 142    /// <param name="world">The world whose grids should be queried.</param>
 143    /// <param name="boundsMin">The minimum corner of the bounding area.</param>
 144    /// <param name="boundsMax">The maximum corner of the bounding area.</param>
 145    /// <param name="results">Caller-owned storage that receives covered voxels.</param>
 146    /// <param name="padding">Value applied to the min/max bounds before normalization.</param>
 147    public static void GetCoveredVoxelsInto(
 148        GridWorld world,
 149        Vector3d boundsMin,
 150        Vector3d boundsMax,
 151        SwiftList<Voxel> results,
 152        Fixed64? padding = null)
 153    {
 4154        SwiftThrowHelper.ThrowIfNull(results, nameof(results));
 155
 3156        results.Clear();
 3157        if (world == null || !world.IsActive)
 1158            return;
 159
 2160        AddCoveredVoxelsTo(world, boundsMin, boundsMax, results, padding);
 2161    }
 162
 163    /// <summary>
 164    /// Clears and fills caller-owned storage with voxels covered by the supplied XZ-plane bounding area.
 165    /// </summary>
 166    /// <param name="world">The world whose grids should be queried.</param>
 167    /// <param name="boundsMin">The 2D minimum corner whose X component maps to world X and Y component maps to world Z.
 168    /// <param name="boundsMax">The 2D maximum corner whose X component maps to world X and Y component maps to world Z.
 169    /// <param name="results">Caller-owned storage that receives covered voxels.</param>
 170    /// <param name="layerY">The world Y layer to cover. Defaults to zero.</param>
 171    /// <param name="padding">Value applied to the min/max bounds before normalization.</param>
 172    public static void GetCoveredVoxelsInto(
 173        GridWorld world,
 174        Vector2d boundsMin,
 175        Vector2d boundsMax,
 176        SwiftList<Voxel> results,
 177        Fixed64 layerY = default,
 178        Fixed64? padding = null)
 179    {
 1180        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 1181        GetCoveredVoxelsInto(world, min, max, results, padding);
 1182    }
 183
 184    /// <summary>
 185    /// Clears and fills caller-owned storage using caller-owned scratch collections.
 186    /// </summary>
 187    /// <param name="world">The world whose grids should be queried.</param>
 188    /// <param name="boundsMin">The minimum corner of the bounding area.</param>
 189    /// <param name="boundsMax">The maximum corner of the bounding area.</param>
 190    /// <param name="results">Caller-owned storage that receives covered voxels.</param>
 191    /// <param name="scratch">Reusable scratch storage for processed-grid and duplicate-voxel guards.</param>
 192    /// <param name="padding">Value applied to the min/max bounds before normalization.</param>
 193    public static void GetCoveredVoxelsInto(
 194        GridWorld world,
 195        Vector3d boundsMin,
 196        Vector3d boundsMax,
 197        SwiftList<Voxel> results,
 198        GridTraceScratch scratch,
 199        Fixed64? padding = null)
 200    {
 5201        SwiftThrowHelper.ThrowIfNull(results, nameof(results));
 4202        SwiftThrowHelper.ThrowIfNull(scratch, nameof(scratch));
 203
 3204        results.Clear();
 3205        if (world == null || !world.IsActive)
 1206            return;
 207
 2208        AddCoveredVoxelsTo(world, boundsMin, boundsMax, results, scratch, padding);
 2209    }
 210
 211    /// <summary>
 212    /// Clears and fills caller-owned storage using caller-owned scratch collections for an XZ-plane bounding area.
 213    /// </summary>
 214    /// <param name="world">The world whose grids should be queried.</param>
 215    /// <param name="boundsMin">The 2D minimum corner whose X component maps to world X and Y component maps to world Z.
 216    /// <param name="boundsMax">The 2D maximum corner whose X component maps to world X and Y component maps to world Z.
 217    /// <param name="results">Caller-owned storage that receives covered voxels.</param>
 218    /// <param name="scratch">Reusable scratch storage for processed-grid and duplicate-voxel guards.</param>
 219    /// <param name="layerY">The world Y layer to cover. Defaults to zero.</param>
 220    /// <param name="padding">Value applied to the min/max bounds before normalization.</param>
 221    public static void GetCoveredVoxelsInto(
 222        GridWorld world,
 223        Vector2d boundsMin,
 224        Vector2d boundsMax,
 225        SwiftList<Voxel> results,
 226        GridTraceScratch scratch,
 227        Fixed64 layerY = default,
 228        Fixed64? padding = null)
 229    {
 1230        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 1231        GetCoveredVoxelsInto(world, min, max, results, scratch, padding);
 1232    }
 233
 234    /// <summary>
 235    /// Retrieves all scan cells within the given bounding area across relevant grids in the supplied world.
 236    /// </summary>
 237    /// <param name="world">The world whose grids should be queried.</param>
 238    /// <param name="boundsMin">The minimum corner of the bounding area.</param>
 239    /// <param name="boundsMax">The maximum corner of the bounding area.</param>
 240    /// <param name="padding">Value applied to the min/max bounds before snapping.</param>
 241    /// <returns>An enumerable of covered scan cells grouped by grid.</returns>
 242    public static IEnumerable<ScanCell> GetCoveredScanCells(
 243        GridWorld world,
 244        Vector3d boundsMin,
 245        Vector3d boundsMax,
 246        Fixed64? padding = null)
 247    {
 13248        if (world == null || !world.IsActive)
 2249            return System.Array.Empty<ScanCell>();
 250
 11251        return GetCoveredScanCellsIterator(world, boundsMin, boundsMax, padding);
 252    }
 253
 254    /// <summary>
 255    /// Retrieves all scan cells within the given XZ-plane bounding area on the supplied world Y layer.
 256    /// </summary>
 257    /// <param name="world">The world whose grids should be queried.</param>
 258    /// <param name="boundsMin">The 2D minimum corner whose X component maps to world X and Y component maps to world Z.
 259    /// <param name="boundsMax">The 2D maximum corner whose X component maps to world X and Y component maps to world Z.
 260    /// <param name="layerY">The world Y layer to cover. Defaults to zero.</param>
 261    /// <param name="padding">Value applied to the min/max bounds before snapping.</param>
 262    /// <returns>An enumerable of covered scan cells grouped by grid.</returns>
 263    public static IEnumerable<ScanCell> GetCoveredScanCells(
 264        GridWorld world,
 265        Vector2d boundsMin,
 266        Vector2d boundsMax,
 267        Fixed64 layerY = default,
 268        Fixed64? padding = null)
 269    {
 1270        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 1271        return GetCoveredScanCells(world, min, max, padding);
 272    }
 273
 274    /// <summary>
 275    /// Clears and fills caller-owned storage with scan cells covered by the supplied bounding area.
 276    /// </summary>
 277    public static void GetCoveredScanCellsInto(
 278        GridWorld world,
 279        Vector3d boundsMin,
 280        Vector3d boundsMax,
 281        SwiftList<ScanCell> results,
 282        Fixed64? padding = null)
 283    {
 5284        SwiftThrowHelper.ThrowIfNull(results, nameof(results));
 285
 4286        results.Clear();
 4287        if (world == null || !world.IsActive)
 2288            return;
 289
 2290        AddCoveredScanCellsTo(world, boundsMin, boundsMax, results, padding);
 2291    }
 292
 293    /// <summary>
 294    /// Clears and fills caller-owned storage with scan cells covered by the supplied XZ-plane bounding area.
 295    /// </summary>
 296    public static void GetCoveredScanCellsInto(
 297        GridWorld world,
 298        Vector2d boundsMin,
 299        Vector2d boundsMax,
 300        SwiftList<ScanCell> results,
 301        Fixed64 layerY = default,
 302        Fixed64? padding = null)
 303    {
 1304        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 1305        GetCoveredScanCellsInto(world, min, max, results, padding);
 1306    }
 307
 308    /// <summary>
 309    /// Clears and fills caller-owned storage using caller-owned scratch collections.
 310    /// </summary>
 311    public static void GetCoveredScanCellsInto(
 312        GridWorld world,
 313        Vector3d boundsMin,
 314        Vector3d boundsMax,
 315        SwiftList<ScanCell> results,
 316        GridScanScratch scratch,
 317        Fixed64? padding = null)
 318    {
 6319        SwiftThrowHelper.ThrowIfNull(results, nameof(results));
 5320        SwiftThrowHelper.ThrowIfNull(scratch, nameof(scratch));
 321
 4322        results.Clear();
 4323        if (world == null || !world.IsActive)
 2324            return;
 325
 2326        AddCoveredScanCellsTo(world, boundsMin, boundsMax, results, scratch, padding);
 2327    }
 328
 329    /// <summary>
 330    /// Clears and fills caller-owned storage using caller-owned scratch collections for an XZ-plane bounding area.
 331    /// </summary>
 332    public static void GetCoveredScanCellsInto(
 333        GridWorld world,
 334        Vector2d boundsMin,
 335        Vector2d boundsMax,
 336        SwiftList<ScanCell> results,
 337        GridScanScratch scratch,
 338        Fixed64 layerY = default,
 339        Fixed64? padding = null)
 340    {
 1341        (Vector3d min, Vector3d max) = GridPlane2d.ToWorldBounds(boundsMin, boundsMax, layerY);
 1342        GetCoveredScanCellsInto(world, min, max, results, scratch, padding);
 1343    }
 344
 345    /// <summary>
 346    /// Appends covered scan cells without allocating an iterator for hot-path callers.
 347    /// </summary>
 348    internal static void AddCoveredScanCellsTo(
 349        GridWorld world,
 350        Vector3d boundsMin,
 351        Vector3d boundsMax,
 352        SwiftList<ScanCell> scanCells,
 353        Fixed64? padding = null)
 354    {
 20355        SwiftHashSet<ushort> processedGrids = SwiftHashSetPool<ushort>.Shared.Rent();
 20356        SwiftHashSet<ScanCell> voxelRedundancyCheck = SwiftHashSetPool<ScanCell>.Shared.Rent();
 357
 358        try
 359        {
 20360            AddCoveredScanCellsCore(
 20361                world,
 20362                boundsMin,
 20363                boundsMax,
 20364                scanCells,
 20365                processedGrids,
 20366                voxelRedundancyCheck,
 20367                padding);
 20368        }
 369        finally
 370        {
 20371            SwiftHashSetPool<ushort>.Shared.Release(processedGrids);
 20372            SwiftHashSetPool<ScanCell>.Shared.Release(voxelRedundancyCheck);
 20373        }
 20374    }
 375
 376    /// <summary>
 377    /// Appends covered scan cells using caller-owned scratch state for allocation-sensitive scans.
 378    /// </summary>
 379    internal static void AddCoveredScanCellsTo(
 380        GridWorld world,
 381        Vector3d boundsMin,
 382        Vector3d boundsMax,
 383        SwiftList<ScanCell> scanCells,
 384        GridScanScratch scratch,
 385        Fixed64? padding = null)
 386    {
 520387        scratch.Clear();
 520388        AddCoveredScanCellsCore(
 520389            world,
 520390            boundsMin,
 520391            boundsMax,
 520392            scanCells,
 520393            scratch.ProcessedGrids,
 520394            scratch.ScanCellRedundancy,
 520395            padding);
 520396    }
 397
 398    /// <summary>
 399    /// Appends covered voxels without allocating an iterator for hot-path callers.
 400    /// </summary>
 401    internal static void AddCoveredVoxelsTo(
 402        GridWorld world,
 403        Vector3d boundsMin,
 404        Vector3d boundsMax,
 405        SwiftList<Voxel> voxels,
 406        Fixed64? padding = null)
 407    {
 2408        SwiftHashSet<ushort> processedGrids = SwiftHashSetPool<ushort>.Shared.Rent();
 2409        SwiftHashSet<Voxel> voxelRedundancyCheck = SwiftHashSetPool<Voxel>.Shared.Rent();
 410
 411        try
 412        {
 2413            AddCoveredVoxelsCore(
 2414                world,
 2415                boundsMin,
 2416                boundsMax,
 2417                voxels,
 2418                processedGrids,
 2419                voxelRedundancyCheck,
 2420                padding);
 2421        }
 422        finally
 423        {
 2424            SwiftHashSetPool<ushort>.Shared.Release(processedGrids);
 2425            SwiftHashSetPool<Voxel>.Shared.Release(voxelRedundancyCheck);
 2426        }
 2427    }
 428
 429    /// <summary>
 430    /// Appends covered voxels using caller-owned scratch state for allocation-sensitive coverage scans.
 431    /// </summary>
 432    internal static void AddCoveredVoxelsTo(
 433        GridWorld world,
 434        Vector3d boundsMin,
 435        Vector3d boundsMax,
 436        SwiftList<Voxel> voxels,
 437        GridTraceScratch scratch,
 438        Fixed64? padding = null)
 439    {
 2440        scratch.Clear();
 2441        AddCoveredVoxelsCore(
 2442            world,
 2443            boundsMin,
 2444            boundsMax,
 2445            voxels,
 2446            scratch.ProcessedGrids,
 2447            scratch.VoxelRedundancy,
 2448            padding);
 2449    }
 450
 451    private static void AddCoveredVoxelsCore(
 452        GridWorld world,
 453        Vector3d boundsMin,
 454        Vector3d boundsMax,
 455        SwiftList<Voxel> voxels,
 456        SwiftHashSet<ushort> processedGrids,
 457        SwiftHashSet<Voxel> voxelRedundancyCheck,
 458        Fixed64? padding = null)
 459    {
 4460        (Vector3d queryMin, Vector3d queryMax) =
 4461            CreatePaddedOrderedBounds(boundsMin, boundsMax, padding);
 4462        (Vector3d candidateMin, Vector3d candidateMax) =
 4463            ExpandOrderedBounds(queryMin, queryMax, world.MaxTopologyCellEdge);
 464
 4465        (int cellXMin, int cellYMin, int cellZMin, int cellXMax, int cellYMax, int cellZMax) =
 4466            world.GetSpatialGridCellBounds(candidateMin, candidateMax);
 467
 16468        for (int cellZ = cellZMin; cellZ <= cellZMax; cellZ++)
 469        {
 16470            for (int cellY = cellYMin; cellY <= cellYMax; cellY++)
 471            {
 16472                for (int cellX = cellXMin; cellX <= cellXMax; cellX++)
 4473                    AddCoveredVoxelsForSpatialCell(
 4474                        world,
 4475                        cellX,
 4476                        cellY,
 4477                        cellZ,
 4478                        queryMin,
 4479                        queryMax,
 4480                        voxels,
 4481                        processedGrids,
 4482                        voxelRedundancyCheck);
 483            }
 484        }
 4485    }
 486
 487    private static void AddCoveredVoxelsForSpatialCell(
 488        GridWorld world,
 489        int cellX,
 490        int cellY,
 491        int cellZ,
 492        Vector3d queryMin,
 493        Vector3d queryMax,
 494        SwiftList<Voxel> voxels,
 495        SwiftHashSet<ushort> processedGrids,
 496        SwiftHashSet<Voxel> voxelRedundancyCheck)
 497    {
 4498        int cellIndex = SwiftHashTools.CombineHashCodes(cellX, cellY, cellZ);
 4499        if (!world.SpatialGridHash.TryGetValue(cellIndex, out SwiftHashSet<ushort> gridList))
 0500            return;
 501
 16502        foreach (ushort gridIndex in gridList)
 503        {
 4504            if (!world.ActiveGrids.IsAllocated(gridIndex) || !processedGrids.Add(gridIndex))
 505                continue;
 506
 4507            AddCoveredGridVoxels(
 4508                world.ActiveGrids[gridIndex],
 4509                queryMin,
 4510                queryMax,
 4511                voxels,
 4512                voxelRedundancyCheck);
 513        }
 4514    }
 515
 516    private static void AddCoveredScanCellsCore(
 517        GridWorld world,
 518        Vector3d boundsMin,
 519        Vector3d boundsMax,
 520        SwiftList<ScanCell> scanCells,
 521        SwiftHashSet<ushort> processedGrids,
 522        SwiftHashSet<ScanCell> voxelRedundancyCheck,
 523        Fixed64? padding = null)
 524    {
 551525        (Vector3d queryMin, Vector3d queryMax) =
 551526            CreatePaddedOrderedBounds(boundsMin, boundsMax, padding);
 551527        (Vector3d candidateMin, Vector3d candidateMax) =
 551528            ExpandOrderedBounds(queryMin, queryMax, world.MaxTopologyCellEdge);
 551529        (int cellXMin, int cellYMin, int cellZMin, int cellXMax, int cellYMax, int cellZMax) =
 551530            world.GetSpatialGridCellBounds(candidateMin, candidateMax);
 531
 2206532        for (int cellZ = cellZMin; cellZ <= cellZMax; cellZ++)
 533        {
 2208534            for (int cellY = cellYMin; cellY <= cellYMax; cellY++)
 535            {
 2218536                for (int cellX = cellXMin; cellX <= cellXMax; cellX++)
 557537                    AddCoveredScanCellsForSpatialCell(
 557538                        world,
 557539                        cellX,
 557540                        cellY,
 557541                        cellZ,
 557542                        queryMin,
 557543                        queryMax,
 557544                        scanCells,
 557545                        processedGrids,
 557546                        voxelRedundancyCheck);
 547            }
 548        }
 551549    }
 550
 551    private static void AddCoveredScanCellsForSpatialCell(
 552        GridWorld world,
 553        int cellX,
 554        int cellY,
 555        int cellZ,
 556        Vector3d queryMin,
 557        Vector3d queryMax,
 558        SwiftList<ScanCell> scanCells,
 559        SwiftHashSet<ushort> processedGrids,
 560        SwiftHashSet<ScanCell> voxelRedundancyCheck)
 561    {
 557562        int cellIndex = SwiftHashTools.CombineHashCodes(cellX, cellY, cellZ);
 557563        if (!world.SpatialGridHash.TryGetValue(cellIndex, out SwiftHashSet<ushort> gridList))
 6564            return;
 565
 2206566        foreach (ushort gridIndex in gridList)
 567        {
 552568            if (!world.ActiveGrids.IsAllocated(gridIndex) || !processedGrids.Add(gridIndex))
 569                continue;
 570
 549571            AddCoveredScanCellsForGrid(
 549572                world.ActiveGrids[gridIndex],
 549573                queryMin,
 549574                queryMax,
 549575                scanCells,
 549576                voxelRedundancyCheck);
 577        }
 551578    }
 579
 580    private static void AddCoveredScanCellsForGrid(
 581        VoxelGrid currentGrid,
 582        Vector3d queryMin,
 583        Vector3d queryMax,
 584        SwiftList<ScanCell> scanCells,
 585        SwiftHashSet<ScanCell> voxelRedundancyCheck)
 586    {
 549587        if (currentGrid.Topology.Kind == GridTopologyKind.HexPrism)
 588        {
 5589            AddCoveredHexScanCellsForGrid(
 5590                currentGrid,
 5591                queryMin,
 5592                queryMax,
 5593                scanCells,
 5594                voxelRedundancyCheck);
 5595            return;
 596        }
 597
 544598        if (!TryGetCoveredScanCellRange(
 544599            currentGrid,
 544600            queryMin,
 544601            queryMax,
 544602            out int xMin,
 544603            out int yMin,
 544604            out int zMin,
 544605            out int xMax,
 544606            out int yMax,
 544607            out int zMax))
 608        {
 3609            return;
 610        }
 611
 541612        currentGrid.AddScanCellsInRange(
 541613            xMin,
 541614            yMin,
 541615            zMin,
 541616            xMax,
 541617            yMax,
 541618            zMax,
 541619            scanCells,
 541620            voxelRedundancyCheck);
 541621    }
 622
 623    private static IEnumerable<GridVoxelSet> TraceLineIterator(
 624        GridWorld world,
 625        Vector3d start,
 626        Vector3d end,
 627        Fixed64? padding,
 628        bool includeEnd)
 629    {
 26630        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping = new();
 26631        SwiftHashSet<Voxel> voxelRedundancyCheck = SwiftHashSetPool<Voxel>.Shared.Rent();
 26632        SwiftHashSet<ushort> processedGrids = SwiftHashSetPool<ushort>.Shared.Rent();
 633
 634        try
 635        {
 26636            AddTraceLineVoxelsToMapping(
 26637                world,
 26638                start,
 26639                end,
 26640                padding,
 26641                includeEnd,
 26642                gridVoxelMapping,
 26643                voxelRedundancyCheck,
 26644                processedGrids);
 645
 26646            AddTraceLineEndVoxel(
 26647                world,
 26648                end,
 26649                includeEnd,
 26650                gridVoxelMapping,
 26651                voxelRedundancyCheck);
 652
 104653            foreach (KeyValuePair<VoxelGrid, SwiftList<Voxel>> kvp in gridVoxelMapping)
 26654                yield return new GridVoxelSet(kvp.Key, kvp.Value);
 26655        }
 656        finally
 657        {
 26658            ReleaseGridVoxelMapping(gridVoxelMapping);
 26659            SwiftHashSetPool<Voxel>.Shared.Release(voxelRedundancyCheck);
 26660            SwiftHashSetPool<ushort>.Shared.Release(processedGrids);
 26661        }
 26662    }
 663
 664    private static void AddTraceLineVoxelsToMapping(
 665        GridWorld world,
 666        Vector3d start,
 667        Vector3d end,
 668        Fixed64? padding,
 669        bool includeEnd,
 670        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping,
 671        SwiftHashSet<Voxel> voxelRedundancyCheck,
 672        SwiftHashSet<ushort> processedGrids)
 673    {
 26674        (Vector3d queryMin, Vector3d queryMax) = CreatePaddedOrderedBounds(start, end, padding);
 26675        (Vector3d candidateMin, Vector3d candidateMax) =
 26676            ExpandOrderedBounds(queryMin, queryMax, world.MaxTopologyCellEdge);
 677
 26678        (int cellXMin, int cellYMin, int cellZMin, int cellXMax, int cellYMax, int cellZMax) =
 26679            world.GetSpatialGridCellBounds(candidateMin, candidateMax);
 680
 104681        for (int cellZ = cellZMin; cellZ <= cellZMax; cellZ++)
 682        {
 104683            for (int cellY = cellYMin; cellY <= cellYMax; cellY++)
 684            {
 110685                for (int cellX = cellXMin; cellX <= cellXMax; cellX++)
 686                {
 29687                    int cellIndex = SwiftHashTools.CombineHashCodes(cellX, cellY, cellZ);
 29688                    if (!world.SpatialGridHash.TryGetValue(cellIndex, out SwiftHashSet<ushort> gridList))
 689                        continue;
 690
 28691                    AddTraceLineVoxelsForCell(
 28692                        world,
 28693                        gridList,
 28694                        start,
 28695                        end,
 28696                        padding,
 28697                        includeEnd,
 28698                        gridVoxelMapping,
 28699                        voxelRedundancyCheck,
 28700                        processedGrids);
 701                }
 702            }
 703        }
 26704    }
 705
 706    private static TraceLinePlan CreateTraceLinePlan(
 707        VoxelGrid grid,
 708        Vector3d start,
 709        Vector3d end,
 710        Fixed64? padding)
 711    {
 19712        (Vector3d snappedMin, Vector3d snappedMax) =
 19713            grid.NormalizeBounds(start, end, padding);
 714
 19715        Vector3d traceStart = CreateTraceEndpoint(start, end, snappedMin, snappedMax, useMinWhenIncreasing: true);
 19716        Vector3d traceEnd = CreateTraceEndpoint(start, end, snappedMin, snappedMax, useMinWhenIncreasing: false);
 717
 19718        Vector3d diff = traceEnd - traceStart;
 19719        Fixed64 steps = CalculateTraceSteps(grid, diff);
 720
 19721        return new TraceLinePlan(
 19722            traceStart,
 19723            steps,
 19724            diff.X / (steps + Fixed64.One),
 19725            diff.Y / (steps + Fixed64.One),
 19726            diff.Z / (steps + Fixed64.One));
 727    }
 728
 729    private static Fixed64 CalculateTraceSteps(VoxelGrid grid, Vector3d diff)
 730    {
 19731        Vector3d delta = Vector3d.Abs(diff);
 19732        Fixed64 stepX = delta.X / grid.Topology.Metrics.CellWidth;
 19733        Fixed64 stepY = delta.Y / grid.Topology.Metrics.LayerHeight;
 19734        Fixed64 stepZ = delta.Z / grid.Topology.Metrics.CellLength;
 19735        return FixedMath.Ceil(FixedMath.Max(FixedMath.Max(stepX, stepY), stepZ));
 736    }
 737
 738    private static Vector3d CreateTraceEndpoint(
 739        Vector3d start,
 740        Vector3d end,
 741        Vector3d snappedMin,
 742        Vector3d snappedMax,
 743        bool useMinWhenIncreasing)
 744    {
 745        // Preserve the caller's trace direction while still using snapped bounds for coverage lookup.
 54746        return new Vector3d(
 54747            SelectTraceCoordinate(start.X, end.X, snappedMin.X, snappedMax.X, useMinWhenIncreasing),
 54748            SelectTraceCoordinate(start.Y, end.Y, snappedMin.Y, snappedMax.Y, useMinWhenIncreasing),
 54749            SelectTraceCoordinate(start.Z, end.Z, snappedMin.Z, snappedMax.Z, useMinWhenIncreasing));
 750    }
 751
 752    private static Fixed64 SelectTraceCoordinate(
 753        Fixed64 start,
 754        Fixed64 end,
 755        Fixed64 snappedMin,
 756        Fixed64 snappedMax,
 757        bool useMinWhenIncreasing)
 758    {
 162759        return (start <= end) == useMinWhenIncreasing ? snappedMin : snappedMax;
 760    }
 761
 762    private static (Vector3d min, Vector3d max) CreatePaddedOrderedBounds(
 763        Vector3d min,
 764        Vector3d max,
 765        Fixed64? padding)
 766    {
 766767        Fixed64 fixedPadding = padding.HasValue && padding.Value > Fixed64.Zero
 766768            ? padding.Value
 766769            : Fixed64.Zero;
 770
 766771        min -= fixedPadding;
 766772        max += fixedPadding;
 773
 766774        (min.X, max.X) = min.X > max.X ? (max.X, min.X) : (min.X, max.X);
 766775        (min.Y, max.Y) = min.Y > max.Y ? (max.Y, min.Y) : (min.Y, max.Y);
 766776        (min.Z, max.Z) = min.Z > max.Z ? (max.Z, min.Z) : (min.Z, max.Z);
 777
 766778        return (min, max);
 779    }
 780
 781    private static (Vector3d min, Vector3d max) ExpandOrderedBounds(
 782        Vector3d min,
 783        Vector3d max,
 784        Fixed64 expansion)
 785    {
 766786        if (expansion <= Fixed64.Zero)
 5787            return (min, max);
 788
 761789        return (
 761790            new Vector3d(min.X - expansion, min.Y - expansion, min.Z - expansion),
 761791            new Vector3d(max.X + expansion, max.Y + expansion, max.Z + expansion));
 792    }
 793
 794    private static bool TryGetCoveredScanCellRange(
 795        VoxelGrid grid,
 796        Vector3d queryMin,
 797        Vector3d queryMax,
 798        out int xMin,
 799        out int yMin,
 800        out int zMin,
 801        out int xMax,
 802        out int yMax,
 803        out int zMax)
 804    {
 544805        xMin = 0;
 544806        yMin = 0;
 544807        zMin = 0;
 544808        xMax = 0;
 544809        yMax = 0;
 544810        zMax = 0;
 811
 544812        (Vector3d snappedMin, Vector3d snappedMax) = grid.NormalizeBounds(queryMin, queryMax);
 544813        if (!TopologyVoxelRangeUtility.TryClipBoundsToGrid(grid, snappedMin, snappedMax, out Vector3d clippedMin, out Ve
 3814            return false;
 815
 541816        (xMin, yMin, zMin) = grid.SnapToScanCell(clippedMin);
 541817        (xMax, yMax, zMax) = grid.SnapToScanCell(clippedMax);
 541818        return true;
 819    }
 820
 821    private static void AddTraceLineVoxelsForCell(
 822        GridWorld world,
 823        SwiftHashSet<ushort> gridList,
 824        Vector3d start,
 825        Vector3d end,
 826        Fixed64? padding,
 827        bool includeEnd,
 828        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping,
 829        SwiftHashSet<Voxel> voxelRedundancyCheck,
 830        SwiftHashSet<ushort> processedGrids)
 831    {
 118832        foreach (ushort gridIndex in gridList)
 833        {
 31834            if (!world.ActiveGrids.IsAllocated(gridIndex) || !processedGrids.Add(gridIndex))
 835                continue;
 836
 28837            VoxelGrid currentGrid = world.ActiveGrids[gridIndex];
 28838            if (!TryClipTraceSegmentToGrid(
 28839                currentGrid,
 28840                start,
 28841                end,
 28842                padding,
 28843                out Vector3d traceStart,
 28844                out Vector3d traceEnd,
 28845                out bool segmentEndsBeforeGlobalEnd))
 846            {
 847                continue;
 848            }
 849
 27850            SwiftList<Voxel> voxelList = SwiftListPool<Voxel>.Shared.Rent();
 851
 27852            AddTraceLineGridVoxels(
 27853                currentGrid,
 27854                traceStart,
 27855                traceEnd,
 27856                padding,
 27857                includeEnd || segmentEndsBeforeGlobalEnd,
 27858                voxelList,
 27859                voxelRedundancyCheck);
 860
 27861            if (voxelList.Count > 0)
 26862                gridVoxelMapping.Add(currentGrid, voxelList);
 863            else
 1864                SwiftListPool<Voxel>.Shared.Release(voxelList);
 865        }
 28866    }
 867
 868    private static void AddTraceLineGridVoxels(
 869        VoxelGrid currentGrid,
 870        Vector3d start,
 871        Vector3d end,
 872        Fixed64? padding,
 873        bool includeEnd,
 874        SwiftList<Voxel> voxelList,
 875        SwiftHashSet<Voxel> voxelRedundancyCheck)
 876    {
 27877        if (currentGrid.Topology.Kind == GridTopologyKind.HexPrism)
 878        {
 8879            AddHexTraceLineGridVoxels(
 8880                currentGrid,
 8881                start,
 8882                end,
 8883                padding,
 8884                includeEnd,
 8885                voxelList,
 8886                voxelRedundancyCheck);
 8887            return;
 888        }
 889
 19890        TraceLinePlan plan = CreateTraceLinePlan(currentGrid, start, end, padding);
 891
 398892        for (Fixed64 i = Fixed64.Zero; i <= plan.Steps; i += Fixed64.One)
 893        {
 180894            Vector3d tracePos = currentGrid.FloorToGrid(
 180895                new Vector3d(
 180896                    plan.TraceStart.X + plan.StepX * i,
 180897                    plan.TraceStart.Y + plan.StepY * i,
 180898                    plan.TraceStart.Z + plan.StepZ * i));
 899
 180900            if (!currentGrid.TryGetVoxel(tracePos, out Voxel? voxel) || voxelRedundancyCheck.Add(voxel!) != true)
 901                continue;
 902
 158903            voxelList.Add(voxel!);
 904        }
 905
 19906        if (includeEnd)
 15907            AddTraceVoxelByPosition(currentGrid, end, voxelList, voxelRedundancyCheck);
 19908    }
 909
 910    private static void AddHexTraceLineGridVoxels(
 911        VoxelGrid currentGrid,
 912        Vector3d start,
 913        Vector3d end,
 914        Fixed64? padding,
 915        bool includeEnd,
 916        SwiftList<Voxel> voxelList,
 917        SwiftHashSet<Voxel> voxelRedundancyCheck)
 918    {
 8919        CreateHexTraceEndpoints(
 8920            currentGrid,
 8921            start,
 8922            end,
 8923            padding,
 8924            out VoxelIndex startIndex,
 8925            out VoxelIndex endIndex);
 926
 8927        int steps = CalculateHexTraceSteps(startIndex, endIndex);
 8928        if (steps == 0)
 929        {
 1930            AddTraceVoxelByIndex(currentGrid, startIndex, voxelList, voxelRedundancyCheck);
 1931            return;
 932        }
 933
 7934        bool includeEndIndex = ShouldIncludeHexTraceEndIndex(currentGrid, end, endIndex, includeEnd);
 7935        int finalStep = includeEndIndex ? steps : steps - 1;
 7936        Fixed64 stepCount = new Fixed64(steps);
 72937        for (int i = 0; i <= finalStep; i++)
 938        {
 29939            Fixed64 t = new Fixed64(i) / stepCount;
 29940            VoxelIndex traceIndex = InterpolateHexTraceIndex(startIndex, endIndex, t);
 29941            AddTraceVoxelByIndex(currentGrid, traceIndex, voxelList, voxelRedundancyCheck);
 942        }
 7943    }
 944
 945    private static void CreateHexTraceEndpoints(
 946        VoxelGrid grid,
 947        Vector3d start,
 948        Vector3d end,
 949        Fixed64? padding,
 950        out VoxelIndex startIndex,
 951        out VoxelIndex endIndex)
 952    {
 8953        (Vector3d snappedMin, Vector3d snappedMax) = grid.NormalizeBounds(start, end, padding);
 8954        Vector3d traceStart = grid.FloorToGrid(CreateTraceEndpoint(
 8955            start,
 8956            end,
 8957            snappedMin,
 8958            snappedMax,
 8959            useMinWhenIncreasing: true));
 8960        Vector3d traceEnd = grid.FloorToGrid(CreateTraceEndpoint(
 8961            start,
 8962            end,
 8963            snappedMin,
 8964            snappedMax,
 8965            useMinWhenIncreasing: false));
 966
 8967        grid.TryGetVoxelIndex(traceStart, out startIndex);
 8968        grid.TryGetVoxelIndex(traceEnd, out endIndex);
 8969    }
 970
 971    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 972    private static int CalculateHexTraceSteps(VoxelIndex start, VoxelIndex end)
 973    {
 8974        int qDelta = System.Math.Abs(end.x - start.x);
 8975        int rDelta = System.Math.Abs(end.z - start.z);
 8976        int sDelta = System.Math.Abs((-end.x - end.z) - (-start.x - start.z));
 8977        int planarSteps = System.Math.Max(qDelta, System.Math.Max(rDelta, sDelta));
 8978        int verticalSteps = System.Math.Abs(end.y - start.y);
 8979        return System.Math.Max(planarSteps, verticalSteps);
 980    }
 981
 982    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 983    private static VoxelIndex InterpolateHexTraceIndex(VoxelIndex start, VoxelIndex end, Fixed64 t)
 984    {
 29985        Fixed64 q = Interpolate(new Fixed64(start.x), new Fixed64(end.x), t);
 29986        Fixed64 y = Interpolate(new Fixed64(start.y), new Fixed64(end.y), t);
 29987        Fixed64 r = Interpolate(new Fixed64(start.z), new Fixed64(end.z), t);
 29988        return HexCoordinateUtility.RoundAxial(q, y, r);
 989    }
 990
 991    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 992    private static Fixed64 Interpolate(Fixed64 start, Fixed64 end, Fixed64 t) =>
 87993        start + (end - start) * t;
 994
 995    private static bool TryClipTraceSegmentToGrid(
 996        VoxelGrid grid,
 997        Vector3d start,
 998        Vector3d end,
 999        Fixed64? padding,
 1000        out Vector3d clippedStart,
 1001        out Vector3d clippedEnd,
 1002        out bool segmentEndsBeforeGlobalEnd)
 1003    {
 281004        clippedStart = default;
 281005        clippedEnd = default;
 281006        segmentEndsBeforeGlobalEnd = false;
 1007
 281008        Fixed64 fixedPadding = padding.HasValue && padding.Value > Fixed64.Zero
 281009            ? padding.Value
 281010            : Fixed64.Zero;
 281011        Vector3d boundsMin = grid.BoundsMin - fixedPadding;
 281012        Vector3d boundsMax = grid.BoundsMax + fixedPadding;
 281013        Fixed64 tMin = Fixed64.Zero;
 281014        Fixed64 tMax = Fixed64.One;
 1015
 281016        if (!(ClipTraceSegmentAxis(start.X, end.X, boundsMin.X, boundsMax.X, ref tMin, ref tMax)
 281017            && ClipTraceSegmentAxis(start.Y, end.Y, boundsMin.Y, boundsMax.Y, ref tMin, ref tMax)
 281018            && ClipTraceSegmentAxis(start.Z, end.Z, boundsMin.Z, boundsMax.Z, ref tMin, ref tMax)))
 1019        {
 11020            return false;
 1021        }
 1022
 271023        clippedStart = InterpolateTraceSegment(start, end, boundsMin, boundsMax, tMin);
 271024        clippedEnd = InterpolateTraceSegment(start, end, boundsMin, boundsMax, tMax);
 271025        segmentEndsBeforeGlobalEnd = tMax < Fixed64.One;
 271026        return true;
 1027    }
 1028
 1029    private static bool ClipTraceSegmentAxis(
 1030        Fixed64 start,
 1031        Fixed64 end,
 1032        Fixed64 boundsMin,
 1033        Fixed64 boundsMax,
 1034        ref Fixed64 tMin,
 1035        ref Fixed64 tMax)
 1036    {
 841037        Fixed64 delta = end - start;
 841038        if (delta == Fixed64.Zero)
 381039            return start >= boundsMin && start <= boundsMax;
 1040
 461041        Fixed64 axisMin = (boundsMin - start) / delta;
 461042        Fixed64 axisMax = (boundsMax - start) / delta;
 461043        if (axisMin > axisMax)
 51044            (axisMin, axisMax) = (axisMax, axisMin);
 1045
 461046        if (axisMin > tMin)
 11047            tMin = axisMin;
 461048        if (axisMax < tMax)
 61049            tMax = axisMax;
 1050
 461051        return tMin <= tMax;
 1052    }
 1053
 1054    private static bool ShouldIncludeHexTraceEndIndex(
 1055        VoxelGrid grid,
 1056        Vector3d end,
 1057        VoxelIndex endIndex,
 1058        bool includeEnd)
 1059    {
 71060        if (includeEnd)
 61061            return true;
 1062
 11063        return !grid.TryGetVoxelIndex(end, out VoxelIndex actualEndIndex)
 11064            || actualEndIndex != endIndex;
 1065    }
 1066
 1067    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1068    private static Vector3d InterpolateTraceSegment(
 1069        Vector3d start,
 1070        Vector3d end,
 1071        Vector3d boundsMin,
 1072        Vector3d boundsMax,
 1073        Fixed64 t) =>
 541074        new(
 541075            InterpolateTraceAxis(start.X, end.X, boundsMin.X, boundsMax.X, t),
 541076            InterpolateTraceAxis(start.Y, end.Y, boundsMin.Y, boundsMax.Y, t),
 541077            InterpolateTraceAxis(start.Z, end.Z, boundsMin.Z, boundsMax.Z, t));
 1078
 1079    private static Fixed64 InterpolateTraceAxis(
 1080        Fixed64 start,
 1081        Fixed64 end,
 1082        Fixed64 boundsMin,
 1083        Fixed64 boundsMax,
 1084        Fixed64 t)
 1085    {
 1621086        Fixed64 delta = end - start;
 1621087        if (delta == Fixed64.Zero)
 721088            return start;
 1089
 901090        if ((boundsMin - start) / delta == t)
 181091            return boundsMin;
 721092        if ((boundsMax - start) / delta == t)
 171093            return boundsMax;
 1094
 551095        return start + delta * t;
 1096    }
 1097
 1098    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1099    private static void AddTraceVoxelByPosition(
 1100        VoxelGrid grid,
 1101        Vector3d position,
 1102        SwiftList<Voxel> voxelList,
 1103        SwiftHashSet<Voxel> voxelRedundancyCheck)
 1104    {
 151105        if (grid.TryGetVoxel(grid.FloorToGrid(position), out Voxel? voxel)
 151106            && voxelRedundancyCheck.Add(voxel!))
 1107        {
 91108            voxelList.Add(voxel!);
 1109        }
 151110    }
 1111
 1112    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1113    private static void AddTraceVoxelByIndex(
 1114        VoxelGrid grid,
 1115        VoxelIndex index,
 1116        SwiftList<Voxel> voxelList,
 1117        SwiftHashSet<Voxel> voxelRedundancyCheck)
 1118    {
 331119        if (grid.TryGetVoxel(index, out Voxel? voxel)
 331120            && voxelRedundancyCheck.Add(voxel!))
 1121        {
 291122            voxelList.Add(voxel!);
 1123        }
 331124    }
 1125
 1126    private static void AddTraceLineEndVoxel(
 1127        GridWorld world,
 1128        Vector3d end,
 1129        bool includeEnd,
 1130        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping,
 1131        SwiftHashSet<Voxel> voxelRedundancyCheck)
 1132    {
 261133        if (!includeEnd
 261134            || !world.TryGetGridAndVoxel(end, out VoxelGrid? endGrid, out Voxel? endVoxel)
 261135            || !voxelRedundancyCheck.Add(endVoxel!))
 1136        {
 261137            return;
 1138        }
 1139
 01140        if (!gridVoxelMapping.TryGetValue(endGrid!, out SwiftList<Voxel> endVoxelList))
 1141        {
 01142            endVoxelList = SwiftListPool<Voxel>.Shared.Rent();
 01143            gridVoxelMapping.Add(endGrid!, endVoxelList);
 1144        }
 1145
 01146        endVoxelList.Add(endVoxel!);
 01147    }
 1148
 1149    private static void ReleaseGridVoxelMapping(SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping)
 1150    {
 8441151        foreach (KeyValuePair<VoxelGrid, SwiftList<Voxel>> kvp in gridVoxelMapping)
 2111152            SwiftListPool<Voxel>.Shared.Release(kvp.Value);
 2111153    }
 1154
 1155    private static IEnumerable<GridVoxelSet> GetCoveredVoxelsIterator(
 1156        GridWorld world,
 1157        Vector3d boundsMin,
 1158        Vector3d boundsMax,
 1159        Fixed64? padding)
 1160    {
 1851161        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping = new();
 1851162        SwiftHashSet<Voxel> voxelRedundancyCheck = SwiftHashSetPool<Voxel>.Shared.Rent();
 1851163        SwiftHashSet<ushort> processedGrids = SwiftHashSetPool<ushort>.Shared.Rent();
 1164
 1165        try
 1166        {
 1851167            AddCoveredVoxelsToMapping(
 1851168                world,
 1851169                boundsMin,
 1851170                boundsMax,
 1851171                padding,
 1851172                gridVoxelMapping,
 1851173                voxelRedundancyCheck,
 1851174                processedGrids);
 1175
 7401176            foreach (KeyValuePair<VoxelGrid, SwiftList<Voxel>> kvp in gridVoxelMapping)
 1851177                yield return new GridVoxelSet(kvp.Key, kvp.Value);
 1851178        }
 1179        finally
 1180        {
 1851181            ReleaseGridVoxelMapping(gridVoxelMapping);
 1851182            SwiftHashSetPool<Voxel>.Shared.Release(voxelRedundancyCheck);
 1851183            SwiftHashSetPool<ushort>.Shared.Release(processedGrids);
 1851184        }
 1851185    }
 1186
 1187    private static void AddCoveredVoxelsToMapping(
 1188        GridWorld world,
 1189        Vector3d boundsMin,
 1190        Vector3d boundsMax,
 1191        Fixed64? padding,
 1192        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping,
 1193        SwiftHashSet<Voxel> voxelRedundancyCheck,
 1194        SwiftHashSet<ushort> processedGrids)
 1195    {
 1851196        (Vector3d queryMin, Vector3d queryMax) =
 1851197            CreatePaddedOrderedBounds(boundsMin, boundsMax, padding);
 1851198        (Vector3d candidateMin, Vector3d candidateMax) =
 1851199            ExpandOrderedBounds(queryMin, queryMax, world.MaxTopologyCellEdge);
 1200
 1851201        (int cellXMin, int cellYMin, int cellZMin, int cellXMax, int cellYMax, int cellZMax) =
 1851202            world.GetSpatialGridCellBounds(candidateMin, candidateMax);
 1203
 7541204        for (int cellZ = cellZMin; cellZ <= cellZMax; cellZ++)
 1205        {
 7681206            for (int cellY = cellYMin; cellY <= cellYMax; cellY++)
 1207            {
 8041208                for (int cellX = cellXMin; cellX <= cellXMax; cellX++)
 1209                {
 2101210                    int cellIndex = SwiftHashTools.CombineHashCodes(cellX, cellY, cellZ);
 2101211                    if (world.SpatialGridHash.TryGetValue(cellIndex, out SwiftHashSet<ushort> gridList))
 1212                    {
 2001213                        AddCoveredVoxelsForCell(
 2001214                            world,
 2001215                            gridList,
 2001216                            queryMin,
 2001217                            queryMax,
 2001218                            gridVoxelMapping,
 2001219                            voxelRedundancyCheck,
 2001220                            processedGrids);
 1221                    }
 1222                }
 1223            }
 1224        }
 1851225    }
 1226
 1227    private static void AddCoveredVoxelsForCell(
 1228        GridWorld world,
 1229        SwiftHashSet<ushort> gridList,
 1230        Vector3d queryMin,
 1231        Vector3d queryMax,
 1232        SwiftDictionary<VoxelGrid, SwiftList<Voxel>> gridVoxelMapping,
 1233        SwiftHashSet<Voxel> voxelRedundancyCheck,
 1234        SwiftHashSet<ushort> processedGrids)
 1235    {
 8141236        foreach (ushort gridIndex in gridList)
 1237        {
 2071238            if (!world.ActiveGrids.IsAllocated(gridIndex) || !processedGrids.Add(gridIndex))
 1239                continue;
 1240
 1891241            VoxelGrid currentGrid = world.ActiveGrids[gridIndex];
 1891242            SwiftList<Voxel> voxelList = SwiftListPool<Voxel>.Shared.Rent();
 1891243            AddCoveredGridVoxels(currentGrid, queryMin, queryMax, voxelList, voxelRedundancyCheck);
 1244
 1891245            if (voxelList.Count > 0)
 1851246                gridVoxelMapping.Add(currentGrid, voxelList);
 1247            else
 41248                SwiftListPool<Voxel>.Shared.Release(voxelList);
 1249        }
 2001250    }
 1251
 1252    private static void AddCoveredGridVoxels(
 1253        VoxelGrid currentGrid,
 1254        Vector3d queryMin,
 1255        Vector3d queryMax,
 1256        SwiftList<Voxel> voxelList,
 1257        SwiftHashSet<Voxel> voxelRedundancyCheck)
 1258    {
 1931259        if (currentGrid.Topology.Kind == GridTopologyKind.HexPrism)
 1260        {
 71261            AddCoveredHexGridVoxels(
 71262                currentGrid,
 71263                queryMin,
 71264                queryMax,
 71265                voxelList,
 71266                voxelRedundancyCheck);
 71267            return;
 1268        }
 1269
 1861270        if (!TopologyVoxelRangeUtility.TryGetCandidateRange(
 1861271            currentGrid,
 1861272            queryMin,
 1861273            queryMax,
 1861274            out VoxelIndex minIndex,
 1861275            out VoxelIndex maxIndex))
 1276        {
 11277            return;
 1278        }
 1279
 1851280        currentGrid.AddVoxelsInIndexRange(minIndex, maxIndex, voxelList, voxelRedundancyCheck);
 1851281    }
 1282
 1283    private static void AddCoveredHexGridVoxels(
 1284        VoxelGrid currentGrid,
 1285        Vector3d queryMin,
 1286        Vector3d queryMax,
 1287        SwiftList<Voxel> voxelList,
 1288        SwiftHashSet<Voxel> voxelRedundancyCheck)
 1289    {
 71290        if (!TopologyVoxelRangeUtility.TryGetCandidateRange(
 71291            currentGrid,
 71292            queryMin,
 71293            queryMax,
 71294            out VoxelIndex minIndex,
 71295            out VoxelIndex maxIndex))
 1296        {
 11297            return;
 1298        }
 1299
 61300        Fixed64 horizontalExpansion = currentGrid.Topology.Metrics.CellRadius;
 61301        Fixed64 coverageMinX = queryMin.X - horizontalExpansion;
 61302        Fixed64 coverageMaxX = queryMax.X + horizontalExpansion;
 61303        Fixed64 coverageMinZ = queryMin.Z - horizontalExpansion;
 61304        Fixed64 coverageMaxZ = queryMax.Z + horizontalExpansion;
 1305
 361306        for (int x = minIndex.x; x <= maxIndex.x; x++)
 1307        {
 481308            for (int y = minIndex.y; y <= maxIndex.y; y++)
 1309            {
 681310                for (int z = minIndex.z; z <= maxIndex.z; z++)
 1311                {
 221312                    if (currentGrid.TryGetVoxel(x, y, z, out Voxel? voxel)
 221313                        && IsHexVoxelCenterInHorizontalCoverage(
 221314                            voxel!,
 221315                            coverageMinX,
 221316                            coverageMaxX,
 221317                            coverageMinZ,
 221318                            coverageMaxZ)
 221319                        && voxelRedundancyCheck.Add(voxel!))
 1320                    {
 111321                        voxelList.Add(voxel!);
 1322                    }
 1323                }
 1324            }
 1325        }
 61326    }
 1327
 1328    private static void AddCoveredHexScanCellsForGrid(
 1329        VoxelGrid currentGrid,
 1330        Vector3d queryMin,
 1331        Vector3d queryMax,
 1332        SwiftList<ScanCell> scanCells,
 1333        SwiftHashSet<ScanCell> scanCellRedundancyCheck)
 1334    {
 51335        if (!TopologyVoxelRangeUtility.TryGetCandidateRange(
 51336            currentGrid,
 51337            queryMin,
 51338            queryMax,
 51339            out VoxelIndex minIndex,
 51340            out VoxelIndex maxIndex))
 1341        {
 11342            return;
 1343        }
 1344
 41345        currentGrid.AddScanCellsInRange(
 41346            minIndex.x / currentGrid.ScanCellSize,
 41347            minIndex.y / currentGrid.ScanCellSize,
 41348            minIndex.z / currentGrid.ScanCellSize,
 41349            maxIndex.x / currentGrid.ScanCellSize,
 41350            maxIndex.y / currentGrid.ScanCellSize,
 41351            maxIndex.z / currentGrid.ScanCellSize,
 41352            scanCells,
 41353            scanCellRedundancyCheck);
 41354    }
 1355
 1356    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1357    private static bool IsHexVoxelCenterInHorizontalCoverage(
 1358        Voxel voxel,
 1359        Fixed64 coverageMinX,
 1360        Fixed64 coverageMaxX,
 1361        Fixed64 coverageMinZ,
 1362        Fixed64 coverageMaxZ)
 1363    {
 201364        Vector3d position = voxel.WorldPosition;
 201365        return position.X >= coverageMinX
 201366            && position.X <= coverageMaxX
 201367            && position.Z >= coverageMinZ
 201368            && position.Z <= coverageMaxZ;
 1369    }
 1370
 1371    private static IEnumerable<ScanCell> GetCoveredScanCellsIterator(
 1372        GridWorld world,
 1373        Vector3d boundsMin,
 1374        Vector3d boundsMax,
 1375        Fixed64? padding)
 1376    {
 111377        SwiftList<ScanCell> scanCells = SwiftListPool<ScanCell>.Shared.Rent();
 111378        SwiftHashSet<ushort> processedGrids = SwiftHashSetPool<ushort>.Shared.Rent();
 111379        SwiftHashSet<ScanCell> voxelRedundancyCheck = SwiftHashSetPool<ScanCell>.Shared.Rent();
 1380
 1381        try
 1382        {
 111383            AddCoveredScanCellsCore(
 111384                world,
 111385                boundsMin,
 111386                boundsMax,
 111387                scanCells,
 111388                processedGrids,
 111389                voxelRedundancyCheck,
 111390                padding);
 1391
 881392            foreach (ScanCell scanCell in scanCells)
 331393                yield return scanCell;
 111394        }
 1395        finally
 1396        {
 111397            SwiftListPool<ScanCell>.Shared.Release(scanCells);
 111398            SwiftHashSetPool<ushort>.Shared.Release(processedGrids);
 111399            SwiftHashSetPool<ScanCell>.Shared.Release(voxelRedundancyCheck);
 111400        }
 111401    }
 1402}

Methods/Properties

.ctor(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
TraceLine(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean)
TraceLine(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean,FixedMathSharp.Fixed64)
GetCoveredVoxels(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredVoxels(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredVoxelsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredVoxelsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredVoxelsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,GridForge.Grids.GridTraceScratch,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredVoxelsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,GridForge.Grids.GridTraceScratch,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCells(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCells(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCellsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCellsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCellsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,GridForge.Grids.GridScanScratch,System.Nullable`1<FixedMathSharp.Fixed64>)
GetCoveredScanCellsInto(GridForge.Grids.GridWorld,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,GridForge.Grids.GridScanScratch,FixedMathSharp.Fixed64,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredScanCellsTo(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredScanCellsTo(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,GridForge.Grids.GridScanScratch,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredVoxelsTo(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredVoxelsTo(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,GridForge.Grids.GridTraceScratch,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredVoxelsCore(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredVoxelsForSpatialCell(GridForge.Grids.GridWorld,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddCoveredScanCellsCore(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,SwiftCollections.SwiftHashSet`1<System.UInt16>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.ScanCell>,System.Nullable`1<FixedMathSharp.Fixed64>)
AddCoveredScanCellsForSpatialCell(GridForge.Grids.GridWorld,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,SwiftCollections.SwiftHashSet`1<System.UInt16>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.ScanCell>)
AddCoveredScanCellsForGrid(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.ScanCell>)
TraceLineIterator()
<>m__Finally1()
AddTraceLineVoxelsToMapping(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean,SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>)
CreateTraceLinePlan(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>)
CalculateTraceSteps(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d)
CreateTraceEndpoint(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Boolean)
SelectTraceCoordinate(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.Boolean)
CreatePaddedOrderedBounds(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>)
ExpandOrderedBounds(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
TryGetCoveredScanCellRange(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32&,System.Int32&,System.Int32&,System.Int32&,System.Int32&,System.Int32&)
AddTraceLineVoxelsForCell(GridForge.Grids.GridWorld,SwiftCollections.SwiftHashSet`1<System.UInt16>,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean,SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>)
AddTraceLineGridVoxels(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddHexTraceLineGridVoxels(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,System.Boolean,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
CreateHexTraceEndpoints(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,GridForge.Spatial.VoxelIndex&,GridForge.Spatial.VoxelIndex&)
CalculateHexTraceSteps(GridForge.Spatial.VoxelIndex,GridForge.Spatial.VoxelIndex)
InterpolateHexTraceIndex(GridForge.Spatial.VoxelIndex,GridForge.Spatial.VoxelIndex,FixedMathSharp.Fixed64)
Interpolate(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
TryClipTraceSegmentToGrid(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&,System.Boolean&)
ClipTraceSegmentAxis(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64&,FixedMathSharp.Fixed64&)
ShouldIncludeHexTraceEndIndex(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,GridForge.Spatial.VoxelIndex,System.Boolean)
InterpolateTraceSegment(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
InterpolateTraceAxis(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
AddTraceVoxelByPosition(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddTraceVoxelByIndex(GridForge.Grids.VoxelGrid,GridForge.Spatial.VoxelIndex,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddTraceLineEndVoxel(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,System.Boolean,SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
ReleaseGridVoxelMapping(SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>)
GetCoveredVoxelsIterator()
<>m__Finally1()
AddCoveredVoxelsToMapping(GridForge.Grids.GridWorld,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>,SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>)
AddCoveredVoxelsForCell(GridForge.Grids.GridWorld,SwiftCollections.SwiftHashSet`1<System.UInt16>,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftDictionary`2<GridForge.Grids.VoxelGrid,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<System.UInt16>)
AddCoveredGridVoxels(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddCoveredHexGridVoxels(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.Voxel>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.Voxel>)
AddCoveredHexScanCellsForGrid(GridForge.Grids.VoxelGrid,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<GridForge.Grids.ScanCell>,SwiftCollections.SwiftHashSet`1<GridForge.Grids.ScanCell>)
IsHexVoxelCenterInHorizontalCoverage(GridForge.Grids.Voxel,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
GetCoveredScanCellsIterator()
<>m__Finally1()