114 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
namespace Engine.Core;
 | 
						|
 | 
						|
/// <summary>
 | 
						|
/// Represents an Axis-Aligned Bounding Box (AABB) in 3D space.
 | 
						|
/// </summary>
 | 
						|
/// <param name="lowerBoundary">The lower boundary of the <see cref="AABB3D"/>.</param>
 | 
						|
/// <param name="upperBoundary">The upper boundary of the <see cref="AABB3D"/>.</param>
 | 
						|
/// <remarks>
 | 
						|
/// Initializes a new instance of the <see cref="AABB3D"/> struct with the specified lower and upper boundaries.
 | 
						|
/// </remarks>
 | 
						|
[System.Diagnostics.DebuggerDisplay("LowerBoundary: {LowerBoundary.ToString(), nq}, UpperBoundary: {UpperBoundary.ToString(), nq}")]
 | 
						|
public readonly struct AABB3D(Vector3D lowerBoundary, Vector3D upperBoundary) : IEquatable<AABB3D>
 | 
						|
{
 | 
						|
    /// <summary>
 | 
						|
    /// The lower boundary of the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    public readonly Vector3D LowerBoundary = lowerBoundary;
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// The upper boundary of the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    public readonly Vector3D UpperBoundary = upperBoundary;
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Gets the center point of the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    public readonly Vector3D Center => (LowerBoundary + UpperBoundary) * .5f;
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Gets the size of the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    public readonly Vector3D Size => LowerBoundary.FromTo(UpperBoundary).Abs();
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Gets half the size of the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    public readonly Vector3D SizeHalf => Size * .5f;
 | 
						|
 | 
						|
    public static bool operator ==(AABB3D left, AABB3D right) => left.UpperBoundary == right.UpperBoundary && left.LowerBoundary == right.LowerBoundary;
 | 
						|
    public static bool operator !=(AABB3D left, AABB3D right) => left.UpperBoundary != right.UpperBoundary || left.LowerBoundary != right.LowerBoundary;
 | 
						|
 | 
						|
    public static implicit operator AABB3D(Sphere3D sphere) => new(sphere.Center - new Vector3D(sphere.Radius, sphere.Radius, sphere.Radius), sphere.Center + new Vector3D(sphere.Radius, sphere.Radius, sphere.Radius));
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Creates an <see cref="AABB3D"/> from a collection of <see cref="Vector3D"/>s.
 | 
						|
    /// </summary>
 | 
						|
    /// <param name="vectors">The collection of <see cref="Vector3D"/>s.</param>
 | 
						|
    /// <returns>An <see cref="AABB3D"/> that bounds all the <see cref="Vector3D"/>s.</returns>
 | 
						|
    public static AABB3D FromVectors(IEnumerable<Vector3D> vectors)
 | 
						|
    {
 | 
						|
        int counter = 0;
 | 
						|
 | 
						|
        Vector3D lowerBoundary = new(float.MaxValue, float.MaxValue, float.MaxValue);
 | 
						|
        Vector3D upperBoundary = new(float.MinValue, float.MinValue, float.MinValue);
 | 
						|
 | 
						|
        foreach (Vector3D vector in vectors)
 | 
						|
        {
 | 
						|
            lowerBoundary = Vector3D.Min(lowerBoundary, vector);
 | 
						|
            upperBoundary = Vector3D.Max(upperBoundary, vector);
 | 
						|
            counter++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (counter < 2)
 | 
						|
            throw new ArgumentException($"Parameter {nameof(vectors)} must have at least 2 items.");
 | 
						|
 | 
						|
        return new(lowerBoundary, upperBoundary);
 | 
						|
    }
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Checks if two <see cref="AABB3D"/>s are approximately equal.
 | 
						|
    /// </summary>
 | 
						|
    /// <param name="left">The first <see cref="AABB3D"/>.</param>
 | 
						|
    /// <param name="right">The second <see cref="AABB3D"/>.</param>
 | 
						|
    /// <param name="epsilon">The epsilon range.</param>
 | 
						|
    /// <returns><see cref="true"/> if the <see cref="AABB3D"/>s are approximately equal; otherwise, <see cref="false"/>.</returns>
 | 
						|
    public static bool ApproximatelyEquals(AABB3D left, AABB3D right, float epsilon = float.Epsilon)
 | 
						|
        => left.LowerBoundary.ApproximatelyEquals(right.LowerBoundary, epsilon) && left.UpperBoundary.ApproximatelyEquals(right.UpperBoundary, epsilon);
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Determines whether the specified object is equal to the current <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    /// <param name="obj">The object to compare with the current <see cref="AABB3D"/>.</param>
 | 
						|
    /// <returns><see cref="true"/> if the specified object is equal to the current <see cref="AABB3D"/>; otherwise, <see cref="false"/>.</returns>
 | 
						|
    public override bool Equals(object? obj) => obj is AABB3D aabb && this == aabb;
 | 
						|
    public bool Equals(AABB3D other) => this == other;
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Generates a hash code for the <see cref="AABB3D"/>.
 | 
						|
    /// </summary>
 | 
						|
    /// <returns>A hash code for the <see cref="AABB3D"/>.</returns>
 | 
						|
    public override int GetHashCode() => System.HashCode.Combine(LowerBoundary, UpperBoundary);
 | 
						|
 | 
						|
    /// <summary>
 | 
						|
    /// Converts the <see cref="AABB3D"/> to its string representation.
 | 
						|
    /// </summary>
 | 
						|
    /// <returns>A string representation of the <see cref="AABB3D"/>.</returns>
 | 
						|
    public override string ToString() => $"{nameof(AABB3D)}({LowerBoundary}, {UpperBoundary})";
 | 
						|
}
 | 
						|
 | 
						|
/// <summary>
 | 
						|
/// Provides extension methods for the <see cref="AABB3D"/> struct.
 | 
						|
/// </summary>
 | 
						|
public static class AABB3DExtensions
 | 
						|
{
 | 
						|
    /// <inheritdoc cref="AABB3D.FromVectors" />
 | 
						|
    public static AABB3D ToAABB3D(this IEnumerable<Vector3D> vectors) => AABB3D.FromVectors(vectors);
 | 
						|
 | 
						|
    /// <inheritdoc cref="AABB3D.ApproximatelyEquals" />
 | 
						|
    public static bool ApproximatelyEquals(this AABB3D left, AABB3D right, float epsilon = float.Epsilon) => AABB3D.ApproximatelyEquals(left, right, epsilon);
 | 
						|
}
 |