< Summary

Information
Class: GridForge.Grids.Topology.RectangularPrismTopology
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/RectangularPrismTopology.cs
Line coverage
100%
Covered lines: 79
Uncovered lines: 0
Coverable lines: 79
Total lines: 212
Line coverage: 100%
Branch coverage
100%
Covered branches: 26
Total branches: 26
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Kind()100%11100%
get_OverlapTolerance()100%11100%
get_MaxCellEdge()100%11100%
get_NeighborSlotCount()100%11100%
.ctor(...)100%11100%
CalculateDimensions(...)100%11100%
NormalizeBounds(...)100%1010100%
IsInBounds(...)100%1010100%
TryGetVoxelIndex(...)100%22100%
GetClosestVoxelIndex(...)100%11100%
GetWorldPosition(...)100%11100%
GetWorldOffset(...)100%11100%
GetNeighborOffset(...)100%11100%
TryGetNeighborSlotFromWorldDelta(...)100%11100%
IsFacingBoundary(...)100%44100%
GetBoundaryRange(...)100%11100%
FloorToGrid(...)100%11100%
CeilToGrid(...)100%11100%
SnapToScanCell(...)100%11100%
FloorToCellOrigin(...)100%11100%
CeilToCellOrigin(...)100%11100%
FloorToCellOrigin(...)100%11100%
CeilToCellOrigin(...)100%11100%
GetClosestAxisIndex(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// RectangularPrismTopology.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.Runtime.CompilerServices;
 9using FixedMathSharp;
 10using GridForge.Spatial;
 11
 12namespace GridForge.Grids.Topology;
 13
 14internal sealed class RectangularPrismTopology : IGridTopology
 15{
 266716    public GridTopologyKind Kind => GridTopologyKind.RectangularPrism;
 17
 18    public GridTopologyMetrics Metrics { get; }
 19
 82220    public Fixed64 OverlapTolerance => Metrics.SmallestRectangularEdge * Fixed64.Half;
 21
 124022    public Fixed64 MaxCellEdge => Metrics.LargestRectangularEdge;
 23
 422424    public int NeighborSlotCount => RectangularDirectionUtility.Offsets.Length;
 25
 86226    public RectangularPrismTopology(GridTopologyMetrics metrics)
 27    {
 86228        Metrics = GridTopologyMetrics.Normalize(GridTopologyKind.RectangularPrism, metrics);
 86229    }
 30
 31    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 32    public GridDimensions CalculateDimensions(Vector3d boundsMin, Vector3d boundsMax) =>
 168333        new(((boundsMax.X - boundsMin.X) / Metrics.CellWidth).FloorToInt() + 1,
 168334            ((boundsMax.Y - boundsMin.Y) / Metrics.LayerHeight).FloorToInt() + 1,
 168335            ((boundsMax.Z - boundsMin.Z) / Metrics.CellLength).FloorToInt() + 1);
 36
 37    public (Vector3d min, Vector3d max) NormalizeBounds(Vector3d min, Vector3d max, Fixed64? padding = null)
 38    {
 229839        Fixed64 fixedPadding = padding.HasValue && padding.Value > Fixed64.Zero
 229840            ? padding.Value
 229841            : Fixed64.Zero;
 42
 229843        min -= fixedPadding;
 229844        max += fixedPadding;
 45
 229846        Vector3d snapMin = FloorToCellOrigin(min);
 229847        Vector3d snapMax = CeilToCellOrigin(max);
 48
 229849        (snapMin.X, snapMax.X) = snapMin.X > snapMax.X ? (snapMax.X, snapMin.X) : (snapMin.X, snapMax.X);
 229850        (snapMin.Y, snapMax.Y) = snapMin.Y > snapMax.Y ? (snapMax.Y, snapMin.Y) : (snapMin.Y, snapMax.Y);
 229851        (snapMin.Z, snapMax.Z) = snapMin.Z > snapMax.Z ? (snapMax.Z, snapMin.Z) : (snapMin.Z, snapMax.Z);
 52
 229853        return (snapMin, snapMax);
 54    }
 55
 56    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 57    public bool IsInBounds(
 58        Vector3d boundsMin,
 59        Vector3d boundsMax,
 60        int width,
 61        int height,
 62        int length,
 63        Vector3d position) =>
 287164        boundsMin.X <= position.X && position.X <= boundsMax.X
 287165        && boundsMin.Y <= position.Y && position.Y <= boundsMax.Y
 287166        && boundsMin.Z <= position.Z && position.Z <= boundsMax.Z;
 67
 68    public bool TryGetVoxelIndex(
 69        Vector3d boundsMin,
 70        Vector3d boundsMax,
 71        int width,
 72        int height,
 73        int length,
 74        Vector3d position,
 75        out VoxelIndex result)
 76    {
 280777        result = default;
 280778        if (!IsInBounds(boundsMin, boundsMax, width, height, length, position))
 1579            return false;
 80
 279281        result = new VoxelIndex(
 279282            ((position.X - boundsMin.X) / Metrics.CellWidth).FloorToInt(),
 279283            ((position.Y - boundsMin.Y) / Metrics.LayerHeight).FloorToInt(),
 279284            ((position.Z - boundsMin.Z) / Metrics.CellLength).FloorToInt());
 279285        return true;
 86    }
 87
 88    public VoxelIndex GetClosestVoxelIndex(
 89        Vector3d boundsMin,
 90        int width,
 91        int height,
 92        int length,
 93        Vector3d position) =>
 2094        new(
 2095            GetClosestAxisIndex(position.X - boundsMin.X, Metrics.CellWidth, width),
 2096            GetClosestAxisIndex(position.Y - boundsMin.Y, Metrics.LayerHeight, height),
 2097            GetClosestAxisIndex(position.Z - boundsMin.Z, Metrics.CellLength, length));
 98
 99    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 100    public Vector3d GetWorldPosition(Vector3d boundsMin, VoxelIndex index) =>
 121700101         new(boundsMin.X + index.x * Metrics.CellWidth,
 121700102            boundsMin.Y + index.y * Metrics.LayerHeight,
 121700103            boundsMin.Z + index.z * Metrics.CellLength);
 104
 105    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 106    public Vector3d GetWorldOffset((int x, int y, int z) offset) =>
 3499107         new(offset.x * Metrics.CellWidth,
 3499108            offset.y * Metrics.LayerHeight,
 3499109            offset.z * Metrics.CellLength);
 110
 111    public VoxelIndex GetNeighborOffset(int slot)
 112    {
 3837113        (int x, int y, int z) offset = RectangularDirectionUtility.Offsets[slot];
 3837114        return new VoxelIndex(offset.x, offset.y, offset.z);
 115    }
 116
 117    public bool TryGetNeighborSlotFromWorldDelta(Vector3d worldDelta, out int slot)
 118    {
 232119        RectangularDirection direction = RectangularDirectionUtility.GetDirectionFromOffset((
 232120            worldDelta.X.Sign(),
 232121            worldDelta.Y.Sign(),
 232122            worldDelta.Z.Sign()));
 232123        slot = (int)direction;
 232124        return direction != RectangularDirection.None;
 125    }
 126
 127    public bool IsFacingBoundary(VoxelIndex voxelIndex, int slot, int width, int height, int length)
 128    {
 54129        (int x, int y, int z) offset = RectangularDirectionUtility.Offsets[slot];
 54130        return RectangularDirectionUtility.IsAxisFacingBoundary(voxelIndex.x, offset.x, width)
 54131            && RectangularDirectionUtility.IsAxisFacingBoundary(voxelIndex.y, offset.y, height)
 54132            && RectangularDirectionUtility.IsAxisFacingBoundary(voxelIndex.z, offset.z, length);
 133    }
 134
 135    public void GetBoundaryRange(
 136        int slot,
 137        int width,
 138        int height,
 139        int length,
 140        out int xStart,
 141        out int xEnd,
 142        out int yStart,
 143        out int yEnd,
 144        out int zStart,
 145        out int zEnd)
 146    {
 1147        (int x, int y, int z) offset = RectangularDirectionUtility.Offsets[slot];
 1148        (xStart, xEnd) = RectangularDirectionUtility.GetBoundaryRange(offset.x, width);
 1149        (yStart, yEnd) = RectangularDirectionUtility.GetBoundaryRange(offset.y, height);
 1150        (zStart, zEnd) = RectangularDirectionUtility.GetBoundaryRange(offset.z, length);
 1151    }
 152
 153    public Vector3d FloorToGrid(
 154        Vector3d boundsMin,
 155        Vector3d boundsMax,
 156        int width,
 157        int height,
 158        int length,
 159        Vector3d position)
 160    {
 363161        return new Vector3d(
 363162            FixedMath.Clamp(((position.X - boundsMin.X) / Metrics.CellWidth).FloorToInt() * Metrics.CellWidth + boundsMi
 363163            FixedMath.Clamp(((position.Y - boundsMin.Y) / Metrics.LayerHeight).FloorToInt() * Metrics.LayerHeight + boun
 363164            FixedMath.Clamp(((position.Z - boundsMin.Z) / Metrics.CellLength).FloorToInt() * Metrics.CellLength + bounds
 165    }
 166
 167    public Vector3d CeilToGrid(
 168        Vector3d boundsMin,
 169        Vector3d boundsMax,
 170        int width,
 171        int height,
 172        int length,
 173        Vector3d position)
 174    {
 2175        return new Vector3d(
 2176            FixedMath.Clamp(((position.X - boundsMin.X) / Metrics.CellWidth).CeilToInt() * Metrics.CellWidth + boundsMin
 2177            FixedMath.Clamp(((position.Y - boundsMin.Y) / Metrics.LayerHeight).CeilToInt() * Metrics.LayerHeight + bound
 2178            FixedMath.Clamp(((position.Z - boundsMin.Z) / Metrics.CellLength).CeilToInt() * Metrics.CellLength + boundsM
 179    }
 180
 181    public (int x, int y, int z) SnapToScanCell(Vector3d boundsMin, Vector3d position, int scanCellSize)
 182    {
 1184183        return (((position.X - boundsMin.X) / Metrics.CellWidth).FloorToInt() / scanCellSize,
 1184184            ((position.Y - boundsMin.Y) / Metrics.LayerHeight).FloorToInt() / scanCellSize,
 1184185            ((position.Z - boundsMin.Z) / Metrics.CellLength).FloorToInt() / scanCellSize);
 186    }
 187
 188    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 189    private Vector3d FloorToCellOrigin(Vector3d position) =>
 2298190        new(FloorToCellOrigin(position.X, Metrics.CellWidth),
 2298191            FloorToCellOrigin(position.Y, Metrics.LayerHeight),
 2298192            FloorToCellOrigin(position.Z, Metrics.CellLength));
 193
 194    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 195    private Vector3d CeilToCellOrigin(Vector3d position) =>
 2298196        new(CeilToCellOrigin(position.X, Metrics.CellWidth),
 2298197            CeilToCellOrigin(position.Y, Metrics.LayerHeight),
 2298198            CeilToCellOrigin(position.Z, Metrics.CellLength));
 199
 200    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 201    private static Fixed64 FloorToCellOrigin(Fixed64 coordinate, Fixed64 cellSize) =>
 6894202        (coordinate / cellSize).FloorToInt() * cellSize;
 203
 204    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 205    private static Fixed64 CeilToCellOrigin(Fixed64 coordinate, Fixed64 cellSize) =>
 6894206        (coordinate / cellSize).CeilToInt() * cellSize;
 207
 208    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 209    private static int GetClosestAxisIndex(Fixed64 offset, Fixed64 cellSize, int size) =>
 60210        FixedMath.Clamp((offset / cellSize).RoundToInt(), 0, size - 1);
 211
 212}

Methods/Properties

get_Kind()
get_OverlapTolerance()
get_MaxCellEdge()
get_NeighborSlotCount()
.ctor(GridForge.Grids.Topology.GridTopologyMetrics)
CalculateDimensions(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
NormalizeBounds(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Nullable`1<FixedMathSharp.Fixed64>)
IsInBounds(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d)
TryGetVoxelIndex(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d,GridForge.Spatial.VoxelIndex&)
GetClosestVoxelIndex(FixedMathSharp.Vector3d,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d)
GetWorldPosition(FixedMathSharp.Vector3d,GridForge.Spatial.VoxelIndex)
GetWorldOffset(System.ValueTuple`3<System.Int32,System.Int32,System.Int32>)
GetNeighborOffset(System.Int32)
TryGetNeighborSlotFromWorldDelta(FixedMathSharp.Vector3d,System.Int32&)
IsFacingBoundary(GridForge.Spatial.VoxelIndex,System.Int32,System.Int32,System.Int32,System.Int32)
GetBoundaryRange(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32&,System.Int32&,System.Int32&,System.Int32&,System.Int32&,System.Int32&)
FloorToGrid(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d)
CeilToGrid(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32,System.Int32,System.Int32,FixedMathSharp.Vector3d)
SnapToScanCell(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,System.Int32)
FloorToCellOrigin(FixedMathSharp.Vector3d)
CeilToCellOrigin(FixedMathSharp.Vector3d)
FloorToCellOrigin(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
CeilToCellOrigin(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
GetClosestAxisIndex(FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,System.Int32)