Implemented a custom physics engine #316
|
@ -106,7 +106,7 @@
|
||||||
Components:
|
Components:
|
||||||
Transform Component:
|
Transform Component:
|
||||||
Translate: {x: 0, y: 5, z: 0}
|
Translate: {x: 0, y: 5, z: 0}
|
||||||
Rotate: {x: -0, y: 0, z: -0}
|
Rotate: {x: -0, y: 0, z: 0}
|
||||||
Scale: {x: 1, y: 1, z: 1}
|
Scale: {x: 1, y: 1, z: 1}
|
||||||
IsActive: true
|
IsActive: true
|
||||||
RigidBody Component:
|
RigidBody Component:
|
||||||
|
@ -130,8 +130,7 @@
|
||||||
DrawColliders: false
|
DrawColliders: false
|
||||||
Colliders:
|
Colliders:
|
||||||
- Is Trigger: false
|
- Is Trigger: false
|
||||||
Type: Sphere
|
Type: Box
|
||||||
Radius: 1
|
|
||||||
Friction: 0.400000006
|
Friction: 0.400000006
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
|
|
|
@ -344,24 +344,24 @@ namespace SHADE
|
||||||
//collider->IsTrigger
|
//collider->IsTrigger
|
||||||
if (shape->GetType() == SHCollisionShape::Type::BOX)
|
if (shape->GetType() == SHCollisionShape::Type::BOX)
|
||||||
{
|
{
|
||||||
//SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Box #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
//
|
|
||||||
//const auto* BOX = reinterpret_cast<const SHAABB*>(collider->GetShape());
|
auto* box = reinterpret_cast<SHBoxCollisionShape*>(shape);
|
||||||
//SHEditorWidgets::DragVec3
|
SHEditorWidgets::DragVec3
|
||||||
//(
|
(
|
||||||
// "Half Extents", { "X", "Y", "Z" },
|
"Half Extents", { "X", "Y", "Z" },
|
||||||
// [BOX] { return BOX->GetRelativeExtents(); },
|
[box] { return box->GetRelativeExtents(); },
|
||||||
// [collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
|
[box](SHVec3 const& vec) { box->SetRelativeExtents(vec); });
|
||||||
}
|
}
|
||||||
else if (shape->GetType() == SHCollisionShape::Type::SPHERE)
|
else if (shape->GetType() == SHCollisionShape::Type::SPHERE)
|
||||||
{
|
{
|
||||||
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
SHEditorWidgets::BeginPanel(std::format("{} Sphere #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
|
||||||
auto* SPHERE = reinterpret_cast<SHSphereCollisionShape*>(shape);
|
auto* sphere = reinterpret_cast<SHSphereCollisionShape*>(shape);
|
||||||
SHEditorWidgets::DragFloat
|
SHEditorWidgets::DragFloat
|
||||||
(
|
(
|
||||||
"Radius",
|
"Radius",
|
||||||
[SPHERE] { return SPHERE->GetRelativeRadius(); },
|
[sphere] { return sphere->GetRelativeRadius(); },
|
||||||
[SPHERE](float const& value) { SPHERE->SetRelativeRadius(value); });
|
[sphere](float const& value) { sphere->SetRelativeRadius(value); });
|
||||||
}
|
}
|
||||||
else if (shape->GetType() == SHCollisionShape::Type::CAPSULE)
|
else if (shape->GetType() == SHCollisionShape::Type::CAPSULE)
|
||||||
{
|
{
|
||||||
|
@ -410,7 +410,7 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable("Box Collider"))
|
if (ImGui::Selectable("Box Collider"))
|
||||||
{
|
{
|
||||||
//component->AddBoundingBox();
|
component->GetCollider()->AddBoxCollisionShape(SHVec3::One);
|
||||||
}
|
}
|
||||||
if (ImGui::Selectable("Sphere Collider"))
|
if (ImGui::Selectable("Sphere Collider"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHBox.cpp
|
* \file SHAABB.cpp
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
|
* \brief Implementation for a 3-Dimensional Axis Aligned Bounding Box
|
||||||
*
|
*
|
||||||
|
@ -26,12 +26,12 @@ namespace SHADE
|
||||||
|
|
||||||
SHAABB::SHAABB() noexcept
|
SHAABB::SHAABB() noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::AABB;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHAABB::SHAABB(const SHVec3& c, const SHVec3& hE) noexcept
|
SHAABB::SHAABB(const SHVec3& c, const SHVec3& hE) noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::AABB;
|
||||||
|
|
||||||
Center = c;
|
Center = c;
|
||||||
Extents = hE;
|
Extents = hE;
|
||||||
|
@ -43,7 +43,7 @@ namespace SHADE
|
||||||
if (this == &rhs)
|
if (this == &rhs)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
type = Type::BOX;
|
type = Type::AABB;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
@ -51,7 +51,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHAABB::SHAABB(SHAABB&& rhs) noexcept
|
SHAABB::SHAABB(SHAABB&& rhs) noexcept
|
||||||
{
|
{
|
||||||
type = Type::BOX;
|
type = Type::AABB;
|
||||||
|
|
||||||
Center = rhs.Center;
|
Center = rhs.Center;
|
||||||
Extents = rhs.Extents;
|
Extents = rhs.Extents;
|
||||||
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHAABB& SHAABB::operator=(const SHAABB& rhs) noexcept
|
SHAABB& SHAABB::operator=(const SHAABB& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (rhs.type != Type::BOX)
|
if (rhs.type != Type::AABB)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ namespace SHADE
|
||||||
|
|
||||||
SHAABB& SHAABB::operator=(SHAABB&& rhs) noexcept
|
SHAABB& SHAABB::operator=(SHAABB&& rhs) noexcept
|
||||||
{
|
{
|
||||||
if (rhs.type != Type::BOX)
|
if (rhs.type != Type::AABB)
|
||||||
{
|
{
|
||||||
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ namespace SHADE
|
||||||
return Center;
|
return Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHVec3 SHAABB::GetWorldExtents() const noexcept
|
SHVec3 SHAABB::GetExtents() const noexcept
|
||||||
{
|
{
|
||||||
return Extents;
|
return Extents;
|
||||||
}
|
}
|
||||||
|
@ -124,9 +124,9 @@ namespace SHADE
|
||||||
Center = newCenter;
|
Center = newCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAABB::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
void SHAABB::SetExtents(const SHVec3& newHalfExtents) noexcept
|
||||||
{
|
{
|
||||||
Extents = newWorldExtents;
|
Extents = newHalfExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAABB::SetMin(const SHVec3& min) noexcept
|
void SHAABB::SetMin(const SHVec3& min) noexcept
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/****************************************************************************************
|
/****************************************************************************************
|
||||||
* \file SHBox.h
|
* \file SHAABB.h
|
||||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
* \brief Interface for a 3-Dimensional Axis Aligned Bounding Box
|
||||||
*
|
*
|
||||||
|
@ -54,21 +54,21 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
[[nodiscard]] SHVec3 GetExtents () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
[[nodiscard]] SHVec3 GetMin () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
[[nodiscard]] SHVec3 GetMax () const noexcept;
|
||||||
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetCenter (const SHVec3& newCenter) noexcept;
|
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||||
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
void SetExtents (const SHVec3& newHalfExtents) noexcept;
|
||||||
void SetMin (const SHVec3& min) noexcept;
|
void SetMin (const SHVec3& min) noexcept;
|
||||||
void SetMax (const SHVec3& max) noexcept;
|
void SetMax (const SHVec3& max) noexcept;
|
||||||
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
void SetMinMax (const SHVec3& min, const SHVec3& max) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHBox.cpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for a 3-Dimensional Oriented 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 <SHpch.h>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHBox.h"
|
||||||
|
// Project Headers
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Math/SHRay.h"
|
||||||
|
#include "Math/SHQuaternion.h"
|
||||||
|
|
||||||
|
using namespace DirectX;
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBox::SHBox() noexcept
|
||||||
|
{
|
||||||
|
type = Type::BOX;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBox::SHBox(const SHVec3& c, const SHVec3& hE, const SHQuaternion& o) noexcept
|
||||||
|
{
|
||||||
|
type = Type::BOX;
|
||||||
|
|
||||||
|
Center = c;
|
||||||
|
Extents = hE;
|
||||||
|
Orientation = o;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SHBox::SHBox(const SHBox& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return;
|
||||||
|
|
||||||
|
type = Type::BOX;
|
||||||
|
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBox::SHBox(SHBox&& rhs) noexcept
|
||||||
|
{
|
||||||
|
type = Type::BOX;
|
||||||
|
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overload Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBox& SHBox::operator=(const SHBox& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (rhs.type != Type::BOX)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||||
|
}
|
||||||
|
else if (this != &rhs)
|
||||||
|
{
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBox& SHBox::operator=(SHBox&& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (rhs.type != Type::BOX)
|
||||||
|
{
|
||||||
|
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
std::vector<SHVec3> SHBox::GetVertices() const noexcept
|
||||||
|
{
|
||||||
|
std::vector<SHVec3> vertices;
|
||||||
|
vertices.resize(8);
|
||||||
|
GetCorners(vertices.data());
|
||||||
|
return vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Public Function Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHBox::TestPoint(const SHVec3& point) const noexcept
|
||||||
|
{
|
||||||
|
return BoundingOrientedBox::Contains(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRaycastResult SHBox::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 SHBox::Contains(const SHBox& rhs) const noexcept
|
||||||
|
{
|
||||||
|
return BoundingOrientedBox::Contains(rhs) == CONTAINS;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHBox::Volume() const noexcept
|
||||||
|
{
|
||||||
|
return 8.0f * (Extents.x * Extents.y * Extents.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHBox::SurfaceArea() const noexcept
|
||||||
|
{
|
||||||
|
return 8.0f * ((Extents.x * Extents.y)
|
||||||
|
+ (Extents.x * Extents.z)
|
||||||
|
+ (Extents.y * Extents.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Function Member Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
bool SHBox::Intersect(const SHBox& lhs, const SHBox& rhs) noexcept
|
||||||
|
{
|
||||||
|
return lhs.Intersects(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBox SHBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
|
||||||
|
{
|
||||||
|
SHBox result;
|
||||||
|
CreateFromPoints(result, numVertices, vertices, stride);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,135 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHBox.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a 3-Dimensional Oriented 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 <DirectXCollision.h>
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "SHShape.h"
|
||||||
|
#include "SH_API.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class SH_API SHBox : public SHShape,
|
||||||
|
public DirectX::BoundingOrientedBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static constexpr size_t NUM_VERTICES = 8;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
~SHBox () override = default;
|
||||||
|
|
||||||
|
SHBox () noexcept;
|
||||||
|
SHBox (const SHVec3& center, const SHVec3& halfExtents, const SHQuaternion& orientation) noexcept;
|
||||||
|
SHBox (const SHBox& rhs) noexcept;
|
||||||
|
SHBox (SHBox&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBox& operator= (const SHBox& rhs) noexcept;
|
||||||
|
SHBox& operator= (SHBox&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<SHVec3> GetVertices () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Function Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if a point is inside the box.
|
||||||
|
* @param point
|
||||||
|
* The point to check.
|
||||||
|
* @return
|
||||||
|
* True if the point is inside the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Casts a ray against the box.
|
||||||
|
* @param ray
|
||||||
|
* The ray to cast.
|
||||||
|
* @return
|
||||||
|
* The result of the raycast. <br/>
|
||||||
|
* See the corresponding header for the contents of the raycast result object.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if an entire other box is contained by this box.
|
||||||
|
* @param rhs
|
||||||
|
* The box to check.
|
||||||
|
* @return
|
||||||
|
* True if the other sphere is completely contained by this box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool Contains (const SHBox& rhs) const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Calculates the volume of the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] float Volume () const noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Calculates the surface area of the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] float SurfaceArea () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Function Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Checks if two boxes are intersecting.
|
||||||
|
* @return
|
||||||
|
* True if they are intersecting.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static bool Intersect (const SHBox& lhs, const SHBox& rhs) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Builds a box from a set of vertices.
|
||||||
|
* @param vertices
|
||||||
|
* The vertices to build a box 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 box that contains all the vertices in the set.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] static SHBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -30,10 +30,9 @@ namespace SHADE
|
||||||
|
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
BOX
|
SPHERE
|
||||||
, SPHERE
|
, AABB
|
||||||
, CAPSULE
|
, BOX
|
||||||
, CONVEX_HULL
|
|
||||||
|
|
||||||
, COUNT
|
, COUNT
|
||||||
, NONE = -1
|
, NONE = -1
|
||||||
|
|
|
@ -40,6 +40,10 @@ namespace SHADE
|
||||||
: XMFLOAT4( vec4.x, vec4.y, vec4.z, vec4.w )
|
: XMFLOAT4( vec4.x, vec4.y, vec4.z, vec4.w )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
SHQuaternion::SHQuaternion(const XMFLOAT4& xmfloat4) noexcept
|
||||||
|
: XMFLOAT4( xmfloat4 )
|
||||||
|
{}
|
||||||
|
|
||||||
SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept
|
SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept
|
||||||
: XMFLOAT4( _x, _y, _z, _w )
|
: XMFLOAT4( _x, _y, _z, _w )
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -47,9 +47,10 @@ namespace SHADE
|
||||||
SHQuaternion (const SHQuaternion& rhs) = default;
|
SHQuaternion (const SHQuaternion& rhs) = default;
|
||||||
SHQuaternion (SHQuaternion&& rhs) = default;
|
SHQuaternion (SHQuaternion&& rhs) = default;
|
||||||
|
|
||||||
SHQuaternion () noexcept;
|
SHQuaternion () noexcept;
|
||||||
SHQuaternion (const SHVec4& vec4) noexcept;
|
SHQuaternion (const SHVec4& vec4) noexcept;
|
||||||
SHQuaternion (float x, float y, float z, float w) noexcept;
|
SHQuaternion (const XMFLOAT4& xmfloat4) noexcept;
|
||||||
|
SHQuaternion (float x, float y, float z, float w) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Operator Overloads */
|
/* Operator Overloads */
|
||||||
|
|
|
@ -204,6 +204,8 @@ namespace SHADE
|
||||||
|
|
||||||
removeLeaf(INDEX_TO_REMOVE);
|
removeLeaf(INDEX_TO_REMOVE);
|
||||||
freeNode(INDEX_TO_REMOVE);
|
freeNode(INDEX_TO_REMOVE);
|
||||||
|
|
||||||
|
nodeMap.erase(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SHCollisionShapeID>& SHAABBTree::Query(SHCollisionShapeID id, const SHAABB& AABB) const noexcept
|
const std::vector<SHCollisionShapeID>& SHAABBTree::Query(SHCollisionShapeID id, const SHAABB& AABB) const noexcept
|
||||||
|
@ -404,6 +406,13 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t PARENT = nodes[index].parent;
|
const int32_t PARENT = nodes[index].parent;
|
||||||
|
|
||||||
|
if (PARENT == NULL_NODE)
|
||||||
|
{
|
||||||
|
freeNode(index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int32_t GRANDPARENT = nodes[PARENT].parent;
|
const int32_t GRANDPARENT = nodes[PARENT].parent;
|
||||||
const int32_t SIBLING = nodes[PARENT].left == index ? nodes[PARENT].right : nodes[PARENT].left;
|
const int32_t SIBLING = nodes[PARENT].left == index ? nodes[PARENT].right : nodes[PARENT].left;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHBoxCollisionShape.cpp
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Implementation for a Box Collision Shape.
|
||||||
|
*
|
||||||
|
* \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 <SHpch.h>
|
||||||
|
|
||||||
|
// Primary Header
|
||||||
|
#include "SHBoxCollisionShape.h"
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "Math/SHMathHelpers.h"
|
||||||
|
#include "Math/SHMatrix.h"
|
||||||
|
#include "Physics/Collision/SHCollider.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBoxCollisionShape::SHBoxCollisionShape(SHCollisionShapeID id) noexcept
|
||||||
|
: SHCollisionShape (id, SHCollisionShape::Type::BOX)
|
||||||
|
, SHBox ()
|
||||||
|
, relativeExtents { SHVec3::One }
|
||||||
|
, scale { SHVec3::One }
|
||||||
|
{}
|
||||||
|
|
||||||
|
SHBoxCollisionShape::SHBoxCollisionShape(const SHBoxCollisionShape& rhs) noexcept
|
||||||
|
: SHCollisionShape (rhs.id, SHCollisionShape::Type::BOX)
|
||||||
|
, SHBox (rhs.Center, rhs.Extents, rhs.Orientation)
|
||||||
|
, relativeExtents { rhs.relativeExtents }
|
||||||
|
, scale { rhs.scale }
|
||||||
|
{
|
||||||
|
|
||||||
|
material = rhs.material;
|
||||||
|
collider = rhs.collider;
|
||||||
|
transform = rhs.transform;
|
||||||
|
rotationOffset = rhs.rotationOffset;
|
||||||
|
flags = rhs.flags;
|
||||||
|
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
|
||||||
|
collisionTag = rhs.collisionTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBoxCollisionShape::SHBoxCollisionShape(SHBoxCollisionShape&& rhs) noexcept
|
||||||
|
: SHCollisionShape (rhs.id, SHCollisionShape::Type::BOX)
|
||||||
|
, SHBox (rhs.Center, rhs.Extents, rhs.Orientation)
|
||||||
|
, relativeExtents { rhs.relativeExtents }
|
||||||
|
, scale { rhs.scale }
|
||||||
|
{
|
||||||
|
|
||||||
|
material = rhs.material;
|
||||||
|
collider = rhs.collider;
|
||||||
|
transform = rhs.transform;
|
||||||
|
rotationOffset = rhs.rotationOffset;
|
||||||
|
flags = rhs.flags;
|
||||||
|
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
|
||||||
|
collisionTag = rhs.collisionTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overload Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBoxCollisionShape& SHBoxCollisionShape::operator=(const SHBoxCollisionShape& rhs) noexcept
|
||||||
|
{
|
||||||
|
if (this == &rhs)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
// Collision Shape Properties
|
||||||
|
|
||||||
|
id = rhs.id;
|
||||||
|
material = rhs.material;
|
||||||
|
collider = rhs.collider;
|
||||||
|
transform = rhs.transform;
|
||||||
|
rotationOffset = rhs.rotationOffset;
|
||||||
|
flags = rhs.flags;
|
||||||
|
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
|
||||||
|
collisionTag = rhs.collisionTag;
|
||||||
|
|
||||||
|
// Box Properties
|
||||||
|
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
|
||||||
|
// Local Properties
|
||||||
|
|
||||||
|
relativeExtents = rhs.relativeExtents;
|
||||||
|
scale = rhs.scale;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBoxCollisionShape& SHBoxCollisionShape::operator=(SHBoxCollisionShape&& rhs) noexcept
|
||||||
|
{
|
||||||
|
// Collision Shape Properties
|
||||||
|
|
||||||
|
id = rhs.id;
|
||||||
|
material = rhs.material;
|
||||||
|
collider = rhs.collider;
|
||||||
|
transform = rhs.transform;
|
||||||
|
rotationOffset = rhs.rotationOffset;
|
||||||
|
flags = rhs.flags;
|
||||||
|
// Since all collision tags are taken from the matrix, we do not need to do a deep copy here.
|
||||||
|
collisionTag = rhs.collisionTag;
|
||||||
|
|
||||||
|
// Box Properties
|
||||||
|
|
||||||
|
Center = rhs.Center;
|
||||||
|
Extents = rhs.Extents;
|
||||||
|
Orientation = rhs.Orientation;
|
||||||
|
|
||||||
|
// Local Properties
|
||||||
|
|
||||||
|
relativeExtents = rhs.relativeExtents;
|
||||||
|
scale = rhs.scale;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHVec3 SHBoxCollisionShape::GetCenter() const noexcept
|
||||||
|
{
|
||||||
|
return Center;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHBoxCollisionShape::GetWorldExtents() const noexcept
|
||||||
|
{
|
||||||
|
return Extents;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHVec3 SHBoxCollisionShape::GetRelativeExtents() const noexcept
|
||||||
|
{
|
||||||
|
return relativeExtents;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHQuaternion SHBoxCollisionShape::GetOrientation() const noexcept
|
||||||
|
{
|
||||||
|
return Orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::SetCenter(const SHVec3& newCenter) noexcept
|
||||||
|
{
|
||||||
|
Center = newCenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
|
||||||
|
{
|
||||||
|
Extents = newWorldExtents;
|
||||||
|
|
||||||
|
// Recompute Relative radius
|
||||||
|
relativeExtents = 2.0f * Extents / scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::SetRelativeExtents(const SHVec3& newRelativeExtents) noexcept
|
||||||
|
{
|
||||||
|
relativeExtents = newRelativeExtents;
|
||||||
|
|
||||||
|
// Recompute world radius
|
||||||
|
Extents = relativeExtents * scale * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::SetOrientation(const SHQuaternion& newOrientation) noexcept
|
||||||
|
{
|
||||||
|
Orientation = newOrientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::SetScale(const SHVec3& newScale) noexcept
|
||||||
|
{
|
||||||
|
scale = SHVec3::Abs(newScale);
|
||||||
|
|
||||||
|
// Recompute world radius
|
||||||
|
Extents = relativeExtents * scale * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Public Member Function Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHBoxCollisionShape::ComputeTransforms() noexcept
|
||||||
|
{
|
||||||
|
const SHTransform& PARENT_TRANSFORM = collider->GetTransform();
|
||||||
|
|
||||||
|
SetScale(PARENT_TRANSFORM.scale);
|
||||||
|
|
||||||
|
// Recompute center
|
||||||
|
const SHQuaternion FINAL_ROT = PARENT_TRANSFORM.orientation * transform.orientation;
|
||||||
|
const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(PARENT_TRANSFORM.position);
|
||||||
|
|
||||||
|
Center = SHVec3::Transform(transform.position, TRS);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHBoxCollisionShape::TestPoint(const SHVec3& point) const noexcept
|
||||||
|
{
|
||||||
|
return SHBox::TestPoint(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHRaycastResult SHBoxCollisionShape::Raycast(const SHRay& ray) const noexcept
|
||||||
|
{
|
||||||
|
return SHBox::Raycast(ray);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMatrix SHBoxCollisionShape::GetInertiaTensor(float mass) const noexcept
|
||||||
|
{
|
||||||
|
static constexpr float ONE_OVER_TWELVE = (1.0f / 12.0f);
|
||||||
|
|
||||||
|
const float H2_PLUS_D2 = Extents.y * Extents.y + Extents.z * Extents.z;
|
||||||
|
const float W2_PLUS_H2 = Extents.x * Extents.x + Extents.y * Extents.y;
|
||||||
|
const float W2_PLUS_D2 = Extents.x * Extents.x + Extents.z * Extents.z;
|
||||||
|
|
||||||
|
SHMatrix result;
|
||||||
|
result.m[0][0] = ONE_OVER_TWELVE * mass * H2_PLUS_D2;
|
||||||
|
result.m[1][1] = ONE_OVER_TWELVE * mass * W2_PLUS_H2;
|
||||||
|
result.m[2][2] = ONE_OVER_TWELVE * mass * W2_PLUS_D2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHMatrix SHBoxCollisionShape::ComputeWorldTransform() const noexcept
|
||||||
|
{
|
||||||
|
const SHTransform& PARENT_TRANSFORM = collider->GetTransform();
|
||||||
|
const SHQuaternion ROTATION = PARENT_TRANSFORM.orientation * transform.orientation;
|
||||||
|
const SHVec3 SCALE = SHVec3{ Extents } *2.0f;
|
||||||
|
|
||||||
|
return SHMatrix::Transform
|
||||||
|
(
|
||||||
|
Center
|
||||||
|
, ROTATION
|
||||||
|
, SCALE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAABB SHBoxCollisionShape::ComputeAABB() const noexcept
|
||||||
|
{
|
||||||
|
SHVec3 min{ std::numeric_limits<float>::max() };
|
||||||
|
SHVec3 max{ std::numeric_limits<float>::lowest() };
|
||||||
|
|
||||||
|
const auto& VERTICES = GetVertices();
|
||||||
|
for (auto& vtx : VERTICES)
|
||||||
|
{
|
||||||
|
min = SHVec3::Min({ vtx, min });
|
||||||
|
max = SHVec3::Max({ vtx, max });
|
||||||
|
}
|
||||||
|
|
||||||
|
const SHVec3 HALF_EXTENTS = (max - min) * 0.5f;
|
||||||
|
const SHVec3 CENTROID = min + HALF_EXTENTS;
|
||||||
|
|
||||||
|
return SHAABB{ CENTROID, HALF_EXTENTS };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -0,0 +1,158 @@
|
||||||
|
/****************************************************************************************
|
||||||
|
* \file SHBoxCollisionShape.h
|
||||||
|
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||||
|
* \brief Interface for a Box Collision Shape.
|
||||||
|
*
|
||||||
|
* \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
|
||||||
|
|
||||||
|
// Project Headers
|
||||||
|
#include "Math/Geometry/SHBox.h"
|
||||||
|
#include "SHCollisionShape.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Type Definitions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulates the information to create a box.
|
||||||
|
*/
|
||||||
|
struct SHBoxCreateInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SHVec3 Center = SHVec3::Zero;
|
||||||
|
SHVec3 Extents = SHVec3::One * 0.5f;
|
||||||
|
SHVec3 RelativeExtents = SHVec3::One;
|
||||||
|
SHQuaternion Orientation = SHQuaternion::Identity;
|
||||||
|
SHVec3 Scale = SHVec3::One;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Encapsulate a Box Collision Shape used for Physics Simulations.
|
||||||
|
*/
|
||||||
|
class SH_API SHBoxCollisionShape final : public SHCollisionShape
|
||||||
|
, private SHBox
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Friends */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
friend class SHCollider;
|
||||||
|
friend class SHCollision;
|
||||||
|
friend class SHCompositeCollider;
|
||||||
|
friend class SHCollisionShapeFactory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors & Destructor */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBoxCollisionShape (SHCollisionShapeID id) noexcept;
|
||||||
|
SHBoxCollisionShape (const SHBoxCollisionShape& rhs) noexcept;
|
||||||
|
SHBoxCollisionShape (SHBoxCollisionShape&& rhs) noexcept;
|
||||||
|
|
||||||
|
~SHBoxCollisionShape () override = default;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Operator Overloads */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHBoxCollisionShape& operator= (const SHBoxCollisionShape& rhs) noexcept;
|
||||||
|
SHBoxCollisionShape& operator= (SHBoxCollisionShape&& rhs) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Getter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
[[nodiscard]] SHVec3 GetCenter () const noexcept;
|
||||||
|
[[nodiscard]] SHVec3 GetWorldExtents () const noexcept;
|
||||||
|
[[nodiscard]] SHVec3 GetRelativeExtents () const noexcept;
|
||||||
|
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Setter Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SetCenter (const SHVec3& newCenter) noexcept;
|
||||||
|
void SetWorldExtents (const SHVec3& newWorldExtents) noexcept;
|
||||||
|
void SetRelativeExtents (const SHVec3& newRelativeExtents) noexcept;
|
||||||
|
void SetOrientation (const SHQuaternion& newOrientation) noexcept;
|
||||||
|
void SetScale (const SHVec3& newScale) noexcept;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Function Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Recomputes the transform of this box.
|
||||||
|
*/
|
||||||
|
void ComputeTransforms () noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Tests if a point is inside the box.
|
||||||
|
* @param point
|
||||||
|
* The point to test.
|
||||||
|
* @return
|
||||||
|
* True if the point is inside the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Casts a ray against this box.
|
||||||
|
* @param ray
|
||||||
|
* The ray to cast.
|
||||||
|
* @return
|
||||||
|
* An object holding the results of the raycast. <br/>
|
||||||
|
* See the corresponding header for the contents of the object.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Computes the inertia tensor of the box.
|
||||||
|
* @param mass
|
||||||
|
* The mass of the sphere.
|
||||||
|
* @return
|
||||||
|
* The inertia tensor of the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHMatrix GetInertiaTensor (float mass) const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Computes the transformation matrix of the box.
|
||||||
|
* @return
|
||||||
|
* The transformation matrix of the box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHMatrix ComputeWorldTransform () const noexcept override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Computes the a tight-fitting AABB that contains this box.
|
||||||
|
* @return
|
||||||
|
* A tight-fitting AABB that contains this box.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHAABB ComputeAABB () const noexcept override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
SHVec3 relativeExtents;
|
||||||
|
SHVec3 scale; // Intended to be passed in by the base collider.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace SHADE
|
|
@ -24,6 +24,10 @@ namespace SHADE
|
||||||
// Free all shapes in each container
|
// Free all shapes in each container
|
||||||
for (auto* sphereCollisionShape : spheres | std::views::values)
|
for (auto* sphereCollisionShape : spheres | std::views::values)
|
||||||
DestroyShape(sphereCollisionShape);
|
DestroyShape(sphereCollisionShape);
|
||||||
|
|
||||||
|
// Free all shapes in each container
|
||||||
|
for (auto* boxCollisionShape : boxes | std::views::values)
|
||||||
|
DestroyShape(boxCollisionShape);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -48,6 +52,26 @@ namespace SHADE
|
||||||
return spheres.find(id)->second;
|
return spheres.find(id)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHBoxCollisionShape* SHCollisionShapeFactory::CreateBox(SHCollisionShapeID id, const SHBoxCreateInfo& createInfo)
|
||||||
|
{
|
||||||
|
const auto RESULT = boxes.emplace(id, new SHBoxCollisionShape{ id });
|
||||||
|
if (RESULT.second)
|
||||||
|
{
|
||||||
|
SHBoxCollisionShape* box = RESULT.first->second;
|
||||||
|
|
||||||
|
box->Center = createInfo.Center;
|
||||||
|
box->Extents = createInfo.Extents;
|
||||||
|
box->relativeExtents = createInfo.RelativeExtents;
|
||||||
|
box->Orientation = createInfo.Orientation;
|
||||||
|
box->scale = createInfo.Scale;
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
return boxes.find(id)->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHCollisionShapeFactory::DestroyShape(SHCollisionShape* shape)
|
void SHCollisionShapeFactory::DestroyShape(SHCollisionShape* shape)
|
||||||
{
|
{
|
||||||
switch (shape->GetType())
|
switch (shape->GetType())
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
// Project Header
|
// Project Header
|
||||||
#include "SHSphereCollisionShape.h"
|
#include "SHSphereCollisionShape.h"
|
||||||
|
#include "SHBoxCollisionShape.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -49,10 +50,22 @@ namespace SHADE
|
||||||
* @param createInfo
|
* @param createInfo
|
||||||
* The info to create the sphere with.
|
* The info to create the sphere with.
|
||||||
* @return
|
* @return
|
||||||
* A newly sphere collision shape.
|
* A new sphere collision shape.
|
||||||
*/
|
*/
|
||||||
SHSphereCollisionShape* CreateSphere (SHCollisionShapeID id, const SHSphereCreateInfo& createInfo);
|
SHSphereCollisionShape* CreateSphere (SHCollisionShapeID id, const SHSphereCreateInfo& createInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Creates a box collision shape.
|
||||||
|
* @param id
|
||||||
|
* The ID of the shape.
|
||||||
|
* @param createInfo
|
||||||
|
* The info to create the box with.
|
||||||
|
* @return
|
||||||
|
* A new box collision shape.
|
||||||
|
*/
|
||||||
|
SHBoxCollisionShape* CreateBox (SHCollisionShapeID id, const SHBoxCreateInfo& createInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Destroys a collision shape.
|
* Destroys a collision shape.
|
||||||
|
@ -63,7 +76,7 @@ namespace SHADE
|
||||||
* @param shape
|
* @param shape
|
||||||
* The shape to destroy.
|
* The shape to destroy.
|
||||||
*/
|
*/
|
||||||
void DestroyShape (SHCollisionShape* shape);
|
void DestroyShape (SHCollisionShape* shape);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -74,13 +87,15 @@ namespace SHADE
|
||||||
// Since we are not instancing shapes (yet?), I'd rather not iterate through an entire vector to find the shape.
|
// Since we are not instancing shapes (yet?), I'd rather not iterate through an entire vector to find the shape.
|
||||||
|
|
||||||
using Spheres = std::unordered_map<SHCollisionShapeID, SHSphereCollisionShape*, SHCollisionShapeIDHash>;
|
using Spheres = std::unordered_map<SHCollisionShapeID, SHSphereCollisionShape*, SHCollisionShapeIDHash>;
|
||||||
|
using Boxes = std::unordered_map<SHCollisionShapeID, SHBoxCollisionShape*, SHCollisionShapeIDHash>;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Spheres spheres;
|
Spheres spheres;
|
||||||
// TODO: Add boxes, capsules and hulls
|
Boxes boxes;
|
||||||
|
// TODO: Add capsules and hulls
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -93,7 +93,7 @@ namespace SHADE
|
||||||
* @brief
|
* @brief
|
||||||
* Recomputes the transform of this sphere.
|
* Recomputes the transform of this sphere.
|
||||||
*/
|
*/
|
||||||
void ComputeTransforms () noexcept override;
|
void ComputeTransforms () noexcept override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
@ -103,7 +103,7 @@ namespace SHADE
|
||||||
* @return
|
* @return
|
||||||
* True if the point is inside the sphere.
|
* True if the point is inside the sphere.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
[[nodiscard]] bool TestPoint (const SHVec3& point) const noexcept override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
@ -114,7 +114,7 @@ namespace SHADE
|
||||||
* An object holding the results of the raycast. <br/>
|
* An object holding the results of the raycast. <br/>
|
||||||
* See the corresponding header for the contents of the object.
|
* See the corresponding header for the contents of the object.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
|
[[nodiscard]] SHRaycastResult Raycast (const SHRay& ray) const noexcept override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
@ -124,11 +124,23 @@ namespace SHADE
|
||||||
* @return
|
* @return
|
||||||
* The inertia tensor of the sphere.
|
* The inertia tensor of the sphere.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] SHMatrix GetInertiaTensor (float mass) const noexcept override;
|
[[nodiscard]] SHMatrix GetInertiaTensor (float mass) const noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] SHMatrix ComputeWorldTransform () const noexcept override;
|
/**
|
||||||
|
* @brief
|
||||||
|
* Computes the transformation matrix of the sphere.
|
||||||
|
* @return
|
||||||
|
* The transformation matrix of the sphere.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHMatrix ComputeWorldTransform () const noexcept override;
|
||||||
|
|
||||||
[[nodiscard]] SHAABB ComputeAABB () const noexcept override;
|
/**
|
||||||
|
* @brief
|
||||||
|
* Computes the a tight-fitting AABB that contains this sphere.
|
||||||
|
* @return
|
||||||
|
* A tight-fitting AABB that contains this sphere.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] SHAABB ComputeAABB () const noexcept override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -332,6 +332,60 @@ namespace SHADE
|
||||||
return static_cast<int>(NEW_INDEX);
|
return static_cast<int>(NEW_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SHCollider::AddBoxCollisionShape(const SHVec3& relativeExtents, const SHVec3& posOffset, const SHVec3& rotOffset)
|
||||||
|
{
|
||||||
|
if (!shapeFactory)
|
||||||
|
{
|
||||||
|
SHLOGV_ERROR("Shape factory is unlinked with Collider {}. Unable to add new shape!", entityID)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute center
|
||||||
|
const SHQuaternion FINAL_ROT = transform.orientation * SHQuaternion::FromEuler(rotOffset);
|
||||||
|
const SHMatrix TRS = SHMatrix::Rotate(FINAL_ROT) * SHMatrix::Translate(transform.position);
|
||||||
|
|
||||||
|
// Create Sphere
|
||||||
|
const SHBoxCreateInfo BOX_CREATE_INFO
|
||||||
|
{
|
||||||
|
.Center = SHVec3::Transform(posOffset, TRS)
|
||||||
|
, .Extents = relativeExtents * SHVec3::Abs(transform.scale) * 0.5f
|
||||||
|
, .RelativeExtents = relativeExtents
|
||||||
|
, .Orientation = FINAL_ROT
|
||||||
|
, .Scale = SHVec3::Abs(transform.scale)
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
|
||||||
|
const SHCollisionShapeID NEW_SHAPE_ID{ entityID, NEW_INDEX };
|
||||||
|
|
||||||
|
SHBoxCollisionShape* box = shapeFactory->CreateBox(NEW_SHAPE_ID, BOX_CREATE_INFO);
|
||||||
|
|
||||||
|
// Set offsets
|
||||||
|
box->collider = this;
|
||||||
|
box->SetPositionOffset(posOffset);
|
||||||
|
box->SetRotationOffset(rotOffset);
|
||||||
|
|
||||||
|
shapes.emplace_back(box);
|
||||||
|
|
||||||
|
if (broadphase)
|
||||||
|
broadphase->Insert(NEW_SHAPE_ID, box->ComputeAABB());
|
||||||
|
|
||||||
|
// Broadcast Event for adding a shape
|
||||||
|
const SHPhysicsColliderAddedEvent EVENT_DATA
|
||||||
|
{
|
||||||
|
.entityID = entityID
|
||||||
|
, .colliderType = SHCollisionShape::Type::BOX
|
||||||
|
, .colliderIndex = static_cast<int>(NEW_INDEX)
|
||||||
|
};
|
||||||
|
|
||||||
|
SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT);
|
||||||
|
|
||||||
|
if (rigidBody)
|
||||||
|
rigidBody->ComputeMassData();
|
||||||
|
|
||||||
|
return static_cast<int>(NEW_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHCollider::RemoveCollisionShape(int index)
|
void SHCollider::RemoveCollisionShape(int index)
|
||||||
{
|
{
|
||||||
if (!shapeFactory)
|
if (!shapeFactory)
|
||||||
|
|
|
@ -123,19 +123,34 @@ namespace SHADE
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Adds a sphere collision shape.
|
* Adds a sphere collision shape.
|
||||||
|
* @param relativeRadius
|
||||||
|
* The relative radius is constructed with respect to the world scale. <br/>
|
||||||
|
* Radius = max(scale.x, scale.y, scale.z) * 0.5 * relativeRadius
|
||||||
* @param posOffset
|
* @param posOffset
|
||||||
* The position offset of the sphere from the center of the collider. Defaults to a Zero Vector.
|
* The position offset of the sphere from the center of the collider. Defaults to a Zero Vector.
|
||||||
* @param rotOffset
|
* @param rotOffset
|
||||||
* The rotation offset of the sphere from the rotation of the collider. Defaults to a Zero Vector.
|
* The rotation offset of the sphere from the rotation of the collider. Defaults to a Zero Vector.
|
||||||
* @param relativeRadius
|
|
||||||
* The relative radius is constructed with respect to the world scale. <br/>
|
|
||||||
* Radius = max(scale.x, scale.y, scale.z) * 0.5 * relativeRadius
|
|
||||||
* @return
|
* @return
|
||||||
* The index of the newly added shape.
|
* The index of the newly added shape.
|
||||||
*/
|
*/
|
||||||
int AddSphereCollisionShape (float relativeRadius, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero);
|
int AddSphereCollisionShape (float relativeRadius, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero);
|
||||||
|
|
||||||
// TODO: Add Box & Capsule
|
/**
|
||||||
|
* @brief
|
||||||
|
* Adds a box collision shape.
|
||||||
|
* @param relativeExtents
|
||||||
|
* The relative extents are constructed with respect to the world scale. <br/>
|
||||||
|
* Extents = scale * 0.5 * relativeExtents
|
||||||
|
* @param posOffset
|
||||||
|
* The position offset of the box from the center of the collider. Defaults to a Zero Vector.
|
||||||
|
* @param rotOffset
|
||||||
|
* The rotation offset of the box from the rotation of the collider. Defaults to a Zero Vector.
|
||||||
|
* @return
|
||||||
|
* The index of the newly added shape.
|
||||||
|
*/
|
||||||
|
int AddBoxCollisionShape (const SHVec3& relativeExtents, const SHVec3& posOffset = SHVec3::Zero, const SHVec3& rotOffset = SHVec3::Zero);
|
||||||
|
|
||||||
|
// TODO: Add Capsule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
|
@ -146,13 +161,13 @@ namespace SHADE
|
||||||
* @throws
|
* @throws
|
||||||
* Invalid argument for out-of-range indices.
|
* Invalid argument for out-of-range indices.
|
||||||
*/
|
*/
|
||||||
void RemoveCollisionShape (int index);
|
void RemoveCollisionShape (int index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Recomputes the transforms for all shapes in this composite collider.
|
* Recomputes the transforms for all shapes in this composite collider.
|
||||||
*/
|
*/
|
||||||
void RecomputeShapes () noexcept;
|
void RecomputeShapes () noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -98,7 +98,7 @@ namespace SHADE
|
||||||
for (auto& aabb : BROADPHASE_AABBS)
|
for (auto& aabb : BROADPHASE_AABBS)
|
||||||
{
|
{
|
||||||
// Compute AABB Transform
|
// Compute AABB Transform
|
||||||
const SHMatrix TRS = SHMatrix::Transform(aabb.GetCenter(), SHQuaternion::Identity, aabb.GetWorldExtents() * 2.0f);
|
const SHMatrix TRS = SHMatrix::Transform(aabb.GetCenter(), SHQuaternion::Identity, aabb.GetExtents() * 2.0f);
|
||||||
debugDrawSystem->DrawWireCube(TRS, AABB_COLOUR);
|
debugDrawSystem->DrawWireCube(TRS, AABB_COLOUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,11 +133,11 @@ namespace SHADE
|
||||||
case SHCollisionShape::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
{
|
{
|
||||||
debugDrawSystem->DrawWireSphere(SHAPE->ComputeWorldTransform(), DRAW_COLOUR, true);
|
debugDrawSystem->DrawWireSphere(SHAPE->ComputeWorldTransform(), DRAW_COLOUR, true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollisionShape::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
|
debugDrawSystem->DrawWireCube(SHAPE->ComputeWorldTransform(), DRAW_COLOUR, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SHCollisionShape::Type::CAPSULE:
|
case SHCollisionShape::Type::CAPSULE:
|
||||||
|
|
|
@ -132,8 +132,8 @@ namespace YAML
|
||||||
{
|
{
|
||||||
case SHCollisionShape::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
//const auto* BOX = reinterpret_cast<const SHAABB*>(rhs.GetShape());
|
const auto& BOX = dynamic_cast<const SHBoxCollisionShape&>(rhs);
|
||||||
//node[HalfExtents] = BOX->GetRelativeExtents();
|
node[HalfExtents] = BOX.GetRelativeExtents();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollisionShape::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
|
@ -170,7 +170,11 @@ namespace YAML
|
||||||
{
|
{
|
||||||
case SHCollisionShape::Type::BOX:
|
case SHCollisionShape::Type::BOX:
|
||||||
{
|
{
|
||||||
|
if (node[HalfExtents].IsDefined())
|
||||||
|
{
|
||||||
|
auto* box = dynamic_cast<SHBoxCollisionShape*>(&rhs);
|
||||||
|
box->SetRelativeExtents(node[HalfExtents].as<SHVec3>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SHCollisionShape::Type::SPHERE:
|
case SHCollisionShape::Type::SPHERE:
|
||||||
|
|
|
@ -137,12 +137,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
Vector3 BoxCollider::HalfExtents::get()
|
Vector3 BoxCollider::HalfExtents::get()
|
||||||
{
|
{
|
||||||
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetWorldExtents());
|
//return Convert::ToCLI(getNativeCollisionShape<SHAABB>().GetExtents());
|
||||||
return Vector3::Zero;
|
return Vector3::Zero;
|
||||||
}
|
}
|
||||||
void BoxCollider::HalfExtents::set(Vector3 value)
|
void BoxCollider::HalfExtents::set(Vector3 value)
|
||||||
{
|
{
|
||||||
//getNativeCollisionShape<SHAABB>().SetWorldExtents(Convert::ToNative(value));
|
//getNativeCollisionShape<SHAABB>().SetExtents(Convert::ToNative(value));
|
||||||
}
|
}
|
||||||
Vector3 BoxCollider::Min::get()
|
Vector3 BoxCollider::Min::get()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue