< Summary

Information
Class: GridForge.Grids.Topology.TopologyVoxelRangeUtility
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/TopologyVoxelRangeUtility.cs
Line coverage
100%
Covered lines: 76
Uncovered lines: 0
Coverable lines: 76
Total lines: 164
Line coverage: 100%
Branch coverage
94%
Covered branches: 17
Total branches: 18
Branch coverage: 94.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
TryGetCandidateRange(...)100%11100%
TryGetCandidateRange(...)100%44100%
TryGetRectangularCandidateRange(...)83.33%66100%
TryGetHexCandidateRange(...)100%22100%
TryClipBoundsToGrid(...)100%66100%
IncludeHexAxialCorner(...)100%11100%

File(s)

/home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/TopologyVoxelRangeUtility.cs

#LineLine coverage
 1//=======================================================================
 2// TopologyVoxelRangeUtility.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.Spatial;
 10using System.Runtime.CompilerServices;
 11
 12namespace GridForge.Grids.Topology;
 13
 14internal static class TopologyVoxelRangeUtility
 15{
 16    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 17    internal static bool TryGetCandidateRange(
 18        VoxelGrid grid,
 19        TopologyVoxelAabb bounds,
 20        out VoxelIndex minIndex,
 21        out VoxelIndex maxIndex) =>
 3122        TryGetCandidateRange(grid, bounds.Min, bounds.Max, out minIndex, out maxIndex);
 23
 24    internal static bool TryGetCandidateRange(
 25        VoxelGrid grid,
 26        Vector3d queryMin,
 27        Vector3d queryMax,
 28        out VoxelIndex minIndex,
 29        out VoxelIndex maxIndex)
 30    {
 23031        if (!grid.IsActive)
 32        {
 133            minIndex = default;
 134            maxIndex = default;
 135            return false;
 36        }
 37
 22938        return grid.Topology.Kind == GridTopologyKind.HexPrism
 22939            ? TryGetHexCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex)
 22940            : TryGetRectangularCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex);
 41    }
 42
 43    private static bool TryGetRectangularCandidateRange(
 44        VoxelGrid grid,
 45        Vector3d queryMin,
 46        Vector3d queryMax,
 47        out VoxelIndex minIndex,
 48        out VoxelIndex maxIndex)
 49    {
 20150        minIndex = default;
 20151        maxIndex = default;
 52
 20153        (Vector3d snappedMin, Vector3d snappedMax) = grid.NormalizeBounds(queryMin, queryMax);
 20154        if (!TryClipBoundsToGrid(grid, snappedMin, snappedMax, out Vector3d clippedMin, out Vector3d clippedMax)
 20155            || !grid.TryGetVoxelIndex(clippedMin, out minIndex)
 20156            || !grid.TryGetVoxelIndex(clippedMax, out maxIndex))
 57        {
 158            return false;
 59        }
 60
 20061        return true;
 62    }
 63
 64    private static bool TryGetHexCandidateRange(
 65        VoxelGrid grid,
 66        Vector3d queryMin,
 67        Vector3d queryMax,
 68        out VoxelIndex minIndex,
 69        out VoxelIndex maxIndex)
 70    {
 2871        minIndex = default;
 2872        maxIndex = default;
 73
 2874        GridTopologyMetrics metrics = grid.Topology.Metrics;
 2875        Fixed64 horizontalExpansion = metrics.CellRadius;
 2876        Fixed64 layerHeight = metrics.LayerHeight;
 2877        Vector3d candidateMin = new(
 2878            queryMin.X - horizontalExpansion,
 2879            queryMin.Y,
 2880            queryMin.Z - horizontalExpansion);
 2881        Vector3d candidateMax = new(
 2882            queryMax.X + horizontalExpansion,
 2883            queryMax.Y,
 2884            queryMax.Z + horizontalExpansion);
 85
 2886        if (!TryClipBoundsToGrid(grid, candidateMin, candidateMax, out Vector3d clippedMin, out Vector3d clippedMax))
 387            return false;
 88
 2589        Fixed64 qMin = Fixed64.MaxValue;
 2590        Fixed64 qMax = Fixed64.MinValue;
 2591        Fixed64 rMin = Fixed64.MaxValue;
 2592        Fixed64 rMax = Fixed64.MinValue;
 93
 2594        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 2595        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 2596        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 2597        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 98
 2599        int xMin = System.Math.Max(0, qMin.FloorToInt() - 1);
 25100        int xMax = System.Math.Min(grid.Width - 1, qMax.CeilToInt() + 1);
 25101        int zMin = System.Math.Max(0, rMin.FloorToInt() - 1);
 25102        int zMax = System.Math.Min(grid.Length - 1, rMax.CeilToInt() + 1);
 25103        int yMin = System.Math.Max(
 25104            0,
 25105            ((clippedMin.Y - grid.BoundsMin.Y) / layerHeight).FloorToInt());
 25106        int yMax = System.Math.Min(
 25107            grid.Height - 1,
 25108            ((clippedMax.Y - grid.BoundsMin.Y) / layerHeight).CeilToInt());
 109
 25110        minIndex = new VoxelIndex(xMin, yMin, zMin);
 25111        maxIndex = new VoxelIndex(xMax, yMax, zMax);
 25112        return true;
 113    }
 114
 115    internal static bool TryClipBoundsToGrid(
 116        VoxelGrid grid,
 117        Vector3d min,
 118        Vector3d max,
 119        out Vector3d clippedMin,
 120        out Vector3d clippedMax)
 121    {
 773122        Fixed64 xMin = FixedMath.Max(min.X, grid.BoundsMin.X);
 773123        Fixed64 yMin = FixedMath.Max(min.Y, grid.BoundsMin.Y);
 773124        Fixed64 zMin = FixedMath.Max(min.Z, grid.BoundsMin.Z);
 773125        Fixed64 xMax = FixedMath.Min(max.X, grid.BoundsMax.X);
 773126        Fixed64 yMax = FixedMath.Min(max.Y, grid.BoundsMax.Y);
 773127        Fixed64 zMax = FixedMath.Min(max.Z, grid.BoundsMax.Z);
 128
 773129        if (xMin > xMax || yMin > yMax || zMin > zMax)
 130        {
 7131            clippedMin = default;
 7132            clippedMax = default;
 7133            return false;
 134        }
 135
 766136        clippedMin = new Vector3d(xMin, yMin, zMin);
 766137        clippedMax = new Vector3d(xMax, yMax, zMax);
 766138        return true;
 139    }
 140
 141    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 142    private static void IncludeHexAxialCorner(
 143        Vector3d gridBoundsMin,
 144        GridTopologyMetrics metrics,
 145        Fixed64 x,
 146        Fixed64 z,
 147        ref Fixed64 qMin,
 148        ref Fixed64 qMax,
 149        ref Fixed64 rMin,
 150        ref Fixed64 rMax)
 151    {
 100152        HexCoordinateUtility.WorldOffsetToAxial(
 100153            x - gridBoundsMin.X,
 100154            z - gridBoundsMin.Z,
 100155            metrics,
 100156            out Fixed64 q,
 100157            out Fixed64 r);
 158
 100159        qMin = FixedMath.Min(qMin, q);
 100160        qMax = FixedMath.Max(qMax, q);
 100161        rMin = FixedMath.Min(rMin, r);
 100162        rMax = FixedMath.Max(rMax, r);
 100163    }
 164}