< Summary

Information
Class: GridForge.Diagnostics.GridDiagnosticGeometry
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Diagnostics/GridDiagnosticGeometry.cs
Line coverage
96%
Covered lines: 106
Uncovered lines: 4
Coverable lines: 110
Total lines: 215
Line coverage: 96.3%
Branch coverage
81%
Covered branches: 18
Total branches: 22
Branch coverage: 81.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
GetVertexCount(...)75%4483.33%
GetEdgeCount(...)75%4483.33%
WriteVertices(...)75%4483.33%
GetEdges(...)75%4483.33%
WriteRectangularVertices(...)100%22100%
WriteHexVertices(...)100%44100%
WritePointyTopHexRing(...)100%11100%
WriteFlatTopHexRing(...)100%11100%

File(s)

/home/runner/work/GridForge/GridForge/src/GridForge/Diagnostics/GridDiagnosticGeometry.cs

#LineLine coverage
 1//=======================================================================
 2// GridDiagnosticGeometry.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.Topology;
 10using GridForge.Spatial;
 11using System;
 12using System.Runtime.CompilerServices;
 13
 14namespace GridForge.Diagnostics;
 15
 16/// <summary>
 17/// Topology-aware diagnostic geometry helpers for cell descriptors.
 18/// </summary>
 19public static class GridDiagnosticGeometry
 20{
 21    /// <summary>
 22    /// Number of vertices in a rectangular-prism diagnostic cell.
 23    /// </summary>
 24    public const int RectangularPrismVertexCount = 8;
 25
 26    /// <summary>
 27    /// Number of vertices in a hex-prism diagnostic cell.
 28    /// </summary>
 29    public const int HexPrismVertexCount = 12;
 30
 31    /// <summary>
 32    /// Number of wireframe edges in a rectangular-prism diagnostic cell.
 33    /// </summary>
 34    public const int RectangularPrismEdgeCount = 12;
 35
 36    /// <summary>
 37    /// Number of wireframe edges in a hex-prism diagnostic cell.
 38    /// </summary>
 39    public const int HexPrismEdgeCount = 18;
 40
 141    private static readonly GridDiagnosticEdge[] RectangularPrismEdges =
 142    {
 143        new GridDiagnosticEdge(0, 1),
 144        new GridDiagnosticEdge(1, 2),
 145        new GridDiagnosticEdge(2, 3),
 146        new GridDiagnosticEdge(3, 0),
 147        new GridDiagnosticEdge(4, 5),
 148        new GridDiagnosticEdge(5, 6),
 149        new GridDiagnosticEdge(6, 7),
 150        new GridDiagnosticEdge(7, 4),
 151        new GridDiagnosticEdge(0, 4),
 152        new GridDiagnosticEdge(1, 5),
 153        new GridDiagnosticEdge(2, 6),
 154        new GridDiagnosticEdge(3, 7)
 155    };
 56
 157    private static readonly GridDiagnosticEdge[] HexPrismEdges =
 158    {
 159        new GridDiagnosticEdge(0, 1),
 160        new GridDiagnosticEdge(1, 2),
 161        new GridDiagnosticEdge(2, 3),
 162        new GridDiagnosticEdge(3, 4),
 163        new GridDiagnosticEdge(4, 5),
 164        new GridDiagnosticEdge(5, 0),
 165        new GridDiagnosticEdge(6, 7),
 166        new GridDiagnosticEdge(7, 8),
 167        new GridDiagnosticEdge(8, 9),
 168        new GridDiagnosticEdge(9, 10),
 169        new GridDiagnosticEdge(10, 11),
 170        new GridDiagnosticEdge(11, 6),
 171        new GridDiagnosticEdge(0, 6),
 172        new GridDiagnosticEdge(1, 7),
 173        new GridDiagnosticEdge(2, 8),
 174        new GridDiagnosticEdge(3, 9),
 175        new GridDiagnosticEdge(4, 10),
 176        new GridDiagnosticEdge(5, 11)
 177    };
 78
 79    /// <summary>
 80    /// Gets the number of vertices written for the supplied topology kind.
 81    /// </summary>
 82    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 283    public static int GetVertexCount(GridTopologyKind topologyKind) => topologyKind switch
 284    {
 185        GridTopologyKind.RectangularPrism => RectangularPrismVertexCount,
 186        GridTopologyKind.HexPrism => HexPrismVertexCount,
 087        _ => 0
 288    };
 89
 90    /// <summary>
 91    /// Gets the number of edges exposed for the supplied topology kind.
 92    /// </summary>
 93    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 294    public static int GetEdgeCount(GridTopologyKind topologyKind) => topologyKind switch
 295    {
 196        GridTopologyKind.RectangularPrism => RectangularPrismEdgeCount,
 197        GridTopologyKind.HexPrism => HexPrismEdgeCount,
 098        _ => 0
 299    };
 100
 101    /// <summary>
 102    /// Writes topology-aware world-space cell vertices into caller-owned
 103    /// storage.
 104    /// </summary>
 105    /// <returns>The number of vertices written, or <c>0</c> when the span is too small.</returns>
 106    public static int WriteVertices(
 107        in GridDiagnosticCell cell,
 7108        Span<Vector3d> vertices) => cell.TopologyKind switch
 7109        {
 2110            GridTopologyKind.RectangularPrism => WriteRectangularVertices(cell.WorldPosition, cell.TopologyMetrics, vert
 5111            GridTopologyKind.HexPrism => WriteHexVertices(cell.WorldPosition, cell.TopologyMetrics, vertices),
 0112            _ => 0
 7113        };
 114
 115    /// <summary>
 116    /// Gets immutable edge topology for the supplied cell topology kind.
 117    /// </summary>
 118    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3119    public static ReadOnlySpan<GridDiagnosticEdge> GetEdges(GridTopologyKind topologyKind) => topologyKind switch
 3120    {
 2121        GridTopologyKind.RectangularPrism => RectangularPrismEdges,
 1122        GridTopologyKind.HexPrism => HexPrismEdges,
 0123        _ => ReadOnlySpan<GridDiagnosticEdge>.Empty
 3124    };
 125
 126    private static int WriteRectangularVertices(
 127        Vector3d center,
 128        GridTopologyMetrics metrics,
 129        Span<Vector3d> vertices)
 130    {
 2131        if (vertices.Length < RectangularPrismVertexCount)
 1132            return 0;
 133
 1134        Fixed64 halfX = metrics.CellWidth * Fixed64.Half;
 1135        Fixed64 halfY = metrics.LayerHeight * Fixed64.Half;
 1136        Fixed64 halfZ = metrics.CellLength * Fixed64.Half;
 1137        Fixed64 minX = center.X - halfX;
 1138        Fixed64 maxX = center.X + halfX;
 1139        Fixed64 minY = center.Y - halfY;
 1140        Fixed64 maxY = center.Y + halfY;
 1141        Fixed64 minZ = center.Z - halfZ;
 1142        Fixed64 maxZ = center.Z + halfZ;
 143
 1144        vertices[0] = new Vector3d(minX, minY, minZ);
 1145        vertices[1] = new Vector3d(maxX, minY, minZ);
 1146        vertices[2] = new Vector3d(maxX, minY, maxZ);
 1147        vertices[3] = new Vector3d(minX, minY, maxZ);
 1148        vertices[4] = new Vector3d(minX, maxY, minZ);
 1149        vertices[5] = new Vector3d(maxX, maxY, minZ);
 1150        vertices[6] = new Vector3d(maxX, maxY, maxZ);
 1151        vertices[7] = new Vector3d(minX, maxY, maxZ);
 152
 1153        return RectangularPrismVertexCount;
 154    }
 155
 156    private static int WriteHexVertices(
 157        Vector3d center,
 158        GridTopologyMetrics metrics,
 159        Span<Vector3d> vertices)
 160    {
 5161        if (vertices.Length < HexPrismVertexCount)
 1162            return 0;
 163
 4164        Fixed64 halfY = metrics.LayerHeight * Fixed64.Half;
 4165        Fixed64 bottomY = center.Y - halfY;
 4166        Fixed64 topY = center.Y + halfY;
 167
 4168        if (metrics.HexOrientation == HexOrientation.FlatTop)
 169        {
 3170            WriteFlatTopHexRing(center.X, bottomY, center.Z, metrics.CellRadius, vertices);
 3171            WriteFlatTopHexRing(center.X, topY, center.Z, metrics.CellRadius, vertices.Slice(6));
 3172            return HexPrismVertexCount;
 173        }
 174
 1175        WritePointyTopHexRing(center.X, bottomY, center.Z, metrics.CellRadius, vertices);
 1176        WritePointyTopHexRing(center.X, topY, center.Z, metrics.CellRadius, vertices.Slice(6));
 1177        return HexPrismVertexCount;
 178    }
 179
 180    private static void WritePointyTopHexRing(
 181        Fixed64 centerX,
 182        Fixed64 y,
 183        Fixed64 centerZ,
 184        Fixed64 radius,
 185        Span<Vector3d> vertices)
 186    {
 2187        Fixed64 halfRadius = radius * Fixed64.Half;
 2188        Fixed64 halfWidth = HexCoordinateUtility.Sqrt3 * radius * Fixed64.Half;
 189
 2190        vertices[0] = new Vector3d(centerX + halfWidth, y, centerZ + halfRadius);
 2191        vertices[1] = new Vector3d(centerX, y, centerZ + radius);
 2192        vertices[2] = new Vector3d(centerX - halfWidth, y, centerZ + halfRadius);
 2193        vertices[3] = new Vector3d(centerX - halfWidth, y, centerZ - halfRadius);
 2194        vertices[4] = new Vector3d(centerX, y, centerZ - radius);
 2195        vertices[5] = new Vector3d(centerX + halfWidth, y, centerZ - halfRadius);
 2196    }
 197
 198    private static void WriteFlatTopHexRing(
 199        Fixed64 centerX,
 200        Fixed64 y,
 201        Fixed64 centerZ,
 202        Fixed64 radius,
 203        Span<Vector3d> vertices)
 204    {
 6205        Fixed64 halfRadius = radius * Fixed64.Half;
 6206        Fixed64 halfWidth = HexCoordinateUtility.Sqrt3 * radius * Fixed64.Half;
 207
 6208        vertices[0] = new Vector3d(centerX + radius, y, centerZ);
 6209        vertices[1] = new Vector3d(centerX + halfRadius, y, centerZ + halfWidth);
 6210        vertices[2] = new Vector3d(centerX - halfRadius, y, centerZ + halfWidth);
 6211        vertices[3] = new Vector3d(centerX - radius, y, centerZ);
 6212        vertices[4] = new Vector3d(centerX - halfRadius, y, centerZ - halfWidth);
 6213        vertices[5] = new Vector3d(centerX + halfRadius, y, centerZ - halfWidth);
 6214    }
 215}