// 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; } } }