From 550b99b3d79e272e5aa26bfffe74570170621c59 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Mon, 6 Mar 2023 17:44:40 +0800 Subject: [PATCH] Added a generic AABB class --- SHADE_Engine/src/Math/Geometry/SHAABB.cpp | 215 ++++++++++++++++++++++ SHADE_Engine/src/Math/Geometry/SHAABB.h | 172 +++++++++++++++++ 2 files changed, 387 insertions(+) create mode 100644 SHADE_Engine/src/Math/Geometry/SHAABB.cpp create mode 100644 SHADE_Engine/src/Math/Geometry/SHAABB.h diff --git a/SHADE_Engine/src/Math/Geometry/SHAABB.cpp b/SHADE_Engine/src/Math/Geometry/SHAABB.cpp new file mode 100644 index 00000000..9ec57073 --- /dev/null +++ b/SHADE_Engine/src/Math/Geometry/SHAABB.cpp @@ -0,0 +1,215 @@ +/**************************************************************************************** + * \file SHAABB.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHAABB.h" +// Project Headers +#include "Math/SHMathHelpers.h" +#include "Math/SHRay.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHAABB::SHAABB() noexcept + { + Center = SHVec3::Zero; + Extents = SHVec3::One * 0.5f; + } + + SHAABB::SHAABB(const SHVec3& c, const SHVec3& hE) noexcept + { + Center = c; + Extents = hE; + } + + + SHAABB::SHAABB(const SHAABB& rhs) noexcept + { + if (this == &rhs) + return; + + Center = rhs.Center; + Extents = rhs.Extents; + } + + SHAABB::SHAABB(SHAABB&& rhs) noexcept + { + Center = rhs.Center; + Extents = rhs.Extents; + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHAABB& SHAABB::operator=(const SHAABB& rhs) noexcept + { + Center = rhs.Center; + Extents = rhs.Extents; + + return *this; + } + + SHAABB& SHAABB::operator=(SHAABB&& rhs) noexcept + { + Center = rhs.Center; + Extents = rhs.Extents; + + return *this; + } + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec3 SHAABB::GetCenter() const noexcept + { + return Center; + } + + SHVec3 SHAABB::GetExtents() const noexcept + { + return Extents; + } + + SHVec3 SHAABB::GetMin() const noexcept + { + return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z }; + } + + SHVec3 SHAABB::GetMax() const noexcept + { + return SHVec3{ Center.x + Extents.x, Center.y + Extents.y, Center.z + Extents.z }; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHAABB::SetCenter(const SHVec3& newCenter) noexcept + { + Center = newCenter; + } + + void SHAABB::SetExtents(const SHVec3& newExtents) noexcept + { + Extents = newExtents; + } + + void SHAABB::SetMin(const SHVec3& min) noexcept + { + const SHVec3 MAX = GetMax(); + + Center = SHVec3::Lerp(min, MAX, 0.5f); + Extents = SHVec3::Abs((MAX - min) * 0.5f); + } + + void SHAABB::SetMax(const SHVec3& max) noexcept + { + const SHVec3 MIN = GetMin(); + + Center = SHVec3::Lerp(MIN, max, 0.5f); + Extents = SHVec3::Abs((max - MIN) * 0.5f); + } + + void SHAABB::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept + { + Center = SHVec3::Lerp(min, max, 0.5f); + Extents = SHVec3::Abs((max - min) * 0.5f); + } + + std::vector SHAABB::GetVertices() const noexcept + { + std::vector vertices{ 8 }; + GetCorners(vertices.data()); + return vertices; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHAABB::TestPoint(const SHVec3& point) const noexcept + { + return BoundingBox::Contains(point); + } + + SHRaycastResult SHAABB::Raycast(const SHRay& ray) const noexcept + { + SHRaycastResult result; + + result.hit = Intersects(ray.position, ray.direction, result.distance); + if (result.hit) + { + result.position = ray.position + ray.direction * result.distance; + result.angle = SHVec3::Angle(ray.position, result.position); + } + + return result; + } + + bool SHAABB::Contains(const SHAABB& rhs) const noexcept + { + return BoundingBox::Contains(rhs) == CONTAINS; + } + + float SHAABB::Volume() const noexcept + { + return 8.0f * (Extents.x * Extents.y * Extents.z); + } + + float SHAABB::SurfaceArea() const noexcept + { + return 8.0f * ((Extents.x * Extents.y) + + (Extents.x * Extents.z) + + (Extents.y * Extents.z)); + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHAABB SHAABB::Combine(const SHAABB& lhs, const SHAABB& rhs) noexcept + { + SHAABB result; + CreateMerged(result, lhs, rhs); + return result; + } + + bool SHAABB::Intersect(const SHAABB& lhs, const SHAABB& rhs) noexcept + { + return lhs.Intersects(rhs); + } + + SHAABB SHAABB::BuildFromBoxes(const SHAABB* boxes, size_t numBoxes) noexcept + { + SHAABB result; + + for (size_t i = 1; i < numBoxes; ++i) + CreateMerged(result, boxes[i - 1], boxes[i]); + + return result; + } + + SHAABB SHAABB::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept + { + SHAABB result; + CreateFromPoints(result, numVertices, vertices, stride); + return result; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Geometry/SHAABB.h b/SHADE_Engine/src/Math/Geometry/SHAABB.h new file mode 100644 index 00000000..36ae9aed --- /dev/null +++ b/SHADE_Engine/src/Math/Geometry/SHAABB.h @@ -0,0 +1,172 @@ +/**************************************************************************************** + * \file SHAABB.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a 3-Dimensional Axis Aligned Bounding Box + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "Math/SHRay.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + /** + * @brief + * Encapsulates a 3D Axis-Aligned Bounding Box. + */ + class SH_API SHAABB : private DirectX::BoundingBox + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t NUM_VERTICES = 8; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + ~SHAABB () noexcept = default; + + SHAABB () noexcept; + SHAABB (const SHVec3& center, const SHVec3& halfExtents) noexcept; + SHAABB (const SHAABB& rhs) noexcept; + SHAABB (SHAABB&& rhs) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHAABB& operator= (const SHAABB& rhs) noexcept; + SHAABB& operator= (SHAABB&& rhs) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHVec3 GetCenter () const noexcept; + [[nodiscard]] SHVec3 GetExtents () const noexcept; + [[nodiscard]] SHVec3 GetMin () const noexcept; + [[nodiscard]] SHVec3 GetMax () const noexcept; + [[nodiscard]] std::vector GetVertices () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + void SetCenter (const SHVec3& newCenter) noexcept; + void SetExtents (const SHVec3& newExtents) noexcept; + void SetMin (const SHVec3& min) noexcept; + void SetMax (const SHVec3& max) noexcept; + void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Member Functions */ + /*---------------------------------------------------------------------------------*/ + + /** + * @brief + * Checks if a point is inside the aabb. + * @param point + * The point to check. + * @return + * True if the point is inside the aabb. + */ + [[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept; + + /** + * @brief + * Casts a ray against the aabb. + * @param ray + * The ray to cast. + * @return + * The result of the raycast.
+ * See the corresponding header for the contents of the raycast result object. + */ + [[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept; + + /** + * @brief + * Checks if an entire other aabb is contained by this aabb. + * @param rhs + * The aabb to check. + * @return + * True if the other sphere is completely contained by this aabb. + */ + [[nodiscard]] bool Contains (const SHAABB& rhs) const noexcept; + + /** + * @brief + * Calculates the volume of the aabb. + */ + [[nodiscard]] float Volume () const noexcept; + + /** + * @brief + * Calculates the surface area of the aabb. + */ + [[nodiscard]] float SurfaceArea () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Static Member Functions */ + /*---------------------------------------------------------------------------------*/ + + /** + * @brief + * Combines two aabbs to form a larger aabb. + * If one aabb is completely contained by the other, the result is the larger aabb. + * @return + * The combined aabb. + */ + [[nodiscard]] static SHAABB Combine (const SHAABB& lhs, const SHAABB& rhs) noexcept; + + /** + * @brief + * Checks if two aabbs are intersecting. + * @return + * True if they are intersecting. + */ + [[nodiscard]] static bool Intersect (const SHAABB& lhs, const SHAABB& rhs) noexcept; + + /** + * @brief + * Builds a single aabb from multiple aabbs. + * @param spheres + * The set of aabbs to build from. + * @param numSpheres + * The number of aabbs in the set to build from. + * @return + * An aabb that contains all the spheres in the set. + */ + [[nodiscard]] static SHAABB BuildFromBoxes (const SHAABB* boxes, size_t numBoxes) noexcept; + + /** + * @brief + * Builds a aabb from a set of vertices. + * @param vertices + * The vertices to build a aabb from. + * @param numVertices + * The number of vertices in the set to build from. + * @param stride + * The stride between each vertex, in the instance there is data in between each + * vertex that does not define the geometry of the object. + * @return + * An aabb that contains all the vertices in the set. + */ + [[nodiscard]] static SHAABB BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept; + }; + + +} // namespace SHADE \ No newline at end of file