< 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
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
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(...)100%22100%
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 System.Diagnostics;
 9using System.Runtime.CompilerServices;
 10using FixedMathSharp;
 11using GridForge.Spatial;
 12
 13namespace GridForge.Grids.Topology;
 14
 15internal static class TopologyVoxelRangeUtility
 16{
 17    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 18    internal static bool TryGetCandidateRange(
 19        VoxelGrid grid,
 20        TopologyVoxelAabb bounds,
 21        out VoxelIndex minIndex,
 22        out VoxelIndex maxIndex) =>
 5123        TryGetCandidateRange(grid, bounds.Min, bounds.Max, out minIndex, out maxIndex);
 24
 25    internal static bool TryGetCandidateRange(
 26        VoxelGrid grid,
 27        Vector3d queryMin,
 28        Vector3d queryMax,
 29        out VoxelIndex minIndex,
 30        out VoxelIndex maxIndex)
 31    {
 31432        if (!grid.IsActive)
 33        {
 134            minIndex = default;
 135            maxIndex = default;
 136            return false;
 37        }
 38
 31339        return grid.Topology.Kind == GridTopologyKind.HexPrism
 31340            ? TryGetHexCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex)
 31341            : TryGetRectangularCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex);
 42    }
 43
 44    private static bool TryGetRectangularCandidateRange(
 45        VoxelGrid grid,
 46        Vector3d queryMin,
 47        Vector3d queryMax,
 48        out VoxelIndex minIndex,
 49        out VoxelIndex maxIndex)
 50    {
 27351        minIndex = default;
 27352        maxIndex = default;
 53
 27354        (Vector3d snappedMin, Vector3d snappedMax) = grid.NormalizeBounds(queryMin, queryMax);
 27355        if (!TryClipBoundsToGrid(grid, snappedMin, snappedMax, out Vector3d clippedMin, out Vector3d clippedMax))
 356            return false;
 57
 27058        bool minResolved = grid.TryGetVoxelIndex(clippedMin, out minIndex);
 27059        bool maxResolved = grid.TryGetVoxelIndex(clippedMax, out maxIndex);
 60        Debug.Assert(minResolved && maxResolved);
 27061        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    {
 4071        minIndex = default;
 4072        maxIndex = default;
 73
 4074        GridTopologyMetrics metrics = grid.Topology.Metrics;
 4075        Fixed64 horizontalExpansion = metrics.CellRadius;
 4076        Fixed64 layerHeight = metrics.LayerHeight;
 4077        Vector3d candidateMin = new(
 4078            queryMin.X - horizontalExpansion,
 4079            queryMin.Y,
 4080            queryMin.Z - horizontalExpansion);
 4081        Vector3d candidateMax = new(
 4082            queryMax.X + horizontalExpansion,
 4083            queryMax.Y,
 4084            queryMax.Z + horizontalExpansion);
 85
 4086        if (!TryClipBoundsToGrid(grid, candidateMin, candidateMax, out Vector3d clippedMin, out Vector3d clippedMax))
 387            return false;
 88
 3789        Fixed64 qMin = Fixed64.MaxValue;
 3790        Fixed64 qMax = Fixed64.MinValue;
 3791        Fixed64 rMin = Fixed64.MaxValue;
 3792        Fixed64 rMax = Fixed64.MinValue;
 93
 3794        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 3795        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 3796        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 3797        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 98
 3799        int xMin = System.Math.Max(0, qMin.FloorToInt() - 1);
 37100        int xMax = System.Math.Min(grid.Width - 1, qMax.CeilToInt() + 1);
 37101        int zMin = System.Math.Max(0, rMin.FloorToInt() - 1);
 37102        int zMax = System.Math.Min(grid.Length - 1, rMax.CeilToInt() + 1);
 37103        int yMin = System.Math.Max(
 37104            0,
 37105            ((clippedMin.Y - grid.BoundsMin.Y) / layerHeight).FloorToInt());
 37106        int yMax = System.Math.Min(
 37107            grid.Height - 1,
 37108            ((clippedMax.Y - grid.BoundsMin.Y) / layerHeight).CeilToInt());
 109
 37110        minIndex = new VoxelIndex(xMin, yMin, zMin);
 37111        maxIndex = new VoxelIndex(xMax, yMax, zMax);
 37112        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    {
 905122        Fixed64 xMin = FixedMath.Max(min.X, grid.BoundsMin.X);
 905123        Fixed64 yMin = FixedMath.Max(min.Y, grid.BoundsMin.Y);
 905124        Fixed64 zMin = FixedMath.Max(min.Z, grid.BoundsMin.Z);
 905125        Fixed64 xMax = FixedMath.Min(max.X, grid.BoundsMax.X);
 905126        Fixed64 yMax = FixedMath.Min(max.Y, grid.BoundsMax.Y);
 905127        Fixed64 zMax = FixedMath.Min(max.Z, grid.BoundsMax.Z);
 128
 905129        if (xMin > xMax || yMin > yMax || zMin > zMax)
 130        {
 7131            clippedMin = default;
 7132            clippedMax = default;
 7133            return false;
 134        }
 135
 898136        clippedMin = new Vector3d(xMin, yMin, zMin);
 898137        clippedMax = new Vector3d(xMax, yMax, zMax);
 898138        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    {
 148152        HexCoordinateUtility.WorldOffsetToAxial(
 148153            x - gridBoundsMin.X,
 148154            z - gridBoundsMin.Z,
 148155            metrics,
 148156            out Fixed64 q,
 148157            out Fixed64 r);
 158
 148159        qMin = FixedMath.Min(qMin, q);
 148160        qMax = FixedMath.Max(qMax, q);
 148161        rMin = FixedMath.Min(rMin, r);
 148162        rMax = FixedMath.Max(rMax, r);
 148163    }
 164}