< Summary

Information
Class: SwiftCollections.Query.BoundVolume
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Query/Shared/Volume/BoundVolume.cs
Line coverage
100%
Covered lines: 42
Uncovered lines: 0
Coverable lines: 42
Total lines: 177
Line coverage: 100%
Branch coverage
100%
Covered branches: 22
Total branches: 22
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%
get_Min()100%11100%
get_Max()100%11100%
get_Center()100%22100%
get_Size()100%22100%
get_Volume()100%22100%
RecalculateMeta()100%11100%
Union(...)100%11100%
Intersects(...)100%1010100%
GetCost(...)100%22100%
BoundsEquals(...)100%22100%
Equals(...)100%11100%
Equals(...)100%22100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
GetHashCode()100%11100%
ToString()100%11100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Query/Shared/Volume/BoundVolume.cs

#LineLine coverage
 1//=======================================================================
 2// BoundVolume.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;
 9using System.Numerics;
 10using System.Runtime.CompilerServices;
 11
 12namespace SwiftCollections.Query;
 13
 14/// <summary>
 15/// Represents an axis-aligned bounding box (AABB) in 3D space.
 16/// </summary>
 17public struct BoundVolume : IBoundVolume<BoundVolume>, IEquatable<BoundVolume>
 18{
 19    /// <summary>
 20    /// The minimum point of the bounding volume.
 21    /// </summary>
 22    private Vector3 _min;
 23
 24    /// <summary>
 25    /// The maximum point of the bounding volume.
 26    /// </summary>
 27    private Vector3 _max;
 28
 29    /// <summary>
 30    /// The center of the bounding volume as the midpoint of the minimum and maximum points.
 31    /// </summary>
 32    private Vector3 _center;
 33
 34    /// <summary>
 35    /// The size of the bounding volume as the difference between the maximum and minimum points.
 36    /// </summary>
 37    private Vector3 _size;
 38
 39    /// <summary>
 40    /// The volume of the bounding box, calculated as the product of its dimensions.
 41    /// </summary>
 42    private double _volume;
 43
 44    /// <summary>
 45    /// Marks the bounding volume as dirty, indicating its properties need recalculation.
 46    /// </summary>
 47    private bool _isDirty;
 48
 49    /// <summary>
 50    /// Initializes a new instance of the <see cref="BoundVolume"/> struct with the specified minimum and maximum points
 51    /// </summary>
 52    /// <param name="min">The minimum point of the bounding volume.</param>
 53    /// <param name="max">The maximum point of the bounding volume.</param>
 54    public BoundVolume(Vector3 min, Vector3 max)
 55    {
 41764556        _min = min;
 41764557        _max = max;
 58
 41764559        _isDirty = true;
 41764560        _center = default;
 41764561        _size = default;
 41764562        _volume = default;
 41764563    }
 64
 65    /// <inheritdoc cref="_min"/>
 280381766    public readonly Vector3 Min => _min;
 67
 68    /// <inheritdoc cref="_max"/>
 280375769    public readonly Vector3 Max => _max;
 70
 71    /// <inheritdoc cref="_center"/>
 72    public Vector3 Center
 73    {
 74        get
 75        {
 676            if (_isDirty)
 377                RecalculateMeta();
 678            return _center;
 79        }
 80    }
 81
 82    /// <inheritdoc cref="_size"/>
 83    public Vector3 Size
 84    {
 85        get
 86        {
 987            if (_isDirty)
 888                RecalculateMeta();
 989            return _size;
 90        }
 91    }
 92
 93    /// <inheritdoc cref="_volume"/>
 94    public double Volume
 95    {
 96        get
 97        {
 25194898            if (_isDirty)
 25194799                RecalculateMeta();
 251948100            return _volume;
 101        }
 102    }
 103
 104    /// <summary>
 105    /// Forces recalculation of the bounding volume's metadata, such as center, size, and volume.
 106    /// </summary>
 107    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 108    private void RecalculateMeta()
 109    {
 251958110        _center = (_min + _max) / 2;
 251958111        _size = _max - _min;
 251958112        _volume = _size.X * _size.Y * _size.Z;
 251958113        _isDirty = false;
 251958114    }
 115
 116    /// <inheritdoc />
 117    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 118    public readonly BoundVolume Union(BoundVolume other)
 119    {
 404258120        return new BoundVolume(
 404258121            new Vector3(Math.Min(Min.X, other.Min.X), Math.Min(Min.Y, other.Min.Y), Math.Min(Min.Z, other.Min.Z)),
 404258122            new Vector3(Math.Max(Max.X, other.Max.X), Math.Max(Max.Y, other.Max.Y), Math.Max(Max.Z, other.Max.Z))
 404258123        );
 124    }
 125
 126    /// <inheritdoc />
 127    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 128    public readonly bool Intersects(BoundVolume other)
 129    {
 21145130        return !(Min.X > other.Max.X || Max.X < other.Min.X ||
 21145131                 Min.Y > other.Max.Y || Max.Y < other.Min.Y ||
 21145132                 Min.Z > other.Max.Z || Max.Z < other.Min.Z);
 133    }
 134
 135    /// <inheritdoc />
 136    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 137    public readonly long GetCost(BoundVolume other)
 138    {
 251947139        BoundVolume union = Union(other);
 251947140        Vector3 size = Max - Min;
 251947141        double volume = size.X * size.Y * size.Z;
 251947142        double delta = union.Volume - volume;
 251947143        return delta >= (double)long.MaxValue ? long.MaxValue : (long)delta;
 144    }
 145
 146    /// <inheritdoc />
 147    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 148    public readonly bool BoundsEquals(BoundVolume other)
 149    {
 19150        return Min.Equals(other.Min) && Max.Equals(other.Max);
 151    }
 152
 153    /// <inheritdoc />
 5154    public readonly bool Equals(BoundVolume other) => BoundsEquals(other);
 155
 156    /// <inheritdoc />
 4157    public override readonly bool Equals(object? obj) => obj is BoundVolume other && BoundsEquals(other);
 158
 159    /// <summary>
 160    /// Determines whether two BoundVolume instances are equal.
 161    /// </summary>
 4162    public static bool operator ==(BoundVolume left, BoundVolume right) => left.Equals(right);
 163
 164    /// <summary>
 165    /// Determines whether two BoundVolume instances are not equal.
 166    /// </summary>
 2167    public static bool operator !=(BoundVolume left, BoundVolume right) => !(left == right);
 168
 169    /// <inheritdoc />
 2170    public override readonly int GetHashCode() => HashCode.Combine(Min, Max);
 171
 172    /// <summary>
 173    /// Returns a string that represents the current object, including the minimum and maximum values.
 174    /// </summary>
 175    /// <returns>A string in the format "Min: {Min}, Max: {Max}" that displays the minimum and maximum values of the obj
 1176    public override readonly string ToString() => $"Min: {Min}, Max: {Max}";
 177}