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