< 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)]
 895523        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    {
 79538        _width = grid.Width;
 79539        _height = grid.Height;
 79540        _length = grid.Length;
 79541        ConfiguredVoxelCount = grid.Size;
 42
 79543        GenerateScanCells(grid);
 79544        GenerateVoxels(grid);
 79545    }
 46
 47    public void Reset(VoxelGrid grid)
 48    {
 79649        ReleaseVoxels(grid);
 79650        ReleaseScanCells();
 51
 79652        ConfiguredVoxelCount = 0;
 79653        _width = 0;
 79654        _height = 0;
 79655        _length = 0;
 79656    }
 57
 58    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 59    public bool TryGetVoxel(int x, int y, int z, out Voxel? result)
 60    {
 235061        result = Voxels![x, y, z];
 235062        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    {
 504126        if (Voxels == null)
 1127            return;
 128
 2558129        for (long x = min.x; x <= max.x; x++)
 130        {
 3264131            for (long y = min.y; y <= max.y; y++)
 132            {
 5848133                for (long z = min.z; z <= max.z; z++)
 134                {
 2068135                    Voxel voxel = Voxels[(int)x, (int)y, (int)z];
 2068136                    if (redundancy.Add(voxel))
 2060137                        results.Add(voxel);
 138                }
 139            }
 140        }
 503141    }
 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    {
 795181        ScanCells = Pools.ScanCellMapPool.Rent();
 182
 3652183        for (int x = 0; x < grid.ScanWidth; x++)
 184        {
 4254185            for (int y = 0; y < grid.ScanHeight; y++)
 186            {
 6946187                for (int z = 0; z < grid.ScanLength; z++)
 188                {
 2377189                    int cellKey = grid.GetScanCellKey(x, y, z);
 190
 2377191                    ScanCell scanCell = Pools.ScanCellPool.Rent();
 2377192                    scanCell.Initialize(grid, cellKey);
 2377193                    ScanCells.Add(cellKey, scanCell);
 194                }
 195            }
 196        }
 795197    }
 198
 199    private void GenerateVoxels(VoxelGrid grid)
 200    {
 795201        Voxels = new SwiftArray3D<Voxel>(_width, _height, _length);
 202
 7722203        for (int x = 0; x < _width; x++)
 204        {
 18546205            for (int y = 0; y < _height; y++)
 206            {
 258950207                for (int z = 0; z < _length; z++)
 208                {
 123268209                    VoxelIndex index = new(x, y, z);
 123268210                    Vector3d position = grid.GetWorldPosition(index);
 123268211                    Voxel voxel = Pools.VoxelPool.Rent();
 212
 123268213                    voxel.Initialize(
 123268214                        new WorldVoxelIndex(grid.World!.SpawnToken, grid.GridIndex, grid.SpawnToken, index),
 123268215                        position,
 123268216                        grid.GetScanCellKey(index),
 123268217                        grid.IsOnBoundary(index),
 123268218                        grid.Version);
 219
 123268220                    Voxels[x, y, z] = voxel;
 221                }
 222            }
 223        }
 795224    }
 225
 226    private void ReleaseVoxels(VoxelGrid grid)
 227    {
 796228        if (Voxels == null)
 1229            return;
 230
 7722231        for (int x = 0; x < _width; x++)
 232        {
 18546233            for (int y = 0; y < _height; y++)
 234            {
 258950235                for (int z = 0; z < _length; z++)
 236                {
 123268237                    Voxel voxel = Voxels[x, y, z];
 123268238                    voxel.Reset(grid);
 123268239                    Pools.VoxelPool.Release(voxel);
 240                }
 241            }
 242        }
 243
 795244        Voxels = null;
 795245    }
 246
 247    private void ReleaseScanCells()
 248    {
 796249        if (ScanCells == null)
 1250            return;
 251
 6344252        foreach (ScanCell cell in ScanCells.Values)
 2377253            Pools.ScanCellPool.Release(cell);
 254
 795255        Pools.ScanCellMapPool.Release(ScanCells);
 795256        ScanCells = null;
 795257    }
 258}