< Summary

Information
Class: GridForge.Grids.Topology.GridCellPrism
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/GridCellPrism.cs
Line coverage
100%
Covered lines: 57
Uncovered lines: 0
Coverable lines: 57
Total lines: 162
Line coverage: 100%
Branch coverage
100%
Covered branches: 43
Total branches: 43
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%88100%
GetFootprintVertex(...)100%1919100%
CopyFootprintTo(...)100%44100%
Contains(...)100%1010100%
GetAabb()100%22100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// GridCellPrism.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;
 9using System.Runtime.CompilerServices;
 10using FixedMathSharp;
 11using FixedMathSharp.Geometry;
 12using GridForge.Spatial;
 13
 14namespace GridForge.Grids.Topology;
 15
 16/// <summary>
 17/// Describes one exact topology cell as an ordered convex XZ footprint and a closed vertical interval.
 18/// </summary>
 19/// <remarks>
 20/// Construction fails when a metric cannot be bisected exactly in the fixed-point scalar domain.
 21/// </remarks>
 22public readonly struct GridCellPrism
 23{
 24    private readonly Vector2d _vertex0;
 25    private readonly Vector2d _vertex1;
 26    private readonly Vector2d _vertex2;
 27    private readonly Vector2d _vertex3;
 28    private readonly Vector2d _vertex4;
 29    private readonly Vector2d _vertex5;
 30
 31    /// <summary>
 32    /// The exact runtime cell identity represented by this prism.
 33    /// </summary>
 34    public WorldVoxelIndex Cell { get; }
 35
 36    /// <summary>
 37    /// The topology that produced the footprint.
 38    /// </summary>
 39    public GridTopologyKind TopologyKind { get; }
 40
 41    /// <summary>
 42    /// The world-space cell center.
 43    /// </summary>
 44    public Vector3d Center { get; }
 45
 46    /// <summary>
 47    /// The inclusive lower Y bound.
 48    /// </summary>
 49    public Fixed64 VerticalMin { get; }
 50
 51    /// <summary>
 52    /// The inclusive upper Y bound.
 53    /// </summary>
 54    public Fixed64 VerticalMax { get; }
 55
 56    /// <summary>
 57    /// The largest radius that can be inset from every horizontal footprint edge.
 58    /// </summary>
 59    public Fixed64 PlanarInradius { get; }
 60
 61    /// <summary>
 62    /// The number of boundary-ordered footprint vertices.
 63    /// </summary>
 64    public int FootprintVertexCount { get; }
 65
 66    internal GridCellPrism(
 67        WorldVoxelIndex cell,
 68        GridTopologyKind topologyKind,
 69        Vector3d center,
 70        Fixed64 verticalMin,
 71        Fixed64 verticalMax,
 72        Fixed64 planarInradius,
 73        ReadOnlySpan<Vector2d> footprint)
 74    {
 763775        if (footprint.Length != 4 && footprint.Length != 6)
 176            throw new ArgumentOutOfRangeException(nameof(footprint));
 77
 763678        Cell = cell;
 763679        TopologyKind = topologyKind;
 763680        Center = center;
 763681        VerticalMin = verticalMin;
 763682        VerticalMax = verticalMax;
 763683        PlanarInradius = planarInradius;
 763684        FootprintVertexCount = footprint.Length;
 763685        _vertex0 = footprint[0];
 763686        _vertex1 = footprint[1];
 763687        _vertex2 = footprint[2];
 763688        _vertex3 = footprint[3];
 763689        _vertex4 = footprint.Length > 4 ? footprint[4] : default;
 763690        _vertex5 = footprint.Length > 5 ? footprint[5] : default;
 763691    }
 92
 93    /// <summary>
 94    /// Gets one boundary-ordered XZ footprint vertex.
 95    /// </summary>
 96    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 12929797    public Vector2d GetFootprintVertex(int index) => index switch
 12929798    {
 5965699        0 when FootprintVertexCount > 0 => _vertex0,
 65100100        1 when FootprintVertexCount > 1 => _vertex1,
 65044101        2 when FootprintVertexCount > 2 => _vertex2,
 64992102        3 when FootprintVertexCount > 3 => _vertex3,
 1901103        4 when FootprintVertexCount > 4 => _vertex4,
 1898104        5 when FootprintVertexCount > 5 => _vertex5,
 2105        _ => throw new ArgumentOutOfRangeException(nameof(index))
 129297106    };
 107
 108    /// <summary>
 109    /// Copies the boundary-ordered XZ footprint into caller-owned storage.
 110    /// </summary>
 111    public void CopyFootprintTo(Span<Vector2d> destination)
 112    {
 5760113        if (destination.Length < FootprintVertexCount)
 1114            throw new ArgumentException("The destination is smaller than the footprint.", nameof(destination));
 115
 58862116        for (int i = 0; i < FootprintVertexCount; i++)
 23672117            destination[i] = GetFootprintVertex(i);
 5759118    }
 119
 120    /// <summary>
 121    /// Determines whether a world-space point lies inside or on this closed prism.
 122    /// </summary>
 123    public bool Contains(Vector3d point)
 124    {
 8945125        if (FootprintVertexCount is not 4 and not 6
 8945126            || point.Y < VerticalMin
 8945127            || point.Y > VerticalMax)
 7128            return false;
 129
 8938130        Span<Vector2d> offsets = stackalloc Vector2d[6];
 8938131        Vector2d origin = new(Center.X, Center.Z);
 89812132        for (int i = 0; i < FootprintVertexCount; i++)
 35968133            offsets[i] = GetFootprintVertex(i) - origin;
 134
 8938135        return FixedConvex2dRelations.ContainsPoint(
 8938136            new Vector2d(point.X, point.Z),
 8938137            origin,
 8938138            offsets[..FootprintVertexCount]);
 139    }
 140
 141    internal TopologyVoxelAabb GetAabb()
 142    {
 2709143        Vector2d first = _vertex0;
 2709144        Fixed64 minX = first.X;
 2709145        Fixed64 maxX = first.X;
 2709146        Fixed64 minZ = first.Y;
 2709147        Fixed64 maxZ = first.Y;
 148
 22464149        for (int i = 1; i < FootprintVertexCount; i++)
 150        {
 8523151            Vector2d vertex = GetFootprintVertex(i);
 8523152            minX = FixedMath.Min(minX, vertex.X);
 8523153            maxX = FixedMath.Max(maxX, vertex.X);
 8523154            minZ = FixedMath.Min(minZ, vertex.Y);
 8523155            maxZ = FixedMath.Max(maxZ, vertex.Y);
 156        }
 157
 2709158        return new TopologyVoxelAabb(
 2709159            new Vector3d(minX, VerticalMin, minZ),
 2709160            new Vector3d(maxX, VerticalMax, maxZ));
 161    }
 162}