< 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: 57
Uncovered lines: 0
Coverable lines: 57
Total lines: 134
Line coverage: 100%
Branch coverage
100%
Covered branches: 36
Total branches: 36
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%11100%
HasMinimumChildSpan(...)100%11100%
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 System.Runtime.CompilerServices;
 9using FixedMathSharp;
 10
 11namespace SwiftCollections.Query;
 12
 13/// <summary>
 14/// Represents a fixed-point octree optimized for deterministic hierarchical spatial queries.
 15/// </summary>
 16public sealed class SwiftFixedOctree<T> : SwiftOctree<T, FixedBoundVolume>
 17{
 18    /// <summary>
 19    /// Initializes a new instance of the <see cref="SwiftFixedOctree{T}"/> class.
 20    /// </summary>
 21    /// <param name="worldBounds">The immutable world bounds covered by the octree.</param>
 22    /// <param name="options">Backend-neutral octree options.</param>
 23    /// <param name="minNodeSize">The minimum child-node axis length allowed for fixed-point subdivision.</param>
 24    public SwiftFixedOctree(FixedBoundVolume worldBounds, SwiftOctreeOptions options, Fixed64 minNodeSize)
 1525        : base(worldBounds, options, new FixedBoundVolumeOctreePartitioner(minNodeSize))
 1326    { }
 27
 28    private sealed class FixedBoundVolumeOctreePartitioner : IOctreeBoundsPartitioner<FixedBoundVolume>
 29    {
 30        private readonly Fixed64 _minNodeSize;
 31
 1532        public FixedBoundVolumeOctreePartitioner(Fixed64 minNodeSize)
 33        {
 1534            if (minNodeSize <= Fixed64.Zero)
 235                throw new System.ArgumentOutOfRangeException(nameof(minNodeSize), minNodeSize, "Minimum node size must b
 36
 1337            _minNodeSize = minNodeSize;
 1338        }
 39
 40        public bool ContainsBounds(FixedBoundVolume outer, FixedBoundVolume inner)
 41        {
 2942            return inner.Min.X >= outer.Min.X &&
 2943                   inner.Min.Y >= outer.Min.Y &&
 2944                   inner.Min.Z >= outer.Min.Z &&
 2945                   inner.Max.X <= outer.Max.X &&
 2946                   inner.Max.Y <= outer.Max.Y &&
 2947                   inner.Max.Z <= outer.Max.Z;
 48        }
 49
 50        public bool CanSubdivide(FixedBoundVolume bounds)
 51        {
 552            Vector3d min = bounds.Min;
 553            Vector3d midpoint = bounds.Center;
 554            Vector3d max = bounds.Max;
 555            ulong requiredRawSpan = (ulong)_minNodeSize.m_rawValue;
 556            return HasMinimumChildSpan(min.X, midpoint.X, max.X, requiredRawSpan)
 557                 & HasMinimumChildSpan(min.Y, midpoint.Y, max.Y, requiredRawSpan)
 558                 & HasMinimumChildSpan(min.Z, midpoint.Z, max.Z, requiredRawSpan);
 59        }
 60
 61        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 62        private static bool HasMinimumChildSpan(
 63            Fixed64 min,
 64            Fixed64 midpoint,
 65            Fixed64 max,
 66            ulong requiredRawSpan)
 67        {
 68            // Ordered raw endpoints can span the complete signed scalar domain;
 69            // unsigned subtraction preserves that exact non-negative distance.
 1570            ulong lowerRawSpan = unchecked((ulong)midpoint.m_rawValue - (ulong)min.m_rawValue);
 1571            ulong upperRawSpan = unchecked((ulong)max.m_rawValue - (ulong)midpoint.m_rawValue);
 1572            return lowerRawSpan >= requiredRawSpan & upperRawSpan >= requiredRawSpan;
 73        }
 74
 75        public bool TryGetContainingChildIndex(FixedBoundVolume nodeBounds, FixedBoundVolume entryBounds, out int childI
 76        {
 1777            Vector3d midpoint = nodeBounds.Center;
 78
 79            int xBit;
 1780            if (entryBounds.Min.X >= midpoint.X)
 781                xBit = 1;
 1082            else if (entryBounds.Max.X <= midpoint.X)
 983                xBit = 0;
 84            else
 85            {
 186                childIndex = -1;
 187                return false;
 88            }
 89
 90            int yBit;
 1691            if (entryBounds.Min.Y >= midpoint.Y)
 792                yBit = 1;
 993            else if (entryBounds.Max.Y <= midpoint.Y)
 894                yBit = 0;
 95            else
 96            {
 197                childIndex = -1;
 198                return false;
 99            }
 100
 101            int zBit;
 15102            if (entryBounds.Min.Z >= midpoint.Z)
 7103                zBit = 1;
 8104            else if (entryBounds.Max.Z <= midpoint.Z)
 7105                zBit = 0;
 106            else
 107            {
 1108                childIndex = -1;
 1109                return false;
 110            }
 111
 14112            childIndex = xBit | (yBit << 1) | (zBit << 2);
 14113            return true;
 114        }
 115
 116        public FixedBoundVolume CreateChildBounds(FixedBoundVolume parentBounds, int childIndex)
 117        {
 32118            Vector3d midpoint = parentBounds.Center;
 32119            bool upperX = (childIndex & 1) != 0;
 32120            bool upperY = (childIndex & 2) != 0;
 32121            bool upperZ = (childIndex & 4) != 0;
 122
 32123            return new FixedBoundVolume(
 32124                new Vector3d(
 32125                    upperX ? midpoint.X : parentBounds.Min.X,
 32126                    upperY ? midpoint.Y : parentBounds.Min.Y,
 32127                    upperZ ? midpoint.Z : parentBounds.Min.Z),
 32128                new Vector3d(
 32129                    upperX ? parentBounds.Max.X : midpoint.X,
 32130                    upperY ? parentBounds.Max.Y : midpoint.Y,
 32131                    upperZ ? parentBounds.Max.Z : midpoint.Z));
 132        }
 133    }
 134}