// 27 Slicer
// Copyright 2021 Deftly Games
// https://slicer.deftly.games/
using System.Collections.Generic;
using UnityEngine;
namespace Slicer.Core
{
///
/// Contains useful methods for working with UnityEngine.Bounds.
///
public static class BoundsUtility
{
///
/// Grow the bounds to encapsulate the bounds.
///
/// the first bounds to encapsulate.
/// the second bounds to encapsulate.
///
/// Returns the bounds that encapsulates both bounds.
///
/// If boundB is null, boundA is returned.
///
public static Bounds Encapsulate(Bounds boundA, Bounds? boundB)
{
return Encapsulate(boundB, boundA);
}
///
/// Grow the bounds to encapsulate the bounds.
///
/// the first bounds to encapsulate.
/// the second bounds to encapsulate.
///
/// Returns the bounds that encapsulates both bounds.
///
/// If boundA is null, boundB is returned.
///
public static Bounds Encapsulate(Bounds? boundA, Bounds boundB)
{
if (!boundA.HasValue)
{
return boundB;
}
boundB.Encapsulate(boundA.Value);
return boundB;
}
///
/// Grow the bounds to encapsulate the bounds.
///
/// the first bounds to encapsulate.
/// the second bounds to encapsulate.
///
/// Returns the bounds that encapsulates both bounds.
///
/// If one of the supplied bounds is null, the other supplied bounds is returned.
///
/// If both bounds are null, null is returned.
///
public static Bounds? Encapsulate(Bounds? boundA, Bounds? boundB)
{
if (!boundA.HasValue && !boundB.HasValue)
{
return null;
}
if (!boundA.HasValue)
{
return boundB;
}
if (!boundB.HasValue)
{
return boundA;
}
var a = boundA.Value;
var b = boundB.Value;
a.Encapsulate(b);
return a;
}
///
/// Converts a bounds into a collection of verts, one for each corner
///
public static void GetVerts(Bounds bounds, List vectors)
{
vectors.Clear();
Vector3 min = bounds.min;
Vector3 s = bounds.size;
Vector3 vert;
vert = new Vector3(min.x, min.y, min.z);
vectors.Add(vert);
vert = new Vector3(min.x + s.x, min.y, min.z);
vectors.Add(vert);
vert = new Vector3(min.x, min.y, min.z + s.z);
vectors.Add(vert);
vert = new Vector3(min.x + s.x, min.y, min.z + s.z);
vectors.Add(vert);
vert = new Vector3(min.x, min.y + s.y, min.z);
vectors.Add(vert);
vert = new Vector3(min.x + s.x, min.y + s.y, min.z);
vectors.Add(vert);
vert = new Vector3(min.x, min.y + s.y, min.z + s.z);
vectors.Add(vert);
vert = new Vector3(min.x + s.x, min.y + s.y, min.z + s.z);
vectors.Add(vert);
}
///
/// Encapsulates a collection of vectors into a bounds.
///
/// The vectors to encapsulate.
/// Returns the bounds that contains the supplied vectors.
public static Bounds Encapsulate(List vectors)
{
var min = vectors[0];
var max = min;
// Iterate through all verts except first one
for (var i = 1; i < vectors.Count; i++)
{
var v = vectors[i];
max = Vector3.Max(v, max);
min = Vector3.Min(v, min);
}
var bounds = new Bounds();
bounds.SetMinMax(min, max);
return bounds;
}
///
/// Converts the properties of a BoxCollider into a bounds, in the objects local space.
///
/// The box collider to convert
/// Returns the bounds of the box collider
public static Bounds AsBounds(BoxCollider boxCollider)
{
var bounds = new Bounds(boxCollider.center, boxCollider.size);
return bounds;
}
///
/// Converts a local bounds into a bounds in slicer space (local space of the parent SlicerComponent).
///
/// The bounds to encapsulate into the returned bounds.
/// The transform of the GameObject that contains the mesh.
/// The transform of the GameObject containing the SlicerController.
/// The bounds that contains the bounds transformed extents.
public static Bounds CalculateBounds(Bounds bounds, Transform childTransform, Transform rootTransform)
{
var matrix = MatrixUtility.BuildTransformMatrix(childTransform, rootTransform);
GetVerts(bounds, TempCollections.Vector3);
var transformedBounds = VectorUtility.CalculateBounds(TempCollections.Vector3, matrix);
TempCollections.Vector3.Clear();
return transformedBounds;
}
}
}