Skip to content

Commit

Permalink
Added a new Calculate Bounds extension and updated documentation for all
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonDarksideJ committed Oct 18, 2023
1 parent 2bca868 commit 90fbee6
Showing 1 changed file with 88 additions and 59 deletions.
147 changes: 88 additions & 59 deletions Runtime/Extensions/BoundsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ public static class BoundsExtensions
#region Public Static Functions

/// <summary>
/// Returns an instance of the 'Bounds' class which is invalid. An invalid 'Bounds' instance
/// is one which has its size vector set to 'float.MaxValue' for all 3 components. The center
/// of an invalid bounds instance is the zero vector.
/// Returns an instance of the <see cref="Bounds"/> class which is invalid.
/// An invalid <see cref="Bounds"/> instance is one which has its size vector set to 'float.MaxValue' for all 3 components.
/// The center of an invalid bounds instance is the zero vector.
/// </summary>
/// <returns>Returns an instance of the <see cref="Bounds"/> class which is invalid.</returns>
public static Bounds GetInvalidBoundsInstance()
{
return new Bounds(Vector3.zero, GetInvalidBoundsSize());
Expand All @@ -80,6 +81,7 @@ public static Bounds GetInvalidBoundsInstance()
/// Checks if the specified bounds instance is valid. A valid 'Bounds' instance is
/// one whose size vector does not have all 3 components set to 'float.MaxValue'.
/// </summary>
/// <param name="bounds">The input bounding volume.</param>
public static bool IsValid(this Bounds bounds)
{
return bounds.size != GetInvalidBoundsSize();
Expand All @@ -88,9 +90,9 @@ public static bool IsValid(this Bounds bounds)
/// <summary>
/// Gets all the corner points of the bounds in world space.
/// </summary>
/// <param name="transform"></param>
/// <param name="positions"></param>
/// <param name="bounds"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transform">A relative transform point.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
public static void GetCornerPositionsWorldSpace(this Bounds bounds, Transform transform, ref Vector3[] positions)
{
// Calculate the local points to transform.
Expand Down Expand Up @@ -125,8 +127,8 @@ public static void GetCornerPositionsWorldSpace(this Bounds bounds, Transform tr
/// <summary>
/// Gets all the corner points of the bounds in local space.
/// </summary>
/// <param name="positions"></param>
/// <param name="bounds"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
public static void GetCornerPositionsLocalSpace(this Bounds bounds, ref Vector3[] positions)
{
// Allocate the array if needed.
Expand All @@ -153,8 +155,8 @@ public static void GetCornerPositionsLocalSpace(this Bounds bounds, ref Vector3[
/// <summary>
/// Gets all the corner points of the bounds.
/// </summary>
/// <param name="bounds"></param>
/// <param name="positions"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
/// <remarks>
/// <see cref="Collider.bounds"/> is world space bounding volume.
/// <see cref="Mesh.bounds"/> is local space bounding volume.
Expand Down Expand Up @@ -188,6 +190,12 @@ public static void GetCornerPositions(this Bounds bounds, ref Vector3[] position
positions[RTB] = new Vector3(rightEdge, topEdge, backEdge);
}

/// <summary>
/// Gets all the face points of the bounds.
/// </summary>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transform">A relative transform point.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
public static void GetFacePositions(this Bounds bounds, Transform transform, ref Vector3[] positions)
{
const int numPoints = 6;
Expand All @@ -211,9 +219,9 @@ public static void GetFacePositions(this Bounds bounds, Transform transform, ref
/// <summary>
/// Gets all the corner points and mid points from Bounds
/// </summary>
/// <param name="bounds"></param>
/// <param name="transform"></param>
/// <param name="positions"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transform">A relative transform point.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
public static void GetCornerAndMidPointPositions(this Bounds bounds, Transform transform, ref Vector3[] positions)
{
// Calculate the local points to transform.
Expand Down Expand Up @@ -262,10 +270,10 @@ public static void GetCornerAndMidPointPositions(this Bounds bounds, Transform t
/// <summary>
/// Gets all the corner points and mid points from Bounds, ignoring the z axis
/// </summary>
/// <param name="bounds"></param>
/// <param name="transform"></param>
/// <param name="positions"></param>
/// <param name="flattenAxis"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transform">A relative transform point.</param>
/// <param name="positions">A reference <see cref="Vector3"/> array of 8 points to populate.</param>
/// <param name="flattenAxis">The <see cref="CardinalAxis"/> to flatten the points against.</param>
public static void GetCornerAndMidPointPositions2D(this Bounds bounds, Transform transform, ref Vector3[] positions, CardinalAxis flattenAxis)
{
// Calculate the local points to transform.
Expand Down Expand Up @@ -334,9 +342,9 @@ public static void GetCornerAndMidPointPositions2D(this Bounds bounds, Transform
/// Method to get bounding box points using Collider method.
/// </summary>
/// <param name="target">gameObject that boundingBox bounds.</param>
/// <param name="boundsPoints">array reference that gets filled with points</param>
/// <param name="ignoreLayers">layerMask to simplify search</param>
/// <param name="colliders">The colliders to use for calculating the bounds of this gameObject</param>
/// <param name="boundsPoints">array reference that gets filled with points.</param>
/// <param name="ignoreLayers">layerMask to simplify search.</param>
/// <param name="colliders">The colliders to use for calculating the bounds of this gameObject.</param>
public static void GetColliderBoundsPoints(GameObject target, ref List<Vector3> boundsPoints, LayerMask ignoreLayers, Collider[] colliders = null)
{
if (colliders == null)
Expand Down Expand Up @@ -400,10 +408,10 @@ public static void GetColliderBoundsPoints(GameObject target, ref List<Vector3>
/// <summary>
/// GetRenderBoundsPoints gets bounding box points using Render method.
/// </summary>
/// <param name="target">gameObject that bounding box bounds</param>
/// <param name="boundsPoints">array reference that gets filled with points</param>
/// <param name="ignoreLayers">layerMask to simplify search</param>
/// <param name="renderers">The renderers to use for calculating the bounds of this gameObject</param>
/// <param name="target">gameObject that bounding box bounds.</param>
/// <param name="boundsPoints">array reference that gets filled with points.</param>
/// <param name="ignoreLayers">layerMask to simplify search.</param>
/// <param name="renderers">The renderers to use for calculating the bounds of this gameObject.</param>
public static void GetRenderBoundsPoints(GameObject target, ref List<Vector3> boundsPoints, LayerMask ignoreLayers, Renderer[] renderers = null)
{
if (renderers == null)
Expand All @@ -430,10 +438,10 @@ public static void GetRenderBoundsPoints(GameObject target, ref List<Vector3> bo
/// <summary>
/// GetMeshFilterBoundsPoints - gets bounding box points using MeshFilter method.
/// </summary>
/// <param name="target">gameObject that bounding box bounds</param>
/// <param name="boundsPoints">array reference that gets filled with points</param>
/// <param name="ignoreLayers">layerMask to simplify search</param>
/// <param name="meshFilters">The mesh filters to use for calculating the bounds of this gameObject</param>
/// <param name="target">gameObject that bounding box bounds.</param>
/// <param name="boundsPoints">array reference that gets filled with points.</param>
/// <param name="ignoreLayers">layerMask to simplify search.</param>
/// <param name="meshFilters">The mesh filters to use for calculating the bounds of this gameObject.</param>
public static void GetMeshFilterBoundsPoints(GameObject target, ref List<Vector3> boundsPoints, LayerMask ignoreLayers, MeshFilter[] meshFilters = null)
{
if (meshFilters == null)
Expand Down Expand Up @@ -465,25 +473,15 @@ public static void GetMeshFilterBoundsPoints(GameObject target, ref List<Vector3
}

/// <summary>
/// Transforms 'bounds' using the specified transform matrix.
/// Transforms <see cref="Bounds"/> using the specified transform matrix.
/// </summary>
/// <remarks>
/// Transforming a 'Bounds' instance means that the function will construct a new 'Bounds'
/// instance which has its center translated using the translation information stored in
/// the specified matrix and its size adjusted to account for rotation and scale. The size
/// of the new 'Bounds' instance will be calculated in such a way that it will contain the
/// old 'Bounds'.
/// Transforming a <see cref="Bounds"/> instance means that the function will construct a new <see cref="Bounds"/> instance which has its center translated using the translation information stored in the specified matrix and its size adjusted to account for rotation and scale.
/// The size of the new <see cref="Bounds"/> instance will be calculated in such a way that it will contain the old <see cref="Bounds"/>.
/// </remarks>
/// <param name="bounds">
/// The 'Bounds' instance which must be transformed.
/// </param>
/// <param name="transformMatrix">
/// The specified 'Bounds' instance will be transformed using this transform matrix. The function
/// assumes that the matrix doesn't contain any projection or skew transformation.
/// </param>
/// <returns>
/// The transformed 'Bounds' instance.
/// </returns>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transformMatrix">The specified <see cref="Bounds"/> instance will be transformed using this transform matrix. The function assumes that the matrix does not contain any projection or skew transformation.</param>
/// <returns>The transformed <see cref="Bounds"/> instance.</returns>
public static Bounds Transform(this Bounds bounds, Matrix4x4 transformMatrix)
{
// We will need access to the right, up and look vector which are encoded inside the transform matrix
Expand Down Expand Up @@ -519,11 +517,9 @@ public static Bounds Transform(this Bounds bounds, Matrix4x4 transformMatrix)
/// <summary>
/// Returns the screen space corner points of the specified 'Bounds' instance.
/// </summary>
/// <param name="bounds"></param>
/// <param name="camera">
/// The camera used for rendering to the screen. This is needed to perform the
/// transformation to screen space.
/// </param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="camera">The camera used for rendering to the screen. This is needed to perform the transformation to screen space.</param>
/// <returns>An array of screen points for the camera corners.</returns>
public static Vector2[] GetScreenSpaceCornerPoints(this Bounds bounds, Camera camera)
{
var aabbCenter = bounds.center;
Expand All @@ -544,9 +540,13 @@ public static Vector2[] GetScreenSpaceCornerPoints(this Bounds bounds, Camera ca
};
}


/// <summary>
/// Returns the rectangle which encloses the specifies 'Bounds' instance in screen space.
/// </summary>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="camera">The camera volume to calculate bounds from.</param>
/// <returns>Returns a <see cref="Rect"/> for the encapsulated screen</returns>
public static Rect GetScreenRectangle(this Bounds bounds, Camera camera)
{
// Retrieve the bounds' corner points in screen space
Expand All @@ -568,8 +568,8 @@ public static Rect GetScreenRectangle(this Bounds bounds, Camera camera)
/// <summary>
/// Returns the volume of the bounds.
/// </summary>
/// <param name="bounds"></param>
/// <returns></returns>
/// <param name="bounds">The input bounding volume.</param>
/// <returns>A <see cref="float"/> representation of the volume.</returns>
public static float Volume(this Bounds bounds)
{
return bounds.size.x * bounds.size.y * bounds.size.z;
Expand All @@ -578,9 +578,9 @@ public static float Volume(this Bounds bounds)
/// <summary>
/// Returns bounds that contain both this bounds and the bounds passed in.
/// </summary>
/// <param name="originalBounds"></param>
/// <param name="otherBounds"></param>
/// <returns></returns>
/// <param name="originalBounds">The original bounding area.</param>
/// <param name="otherBounds">The additional bounded area to expand the original bounds with.</param>
/// <returns>Returns the collective <see cref="Bounds"/> volume.</returns>
public static Bounds ExpandToContain(this Bounds originalBounds, Bounds otherBounds)
{
var tmpBounds = originalBounds;
Expand All @@ -591,8 +591,8 @@ public static Bounds ExpandToContain(this Bounds originalBounds, Bounds otherBou
/// <summary>
/// Checks to see if bounds contains the other bounds completely.
/// </summary>
/// <param name="bounds"></param>
/// <param name="otherBounds"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="otherBounds">The testing bounding volume for contact.</param>
/// <returns></returns>
public static bool ContainsBounds(this Bounds bounds, Bounds otherBounds)
{
Expand All @@ -602,9 +602,9 @@ public static bool ContainsBounds(this Bounds bounds, Bounds otherBounds)
/// <summary>
/// Checks to see whether point is closer to bounds or otherBounds
/// </summary>
/// <param name="bounds"></param>
/// <param name="point"></param>
/// <param name="otherBounds"></param>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="point">The point to test against.</param>
/// <param name="otherBounds">The comparative bounds volume to compare against.</param>
/// <returns></returns>
public static bool CloserToPoint(this Bounds bounds, Vector3 point, Bounds otherBounds)
{
Expand All @@ -622,6 +622,35 @@ public static bool CloserToPoint(this Bounds bounds, Vector3 point, Bounds other
return (distToClosestPoint1.magnitude <= distToClosestPoint2.magnitude);
}

/// <summary>
/// Returns the bounds of the model and all its contained meshes.
/// </summary>
/// <param name="bounds">The input bounding volume.</param>
/// <param name="transform">The target transform to inspect and calculate the bounds from.</param>
/// <param name="includeInactive">Should the mesh query also include inactive components/objects.</param>
/// <returns>Returns a <see cref="Bounds"/> object with the updated bounds (used to apply to the Size and Center points of a bounding volume)</returns>
public static Bounds CalculateBoundsForModel(this Bounds bounds, Transform transform, bool includeInactive = false)
{
var renderers = transform.GetComponentsInChildren<Renderer>(includeInactive);

if (renderers.Length > 0)
{
bounds = renderers[0].bounds;

for (int i = 1; i < renderers.Length; i++)
{
bounds.Encapsulate(renderers[i].bounds);
}
}

foreach (Transform child in transform)
{
bounds.CalculateBoundsForModel(child);
}

return bounds;
}

#endregion

#region Private Static Functions
Expand Down

0 comments on commit 90fbee6

Please sign in to comment.