// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Platform/Platform.h" #include "Vector3.h" #include "Math.h" #include "CollisionsHelper.h" /// /// Represents a bounding sphere in three dimensional space. /// API_STRUCT() struct FLAXENGINE_API BoundingSphere { DECLARE_SCRIPTING_TYPE_MINIMAL(BoundingSphere); public: /// /// An empty bounding sphere (Center = 0 and Radius = 0). /// static const BoundingSphere Empty; public: /// /// The center of the sphere in three dimensional space. /// API_FIELD() Vector3 Center; /// /// The radius of the sphere. /// API_FIELD() Real Radius; public: /// /// Empty constructor. /// BoundingSphere() { } /// /// Initializes a new instance of the struct. /// /// The center of the sphere in three dimensional space. /// The radius of the sphere. BoundingSphere(const Vector3& center, Real radius) : Center(center) , Radius(radius) { } public: String ToString() const; public: FORCE_INLINE bool operator==(const BoundingSphere& other) const { return Center == other.Center && Radius == other.Radius; } FORCE_INLINE bool operator!=(const BoundingSphere& other) const { return Center != other.Center || Radius != other.Radius; } public: static bool NearEqual(const BoundingSphere& a, const BoundingSphere& b) { return Vector3::NearEqual(a.Center, b.Center) && Math::NearEqual(a.Radius, b.Radius); } static bool NearEqual(const BoundingSphere& a, const BoundingSphere& b, Real epsilon) { return Vector3::NearEqual(a.Center, b.Center, epsilon) && Math::NearEqual(a.Radius, b.Radius, epsilon); } public: /// /// Determines if there is an intersection between the current object and a Ray. /// /// The ray to test. /// Whether the two objects intersected. bool Intersects(const Ray& ray) const; /// /// Determines if there is an intersection between the current object and a Ray. /// /// The ray to test. /// When the method completes, contains the distance of the intersection, or 0 if there was no intersection. /// Whether the two objects intersected. bool Intersects(const Ray& ray, Real& distance) const; /// /// Determines if there is an intersection between the current object and a Ray. /// /// The ray to test. /// When the method completes, contains the distance of the intersection, or 0 if there was no intersection. /// When the method completes, contains the intersection surface normal vector, or Vector3::Up if there was no intersection. /// Whether the two objects intersected. bool Intersects(const Ray& ray, Real& distance, Vector3& normal) const; /// /// Determines if there is an intersection between the current object and a Ray. /// /// The ray to test. /// When the method completes, contains the point of intersection, or Vector3::Zero if there was no intersection. /// Whether the two objects intersected. bool Intersects(const Ray& ray, Vector3& point) const; /// /// Determines if there is an intersection between the current object and a Plane. /// /// The plane to test. /// Whether the two objects intersected. PlaneIntersectionType Intersects(const Plane& plane) const; /// /// Determines if there is an intersection between the current object and a triangle. /// /// The first vertex of the triangle to test. /// The second vertex of the triangle to test. /// The third vertex of the triangle to test. /// Whether the two objects intersected. bool Intersects(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const; /// /// Determines if there is an intersection between the current object and a Bounding Box. /// /// The box to test. /// Whether the two objects intersected. bool Intersects(const BoundingBox& box) const; /// /// Determines if there is an intersection between the current object and a Bounding Sphere. /// /// The sphere to test. /// Whether the two objects intersected. bool Intersects(const BoundingSphere& sphere) const; /// /// Determines whether the current objects contains a point. /// /// The point to test. /// The type of containment the two objects have. ContainmentType Contains(const Vector3& point) const; /// /// Determines whether the current objects contains a triangle. /// /// The first vertex of the triangle to test. /// The second vertex of the triangle to test. /// The third vertex of the triangle to test. /// The type of containment the two objects have. ContainmentType Contains(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3) const; /// /// Determines whether the current objects contains a Bounding Box /// /// The box to test. /// The type of containment the two objects have. ContainmentType Contains(const BoundingBox& box) const; /// /// Determines whether the current objects contains a Bounding Sphere. /// /// The sphere to test. /// The type of containment the two objects have. ContainmentType Contains(const BoundingSphere& sphere) const; public: /// /// Gets the box which contains whole sphere. /// /// The box. BoundingBox GetBoundingBox() const; /// /// Gets the box which contains whole sphere. /// /// The result box. void GetBoundingBox(BoundingBox& result) const; /// /// Constructs a BoundingSphere that fully contains the given points /// /// The points that will be contained by the sphere. /// The amount of points to use. /// When the method completes, contains the newly constructed bounding sphere. static void FromPoints(const Float3* points, int32 pointsCount, BoundingSphere& result); /// /// Constructs a BoundingSphere that fully contains the given points /// /// The points that will be contained by the sphere. /// The amount of points to use. /// When the method completes, contains the newly constructed bounding sphere. static void FromPoints(const Double3* points, int32 pointsCount, BoundingSphere& result); /// /// Constructs a Bounding Sphere from a given box. /// /// The box that will designate the extents of the sphere. /// When the method completes, the newly constructed bounding sphere. static void FromBox(const BoundingBox& box, BoundingSphere& result); /// /// Constructs a BoundingSphere that is the as large as the total combined area of the two specified spheres /// /// The first sphere to merge. /// The second sphere to merge. /// When the method completes, contains the newly constructed bounding sphere. static void Merge(const BoundingSphere& value1, const BoundingSphere& value2, BoundingSphere& result); /// /// Constructs a BoundingSphere that is the as large as the total combined area of the specified sphere and the point. /// /// The sphere to merge. /// The point to merge. /// When the method completes, contains the newly constructed bounding sphere. static void Merge(const BoundingSphere& value1, const Vector3& value2, BoundingSphere& result); /// /// Transforms the bounding sphere using the specified matrix. /// /// The sphere. /// The matrix. /// The result transformed sphere. static void Transform(const BoundingSphere& sphere, const Matrix& matrix, BoundingSphere& result); }; template<> struct TIsPODType { enum { Value = true }; }; DEFINE_DEFAULT_FORMATTING(BoundingSphere, "Center:{0} Radius:{1}", v.Center, v.Radius);