< 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: 88
Uncovered lines: 0
Coverable lines: 88
Total lines: 193
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
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%
TryGetPrismCandidateRange(...)100%22100%
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) =>
 39823        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    {
 87232        if (!grid.IsActive)
 33        {
 134            minIndex = default;
 135            maxIndex = default;
 136            return false;
 37        }
 38
 87139        return grid.Topology.Kind == GridTopologyKind.HexPrism
 87140            ? TryGetHexCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex)
 87141            : TryGetRectangularCandidateRange(grid, queryMin, queryMax, out minIndex, out maxIndex);
 42    }
 43
 44    internal static bool TryGetPrismCandidateRange(
 45        VoxelGrid grid,
 46        Vector3d queryMin,
 47        Vector3d queryMax,
 48        out VoxelIndex minIndex,
 49        out VoxelIndex maxIndex)
 50    {
 19451        GridTopologyMetrics metrics = grid.Topology.Metrics;
 52        Vector3d rangeMin;
 53        Vector3d rangeMax;
 19454        if (grid.Topology.Kind == GridTopologyKind.RectangularPrism)
 55        {
 14456            Vector3d halfExtents = new(
 14457                metrics.CellWidth * Fixed64.Half,
 14458                metrics.LayerHeight * Fixed64.Half,
 14459                metrics.CellLength * Fixed64.Half);
 14460            rangeMin = queryMin - halfExtents;
 14461            rangeMax = queryMax + halfExtents;
 62        }
 63        else
 64        {
 5065            Fixed64 halfHeight = metrics.LayerHeight * Fixed64.Half;
 5066            rangeMin = new Vector3d(queryMin.X, queryMin.Y - halfHeight, queryMin.Z);
 5067            rangeMax = new Vector3d(queryMax.X, queryMax.Y + halfHeight, queryMax.Z);
 68        }
 69
 19470        return TryGetCandidateRange(grid, rangeMin, rangeMax, out minIndex, out maxIndex);
 71    }
 72
 73    private static bool TryGetRectangularCandidateRange(
 74        VoxelGrid grid,
 75        Vector3d queryMin,
 76        Vector3d queryMax,
 77        out VoxelIndex minIndex,
 78        out VoxelIndex maxIndex)
 79    {
 77180        minIndex = default;
 77181        maxIndex = default;
 82
 77183        (Vector3d snappedMin, Vector3d snappedMax) = grid.NormalizeBounds(queryMin, queryMax);
 77184        if (!TryClipBoundsToGrid(grid, snappedMin, snappedMax, out Vector3d clippedMin, out Vector3d clippedMax))
 485            return false;
 86
 76787        bool minResolved = grid.TryGetVoxelIndex(clippedMin, out minIndex);
 76788        bool maxResolved = grid.TryGetVoxelIndex(clippedMax, out maxIndex);
 89        Debug.Assert(minResolved && maxResolved);
 76790        return true;
 91    }
 92
 93    private static bool TryGetHexCandidateRange(
 94        VoxelGrid grid,
 95        Vector3d queryMin,
 96        Vector3d queryMax,
 97        out VoxelIndex minIndex,
 98        out VoxelIndex maxIndex)
 99    {
 100100        minIndex = default;
 100101        maxIndex = default;
 102
 100103        GridTopologyMetrics metrics = grid.Topology.Metrics;
 100104        Fixed64 horizontalExpansion = metrics.CellRadius;
 100105        Fixed64 layerHeight = metrics.LayerHeight;
 100106        Vector3d candidateMin = new(
 100107            queryMin.X - horizontalExpansion,
 100108            queryMin.Y,
 100109            queryMin.Z - horizontalExpansion);
 100110        Vector3d candidateMax = new(
 100111            queryMax.X + horizontalExpansion,
 100112            queryMax.Y,
 100113            queryMax.Z + horizontalExpansion);
 114
 100115        if (!TryClipBoundsToGrid(grid, candidateMin, candidateMax, out Vector3d clippedMin, out Vector3d clippedMax))
 4116            return false;
 117
 96118        Fixed64 qMin = Fixed64.MaxValue;
 96119        Fixed64 qMax = Fixed64.MinValue;
 96120        Fixed64 rMin = Fixed64.MaxValue;
 96121        Fixed64 rMax = Fixed64.MinValue;
 122
 96123        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 96124        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMin.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 96125        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMin.Z, ref qMin, ref qMax, ref rMin, ref rMa
 96126        IncludeHexAxialCorner(grid.BoundsMin, metrics, clippedMax.X, clippedMax.Z, ref qMin, ref qMax, ref rMin, ref rMa
 127
 96128        int xMin = System.Math.Max(0, qMin.FloorToInt() - 1);
 96129        int xMax = System.Math.Min(grid.Width - 1, qMax.CeilToInt() + 1);
 96130        int zMin = System.Math.Max(0, rMin.FloorToInt() - 1);
 96131        int zMax = System.Math.Min(grid.Length - 1, rMax.CeilToInt() + 1);
 96132        int yMin = System.Math.Max(
 96133            0,
 96134            ((clippedMin.Y - grid.BoundsMin.Y) / layerHeight).FloorToInt());
 96135        int yMax = System.Math.Min(
 96136            grid.Height - 1,
 96137            ((clippedMax.Y - grid.BoundsMin.Y) / layerHeight).CeilToInt());
 138
 96139        minIndex = new VoxelIndex(xMin, yMin, zMin);
 96140        maxIndex = new VoxelIndex(xMax, yMax, zMax);
 96141        return true;
 142    }
 143
 144    internal static bool TryClipBoundsToGrid(
 145        VoxelGrid grid,
 146        Vector3d min,
 147        Vector3d max,
 148        out Vector3d clippedMin,
 149        out Vector3d clippedMax)
 150    {
 1463151        Fixed64 xMin = FixedMath.Max(min.X, grid.BoundsMin.X);
 1463152        Fixed64 yMin = FixedMath.Max(min.Y, grid.BoundsMin.Y);
 1463153        Fixed64 zMin = FixedMath.Max(min.Z, grid.BoundsMin.Z);
 1463154        Fixed64 xMax = FixedMath.Min(max.X, grid.BoundsMax.X);
 1463155        Fixed64 yMax = FixedMath.Min(max.Y, grid.BoundsMax.Y);
 1463156        Fixed64 zMax = FixedMath.Min(max.Z, grid.BoundsMax.Z);
 157
 1463158        if (xMin > xMax || yMin > yMax || zMin > zMax)
 159        {
 9160            clippedMin = default;
 9161            clippedMax = default;
 9162            return false;
 163        }
 164
 1454165        clippedMin = new Vector3d(xMin, yMin, zMin);
 1454166        clippedMax = new Vector3d(xMax, yMax, zMax);
 1454167        return true;
 168    }
 169
 170    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 171    private static void IncludeHexAxialCorner(
 172        Vector3d gridBoundsMin,
 173        GridTopologyMetrics metrics,
 174        Fixed64 x,
 175        Fixed64 z,
 176        ref Fixed64 qMin,
 177        ref Fixed64 qMax,
 178        ref Fixed64 rMin,
 179        ref Fixed64 rMax)
 180    {
 384181        HexCoordinateUtility.WorldOffsetToAxial(
 384182            x - gridBoundsMin.X,
 384183            z - gridBoundsMin.Z,
 384184            metrics,
 384185            out Fixed64 q,
 384186            out Fixed64 r);
 187
 384188        qMin = FixedMath.Min(qMin, q);
 384189        qMax = FixedMath.Max(qMax, q);
 384190        rMin = FixedMath.Min(rMin, r);
 384191        rMax = FixedMath.Max(rMax, r);
 384192    }
 193}