using System.Data.SqlTypes; using System.Collections.Generic; using UnityEngine; namespace Rokid.UXR.Utility { /// /// Bounds related utilities /// public static class BoundsUtils { // Local method use only -- created here to reduce garbage collection. Collections must be cleared before use static readonly List k_Renderers = new List(); static readonly List k_Transforms = new List(); /// /// Get the aggregated bounds of a list of GameObjects and their children /// /// The list of GameObjects /// The aggregated bounds public static Bounds GetBounds(List gameObjects) { Bounds? bounds = null; foreach (var gameObject in gameObjects) { var goBounds = GetBounds(gameObject.transform); if (!bounds.HasValue) { bounds = goBounds; } else { goBounds.Encapsulate(bounds.Value); bounds = goBounds; } } return bounds ?? new Bounds(); } /// /// Get the aggregated bounds of an array of transforms and their children /// /// The array of transforms /// The aggregated bounds public static Bounds GetBounds(Transform[] transforms) { Bounds? bounds = null; foreach (var t in transforms) { var goBounds = GetBounds(t); if (!bounds.HasValue) { bounds = goBounds; } else { goBounds.Encapsulate(bounds.Value); bounds = goBounds; } } return bounds ?? new Bounds(); } /// /// Get the aggregated bounds of a transform and its children /// /// The transform /// The aggregated bounds public static Bounds GetBounds(Transform transform) { // Static collections used below are cleared by the methods that use them transform.GetComponentsInChildren(k_Renderers); var b = GetBounds(k_Renderers); // As a fallback when there are no bounds, collect all transform positions if (b.size == Vector3.zero) { transform.GetComponentsInChildren(k_Transforms); if (k_Transforms.Count > 0) b.center = k_Transforms[0].position; foreach (var t in k_Transforms) { b.Encapsulate(t.position); } } return b; } /// /// Get the aggregated bounds of a list of renderers /// /// The list of renderers /// The aggregated bounds public static Bounds GetBounds(List renderers) { if (renderers.Count > 0) { var first = renderers[0]; var b = new Bounds(first.transform.position, Vector3.zero); foreach (var r in renderers) { if (r.bounds.size != Vector3.zero) b.Encapsulate(r.bounds); } return b; } return default; } #if INCLUDE_PHYSICS_MODULE /// /// Get the aggregated bounds of a list of colliders /// /// The list of colliders /// The type of object in the list of colliders /// The aggregated bounds public static Bounds GetBounds(List colliders) where T : Collider { if (colliders.Count > 0) { var first = colliders[0]; var b = new Bounds(first.transform.position, Vector3.zero); foreach (var c in colliders) { if (c.bounds.size != Vector3.zero) b.Encapsulate(c.bounds); } return b; } return default; } #endif /// /// Gets the bounds that encapsulate a list of points /// /// The list of points to encapsulate /// The aggregated bounds public static Bounds GetBounds(List points) { var bounds = default(Bounds); if (points.Count < 1) return bounds; var minPoint = points[0]; var maxPoint = minPoint; for (var i = 1; i < points.Count; ++i) { var point = points[i]; if (point.x < minPoint.x) minPoint.x = point.x; if (point.y < minPoint.y) minPoint.y = point.y; if (point.z < minPoint.z) minPoint.z = point.z; if (point.x > maxPoint.x) maxPoint.x = point.x; if (point.y > maxPoint.y) maxPoint.y = point.y; if (point.z > maxPoint.z) maxPoint.z = point.z; } bounds.SetMinMax(minPoint, maxPoint); return bounds; } /// /// Gets the bounds that encapsulate a array of points /// /// The list of points to encapsulate /// The aggregated bounds public static Bounds GetBounds(Vector3[] points) { var bounds = default(Bounds); if (points.Length < 1) return bounds; var minPoint = points[0]; var maxPoint = minPoint; for (var i = 1; i < points.Length; ++i) { var point = points[i]; if (point.x < minPoint.x) minPoint.x = point.x; if (point.y < minPoint.y) minPoint.y = point.y; if (point.z < minPoint.z) minPoint.z = point.z; if (point.x > maxPoint.x) maxPoint.x = point.x; if (point.y > maxPoint.y) maxPoint.y = point.y; if (point.z > maxPoint.z) maxPoint.z = point.z; } bounds.SetMinMax(minPoint, maxPoint); return bounds; } } }