BoundsUtils.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. using System.Data.SqlTypes;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace Rokid.UXR.Utility
  5. {
  6. /// <summary>
  7. /// Bounds related utilities
  8. /// </summary>
  9. public static class BoundsUtils
  10. {
  11. // Local method use only -- created here to reduce garbage collection. Collections must be cleared before use
  12. static readonly List<Renderer> k_Renderers = new List<Renderer>();
  13. static readonly List<Transform> k_Transforms = new List<Transform>();
  14. /// <summary>
  15. /// Get the aggregated bounds of a list of GameObjects and their children
  16. /// </summary>
  17. /// <param name="gameObjects">The list of GameObjects</param>
  18. /// <returns>The aggregated bounds</returns>
  19. public static Bounds GetBounds(List<GameObject> gameObjects)
  20. {
  21. Bounds? bounds = null;
  22. foreach (var gameObject in gameObjects)
  23. {
  24. var goBounds = GetBounds(gameObject.transform);
  25. if (!bounds.HasValue)
  26. {
  27. bounds = goBounds;
  28. }
  29. else
  30. {
  31. goBounds.Encapsulate(bounds.Value);
  32. bounds = goBounds;
  33. }
  34. }
  35. return bounds ?? new Bounds();
  36. }
  37. /// <summary>
  38. /// Get the aggregated bounds of an array of transforms and their children
  39. /// </summary>
  40. /// <param name="transforms">The array of transforms</param>
  41. /// <returns>The aggregated bounds</returns>
  42. public static Bounds GetBounds(Transform[] transforms)
  43. {
  44. Bounds? bounds = null;
  45. foreach (var t in transforms)
  46. {
  47. var goBounds = GetBounds(t);
  48. if (!bounds.HasValue)
  49. {
  50. bounds = goBounds;
  51. }
  52. else
  53. {
  54. goBounds.Encapsulate(bounds.Value);
  55. bounds = goBounds;
  56. }
  57. }
  58. return bounds ?? new Bounds();
  59. }
  60. /// <summary>
  61. /// Get the aggregated bounds of a transform and its children
  62. /// </summary>
  63. /// <param name="transform">The transform</param>
  64. /// <returns>The aggregated bounds</returns>
  65. public static Bounds GetBounds(Transform transform)
  66. {
  67. // Static collections used below are cleared by the methods that use them
  68. transform.GetComponentsInChildren(k_Renderers);
  69. var b = GetBounds(k_Renderers);
  70. // As a fallback when there are no bounds, collect all transform positions
  71. if (b.size == Vector3.zero)
  72. {
  73. transform.GetComponentsInChildren(k_Transforms);
  74. if (k_Transforms.Count > 0)
  75. b.center = k_Transforms[0].position;
  76. foreach (var t in k_Transforms)
  77. {
  78. b.Encapsulate(t.position);
  79. }
  80. }
  81. return b;
  82. }
  83. /// <summary>
  84. /// Get the aggregated bounds of a list of renderers
  85. /// </summary>
  86. /// <param name="renderers">The list of renderers</param>
  87. /// <returns>The aggregated bounds</returns>
  88. public static Bounds GetBounds(List<Renderer> renderers)
  89. {
  90. if (renderers.Count > 0)
  91. {
  92. var first = renderers[0];
  93. var b = new Bounds(first.transform.position, Vector3.zero);
  94. foreach (var r in renderers)
  95. {
  96. if (r.bounds.size != Vector3.zero)
  97. b.Encapsulate(r.bounds);
  98. }
  99. return b;
  100. }
  101. return default;
  102. }
  103. #if INCLUDE_PHYSICS_MODULE
  104. /// <summary>
  105. /// Get the aggregated bounds of a list of colliders
  106. /// </summary>
  107. /// <param name="colliders">The list of colliders</param>
  108. /// <typeparam name="T">The type of object in the list of colliders</typeparam>
  109. /// <returns>The aggregated bounds</returns>
  110. public static Bounds GetBounds<T>(List<T> colliders) where T : Collider
  111. {
  112. if (colliders.Count > 0)
  113. {
  114. var first = colliders[0];
  115. var b = new Bounds(first.transform.position, Vector3.zero);
  116. foreach (var c in colliders)
  117. {
  118. if (c.bounds.size != Vector3.zero)
  119. b.Encapsulate(c.bounds);
  120. }
  121. return b;
  122. }
  123. return default;
  124. }
  125. #endif
  126. /// <summary>
  127. /// Gets the bounds that encapsulate a list of points
  128. /// </summary>
  129. /// <param name="points">The list of points to encapsulate</param>
  130. /// <returns>The aggregated bounds</returns>
  131. public static Bounds GetBounds(List<Vector3> points)
  132. {
  133. var bounds = default(Bounds);
  134. if (points.Count < 1)
  135. return bounds;
  136. var minPoint = points[0];
  137. var maxPoint = minPoint;
  138. for (var i = 1; i < points.Count; ++i)
  139. {
  140. var point = points[i];
  141. if (point.x < minPoint.x)
  142. minPoint.x = point.x;
  143. if (point.y < minPoint.y)
  144. minPoint.y = point.y;
  145. if (point.z < minPoint.z)
  146. minPoint.z = point.z;
  147. if (point.x > maxPoint.x)
  148. maxPoint.x = point.x;
  149. if (point.y > maxPoint.y)
  150. maxPoint.y = point.y;
  151. if (point.z > maxPoint.z)
  152. maxPoint.z = point.z;
  153. }
  154. bounds.SetMinMax(minPoint, maxPoint);
  155. return bounds;
  156. }
  157. /// <summary>
  158. /// Gets the bounds that encapsulate a array of points
  159. /// </summary>
  160. /// <param name="points">The list of points to encapsulate</param>
  161. /// <returns>The aggregated bounds</returns>
  162. public static Bounds GetBounds(Vector3[] points)
  163. {
  164. var bounds = default(Bounds);
  165. if (points.Length < 1)
  166. return bounds;
  167. var minPoint = points[0];
  168. var maxPoint = minPoint;
  169. for (var i = 1; i < points.Length; ++i)
  170. {
  171. var point = points[i];
  172. if (point.x < minPoint.x)
  173. minPoint.x = point.x;
  174. if (point.y < minPoint.y)
  175. minPoint.y = point.y;
  176. if (point.z < minPoint.z)
  177. minPoint.z = point.z;
  178. if (point.x > maxPoint.x)
  179. maxPoint.x = point.x;
  180. if (point.y > maxPoint.y)
  181. maxPoint.y = point.y;
  182. if (point.z > maxPoint.z)
  183. maxPoint.z = point.z;
  184. }
  185. bounds.SetMinMax(minPoint, maxPoint);
  186. return bounds;
  187. }
  188. }
  189. }