< Summary

Information
Class: GridForge.Utility.GridTraversal
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Utility/GridTraversal.cs
Line coverage
100%
Covered lines: 15
Uncovered lines: 0
Coverable lines: 15
Total lines: 144
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
TryGetUniquePartition(...)100%22100%
IsWorldPositionInPaddedBounds(...)100%1010100%
IsPlanarPositionInPaddedBounds(...)100%66100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// GridTraversal.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 System.Runtime.CompilerServices;
 14
 15namespace GridForge.Utility;
 16
 17/// <summary>
 18/// Selects which topology edge measurement a grid traversal should use for padding.
 19/// </summary>
 20public enum GridTraversalPaddingMode
 21{
 22    /// <summary>
 23    /// Use the largest three-dimensional cell edge.
 24    /// </summary>
 25    MaxCellEdge,
 26
 27    /// <summary>
 28    /// Use the largest X/Z-plane cell edge.
 29    /// </summary>
 30    PlanarMaxCellEdge
 31}
 32
 33/// <summary>
 34/// Tracks per-grid traversal padding while suppressing duplicate voxel visits.
 35/// </summary>
 36public struct GridTraversalState
 37{
 38    private readonly GridWorld _world;
 39    private readonly GridTraversalPaddingMode _paddingMode;
 40    private ushort _currentGridIndex;
 41    private Fixed64 _cellEdge;
 42    private bool _hasCachedGrid;
 43
 44    /// <summary>
 45    /// Initializes traversal state for one world and padding mode.
 46    /// </summary>
 47    public GridTraversalState(GridWorld world, GridTraversalPaddingMode paddingMode)
 48    {
 49        _world = world;
 50        _paddingMode = paddingMode;
 51        _currentGridIndex = 0;
 52        _cellEdge = Fixed64.Zero;
 53        _hasCachedGrid = false;
 54    }
 55
 56    /// <summary>
 57    /// Visits a voxel only once and returns the selected cell-edge measurement for its grid.
 58    /// </summary>
 59    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 60    public bool TryVisitUnique(Voxel voxel, SwiftHashSet<int> visited, out Fixed64 cellEdge)
 61    {
 62        cellEdge = Fixed64.Zero;
 63        if (!visited.Add(voxel.SpawnToken))
 64            return false;
 65
 66        cellEdge = GetCellEdge(voxel);
 67        return true;
 68    }
 69
 70    /// <summary>
 71    /// Gets the selected cell-edge measurement for a voxel's grid, caching repeated grid lookups.
 72    /// </summary>
 73    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 74    public Fixed64 GetCellEdge(Voxel voxel)
 75    {
 76        if (_hasCachedGrid && voxel.GridIndex == _currentGridIndex)
 77            return _cellEdge;
 78
 79        _currentGridIndex = voxel.GridIndex;
 80        _hasCachedGrid = true;
 81        VoxelGrid grid = _world.ActiveGrids[_currentGridIndex];
 82        _cellEdge = _paddingMode == GridTraversalPaddingMode.PlanarMaxCellEdge
 83            ? GridTopologyMetricUtility.GetPlanarMaxCellEdge(grid)
 84            : GridTopologyMetricUtility.GetMaxCellEdge(grid);
 85        return _cellEdge;
 86    }
 87}
 88
 89/// <summary>
 90/// Provides deterministic helpers for duplicate-safe voxel traversal.
 91/// </summary>
 92public static class GridTraversal
 93{
 94    /// <summary>
 95    /// Gets a voxel partition once per voxel spawn token.
 96    /// </summary>
 97    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 98    public static bool TryGetUniquePartition<TPartition>(
 99        Voxel voxel,
 100        SwiftHashSet<int> visited,
 101        out TPartition? partition)
 102        where TPartition : class, IVoxelPartition
 103    {
 2104        partition = null;
 2105        return visited.Add(voxel.SpawnToken)
 2106            && voxel.TryGetPartition(out partition);
 107    }
 108
 109    /// <summary>
 110    /// Tests whether a 3D world position lies inside bounds expanded by half of a cell edge.
 111    /// </summary>
 112    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 113    public static bool IsWorldPositionInPaddedBounds(
 114        Vector3d min,
 115        Vector3d max,
 116        Fixed64 cellEdge,
 117        Vector3d worldPosition)
 118    {
 2119        Fixed64 padding = cellEdge * Fixed64.Half;
 2120        return worldPosition.X >= min.X - padding
 2121            && worldPosition.X <= max.X + padding
 2122            && worldPosition.Y >= min.Y - padding
 2123            && worldPosition.Y <= max.Y + padding
 2124            && worldPosition.Z >= min.Z - padding
 2125            && worldPosition.Z <= max.Z + padding;
 126    }
 127
 128    /// <summary>
 129    /// Tests whether a world position's X/Z projection lies inside bounds expanded by half of a cell edge.
 130    /// </summary>
 131    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 132    public static bool IsPlanarPositionInPaddedBounds(
 133        Vector2d min,
 134        Vector2d max,
 135        Fixed64 cellEdge,
 136        Vector3d worldPosition)
 137    {
 2138        Fixed64 padding = cellEdge * Fixed64.Half;
 2139        return worldPosition.X >= min.X - padding
 2140            && worldPosition.X <= max.X + padding
 2141            && worldPosition.Z >= min.Y - padding
 2142            && worldPosition.Z <= max.Y + padding;
 143    }
 144}