< Summary

Information
Class: SwiftCollections.Query.SwiftFixedOctree<T>
Assembly: SwiftCollections.FixedMathSharp
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections.FixedMathSharp/Query/Octree/SwiftFixedOctree.cs
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 116
Line coverage: 100%
Branch coverage
100%
Covered branches: 40
Total branches: 40
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%11100%
.ctor(...)100%22100%
ContainsBounds(...)100%1010100%
CanSubdivide(...)100%44100%
TryGetContainingChildIndex(...)100%1212100%
CreateChildBounds(...)100%1212100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections.FixedMathSharp/Query/Octree/SwiftFixedOctree.cs

#LineLine coverage
 1//=======================================================================
 2// SwiftFixedOctree.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;
 9
 10namespace SwiftCollections.Query;
 11
 12/// <summary>
 13/// Represents a fixed-point octree optimized for deterministic hierarchical spatial queries.
 14/// </summary>
 15public sealed class SwiftFixedOctree<T> : SwiftOctree<T, FixedBoundVolume>
 16{
 17    /// <summary>
 18    /// Initializes a new instance of the <see cref="SwiftFixedOctree{T}"/> class.
 19    /// </summary>
 20    /// <param name="worldBounds">The immutable world bounds covered by the octree.</param>
 21    /// <param name="options">Backend-neutral octree options.</param>
 22    /// <param name="minNodeSize">The minimum child-node axis length allowed for fixed-point subdivision.</param>
 23    public SwiftFixedOctree(FixedBoundVolume worldBounds, SwiftOctreeOptions options, Fixed64 minNodeSize)
 1424        : base(worldBounds, options, new FixedBoundVolumeOctreePartitioner(minNodeSize))
 1225    { }
 26
 27    private sealed class FixedBoundVolumeOctreePartitioner : IOctreeBoundsPartitioner<FixedBoundVolume>
 28    {
 29        private readonly Fixed64 _minNodeSize;
 30
 1431        public FixedBoundVolumeOctreePartitioner(Fixed64 minNodeSize)
 32        {
 1433            if (minNodeSize <= Fixed64.Zero)
 234                throw new System.ArgumentOutOfRangeException(nameof(minNodeSize), minNodeSize, "Minimum node size must b
 35
 1236            _minNodeSize = minNodeSize;
 1237        }
 38
 39        public bool ContainsBounds(FixedBoundVolume outer, FixedBoundVolume inner)
 40        {
 2741            return inner.Min.X >= outer.Min.X &&
 2742                   inner.Min.Y >= outer.Min.Y &&
 2743                   inner.Min.Z >= outer.Min.Z &&
 2744                   inner.Max.X <= outer.Max.X &&
 2745                   inner.Max.Y <= outer.Max.Y &&
 2746                   inner.Max.Z <= outer.Max.Z;
 47        }
 48
 49        public bool CanSubdivide(FixedBoundVolume bounds)
 50        {
 451            Vector3d childSize = bounds.Size * Fixed64.Half;
 452            return childSize.X >= _minNodeSize &&
 453                   childSize.Y >= _minNodeSize &&
 454                   childSize.Z >= _minNodeSize;
 55        }
 56
 57        public bool TryGetContainingChildIndex(FixedBoundVolume nodeBounds, FixedBoundVolume entryBounds, out int childI
 58        {
 1559            Vector3d midpoint = (nodeBounds.Min + nodeBounds.Max) * Fixed64.Half;
 60
 61            int xBit;
 1562            if (entryBounds.Min.X >= midpoint.X)
 663                xBit = 1;
 964            else if (entryBounds.Max.X <= midpoint.X)
 865                xBit = 0;
 66            else
 67            {
 168                childIndex = -1;
 169                return false;
 70            }
 71
 72            int yBit;
 1473            if (entryBounds.Min.Y >= midpoint.Y)
 674                yBit = 1;
 875            else if (entryBounds.Max.Y <= midpoint.Y)
 776                yBit = 0;
 77            else
 78            {
 179                childIndex = -1;
 180                return false;
 81            }
 82
 83            int zBit;
 1384            if (entryBounds.Min.Z >= midpoint.Z)
 685                zBit = 1;
 786            else if (entryBounds.Max.Z <= midpoint.Z)
 687                zBit = 0;
 88            else
 89            {
 190                childIndex = -1;
 191                return false;
 92            }
 93
 1294            childIndex = xBit | (yBit << 1) | (zBit << 2);
 1295            return true;
 96        }
 97
 98        public FixedBoundVolume CreateChildBounds(FixedBoundVolume parentBounds, int childIndex)
 99        {
 24100            Vector3d midpoint = (parentBounds.Min + parentBounds.Max) * Fixed64.Half;
 24101            bool upperX = (childIndex & 1) != 0;
 24102            bool upperY = (childIndex & 2) != 0;
 24103            bool upperZ = (childIndex & 4) != 0;
 104
 24105            return new FixedBoundVolume(
 24106                new Vector3d(
 24107                    upperX ? midpoint.X : parentBounds.Min.X,
 24108                    upperY ? midpoint.Y : parentBounds.Min.Y,
 24109                    upperZ ? midpoint.Z : parentBounds.Min.Z),
 24110                new Vector3d(
 24111                    upperX ? parentBounds.Max.X : midpoint.X,
 24112                    upperY ? parentBounds.Max.Y : midpoint.Y,
 24113                    upperZ ? parentBounds.Max.Z : midpoint.Z));
 114        }
 115    }
 116}