< Summary

Information
Class: GridForge.Grids.Storage.DenseVoxelGridStorage
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Grids/Storage/DenseVoxelGridStorage.cs
Line coverage
100%
Covered lines: 101
Uncovered lines: 0
Coverable lines: 101
Total lines: 258
Line coverage: 100%
Branch coverage
100%
Covered branches: 66
Total branches: 66
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%
Initialize(...)100%11100%
Reset(...)100%11100%
TryGetVoxel(...)100%11100%
TryGetClosestVoxel(...)100%11100%
TryGetScanCell(...)100%22100%
EnumerateVoxels()100%88100%
VisitVoxels(...)100%1010100%
AddVoxelsInIndexRange(...)100%1010100%
AddScanCellsInRange(...)100%1212100%
GenerateScanCells(...)100%66100%
GenerateVoxels(...)100%66100%
ReleaseVoxels(...)100%88100%
ReleaseScanCells()100%44100%

File(s)

/home/runner/work/GridForge/GridForge/src/GridForge/Grids/Storage/DenseVoxelGridStorage.cs

#LineLine coverage
 1//=======================================================================
 2// DenseVoxelGridStorage.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.Collections.Generic;
 9using System.Diagnostics;
 10using System.Runtime.CompilerServices;
 11using FixedMathSharp;
 12using GridForge.Spatial;
 13using SwiftCollections;
 14using SwiftCollections.Dimensions;
 15
 16namespace GridForge.Grids.Storage;
 17
 18internal sealed class DenseVoxelGridStorage : IVoxelGridStorage
 19{
 20    public GridStorageKind Kind
 21    {
 22        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 861923        get => GridStorageKind.Dense;
 24    }
 25
 26    public int ConfiguredVoxelCount { get; private set; }
 27
 28    public SwiftSparseMap<ScanCell>? ScanCells { get; private set; }
 29
 30    internal SwiftArray3D<Voxel>? Voxels { get; private set; }
 31
 32    private int _width;
 33    private int _height;
 34    private int _length;
 35
 36    public void Initialize(VoxelGrid grid)
 37    {
 45738        _width = grid.Width;
 45739        _height = grid.Height;
 45740        _length = grid.Length;
 45741        ConfiguredVoxelCount = grid.Size;
 42
 45743        GenerateScanCells(grid);
 45744        GenerateVoxels(grid);
 45745    }
 46
 47    public void Reset(VoxelGrid grid)
 48    {
 45849        ReleaseVoxels(grid);
 45850        ReleaseScanCells();
 51
 45852        ConfiguredVoxelCount = 0;
 45853        _width = 0;
 45854        _height = 0;
 45855        _length = 0;
 45856    }
 57
 58    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 59    public bool TryGetVoxel(int x, int y, int z, out Voxel? result)
 60    {
 139161        result = Voxels![x, y, z];
 139162        return result!.IsAllocated;
 63    }
 64
 65    public bool TryGetClosestVoxel(
 66        VoxelGrid grid,
 67        VoxelIndex closestIndex,
 68        Vector3d position,
 69        out Voxel? result,
 70        out Fixed64 distanceSquared)
 71    {
 1372        result = Voxels![closestIndex.x, closestIndex.y, closestIndex.z];
 1373        distanceSquared = (result!.WorldPosition - position).MagnitudeSquared;
 1374        return true;
 75    }
 76
 77    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 78    public bool TryGetScanCell(int key, out ScanCell? result)
 79    {
 95080        result = null;
 95081        return ScanCells?.TryGetValue(key, out result) == true;
 82    }
 83
 84    public IEnumerable<Voxel> EnumerateVoxels()
 85    {
 386        if (Voxels == null)
 187            yield break;
 88
 889        for (int x = 0; x < _width; x++)
 90        {
 4491            for (int y = 0; y < _height; y++)
 92            {
 56693                for (int z = 0; z < _length; z++)
 94                {
 26495                    yield return Voxels[x, y, z];
 96                }
 97            }
 98        }
 199    }
 100
 101    public void VisitVoxels<TVisitor>(ref TVisitor visitor)
 102        where TVisitor : struct, IVoxelStorageVisitor
 103    {
 51104        if (Voxels == null)
 1105            return;
 106
 1236107        for (int x = 0; x < _width; x++)
 108        {
 2360109            for (int y = 0; y < _height; y++)
 110            {
 18616111                for (int z = 0; z < _length; z++)
 112                {
 8698113                    if (!visitor.Visit(Voxels[x, y, z]))
 2114                        return;
 115                }
 116            }
 117        }
 48118    }
 119
 120    public void AddVoxelsInIndexRange(
 121        VoxelIndex min,
 122        VoxelIndex max,
 123        SwiftList<Voxel> results,
 124        SwiftHashSet<Voxel> redundancy)
 125    {
 243126        if (Voxels == null)
 1127            return;
 128
 1474129        for (long x = min.x; x <= max.x; x++)
 130        {
 1980131            for (long y = min.y; y <= max.y; y++)
 132            {
 3604133                for (long z = min.z; z <= max.z; z++)
 134                {
 1307135                    Voxel voxel = Voxels[(int)x, (int)y, (int)z];
 1307136                    if (redundancy.Add(voxel))
 1303137                        results.Add(voxel);
 138                }
 139            }
 140        }
 242141    }
 142
 143    public void AddScanCellsInRange(
 144        VoxelGrid grid,
 145        int xMin,
 146        int yMin,
 147        int zMin,
 148        int xMax,
 149        int yMax,
 150        int zMax,
 151        SwiftList<ScanCell> results,
 152        SwiftHashSet<ScanCell> redundancy)
 153    {
 578154        if (ScanCells == null)
 1155            return;
 156
 3444157        for (long x = xMin; x <= xMax; x++)
 158        {
 4588159            for (long y = yMin; y <= yMax; y++)
 160            {
 6852161                for (long z = zMin; z <= zMax; z++)
 162                {
 2277163                    int scanCellKey = grid.GetScanCellKey(
 2277164                        (int)x,
 2277165                        (int)y,
 2277166                        (int)z);
 2277167                    if (scanCellKey >= 0)
 168                    {
 2275169                        bool found = ScanCells.TryGetValue(scanCellKey, out ScanCell? scanCell);
 170                        Debug.Assert(found);
 2275171                        if (redundancy.Add(scanCell!))
 2274172                            results.Add(scanCell!);
 173                    }
 174                }
 175            }
 176        }
 577177    }
 178
 179    private void GenerateScanCells(VoxelGrid grid)
 180    {
 457181        ScanCells = Pools.ScanCellMapPool.Rent();
 182
 2296183        for (int x = 0; x < grid.ScanWidth; x++)
 184        {
 2894185            for (int y = 0; y < grid.ScanHeight; y++)
 186            {
 5578187                for (int z = 0; z < grid.ScanLength; z++)
 188                {
 2033189                    int cellKey = grid.GetScanCellKey(x, y, z);
 190
 2033191                    ScanCell scanCell = Pools.ScanCellPool.Rent();
 2033192                    scanCell.Initialize(grid, cellKey);
 2033193                    ScanCells.Add(cellKey, scanCell);
 194                }
 195            }
 196        }
 457197    }
 198
 199    private void GenerateVoxels(VoxelGrid grid)
 200    {
 457201        Voxels = new SwiftArray3D<Voxel>(_width, _height, _length);
 202
 6158203        for (int x = 0; x < _width; x++)
 204        {
 16560205            for (int y = 0; y < _height; y++)
 206            {
 255400207                for (int z = 0; z < _length; z++)
 208                {
 122042209                    VoxelIndex index = new(x, y, z);
 122042210                    Vector3d position = grid.GetWorldPosition(index);
 122042211                    Voxel voxel = Pools.VoxelPool.Rent();
 212
 122042213                    voxel.Initialize(
 122042214                        new WorldVoxelIndex(grid.World!.SpawnToken, grid.GridIndex, grid.SpawnToken, index),
 122042215                        position,
 122042216                        grid.GetScanCellKey(index),
 122042217                        grid.IsOnBoundary(index),
 122042218                        grid.Version);
 219
 122042220                    Voxels[x, y, z] = voxel;
 221                }
 222            }
 223        }
 457224    }
 225
 226    private void ReleaseVoxels(VoxelGrid grid)
 227    {
 458228        if (Voxels == null)
 1229            return;
 230
 6158231        for (int x = 0; x < _width; x++)
 232        {
 16560233            for (int y = 0; y < _height; y++)
 234            {
 255400235                for (int z = 0; z < _length; z++)
 236                {
 122042237                    Voxel voxel = Voxels[x, y, z];
 122042238                    voxel.Reset(grid);
 122042239                    Pools.VoxelPool.Release(voxel);
 240                }
 241            }
 242        }
 243
 457244        Voxels = null;
 457245    }
 246
 247    private void ReleaseScanCells()
 248    {
 458249        if (ScanCells == null)
 1250            return;
 251
 4980252        foreach (ScanCell cell in ScanCells.Values)
 2033253            Pools.ScanCellPool.Release(cell);
 254
 457255        Pools.ScanCellMapPool.Release(ScanCells);
 457256        ScanCells = null;
 457257    }
 258}