SP3-2 Cleaned Up Physics System #85

Merged
direnbharwani merged 11 commits from SP3-2-Physics into main 2022-10-13 18:32:25 +08:00
31 changed files with 1796 additions and 944 deletions

View File

@ -104,8 +104,10 @@ namespace Sandbox
transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber());
transform.SetWorldScale(TEST_OBJ_SCALE); transform.SetWorldScale(TEST_OBJ_SCALE);
auto* box = collider.AddBoundingBox(); if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN)
box->SetHalfExtents(transform.GetWorldScale() * 0.5f); collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero);
else
collider.AddBoundingSphere(0.5f, SHVec3::Zero);
stressTestObjects.emplace_back(entity); stressTestObjects.emplace_back(entity);
} }

View File

@ -14,6 +14,9 @@
#include "SHBoundingBox.h" #include "SHBoundingBox.h"
// Project Headers // Project Headers
#include "Math/SHMathHelpers.h" #include "Math/SHMathHelpers.h"
#include "Math/SHRay.h"
using namespace DirectX;
namespace SHADE namespace SHADE
{ {
@ -21,89 +24,53 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHBoundingBox::SHBoundingBox() noexcept
{
type = Type::BOX;
}
SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept SHBoundingBox::SHBoundingBox(const SHVec3& c, const SHVec3& hE) noexcept
: SHShape {}
, center { c }
, halfExtents { hE }
{ {
type = Type::BOUNDING_BOX; type = Type::BOX;
Center = c;
Extents = hE;
} }
SHBoundingBox::SHBoundingBox(const SHVec3* vertices, size_t numVertices) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
if (vertices == nullptr || numVertices < 2)
{
SHLOG_ERROR("Insufficient number of vertices passed into bounding box constructor!")
return;
}
SHVec3 min { std::numeric_limits<float>::max() };
SHVec3 max { std::numeric_limits<float>::min() };
for (size_t i = 0; i < numVertices; ++i)
{
const SHVec3& v = vertices[i];
min.x = SHMath::Min(min.x, v.x);
min.y = SHMath::Min(min.y, v.y);
min.z = SHMath::Min(min.z, v.z);
max.x = SHMath::Max(max.x, v.x);
max.y = SHMath::Max(max.y, v.y);
max.z = SHMath::Max(max.z, v.z);
}
center = SHVec3::Lerp(min, max, 0.5f);
halfExtents = SHVec3::Abs((max - min) * 0.5f);
}
SHBoundingBox::SHBoundingBox(const SHBoundingBox* boxes, size_t numBoxes) noexcept
: SHShape {}
{
type = Type::BOUNDING_BOX;
if (boxes == nullptr || numBoxes == 0)
{
SHLOG_ERROR("Insufficient number of boxes passed into bounding box constructor!")
return;
}
center = boxes->center;
halfExtents = boxes->halfExtents;
for (size_t i = 1; i < numBoxes; ++i)
*this = Combine(*this, boxes[i]);
}
SHBoundingBox::SHBoundingBox(const SHBoundingBox& rhs) noexcept SHBoundingBox::SHBoundingBox(const SHBoundingBox& rhs) noexcept
: SHShape {}
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{ {
type = Type::BOUNDING_BOX; if (this == &rhs)
return;
type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
} }
SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept SHBoundingBox::SHBoundingBox(SHBoundingBox&& rhs) noexcept
: SHShape {}
, center { rhs.center }
, halfExtents { rhs.halfExtents }
{ {
type = Type::BOUNDING_BOX; type = Type::BOX;
Center = rhs.Center;
Extents = rhs.Extents;
} }
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept SHBoundingBox& SHBoundingBox::operator=(const SHBoundingBox& rhs) noexcept
{ {
if (rhs.type != Type::BOUNDING_BOX) if (rhs.type != Type::BOX)
{ {
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
} }
else else if (this != &rhs)
{ {
center = rhs.center; Center = rhs.Center;
halfExtents = rhs.halfExtents; Extents = rhs.Extents;
} }
return *this; return *this;
@ -111,14 +78,14 @@ namespace SHADE
SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept SHBoundingBox& SHBoundingBox::operator=(SHBoundingBox&& rhs) noexcept
{ {
if (rhs.type != Type::BOUNDING_BOX) if (rhs.type != Type::BOX)
{ {
SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!") SHLOG_WARNING("Cannot assign a non-bounding box to a bounding box!")
} }
else else
{ {
center = rhs.center; Center = rhs.Center;
halfExtents = rhs.halfExtents; Extents = rhs.Extents;
} }
return *this; return *this;
@ -128,24 +95,24 @@ namespace SHADE
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
const SHVec3& SHBoundingBox::GetCenter() const noexcept SHVec3 SHBoundingBox::GetCenter() const noexcept
{ {
return center; return Center;
} }
const SHVec3& SHBoundingBox::GetHalfExtents() const noexcept SHVec3 SHBoundingBox::GetHalfExtents() const noexcept
{ {
return halfExtents; return Extents;
} }
SHVec3 SHBoundingBox::GetMin() const noexcept SHVec3 SHBoundingBox::GetMin() const noexcept
{ {
return center - halfExtents; return SHVec3{ Center.x - Extents.x, Center.y - Extents.y, Center.z - Extents.z };
} }
SHVec3 SHBoundingBox::GetMax() const noexcept SHVec3 SHBoundingBox::GetMax() const noexcept
{ {
return center + halfExtents; return SHVec3{ Center.x + Extents.x, Center.y + Extents.y, Center.z + Extents.z };
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -154,36 +121,42 @@ namespace SHADE
void SHBoundingBox::SetCenter(const SHVec3& newCenter) noexcept void SHBoundingBox::SetCenter(const SHVec3& newCenter) noexcept
{ {
center = newCenter; Center = newCenter;
} }
void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept void SHBoundingBox::SetHalfExtents(const SHVec3& newHalfExtents) noexcept
{ {
halfExtents = newHalfExtents; Extents = newHalfExtents;
} }
void SHBoundingBox::SetMin(const SHVec3& min) noexcept void SHBoundingBox::SetMin(const SHVec3& min) noexcept
{ {
const SHVec3 MAX = center + halfExtents; const SHVec3 MAX = GetMax();
center = SHVec3::Lerp(min, MAX, 0.5f); Center = SHVec3::Lerp(min, MAX, 0.5f);
halfExtents = SHVec3::Abs((MAX - min) * 0.5f); Extents = SHVec3::Abs((MAX - min) * 0.5f);
} }
void SHBoundingBox::SetMax(const SHVec3& max) noexcept void SHBoundingBox::SetMax(const SHVec3& max) noexcept
{ {
const SHVec3 MIN = center - halfExtents; const SHVec3 MIN = GetMin();
center = SHVec3::Lerp(MIN, max, 0.5f); Center = SHVec3::Lerp(MIN, max, 0.5f);
halfExtents = SHVec3::Abs((max - MIN) * 0.5f); Extents = SHVec3::Abs((max - MIN) * 0.5f);
} }
void SHBoundingBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept void SHBoundingBox::SetMinMax(const SHVec3& min, const SHVec3& max) noexcept
{ {
center = SHVec3::Lerp(min, max, 0.5f); Center = SHVec3::Lerp(min, max, 0.5f);
halfExtents = SHVec3::Abs((max - min) * 0.5f); Extents = SHVec3::Abs((max - min) * 0.5f);
} }
std::vector<SHVec3> SHBoundingBox::GetVertices() const noexcept
{
std::vector<SHVec3> vertices{ 8 };
GetCorners(vertices.data());
return vertices;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */ /* Public Function Member Definitions */
@ -191,38 +164,29 @@ namespace SHADE
bool SHBoundingBox::TestPoint(const SHVec3& point) noexcept bool SHBoundingBox::TestPoint(const SHVec3& point) noexcept
{ {
const SHVec3 V = SHVec3::Abs(point - center); return BoundingBox::Contains(point);
for (size_t i = 0; i < SHVec3::SIZE; ++i) }
{
if (V[i] > halfExtents[i])
return false;
}
return true; bool SHBoundingBox::Raycast(const SHRay& ray, float& distance) noexcept
{
return BoundingBox::Intersects(ray.position, ray.direction, distance);
} }
bool SHBoundingBox::Contains(const SHBoundingBox& rhs) const noexcept bool SHBoundingBox::Contains(const SHBoundingBox& rhs) const noexcept
{ {
const SHVec3 V = SHVec3::Abs(rhs.center - center); return BoundingBox::Contains(rhs);
for (size_t i = 0; i < SHVec3::SIZE; ++i)
{
if (V[i] > rhs.halfExtents[i])
return false;
}
return true;
} }
float SHBoundingBox::Volume() const noexcept float SHBoundingBox::Volume() const noexcept
{ {
return 8.0f * (halfExtents.x * halfExtents.y * halfExtents.z); return 8.0f * (Extents.x * Extents.y * Extents.z);
} }
float SHBoundingBox::SurfaceArea() const noexcept float SHBoundingBox::SurfaceArea() const noexcept
{ {
return 8.0f * ((halfExtents.x * halfExtents.y) return 8.0f * ((Extents.x * Extents.y)
+ (halfExtents.x * halfExtents.z) + (Extents.x * Extents.z)
+ (halfExtents.y * halfExtents.z)); + (Extents.y * Extents.z));
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -231,37 +195,31 @@ namespace SHADE
SHBoundingBox SHBoundingBox::Combine(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept SHBoundingBox SHBoundingBox::Combine(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept
{ {
if (lhs.Contains(rhs)) SHBoundingBox result;
return lhs; CreateMerged(result, lhs, rhs);
if (rhs.Contains(lhs))
return rhs;
const SHVec3 LHS_MIN = lhs.GetMin();
const SHVec3 LHS_MAX = lhs.GetMax();
const SHVec3 RHS_MIN = rhs.GetMin();
const SHVec3 RHS_MAX = rhs.GetMax();
SHVec3 min = SHVec3::Min({ LHS_MIN, RHS_MIN });
SHVec3 max = SHVec3::Max({ LHS_MAX, RHS_MAX });
SHBoundingBox result{ lhs };
result.SetMinMax(min, max);
return result; return result;
} }
bool SHBoundingBox::Intersect(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept bool SHBoundingBox::Intersect(const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept
{ {
const SHVec3 V = SHVec3::Abs(lhs.center - rhs.center); return lhs.Intersects(rhs);
const SHVec3 D = lhs.halfExtents + rhs.halfExtents; }
for (size_t i = 0; i < SHVec3::SIZE; ++i) SHBoundingBox SHBoundingBox::BuildFromBoxes(const SHBoundingBox* boxes, size_t numBoxes) noexcept
{ {
if (V[i] > D[i]) SHBoundingBox result;
return false;
}
return true; for (size_t i = 1; i < numBoxes; ++i)
CreateMerged(result, boxes[i - 1], boxes[i]);
return result;
}
SHBoundingBox SHBoundingBox::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
{
SHBoundingBox result;
CreateFromPoints(result, numVertices, vertices, stride);
return result;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -22,32 +22,43 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
// TODO(Diren): Use DirectX BoundingBox instead of custom class SH_API SHBoundingBox : public SHShape,
class SH_API SHBoundingBox : public SHShape private DirectX::BoundingBox
{ {
public: public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static constexpr size_t NUM_VERTICES = 8;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept; ~SHBoundingBox () override = default;
SHBoundingBox (const SHVec3* vertices, size_t numVertices) noexcept;
SHBoundingBox (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
SHBoundingBox (const SHBoundingBox& rhs) noexcept; SHBoundingBox () noexcept;
SHBoundingBox (SHBoundingBox&& rhs) noexcept; SHBoundingBox (const SHVec3& center, const SHVec3& halfExtents) noexcept;
SHBoundingBox (const SHBoundingBox& rhs) noexcept;
SHBoundingBox (SHBoundingBox&& rhs) noexcept;
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept; /*---------------------------------------------------------------------------------*/
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept; /* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHBoundingBox& operator= (const SHBoundingBox& rhs) noexcept;
SHBoundingBox& operator= (SHBoundingBox&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] const SHVec3& GetCenter () const noexcept; [[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] const SHVec3& GetHalfExtents () const noexcept; [[nodiscard]] SHVec3 GetHalfExtents() 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;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
@ -59,31 +70,25 @@ namespace SHADE
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 */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override; [[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override;
[[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override;
[[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept; [[nodiscard]] bool Contains (const SHBoundingBox& rhs) const noexcept;
[[nodiscard]] float Volume () const noexcept; [[nodiscard]] float Volume () const noexcept;
[[nodiscard]] float SurfaceArea () const noexcept; [[nodiscard]] float SurfaceArea () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Static Function Members */ /* Static Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[nodiscard]] static SHBoundingBox Combine (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept; [[nodiscard]] static bool Intersect (const SHBoundingBox& lhs, const SHBoundingBox& rhs) noexcept;
[[nodiscard]] static SHBoundingBox BuildFromBoxes (const SHBoundingBox* boxes, size_t numBoxes) noexcept;
private: [[nodiscard]] static SHBoundingBox BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 center;
SHVec3 halfExtents;
}; };

View File

@ -0,0 +1,183 @@
/****************************************************************************************
* \file SHBoundingSphere.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Bounding Sphere
*
* \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 "SHBoundingSphere.h"
// Project Headers
#include "Math/SHMathHelpers.h"
#include "Math/SHRay.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere::SHBoundingSphere() noexcept
{
type = Type::SPHERE;
}
SHBoundingSphere::SHBoundingSphere(const SHVec3& center, float radius) noexcept
{
type = Type::SPHERE;
Center = center;
Radius = radius;
}
SHBoundingSphere::SHBoundingSphere(const SHBoundingSphere& rhs) noexcept
{
if (this == &rhs)
return;
type = Type::SPHERE;
Center = rhs.Center;
Radius = rhs.Radius;
}
SHBoundingSphere::SHBoundingSphere(SHBoundingSphere&& rhs) noexcept
{
type = Type::SPHERE;
Center = rhs.Center;
Radius = rhs.Radius;
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere& SHBoundingSphere::operator=(const SHBoundingSphere& rhs) noexcept
{
if (rhs.type != Type::SPHERE)
{
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
}
else if (this != &rhs)
{
Center = rhs.Center;
Radius = rhs.Radius;
}
return *this;
}
SHBoundingSphere& SHBoundingSphere::operator=(SHBoundingSphere&& rhs) noexcept
{
if (rhs.type != Type::SPHERE)
{
SHLOG_WARNING("Cannot assign a non-sphere to a sphere!")
}
else
{
Center = rhs.Center;
Radius = rhs.Radius;
}
return *this;
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
SHVec3 SHBoundingSphere::GetCenter() const noexcept
{
return Center;
}
float SHBoundingSphere::GetRadius() const noexcept
{
return Radius;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHBoundingSphere::SetCenter(const SHVec3& center) noexcept
{
Center = center;
}
void SHBoundingSphere::SetRadius(float radius) noexcept
{
Radius = radius;
}
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHBoundingSphere::TestPoint(const SHVec3& point) noexcept
{
return BoundingSphere::Contains(point);
}
bool SHBoundingSphere::Raycast(const SHRay& ray, float& distance) noexcept
{
return Intersects(ray.position, ray.direction, distance);
}
bool SHBoundingSphere::Contains(const SHBoundingSphere& rhs) const noexcept
{
return BoundingSphere::Contains(rhs);
}
float SHBoundingSphere::Volume() const noexcept
{
return (4.0f / 3.0f) * SHMath::PI * (Radius * Radius * Radius);
}
float SHBoundingSphere::SurfaceArea() const noexcept
{
return 4.0f * SHMath::PI * (Radius * Radius);
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHBoundingSphere SHBoundingSphere::Combine(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept
{
SHBoundingSphere result;
CreateMerged(result, lhs, rhs);
return result;
}
bool SHBoundingSphere::Intersect(const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept
{
return lhs.Intersects(rhs);
}
SHBoundingSphere SHBoundingSphere::BuildFromSpheres(const SHBoundingSphere* spheres, size_t numSpheres) noexcept
{
SHBoundingSphere result;
for (size_t i = 1; i < numSpheres; ++i)
CreateMerged(result, spheres[i - 1], spheres[i]);
return result;
}
SHBoundingSphere SHBoundingSphere::BuildFromVertices(const SHVec3* vertices, size_t numVertices, size_t stride) noexcept
{
SHBoundingSphere result;
CreateFromPoints(result, numVertices, vertices, stride);
return result;
}
} // namespace SHADE

View File

@ -0,0 +1,83 @@
/****************************************************************************************
* \file SHBoundingSphere.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Bounding Sphere.
*
* \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 SHBoundingSphere : public SHShape,
private DirectX::BoundingSphere
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHBoundingSphere () noexcept;
SHBoundingSphere (const SHVec3& center, float radius) noexcept;
SHBoundingSphere (const SHBoundingSphere& rhs) noexcept;
SHBoundingSphere (SHBoundingSphere&& rhs) noexcept;
~SHBoundingSphere () override = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHBoundingSphere& operator= (const SHBoundingSphere& rhs) noexcept;
SHBoundingSphere& operator= (SHBoundingSphere&& rhs) noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] SHVec3 GetCenter () const noexcept;
[[nodiscard]] float GetRadius () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
void SetCenter (const SHVec3& center) noexcept;
void SetRadius (float radius) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] bool TestPoint (const SHVec3& point) noexcept override;
[[nodiscard]] bool Raycast (const SHRay& ray, float& distance) noexcept override;
[[nodiscard]] bool Contains (const SHBoundingSphere& rhs) const noexcept;
[[nodiscard]] float Volume () const noexcept;
[[nodiscard]] float SurfaceArea () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHBoundingSphere Combine (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept;
[[nodiscard]] static bool Intersect (const SHBoundingSphere& lhs, const SHBoundingSphere& rhs) noexcept;
[[nodiscard]] static SHBoundingSphere BuildFromSpheres (const SHBoundingSphere* spheres, size_t numSpheres) noexcept;
[[nodiscard]] static SHBoundingSphere BuildFromVertices (const SHVec3* vertices, size_t numVertices, size_t stride = 0) noexcept;
};
} // namespace SHADE

View File

@ -11,8 +11,9 @@
#pragma once #pragma once
// Project Headers // Project Headers
#include "Math/Transform/SHTransform.h"
#include "SH_API.h" #include "SH_API.h"
#include "Math/SHRay.h"
namespace SHADE namespace SHADE
{ {
@ -29,11 +30,10 @@ namespace SHADE
enum class Type enum class Type
{ {
BOUNDING_BOX BOX
, SPHERE , SPHERE
, CAPSULE , CAPSULE
, CONVEX_HULL , CONVEX_HULL
, TRIANGLE
, COUNT , COUNT
, NONE = -1 , NONE = -1
@ -69,7 +69,8 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0; [[nodiscard]] virtual bool TestPoint (const SHVec3& point) noexcept = 0;
[[nodiscard]] virtual bool Raycast (const SHRay& ray, float& distance) noexcept = 0;
protected: protected:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -0,0 +1,297 @@
/****************************************************************************************
* \file SHColour.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Colour.
*
* \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>
#include <DirectXColors.h>
// Primary Header
#include "SHColour.h"
// Project Headers
#include "SHMathHelpers.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHColour SHColour::BEIGE = DirectX::Colors::Beige;
const SHColour SHColour::BLACK = DirectX::Colors::Black;
const SHColour SHColour::BLUE = DirectX::Colors::Blue;
const SHColour SHColour::BROWN = DirectX::Colors::Brown;
const SHColour SHColour::CHOCOLATE = DirectX::Colors::Chocolate;
const SHColour SHColour::CORAL = DirectX::Colors::Coral;
const SHColour SHColour::CRIMSON = DirectX::Colors::Crimson;
const SHColour SHColour::CYAN = DirectX::Colors::Cyan;
const SHColour SHColour::DARKBLUE = DirectX::Colors::DarkBlue;
const SHColour SHColour::DARKGRAY = DirectX::Colors::DarkGray;
const SHColour SHColour::DARKGREEN = DirectX::Colors::DarkGreen;
const SHColour SHColour::DARKMAGENTA = DirectX::Colors::DarkMagenta;
const SHColour SHColour::DARKORANGE = DirectX::Colors::DarkOrange;
const SHColour SHColour::DARKRED = DirectX::Colors::DarkRed;
const SHColour SHColour::DEEPPINK = DirectX::Colors::DeepPink;
const SHColour SHColour::FORESTGREEN = DirectX::Colors::ForestGreen;
const SHColour SHColour::FUCHSIA = DirectX::Colors::Fuchsia;
const SHColour SHColour::GOLD = DirectX::Colors::Gold;
const SHColour SHColour::GRAY = DirectX::Colors::Gray;
const SHColour SHColour::GREEN = DirectX::Colors::Green;
const SHColour SHColour::HOTPINK = DirectX::Colors::HotPink;
const SHColour SHColour::INDIGO = DirectX::Colors::Indigo;
const SHColour SHColour::LAVENDER = DirectX::Colors::Lavender;
const SHColour SHColour::LIGHTBLUE = DirectX::Colors::LightBlue;
const SHColour SHColour::LIGHTGRAY = DirectX::Colors::LightGray;
const SHColour SHColour::LIGHTGREEN = DirectX::Colors::LightGreen;
const SHColour SHColour::LIGHTPINK = DirectX::Colors::LightPink;
const SHColour SHColour::LIGHTYELLOW = DirectX::Colors::LightYellow;
const SHColour SHColour::LIME = DirectX::Colors::Lime;
const SHColour SHColour::LIMEGREEN = DirectX::Colors::LimeGreen;
const SHColour SHColour::MAGENTA = DirectX::Colors::Magenta;
const SHColour SHColour::MAROON = DirectX::Colors::Maroon;
const SHColour SHColour::MEDIUMBLUE = DirectX::Colors::MediumBlue;
const SHColour SHColour::MEDIUMPURPLE = DirectX::Colors::MediumPurple;
const SHColour SHColour::NAVY = DirectX::Colors::Navy;
const SHColour SHColour::OLIVE = DirectX::Colors::Olive;
const SHColour SHColour::ORANGE = DirectX::Colors::Orange;
const SHColour SHColour::ORCHID = DirectX::Colors::Orchid;
const SHColour SHColour::PINK = DirectX::Colors::Pink;
const SHColour SHColour::PURPLE = DirectX::Colors::Purple;
const SHColour SHColour::RED = DirectX::Colors::Red;
const SHColour SHColour::ROYALBLUE = DirectX::Colors::RoyalBlue;
const SHColour SHColour::SALMON = DirectX::Colors::Salmon;
const SHColour SHColour::SANDYBROWN = DirectX::Colors::SandyBrown;
const SHColour SHColour::SILVER = DirectX::Colors::Silver;
const SHColour SHColour::SKYBLUE = DirectX::Colors::SkyBlue;
const SHColour SHColour::SLATEGRAY = DirectX::Colors::SlateGray;
const SHColour SHColour::SNOW = DirectX::Colors::Snow;
const SHColour SHColour::STEELBLUE = DirectX::Colors::SteelBlue;
const SHColour SHColour::TAN = DirectX::Colors::Tan;
const SHColour SHColour::TEAL = DirectX::Colors::Teal;
const SHColour SHColour::TURQUOISE = DirectX::Colors::Turquoise;
const SHColour SHColour::VIOLET = DirectX::Colors::Violet;
const SHColour SHColour::WHITE = DirectX::Colors::White;
const SHColour SHColour::YELLOW = DirectX::Colors::Yellow;
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHColour::SHColour() noexcept
: SHVec4 { 0.0f, 0.0f, 0.0f, 1.0f }
{}
SHColour::SHColour(float r, float g, float b) noexcept
: SHVec4 { r, g, b, 1.0f }
{}
SHColour::SHColour(float r, float g, float b, float a) noexcept
: SHVec4 { r, g, b, a }
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b) noexcept
: SHVec4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
static_cast<float>(b) / 255.0f,
1.0f
}
{}
SHColour::SHColour(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
: SHVec4
{
static_cast<float>(r) / 255.0f,
static_cast<float>(g) / 255.0f,
static_cast<float>(b) / 255.0f,
static_cast<float>(a) / 255.0f
}
{}
SHColour::SHColour(const DirectX::XMFLOAT3& colour) noexcept
: SHVec4 { colour.x, colour.y, colour.z, 1.0f }
{}
SHColour::SHColour(const DirectX::XMVECTORF32& colour) noexcept
: SHVec4
{
XMVectorGetX(colour),
XMVectorGetY(colour),
XMVectorGetZ(colour),
XMVectorGetW(colour)
}
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHColour::operator==(const SHColour& rhs) const noexcept
{
return XMColorEqual(*this, rhs);
}
bool SHColour::operator!=(const SHColour& rhs) const noexcept
{
return XMColorNotEqual(*this, rhs);
}
/*-----------------------------------------------------------------------------------*/
/* Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHColourHSV SHColour::ToHSV() noexcept
{
SHColourHSV hsv;
const float MIN = SHMath::Min({ x, y, z });
const float MAX = SHMath::Max({ x, y, z });
hsv.v = MAX;
const float DELTA = MAX - MIN;
hsv.s = (MAX != 0.0f) ? DELTA / MAX : 0.0f;
static const float SIN_60 = sin(SHMath::DegreesToRadians(60.0f));
if (DELTA == 0.0f)
hsv.h = 0.0f;
else if (x == MAX)
hsv.h = (y - z) / DELTA;
else if (y == MAX)
hsv.h = 2.0f + (z - x) / DELTA;
else
hsv.h = 4.0f + (x - y) / DELTA;
hsv.h *= 60;
if (hsv.h < 0.0f)
hsv.h += 360.f;
return hsv;
}
void SHColour::Negate() noexcept
{
XMStoreFloat4(this, XMColorNegative(*this));
}
void SHColour::Saturate() noexcept
{
XMStoreFloat4(this, XMVectorSaturate(*this));
}
void SHColour::AdjustSaturation(float saturation) noexcept
{
XMStoreFloat4(this, XMColorAdjustSaturation(*this, saturation));
}
void SHColour::AdjustContrast(float contrast) noexcept
{
XMStoreFloat4(this, XMColorAdjustContrast(*this, contrast));
}
/*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHColour SHColour::Modulate(const SHColour& lhs, const SHColour& rhs) noexcept
{
SHColour result;
XMStoreFloat4(&result, XMColorModulate(lhs, rhs));
return result;
}
SHColour SHColour::FromHSV(float hue, float saturation, float value)
{
if (hue < 0.0f || saturation < 0.0f || value < 0.0f)
throw std::invalid_argument("One or more of the hsv values are invalid!");
SHColour colour;
if (saturation == 0.0f)
{
colour.x = colour.y = colour.z = value;
}
else
{
hue /= 60.0f;
const int SECTOR = static_cast<int>(hue);
const float F = hue - static_cast<float>(SECTOR);
const float P = value * (1.0f - saturation);
const float Q = value * (1.0f - saturation * F);
const float T = value * (1.0f - saturation * (1.0f - F));
switch (SECTOR)
{
case 0:
{
colour.x = value;
colour.y = T;
colour.z = P;
break;
}
case 1:
{
colour.x = Q;
colour.y = value;
colour.z = P;
break;
}
case 2:
{
colour.x = P;
colour.y = value;
colour.z = T;
break;
}
case 3:
{
colour.x = P;
colour.y = Q;
colour.z = value;
break;
}
case 4:
{
colour.x = T;
colour.y = P;
colour.z = value;
break;
}
default:
{
colour.x = value;
colour.y = P;
colour.z = Q;
break;
}
}
}
return colour;
}
SHColour SHColour::FromHSV(const SHColourHSV& hsv)
{
return FromHSV(hsv.h, hsv.s, hsv.v);
}
} // namespace SHADE

View File

@ -0,0 +1,166 @@
/****************************************************************************************
* \file SHColour.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Colour.
*
* \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 <DirectXMath.h>
// Project Headers
#include "SH_API.h"
#include "Vector/SHVec3.h"
#include "Vector/SHVec4.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHColour;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
struct SH_API SHColourHSV
{
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
float h = 0.0f;
float s = 0.0f;
float v = 0.0f;
};
class SH_API SHColour : private SHVec4
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHColour () noexcept;
SHColour (float r, float g, float b) noexcept;
SHColour (float r, float g, float b, float a) noexcept;
SHColour (uint8_t r, uint8_t g, uint8_t b) noexcept;
SHColour (uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept;
SHColour (const SHVec3& colour) noexcept;
SHColour (const DirectX::XMFLOAT3& colour) noexcept;
SHColour (const DirectX::XMVECTORF32& colour) noexcept;
SHColour (const SHColour&) = default;
SHColour (SHColour&&) = default;
~SHColour () = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHColour& operator= (const SHColour&) = default;
SHColour& operator= (SHColour&&) = default;
bool operator== (const SHColour& rhs) const noexcept;
bool operator!= (const SHColour& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] inline float& r() noexcept { return x; }
[[nodiscard]] inline float& g() noexcept { return y; }
[[nodiscard]] inline float& b() noexcept { return z; }
[[nodiscard]] inline float& a() noexcept { return w; }
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHColourHSV ToHSV () noexcept;
void Negate () noexcept;
void Saturate () noexcept;
void AdjustSaturation (float saturation) noexcept;
void AdjustContrast (float contrast) noexcept;
/*---------------------------------------------------------------------------------*/
/* Static Function Members */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] static SHColour Modulate (const SHColour& lhs, const SHColour& rhs) noexcept;
[[nodiscard]] static SHColour FromHSV (float hue, float saturation, float value);
[[nodiscard]] static SHColour FromHSV (const SHColourHSV& hsv);
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static const SHColour BEIGE ;
static const SHColour BLACK ;
static const SHColour BLUE ;
static const SHColour BROWN ;
static const SHColour CHOCOLATE ;
static const SHColour CORAL ;
static const SHColour CRIMSON ;
static const SHColour CYAN ;
static const SHColour DARKBLUE ;
static const SHColour DARKGRAY ;
static const SHColour DARKGREEN ;
static const SHColour DARKMAGENTA ;
static const SHColour DARKORANGE ;
static const SHColour DARKRED ;
static const SHColour DEEPPINK ;
static const SHColour FORESTGREEN ;
static const SHColour FUCHSIA ;
static const SHColour GOLD ;
static const SHColour GRAY ;
static const SHColour GREEN ;
static const SHColour HOTPINK ;
static const SHColour INDIGO ;
static const SHColour LAVENDER ;
static const SHColour LIGHTBLUE ;
static const SHColour LIGHTGRAY ;
static const SHColour LIGHTGREEN ;
static const SHColour LIGHTPINK ;
static const SHColour LIGHTYELLOW ;
static const SHColour LIME ;
static const SHColour LIMEGREEN ;
static const SHColour MAGENTA ;
static const SHColour MAROON ;
static const SHColour MEDIUMBLUE ;
static const SHColour MEDIUMPURPLE;
static const SHColour NAVY ;
static const SHColour OLIVE ;
static const SHColour ORANGE ;
static const SHColour ORCHID ;
static const SHColour PINK ;
static const SHColour PURPLE ;
static const SHColour RED ;
static const SHColour ROYALBLUE ;
static const SHColour SALMON ;
static const SHColour SANDYBROWN ;
static const SHColour SILVER ;
static const SHColour SKYBLUE ;
static const SHColour SLATEGRAY ;
static const SHColour SNOW ;
static const SHColour STEELBLUE ;
static const SHColour TAN ;
static const SHColour TEAL ;
static const SHColour TURQUOISE ;
static const SHColour VIOLET ;
static const SHColour WHITE ;
static const SHColour YELLOW;
};
} // namespace SHADE

View File

@ -334,6 +334,39 @@ namespace SHADE
return ss.str(); return ss.str();
} }
bool SHMatrix::Decompose(SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept
{
XMVECTOR s, r, t;
const XMMATRIX M = XMLoadFloat4x4(this);
if (!XMMatrixDecompose(&s, &r, &t, M))
return false;
SHQuaternion orientation;
XMStoreFloat3(&scale, s);
XMStoreFloat4(&orientation, r);
XMStoreFloat3(&translation, t);
rotation = orientation.ToEuler();
return true;
}
bool SHMatrix::Decompose(SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept
{
XMVECTOR s, r, t;
const XMMATRIX M = XMLoadFloat4x4(this);
if (!XMMatrixDecompose(&s, &r, &t, M))
return false;
XMStoreFloat3(&scale, s);
XMStoreFloat4(&orientation, r);
XMStoreFloat3(&translation, t);
return true;
}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Static Function Member Definitions */ /* Static Function Member Definitions */

View File

@ -16,7 +16,6 @@
// Project Headers // Project Headers
#include "SH_API.h" #include "SH_API.h"
#include "Vector/SHVec4.h" #include "Vector/SHVec4.h"
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
@ -25,7 +24,6 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
class SHVec2; class SHVec2;
class SHVec3; class SHVec3;
class SHVec4;
class SHQuaternion; class SHQuaternion;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -109,6 +107,24 @@ namespace SHADE
[[nodiscard]] float Determinant () const noexcept; [[nodiscard]] float Determinant () const noexcept;
[[nodiscard]] std::string ToString () const noexcept; [[nodiscard]] std::string ToString () const noexcept;
/**
* @brief Decomposes a transformation matrix into translation, euler angles and scale.
* @param[out] scale The scaling factor of the matrix.
* @param[out] rotation The euler angles of the matrix.
* @param[out] translation The translation of the matrix.
* @return True if decomposition was successful.
*/
bool Decompose (SHVec3& translation, SHVec3& rotation, SHVec3& scale) const noexcept;
/**
* @brief Decomposes a transformation matrix into translation, orientation and scale.
* @param[out] scale The scaling factor of the matrix.
* @param[out] orientation The orientation of the matrix.
* @param[out] translation The translation of the matrix.
* @return True if decomposition was successful.
*/
bool Decompose (SHVec3& translation, SHQuaternion& orientation, SHVec3& scale) const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Static Function Members */ /* Static Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -67,6 +67,19 @@ namespace SHADE
XMStoreFloat4(this, XMQuaternionRotationMatrix(M)); XMStoreFloat4(this, XMQuaternionRotationMatrix(M));
} }
SHQuaternion::SHQuaternion(const reactphysics3d::Vector3& rp3dEuler) noexcept
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f )
{
const SHVec3& SHADE_VEC{ rp3dEuler };
const XMVECTOR V = XMLoadFloat3(&SHADE_VEC);
XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V));
}
SHQuaternion::SHQuaternion(const reactphysics3d::Quaternion& rp3dQuat) noexcept
: XMFLOAT4( rp3dQuat.x, rp3dQuat.y, rp3dQuat.z, rp3dQuat.w )
{}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */ /* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -176,6 +189,16 @@ namespace SHADE
return XMQuaternionNotEqual(Q1, Q2); return XMQuaternionNotEqual(Q1, Q2);
} }
SHQuaternion::operator reactphysics3d::Quaternion() const noexcept
{
return reactphysics3d::Quaternion{ x, y, z, w };
}
SHQuaternion::operator reactphysics3d::Vector3() const noexcept
{
return reactphysics3d::Vector3{ ToEuler() };
}
SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept
{ {
return rhs * lhs; return rhs * lhs;

View File

@ -11,6 +11,8 @@
#pragma once #pragma once
#include <DirectXMath.h> #include <DirectXMath.h>
#include <reactphysics3d/mathematics/Quaternion.h>
#include <string> #include <string>
// Project Headers // Project Headers
@ -46,12 +48,17 @@ 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 (float x, float y, float z, float w) noexcept; SHQuaternion (float x, float y, float z, float w) noexcept;
SHQuaternion (float yaw, float pitch, float roll) noexcept; SHQuaternion (float yaw, float pitch, float roll) noexcept;
SHQuaternion (const SHVec3& eulerAngles) noexcept; SHQuaternion (const SHVec3& eulerAngles) noexcept;
SHQuaternion (const SHVec3& axis, float angleInRad) noexcept; SHQuaternion (const SHVec3& axis, float angleInRad) noexcept;
SHQuaternion (const SHMatrix& rotationMatrix) noexcept; SHQuaternion (const SHMatrix& rotationMatrix) noexcept;
// Conversion from other math types
SHQuaternion (const reactphysics3d::Vector3& rp3dEuler) noexcept;
SHQuaternion (const reactphysics3d::Quaternion& rp3dQuat) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */
@ -76,6 +83,11 @@ namespace SHADE
[[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept; [[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept; [[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept;
// Conversion to other math types used by SHADE
operator reactphysics3d::Quaternion () const noexcept;
operator reactphysics3d::Vector3 () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -0,0 +1,60 @@
/****************************************************************************************
* \file SHRay.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Ray.
*
* \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 "SHRay.h"
using namespace DirectX;
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHRay::SHRay() noexcept
: direction { 0.0f, 0.0f, 1.0f }
{}
SHRay::SHRay(const SHVec3& pos, const SHVec3& dir) noexcept
: position { pos }
, direction { dir }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHRay::operator==(const SHRay& rhs) noexcept
{
const XMVECTOR LHS_POS = XMLoadFloat3(&position);
const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position);
const XMVECTOR LHS_DIR = XMLoadFloat3(&direction);
const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction);
return XMVector3Equal(LHS_POS, RHS_POS) && XMVector3NotEqual(LHS_DIR, RHS_DIR);
}
bool SHRay::operator!=(const SHRay& rhs) noexcept
{
const XMVECTOR LHS_POS = XMLoadFloat3(&position);
const XMVECTOR RHS_POS = XMLoadFloat3(&rhs.position);
const XMVECTOR LHS_DIR = XMLoadFloat3(&direction);
const XMVECTOR RHS_DIR = XMLoadFloat3(&rhs.direction);
return XMVector3NotEqual(LHS_POS, RHS_POS) || XMVector3NotEqual(LHS_DIR, RHS_DIR);
}
} // namespace SHADE

View File

@ -0,0 +1,54 @@
/****************************************************************************************
* \file SHRay.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Ray.
*
* \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 <DirectXMath.h>
// Project Headers
#include "SH_API.h"
#include "Vector/SHVec3.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
struct SH_API SHRay
{
public:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
SHVec3 position;
SHVec3 direction;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHRay() noexcept;
SHRay(const SHVec3& pos, const SHVec3& dir) noexcept;
SHRay(const SHRay& rhs) noexcept = default;
SHRay(SHRay&& rhs) noexcept = default;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHRay& operator= (const SHRay& rhs) noexcept = default;
SHRay& operator= (SHRay&& rhs) noexcept = default;
[[nodiscard]] bool operator==(const SHRay& rhs) noexcept;
[[nodiscard]] bool operator!=(const SHRay& rhs) noexcept;
};
} // namespace SHADE

View File

@ -38,6 +38,10 @@ namespace SHADE
: XMFLOAT2( 0.0f, 0.0f ) : XMFLOAT2( 0.0f, 0.0f )
{} {}
SHVec2::SHVec2(const XMFLOAT2& xmfloat2) noexcept
: XMFLOAT2 ( xmfloat2.x, xmfloat2.y )
{}
SHVec2::SHVec2(float n) noexcept SHVec2::SHVec2(float n) noexcept
: XMFLOAT2( n, n ) : XMFLOAT2( n, n )
{} {}
@ -46,10 +50,19 @@ namespace SHADE
: XMFLOAT2( _x, _y ) : XMFLOAT2( _x, _y )
{} {}
SHVec2::SHVec2(const reactphysics3d::Vector2& rp3dVec2) noexcept
: XMFLOAT2( rp3dVec2.x, rp3dVec2.y )
{}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */ /* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHVec2::operator XMVECTOR() const noexcept
{
return XMLoadFloat2(this);
}
SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept
{ {
return *this = *this + rhs; return *this = *this + rhs;
@ -83,22 +96,16 @@ namespace SHADE
SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorAdd(V1, V2)); XMStoreFloat2(&result, XMVectorAdd(*this, rhs));
return result; return result;
} }
SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorSubtract(V1, V2)); XMStoreFloat2(&result, XMVectorSubtract(*this, rhs));
return result; return result;
} }
@ -110,59 +117,43 @@ namespace SHADE
SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorMultiply(V1, V2)); XMStoreFloat2(&result, XMVectorMultiply(*this, rhs));
return result; return result;
} }
SHVec2 SHVec2::operator*(float rhs) const noexcept SHVec2 SHVec2::operator*(float rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, rhs)); XMStoreFloat2(&result, XMVectorScale(*this, rhs));
return result; return result;
} }
SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorDivide(V1, V2)); XMStoreFloat2(&result, XMVectorDivide(*this, rhs));
return result; return result;
} }
SHVec2 SHVec2::operator/(float rhs) const noexcept SHVec2 SHVec2::operator/(float rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(this);
XMStoreFloat2(&result, XMVectorScale(V, 1.0f / rhs)); XMStoreFloat2(&result, XMVectorScale(*this, 1.0f / rhs));
return result; return result;
} }
bool SHVec2::operator==(const SHVec2& rhs) const noexcept bool SHVec2::operator==(const SHVec2& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat2(this); return XMVector2Equal(*this, rhs);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2Equal(V1, V2);
} }
bool SHVec2::operator!=(const SHVec2& rhs) const noexcept bool SHVec2::operator!=(const SHVec2& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat2(this); return XMVector2NotEqual(*this, rhs);
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVector2NotEqual(V1, V2);
} }
float& SHVec2::operator[](int index) float& SHVec2::operator[](int index)
@ -213,13 +204,16 @@ namespace SHADE
} }
} }
SHVec2::operator reactphysics3d::Vector2() const noexcept
{
return reactphysics3d::Vector2{ x, y };
}
SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVectorScale(V, lhs)); XMStoreFloat2(&result, XMVectorScale(rhs, lhs));
return result; return result;
} }
@ -229,16 +223,12 @@ namespace SHADE
float SHVec2::Length() const noexcept float SHVec2::Length() const noexcept
{ {
const XMVECTOR V = XMLoadFloat2(this); return XMVectorGetX(XMVector2Length(*this));
return XMVectorGetX(XMVector2Length(V));
} }
float SHVec2::LengthSquared() const noexcept float SHVec2::LengthSquared() const noexcept
{ {
const XMVECTOR V = XMLoadFloat2(this); return XMVectorGetX(XMVector2LengthSq(*this));
return XMVectorGetX(XMVector2LengthSq(V));
} }
std::string SHVec2::ToString() const noexcept std::string SHVec2::ToString() const noexcept
@ -251,20 +241,14 @@ namespace SHADE
float SHVec2::Dot(const SHVec2& rhs) const noexcept float SHVec2::Dot(const SHVec2& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat2(this); return XMVectorGetX(XMVector2Dot(*this, rhs));
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2Dot(V1, V2));
} }
SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(this); XMStoreFloat2(&result, XMVector2Cross(*this, rhs));
const XMVECTOR V2 = XMLoadFloat2(&rhs);
XMStoreFloat2(&result, XMVector2Cross(V1, V2));
return result; return result;
} }
@ -276,9 +260,7 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&vec2); XMStoreFloat2(&result, XMVector2Normalize(vec2));
XMStoreFloat2(&result, XMVector2Normalize(V));
return result; return result;
} }
@ -297,10 +279,10 @@ namespace SHADE
SHVec2 result; SHVec2 result;
XMVECTOR min = XMLoadFloat2(&(*vec2s.begin())); XMVECTOR min = *vec2s.begin();
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat2(&(*it)); const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp); min = XMVectorMin(min, tmp);
} }
@ -318,10 +300,10 @@ namespace SHADE
SHVec2 result; SHVec2 result;
XMVECTOR max = XMLoadFloat2(&(*vec2s.begin())); XMVECTOR max = *vec2s.begin();
for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat2(&(*it)); const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp); max = XMVectorMax(max, tmp);
} }
@ -333,11 +315,7 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v); XMStoreFloat2(&result, XMVectorClamp(v, vMin, vMax));
const XMVECTOR MIN = XMLoadFloat2(&vMin);
const XMVECTOR MAX = XMLoadFloat2(&vMax);
XMStoreFloat2(&result, XMVectorClamp(V, MIN, MAX));
return result; return result;
} }
@ -345,10 +323,7 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V1 = XMLoadFloat2(&a); XMStoreFloat2(&result, XMVectorLerp(a, b, t));
const XMVECTOR V2 = XMLoadFloat2(&b);
XMStoreFloat2(&result, XMVectorLerp(V1, V2, t));
return result; return result;
} }
@ -369,10 +344,7 @@ namespace SHADE
float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept
{ {
const XMVECTOR V1 = XMLoadFloat2(&lhs); return XMVectorGetX(XMVector2AngleBetweenVectors(lhs, rhs));
const XMVECTOR V2 = XMLoadFloat2(&rhs);
return XMVectorGetX(XMVector2AngleBetweenVectors(V1, V2));
} }
float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept
@ -384,11 +356,10 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR U = XMLoadFloat2(&u);
const float V_DOT_U = Dot(v, u); const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared(); const float U_LENSQ = u.LengthSquared();
XMStoreFloat2(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); XMStoreFloat2(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result; return result;
} }
@ -396,10 +367,8 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMVECTOR N = XMLoadFloat2(&normal);
XMStoreFloat2(&result, XMVector2Reflect(V, N)); XMStoreFloat2(&result, XMVector2Reflect(v, normal));
return result; return result;
} }
@ -407,10 +376,9 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX R = XMMatrixRotationZ(angleInRad); const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat2(&result, XMVector2Transform(V, R)); XMStoreFloat2(&result, XMVector2Transform(v, R));
return result; return result;
} }
@ -418,10 +386,9 @@ namespace SHADE
{ {
SHVec2 result; SHVec2 result;
const XMVECTOR V = XMLoadFloat2(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat2(&result, XMVector2TransformCoord(V, TF)); XMStoreFloat2(&result, XMVector2TransformCoord(v, TF));
return result; return result;
} }

View File

@ -11,6 +11,8 @@
#pragma once #pragma once
#include <DirectXMath.h> #include <DirectXMath.h>
#include <reactphysics3d/mathematics/Vector2.h>
#include <string> #include <string>
#include <initializer_list> #include <initializer_list>
@ -52,9 +54,14 @@ namespace SHADE
SHVec2 (SHVec2&& rhs) = default; SHVec2 (SHVec2&& rhs) = default;
~SHVec2 () = default; ~SHVec2 () = default;
SHVec2 () noexcept; SHVec2 () noexcept;
SHVec2 (float n) noexcept; SHVec2 (const XMFLOAT2& xmfloat2) noexcept;
SHVec2 (float x, float y) noexcept; SHVec2 (float n) noexcept;
SHVec2 (float x, float y) noexcept;
// Conversion from other math types to SHADE
SHVec2 (const reactphysics3d::Vector2& rp3dVec2) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */
@ -63,6 +70,11 @@ namespace SHADE
SHVec2& operator= (const SHVec2& rhs) = default; SHVec2& operator= (const SHVec2& rhs) = default;
SHVec2& operator= (SHVec2&& rhs) = default; SHVec2& operator= (SHVec2&& rhs) = default;
// Conversion to other math types used by SHADE
operator DirectX::XMVECTOR () const noexcept;
operator reactphysics3d::Vector2 () const noexcept;
SHVec2& operator+= (const SHVec2& rhs) noexcept; SHVec2& operator+= (const SHVec2& rhs) noexcept;
SHVec2& operator-= (const SHVec2& rhs) noexcept; SHVec2& operator-= (const SHVec2& rhs) noexcept;
SHVec2& operator*= (const SHVec2& rhs) noexcept; SHVec2& operator*= (const SHVec2& rhs) noexcept;
@ -86,6 +98,7 @@ namespace SHADE
[[nodiscard]] float operator[] (int index) const; [[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const; [[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -14,6 +14,7 @@
#include "SHVec3.h" #include "SHVec3.h"
// Project Headers // Project Headers
#include "Math/SHMatrix.h" #include "Math/SHMatrix.h"
#include "Math/SHQuaternion.h"
#include "Tools/SHLogger.h" #include "Tools/SHLogger.h"
using namespace DirectX; using namespace DirectX;
@ -23,6 +24,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */ /* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f }; SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f };
SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f }; SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f };
SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f }; SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f };
@ -43,6 +45,10 @@ namespace SHADE
: XMFLOAT3( 0.0f, 0.0f, 0.0f ) : XMFLOAT3( 0.0f, 0.0f, 0.0f )
{} {}
SHVec3::SHVec3(const XMFLOAT3& xmfloat3) noexcept
: XMFLOAT3 ( xmfloat3.x, xmfloat3.y, xmfloat3.z )
{}
SHVec3::SHVec3(float n) noexcept SHVec3::SHVec3(float n) noexcept
: XMFLOAT3( n, n, n ) : XMFLOAT3( n, n, n )
{} {}
@ -51,10 +57,24 @@ namespace SHADE
: XMFLOAT3( _x, _y, _z ) : XMFLOAT3( _x, _y, _z )
{} {}
SHVec3::SHVec3(const reactphysics3d::Vector3& rp3dVec3) noexcept
: XMFLOAT3( rp3dVec3.x, rp3dVec3.y, rp3dVec3.z )
{}
SHVec3::SHVec3(const reactphysics3d::Quaternion& rp3dVec3) noexcept
: XMFLOAT3( SHQuaternion{rp3dVec3}.ToEuler() )
{}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */ /* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHVec3::operator XMVECTOR() const noexcept
{
return XMLoadFloat3(this);
}
SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept
{ {
return *this = *this + rhs; return *this = *this + rhs;
@ -88,22 +108,16 @@ namespace SHADE
SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorAdd(V1, V2)); XMStoreFloat3(&result, XMVectorAdd(*this, rhs));
return result; return result;
} }
SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorSubtract(V1, V2)); XMStoreFloat3(&result, XMVectorSubtract(*this, rhs));
return result; return result;
} }
@ -116,59 +130,43 @@ namespace SHADE
SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorMultiply(V1, V2)); XMStoreFloat3(&result, XMVectorMultiply(*this, rhs));
return result; return result;
} }
SHVec3 SHVec3::operator*(float rhs) const noexcept SHVec3 SHVec3::operator*(float rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, rhs)); XMStoreFloat3(&result, XMVectorScale(*this, rhs));
return result; return result;
} }
SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorDivide(V1, V2)); XMStoreFloat3(&result, XMVectorDivide(*this, rhs));
return result; return result;
} }
SHVec3 SHVec3::operator/(float rhs) const noexcept SHVec3 SHVec3::operator/(float rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(this);
XMStoreFloat3(&result, XMVectorScale(V, 1.0f / rhs)); XMStoreFloat3(&result, XMVectorScale(*this, 1.0f / rhs));
return result; return result;
} }
bool SHVec3::operator==(const SHVec3& rhs) const noexcept bool SHVec3::operator==(const SHVec3& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat3(this); return XMVector3Equal(*this, rhs);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3Equal(V1, V2);
} }
bool SHVec3::operator!=(const SHVec3& rhs) const noexcept bool SHVec3::operator!=(const SHVec3& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat3(this); return XMVector3NotEqual(*this, rhs);
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVector3NotEqual(V1, V2);
} }
float& SHVec3::operator[](int index) float& SHVec3::operator[](int index)
@ -223,13 +221,21 @@ namespace SHADE
} }
} }
SHVec3::operator reactphysics3d::Vector3() const noexcept
{
return reactphysics3d::Vector3{ x, y , z };
}
SHVec3::operator reactphysics3d::Quaternion() const noexcept
{
return reactphysics3d::Quaternion::fromEulerAngles(x, y, z);
}
SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVectorScale(V, lhs)); XMStoreFloat3(&result, XMVectorScale(rhs, lhs));
return result; return result;
} }
@ -239,16 +245,12 @@ namespace SHADE
float SHVec3::Length() const noexcept float SHVec3::Length() const noexcept
{ {
const XMVECTOR V = XMLoadFloat3(this); return XMVectorGetX(XMVector3Length(*this));
return XMVectorGetX(XMVector3Length(V));
} }
float SHVec3::LengthSquared() const noexcept float SHVec3::LengthSquared() const noexcept
{ {
const XMVECTOR V = XMLoadFloat3(this); return XMVectorGetX(XMVector3LengthSq(*this));
return XMVectorGetX(XMVector3LengthSq(V));
} }
std::string SHVec3::ToString() const noexcept std::string SHVec3::ToString() const noexcept
@ -261,20 +263,14 @@ namespace SHADE
float SHVec3::Dot(const SHVec3& rhs) const noexcept float SHVec3::Dot(const SHVec3& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat3(this); return XMVectorGetX(XMVector3Dot(*this, rhs));
const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
} }
SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(this); XMStoreFloat3(&result, XMVector3Cross(*this, rhs));
const XMVECTOR V2 = XMLoadFloat3(&rhs);
XMStoreFloat3(&result, XMVector3Cross(V1, V2));
return result; return result;
} }
@ -286,9 +282,7 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); XMStoreFloat3(&result, XMVector3Normalize(v));
XMStoreFloat3(&result, XMVector3Normalize(V));
return result; return result;
} }
@ -307,10 +301,10 @@ namespace SHADE
SHVec3 result; SHVec3 result;
XMVECTOR min = XMLoadFloat3(&(*vs.begin())); XMVECTOR min = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it) for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat3(&(*it)); const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp); min = XMVectorMin(min, tmp);
} }
@ -328,10 +322,10 @@ namespace SHADE
SHVec3 result; SHVec3 result;
XMVECTOR max = XMLoadFloat3(&(*vs.begin())); XMVECTOR max = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it) for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat3(&(*it)); const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp); max = XMVectorMax(max, tmp);
} }
@ -343,11 +337,7 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); XMStoreFloat3(&result, XMVectorClamp(v, vMin, vMax));
const XMVECTOR MIN = XMLoadFloat3(&vMin);
const XMVECTOR MAX = XMLoadFloat3(&vMax);
XMStoreFloat3(&result, XMVectorClamp(V, MIN, MAX));
return result; return result;
} }
@ -355,10 +345,7 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V1 = XMLoadFloat3(&a); XMStoreFloat3(&result, XMVectorLerp(a, b, t));
const XMVECTOR V2 = XMLoadFloat3(&b);
XMStoreFloat3(&result, XMVectorLerp(V1, V2, t));
return result; return result;
} }
@ -382,7 +369,7 @@ namespace SHADE
const XMVECTOR V1 = XMLoadFloat3(&lhs); const XMVECTOR V1 = XMLoadFloat3(&lhs);
const XMVECTOR V2 = XMLoadFloat3(&rhs); const XMVECTOR V2 = XMLoadFloat3(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2)); return XMVectorGetX(XMVector3AngleBetweenVectors(lhs, rhs));
} }
float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept
@ -399,22 +386,18 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR U = XMLoadFloat3(&u);
const float V_DOT_U = Dot(v, u); const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared(); const float U_LENSQ = u.LengthSquared();
XMStoreFloat3(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); XMStoreFloat3(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result; return result;
} }
SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMVECTOR N = XMLoadFloat3(&normal);
XMStoreFloat3(&result, XMVector3Reflect(V, N)); XMStoreFloat3(&result, XMVector3Reflect(v, normal));
return result; return result;
} }
@ -422,12 +405,9 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); const XMVECTOR Q = XMQuaternionRotationAxis(axis, angleInRad);
const XMVECTOR AXIS = XMLoadFloat3(&axis); XMStoreFloat3(&result, XMVector3Rotate(v, Q));
const XMVECTOR Q = XMQuaternionRotationAxis(AXIS, angleInRad);
XMStoreFloat3(&result, XMVector3Rotate(V, Q));
return result; return result;
} }
@ -435,10 +415,9 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); const XMMATRIX R = XMMatrixRotationX(angleInRad);
const XMMATRIX R = XMMatrixRotationX(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result; return result;
} }
@ -446,10 +425,9 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); const XMMATRIX R = XMMatrixRotationY(angleInRad);
const XMMATRIX R = XMMatrixRotationY(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result; return result;
} }
@ -457,10 +435,9 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v); const XMMATRIX R = XMMatrixRotationZ(angleInRad);
const XMMATRIX R = XMMatrixRotationZ(angleInRad);
XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); XMStoreFloat3(&result, XMVector3TransformCoord(v, R));
return result; return result;
} }
@ -468,10 +445,9 @@ namespace SHADE
{ {
SHVec3 result; SHVec3 result;
const XMVECTOR V = XMLoadFloat3(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat3(&result, XMVector3TransformCoord(V, TF)); XMStoreFloat3(&result, XMVector3TransformCoord(v, TF));
return result; return result;
} }
} }

View File

@ -11,6 +11,9 @@
#pragma once #pragma once
#include <DirectXMath.h> #include <DirectXMath.h>
#include <reactphysics3d/mathematics/Vector3.h>
#include <reactphysics3d/mathematics/Quaternion.h>
#include <string> #include <string>
#include <initializer_list> #include <initializer_list>
@ -58,39 +61,50 @@ namespace SHADE
~SHVec3 () = default; ~SHVec3 () = default;
SHVec3 () noexcept; SHVec3 () noexcept;
SHVec3 (const XMFLOAT3& xmfloat3) noexcept;
SHVec3 (float n) noexcept; SHVec3 (float n) noexcept;
SHVec3 (float x, float y, float z) noexcept; SHVec3 (float x, float y, float z) noexcept;
// Conversion from other math types to SHADE
SHVec3 (const reactphysics3d::Vector3& rp3dVec3) noexcept;
SHVec3 (const reactphysics3d::Quaternion& rp3dVec3) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHVec3& operator= (const SHVec3& rhs) = default; SHVec3& operator= (const SHVec3& rhs) = default;
SHVec3& operator= (SHVec3&& rhs) = default; SHVec3& operator= (SHVec3&& rhs) = default;
SHVec3& operator+= (const SHVec3& rhs) noexcept; // Conversion to other math types used by SHADE
SHVec3& operator-= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (float rhs) noexcept;
SHVec3& operator/= (const SHVec3& rhs) noexcept;
SHVec3& operator/= (float rhs) noexcept;
[[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept; operator reactphysics3d::Vector3 () const noexcept;
[[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept; operator reactphysics3d::Quaternion () const noexcept;
[[nodiscard]] SHVec3 operator- () const noexcept; operator DirectX::XMVECTOR () const noexcept;
[[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; SHVec3& operator+= (const SHVec3& rhs) noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; SHVec3& operator-= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (const SHVec3& rhs) noexcept;
SHVec3& operator*= (float rhs) noexcept;
SHVec3& operator/= (const SHVec3& rhs) noexcept;
SHVec3& operator/= (float rhs) noexcept;
[[nodiscard]] float& operator[] (int index); [[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept;
[[nodiscard]] float& operator[] (size_t index); [[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept;
[[nodiscard]] float operator[] (int index) const; [[nodiscard]] SHVec3 operator- () const noexcept;
[[nodiscard]] float operator[] (size_t index) const; [[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator* (float rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept;
[[nodiscard]] SHVec3 operator/ (float rhs) const noexcept;
[[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept;
[[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept;
[[nodiscard]] float& operator[] (int index);
[[nodiscard]] float& operator[] (size_t index);
[[nodiscard]] float operator[] (int index) const;
[[nodiscard]] float operator[] (size_t index) const;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */

View File

@ -38,6 +38,10 @@ namespace SHADE
: XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) : XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f )
{} {}
SHVec4::SHVec4(const XMFLOAT4& xmfloat4) noexcept
: XMFLOAT4( xmfloat4.x, xmfloat4.y, xmfloat4.z, xmfloat4.w )
{}
SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept
: XMFLOAT4( _x, _y, _z, _w ) : XMFLOAT4( _x, _y, _z, _w )
{} {}
@ -46,6 +50,11 @@ namespace SHADE
/* Operator Overload Definitions */ /* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHVec4::operator XMVECTOR() const noexcept
{
return XMLoadFloat4(this);
}
SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept
{ {
return *this = *this + rhs; return *this = *this + rhs;
@ -79,22 +88,16 @@ namespace SHADE
SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorAdd(V1, V2)); XMStoreFloat4(&result, XMVectorAdd(*this, rhs));
return result; return result;
} }
SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorSubtract(V1, V2)); XMStoreFloat4(&result, XMVectorSubtract(*this, rhs));
return result; return result;
} }
@ -106,59 +109,43 @@ namespace SHADE
SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorMultiply(V1, V2)); XMStoreFloat4(&result, XMVectorMultiply(*this, rhs));
return result; return result;
} }
SHVec4 SHVec4::operator*(float rhs) const noexcept SHVec4 SHVec4::operator*(float rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, rhs)); XMStoreFloat4(&result, XMVectorScale(*this, rhs));
return result; return result;
} }
SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorDivide(V1, V2)); XMStoreFloat4(&result, XMVectorDivide(*this, rhs));
return result; return result;
} }
SHVec4 SHVec4::operator/(float rhs) const noexcept SHVec4 SHVec4::operator/(float rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(this);
XMStoreFloat4(&result, XMVectorScale(V, 1.0f / rhs)); XMStoreFloat4(&result, XMVectorScale(*this, 1.0f / rhs));
return result; return result;
} }
bool SHVec4::operator==(const SHVec4& rhs) const noexcept bool SHVec4::operator==(const SHVec4& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(this); return XMVector4Equal(*this, rhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4Equal(V1, V2);
} }
bool SHVec4::operator!=(const SHVec4& rhs) const noexcept bool SHVec4::operator!=(const SHVec4& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(this); return XMVector4NotEqual(*this, rhs);
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVector4NotEqual(V1, V2);
} }
float& SHVec4::operator[](int index) float& SHVec4::operator[](int index)
@ -220,10 +207,8 @@ namespace SHADE
SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVectorScale(V, lhs)); XMStoreFloat4(&result, XMVectorScale(rhs, lhs));
return result; return result;
} }
@ -233,30 +218,22 @@ namespace SHADE
float SHVec4::Length() const noexcept float SHVec4::Length() const noexcept
{ {
const XMVECTOR V = XMLoadFloat4(this); return XMVectorGetX(XMVector4Length(*this));
return XMVectorGetX(XMVector4Length(V));
} }
float SHVec4::Length3D() const noexcept float SHVec4::Length3D() const noexcept
{ {
const XMVECTOR V = XMLoadFloat4(this); return XMVectorGetX(XMVector3Length(*this));
return XMVectorGetX(XMVector3Length(V));
} }
float SHVec4::LengthSquared() const noexcept float SHVec4::LengthSquared() const noexcept
{ {
const XMVECTOR V = XMLoadFloat4(this); return XMVectorGetX(XMVector4LengthSq(*this));
return XMVectorGetX(XMVector4LengthSq(V));
} }
float SHVec4::LengthSquared3D() const noexcept float SHVec4::LengthSquared3D() const noexcept
{ {
const XMVECTOR V = XMLoadFloat4(this); return XMVectorGetX(XMVector3LengthSq(*this));
return XMVectorGetX(XMVector3LengthSq(V));
} }
std::string SHVec4::ToString() const noexcept std::string SHVec4::ToString() const noexcept
@ -269,28 +246,19 @@ namespace SHADE
float SHVec4::Dot(const SHVec4& rhs) const noexcept float SHVec4::Dot(const SHVec4& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(this); return XMVectorGetX(XMVector4Dot(*this, rhs));
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4Dot(V1, V2));
} }
float SHVec4::Dot3D(const SHVec4& rhs) const noexcept float SHVec4::Dot3D(const SHVec4& rhs) const noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(this); return XMVectorGetX(XMVector3Dot(*this, rhs));
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3Dot(V1, V2));
} }
SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(this); XMStoreFloat4(&result, XMVector3Cross(*this, rhs));
const XMVECTOR V2 = XMLoadFloat4(&rhs);
XMStoreFloat4(&result, XMVector3Cross(V1, V2));
result.w = 1.0f; result.w = 1.0f;
return result; return result;
} }
@ -299,11 +267,7 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V3 = XMLoadFloat4(this); XMStoreFloat4(&result, XMVector4Cross(*this, v1, v2));
const XMVECTOR V1 = XMLoadFloat4(&v1);
const XMVECTOR V2 = XMLoadFloat4(&v2);
XMStoreFloat4(&result, XMVector4Cross(V3, V1, V2));
return result; return result;
} }
@ -315,9 +279,7 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v); XMStoreFloat4(&result, XMVector4Normalize(v));
XMStoreFloat4(&result, XMVector4Normalize(V));
return result; return result;
} }
@ -325,9 +287,7 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v); XMStoreFloat4(&result, XMVector3Normalize(v));
XMStoreFloat4(&result, XMVector3Normalize(V));
result.w = 1.0f; result.w = 1.0f;
return result; return result;
} }
@ -347,10 +307,10 @@ namespace SHADE
SHVec4 result; SHVec4 result;
XMVECTOR min = XMLoadFloat4(&(*vs.begin())); XMVECTOR min = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it) for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat4(&(*it)); const XMVECTOR tmp = *it;
min = XMVectorMin(min, tmp); min = XMVectorMin(min, tmp);
} }
@ -368,10 +328,10 @@ namespace SHADE
SHVec4 result; SHVec4 result;
XMVECTOR max = XMLoadFloat4(&(*vs.begin())); XMVECTOR max = *vs.begin();
for (auto it = vs.begin() + 1; it != vs.end(); ++it) for (auto it = vs.begin() + 1; it != vs.end(); ++it)
{ {
const XMVECTOR tmp = XMLoadFloat4(&(*it)); const XMVECTOR tmp = *it;
max = XMVectorMax(max, tmp); max = XMVectorMax(max, tmp);
} }
@ -383,11 +343,7 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v); XMStoreFloat4(&result, XMVectorClamp(v, vMin, vMax));
const XMVECTOR MIN = XMLoadFloat4(&vMin);
const XMVECTOR MAX = XMLoadFloat4(&vMax);
XMStoreFloat4(&result, XMVectorClamp(V, MIN, MAX));
return result; return result;
} }
@ -395,10 +351,7 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V1 = XMLoadFloat4(&a); XMStoreFloat4(&result, XMVectorLerp(a, b, t));
const XMVECTOR V2 = XMLoadFloat4(&b);
XMStoreFloat4(&result, XMVectorLerp(V1, V2, t));
return result; return result;
} }
@ -429,18 +382,12 @@ namespace SHADE
float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(&lhs); return XMVectorGetX(XMVector4AngleBetweenVectors(lhs,rhs));
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector4AngleBetweenVectors(V1, V2));
} }
float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept
{ {
const XMVECTOR V1 = XMLoadFloat4(&lhs); return XMVectorGetX(XMVector3AngleBetweenVectors(lhs,rhs));
const XMVECTOR V2 = XMLoadFloat4(&rhs);
return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2));
} }
float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept
@ -467,11 +414,10 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot(v, u); const float V_DOT_U = Dot(v, u);
const float U_LENSQ = u.LengthSquared(); const float U_LENSQ = u.LengthSquared();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
return result; return result;
} }
@ -479,11 +425,10 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR U = XMLoadFloat4(&u);
const float V_DOT_U = Dot3D(v, u); const float V_DOT_U = Dot3D(v, u);
const float U_LENSQ = u.LengthSquared3D(); const float U_LENSQ = u.LengthSquared3D();
XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); XMStoreFloat4(&result, XMVectorScale(u, V_DOT_U / U_LENSQ));
result.w = 1.0f; result.w = 1.0f;
return result; return result;
} }
@ -491,11 +436,8 @@ namespace SHADE
SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector4Reflect(V, N)); XMStoreFloat4(&result, XMVector4Reflect(v, normal));
result.w = 1.0f; result.w = 1.0f;
return result; return result;
} }
@ -503,11 +445,8 @@ namespace SHADE
SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMVECTOR N = XMLoadFloat4(&normal);
XMStoreFloat4(&result, XMVector3Reflect(V, N)); XMStoreFloat4(&result, XMVector3Reflect(v, normal));
result.w = 1.0f; result.w = 1.0f;
return result; return result;
} }
@ -516,10 +455,9 @@ namespace SHADE
{ {
SHVec4 result; SHVec4 result;
const XMVECTOR V = XMLoadFloat4(&v);
const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); const XMMATRIX TF = XMLoadFloat4x4(&transformMtx);
XMStoreFloat4(&result, XMVector3TransformCoord(V, TF)); XMStoreFloat4(&result, XMVector3TransformCoord(v, TF));
return result; return result;
} }
} }

View File

@ -52,8 +52,9 @@ namespace SHADE
SHVec4 (SHVec4&& rhs) = default; SHVec4 (SHVec4&& rhs) = default;
~SHVec4 () = default; ~SHVec4 () = default;
SHVec4 () noexcept; SHVec4 () noexcept;
SHVec4 (float x, float y, float z, float w) noexcept; SHVec4 (const XMFLOAT4& xmfloat4) noexcept;
SHVec4 (float x, float y, float z, float w) noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Operator Overloads */ /* Operator Overloads */
@ -62,6 +63,8 @@ namespace SHADE
SHVec4& operator= (const SHVec4& rhs) = default; SHVec4& operator= (const SHVec4& rhs) = default;
SHVec4& operator= (SHVec4&& rhs) = default; SHVec4& operator= (SHVec4&& rhs) = default;
operator DirectX::XMVECTOR () const noexcept;
SHVec4& operator+= (const SHVec4& rhs) noexcept; SHVec4& operator+= (const SHVec4& rhs) noexcept;
SHVec4& operator-= (const SHVec4& rhs) noexcept; SHVec4& operator-= (const SHVec4& rhs) noexcept;
SHVec4& operator*= (const SHVec4& rhs) noexcept; SHVec4& operator*= (const SHVec4& rhs) noexcept;

View File

@ -15,6 +15,7 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "Math/SHMathHelpers.h"
#include "Physics/SHPhysicsSystem.h" #include "Physics/SHPhysicsSystem.h"
namespace SHADE namespace SHADE
@ -24,7 +25,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHColliderComponent::SHColliderComponent() noexcept SHColliderComponent::SHColliderComponent() noexcept
: system { nullptr } : system { nullptr }
, colliders {}
{} {}
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -87,12 +89,17 @@ namespace SHADE
system->RemoveCollider(GetEID()); system->RemoveCollider(GetEID());
} }
SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept
{ {
const auto TYPE = SHCollider::Type::BOX; const auto TYPE = SHCollider::Type::BOX;
const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true); auto boxPair = std::make_pair(SHCollider{TYPE}, true);
auto& collider = colliders.emplace_back(BOX_PAIR).first; auto& collider = colliders.emplace_back(boxPair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.SetPositionOffset(posOffset);
collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents);
if (!system) if (!system)
{ {
@ -101,23 +108,37 @@ namespace SHADE
} }
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), collider.GetShape()); system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingBox*>(collider.GetShape()); return reinterpret_cast<SHBoundingBox*>(collider.GetShape());
} }
//void SHColliderComponent::AddSphere() noexcept SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
//{ {
// const auto TYPE = SHCollider::Type::SPHERE; const auto TYPE = SHCollider::Type::SPHERE;
// if (!system) auto spherePair = std::make_pair(SHCollider{ TYPE }, true);
// { auto& collider = colliders.emplace_back(spherePair).first;
// SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
// return;
// }
// // Notify Physics System const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
//}
collider.SetPositionOffset(posOffset);
const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
collider.SetAsBoundingSphere(MAX_SCALE * 0.5f);
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
return nullptr;
}
// Notify Physics System
system->AddCollisionShape(GetEID(), &collider);
return reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
}
void SHColliderComponent::RemoveCollider(int index) void SHColliderComponent::RemoveCollider(int index)
{ {

View File

@ -15,6 +15,13 @@
// Project Headers // Project Headers
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHCollider.h" #include "Physics/SHCollider.h"
#include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE namespace SHADE
{ {
@ -30,6 +37,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem; friend class SHPhysicsSystem;
friend class SHPhysicsObject;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -76,10 +84,11 @@ namespace SHADE
void OnCreate () override; void OnCreate () override;
void OnDestroy () override; void OnDestroy () override;
SHBoundingBox* AddBoundingBox () noexcept;
void RemoveCollider (int index); void RemoveCollider (int index);
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -392,9 +392,9 @@ RTTR_REGISTRATION
registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type") registration::enumeration<SHRigidBodyComponent::Type>("RigidBody Type")
( (
value("Static", SHRigidBodyComponent::Type::STATIC), value("Static", SHRigidBodyComponent::Type::STATIC),
value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC), value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC),
value("Kinematic", SHRigidBodyComponent::Type::KINEMATIC) value("Dynamic", SHRigidBodyComponent::Type::DYNAMIC)
); );
registration::class_<SHRigidBodyComponent>("RigidBody Component") registration::class_<SHRigidBodyComponent>("RigidBody Component")

View File

@ -14,7 +14,13 @@
// Project Headers // Project Headers
#include "ECS_Base/Components/SHComponent.h" #include "ECS_Base/Components/SHComponent.h"
#include "Physics/SHPhysicsObject.h" #include "Math/Vector/SHVec3.h"
#include "Math/SHQuaternion.h"
//namespace SHADE
//{
// class SHPhysicsSystem;
//}
namespace SHADE namespace SHADE
{ {
@ -30,6 +36,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem; friend class SHPhysicsSystem;
friend class SHPhysicsObject;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -137,6 +144,9 @@ namespace SHADE
/* Data Members */ /* Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static constexpr size_t NUM_FLAGS = 8;
static constexpr size_t NUM_DIRTY_FLAGS = 16;
Type type; Type type;
// rX rY rZ pX pY pZ slp g // rX rY rZ pX pY pZ slp g
@ -162,10 +172,6 @@ namespace SHADE
SHVec3 position; SHVec3 position;
SHQuaternion orientation; SHQuaternion orientation;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
RTTR_ENABLE() RTTR_ENABLE()
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -12,6 +12,9 @@
// Primary Header // Primary Header
#include "SHCollider.h" #include "SHCollider.h"
// Project Headers
#include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h"
namespace SHADE namespace SHADE
{ {
@ -25,34 +28,41 @@ namespace SHADE
, dirty { true } , dirty { true }
, shape { nullptr } , shape { nullptr }
{ {
CreateShape(); switch (type)
{
case Type::BOX:
{
SetAsBoundingBox(SHVec3::One);
break;
}
case Type::SPHERE:
{
SetAsBoundingSphere(1.0f);
break;
}
default: break;
}
} }
SHCollider::SHCollider(const SHCollider& rhs) noexcept SHCollider::SHCollider(const SHCollider& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { nullptr } , shape { rhs.shape }
{ , positionOffset { rhs.positionOffset }
CreateShape(); {}
// TODO(Diren): Copy transform data over
}
SHCollider::SHCollider(SHCollider&& rhs) noexcept SHCollider::SHCollider(SHCollider&& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { nullptr } , shape { rhs.shape }
{ , positionOffset { rhs.positionOffset }
CreateShape(); {}
// TODO(Diren): Copy transform data over
}
SHCollider::~SHCollider() noexcept SHCollider::~SHCollider() noexcept
{ {
delete shape; shape = nullptr;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -61,26 +71,25 @@ namespace SHADE
SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept
{ {
type = rhs.type; if (this == &rhs)
isTrigger = rhs.isTrigger; return *this;
dirty = true;
type = rhs.type;
CreateShape(); isTrigger = rhs.isTrigger;
dirty = true;
// TODO(Diren): Copy transform data over shape = rhs.shape;
positionOffset = rhs.positionOffset;
return *this; return *this;
} }
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{ {
type = rhs.type; type = rhs.type;
isTrigger = rhs.isTrigger; isTrigger = rhs.isTrigger;
dirty = true; dirty = true;
shape = rhs.shape;
CreateShape(); positionOffset = rhs.positionOffset;
// TODO(Diren): Copy transform data over
return *this; return *this;
} }
@ -104,11 +113,6 @@ namespace SHADE
return type; return type;
} }
SHShape* SHCollider::GetShape() const noexcept
{
return shape;
}
float SHCollider::GetFriction() const noexcept float SHCollider::GetFriction() const noexcept
{ {
// TODO(Diren): Fix after implementing materials // TODO(Diren): Fix after implementing materials
@ -126,36 +130,37 @@ namespace SHADE
return 0.0f; return 0.0f;
} }
SHVec3 SHCollider::GetPosition() const noexcept
{
// TODO(Diren): Fix after linking transform data
return SHVec3::Zero;
}
const SHVec3& SHCollider::GetPositionOffset() const noexcept const SHVec3& SHCollider::GetPositionOffset() const noexcept
{ {
return positionOffset; return positionOffset;
} }
SHQuaternion SHCollider::GetOrientation() const noexcept SHShape* SHCollider::GetShape() noexcept
{ {
// TODO(Diren): Fix after linking transform data dirty = true;
return SHQuaternion::Identity; return shape;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHCollider::SetType(Type newType) noexcept void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents)
{ {
if (type == newType)
return;
dirty = true; dirty = true;
type = Type::BOX;
type = newType; delete shape;
CreateShape(); shape = new SHBoundingBox{ positionOffset, halfExtents };
}
void SHCollider::SetAsBoundingSphere(float radius)
{
dirty = true;
type = Type::SPHERE;
delete shape;
shape = new SHBoundingSphere{ positionOffset, radius };
} }
void SHCollider::SetIsTrigger(bool trigger) noexcept void SHCollider::SetIsTrigger(bool trigger) noexcept
@ -184,32 +189,21 @@ namespace SHADE
dirty = true; dirty = true;
positionOffset = posOffset; positionOffset = posOffset;
} }
} // namespace SHADE
/*-----------------------------------------------------------------------------------*/ RTTR_REGISTRATION
/* Private Member Function Definitions */ {
/*-----------------------------------------------------------------------------------*/ using namespace SHADE;
using namespace rttr;
void SHCollider::CreateShape() registration::enumeration<SHCollider::Type>("Collider Type")
{ (
// Remove current shape value("Box", SHCollider::Type::BOX),
delete shape; value("Sphere", SHCollider::Type::SPHERE)
// TODO(Diren): Add More Shapes
);
switch (type) registration::class_<SHCollider>("Collider")
{ .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
case Type::BOX: CreateBoundingBox(); break; // TODO(Diren): Add Physics Materials
case Type::SPHERE: CreateSphere(); break; }
default: break;
}
}
void SHCollider::CreateBoundingBox()
{
shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One };
}
void SHCollider::CreateSphere()
{
}
} // namespace SHADE

View File

@ -10,8 +10,10 @@
#pragma once #pragma once
#include <rttr/registration>
// Project Headers // Project Headers
#include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h" #include "Math/SHQuaternion.h"
namespace SHADE namespace SHADE
@ -32,15 +34,13 @@ namespace SHADE
BOX BOX
, SPHERE , SPHERE
, CAPSULE , CAPSULE
, CONVEX_HULL
, CONVEX_MESH
}; };
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHCollider (Type colliderType); SHCollider (Type colliderType = Type::BOX);
SHCollider (const SHCollider& rhs) noexcept; SHCollider (const SHCollider& rhs) noexcept;
SHCollider (SHCollider&& rhs) noexcept; SHCollider (SHCollider&& rhs) noexcept;
@ -62,28 +62,28 @@ namespace SHADE
[[nodiscard]] bool IsTrigger () const noexcept; [[nodiscard]] bool IsTrigger () const noexcept;
[[nodiscard]] Type GetType () const noexcept; [[nodiscard]] Type GetType () const noexcept;
[[nodiscard]] SHShape* GetShape () const noexcept;
[[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetFriction () const noexcept;
[[nodiscard]] float GetBounciness () const noexcept; [[nodiscard]] float GetBounciness () const noexcept;
[[nodiscard]] float GetDensity () const noexcept; [[nodiscard]] float GetDensity () const noexcept;
[[nodiscard]] SHVec3 GetPosition () const noexcept;
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
[[nodiscard]] SHQuaternion GetOrientation () const noexcept;
[[nodiscard]] SHShape* GetShape () noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetType (Type newType) noexcept; void SetAsBoundingBox (const SHVec3& halfExtents);
void SetAsBoundingSphere (float radius);
void SetIsTrigger (bool isTrigger) noexcept; void SetIsTrigger (bool isTrigger) noexcept;
void SetFriction (float friction) noexcept; void SetFriction (float friction) noexcept;
void SetBounciness (float bounciness) noexcept; void SetBounciness (float bounciness) noexcept;
void SetDensity (float density) noexcept; void SetDensity (float density) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept; void SetPositionOffset (const SHVec3& positionOffset) noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -96,13 +96,7 @@ namespace SHADE
SHShape* shape; SHShape* shape;
SHVec3 positionOffset; SHVec3 positionOffset;
/*---------------------------------------------------------------------------------*/ RTTR_ENABLE()
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateShape ();
void CreateBoundingBox ();
void CreateSphere ();
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -15,7 +15,8 @@
// Project Headers // Project Headers
#include "ECS_Base/Managers/SHSystemManager.h" #include "ECS_Base/Managers/SHSystemManager.h"
#include "SHPhysicsSystem.h" #include "ECS_Base/Managers/SHComponentManager.h"
namespace SHADE namespace SHADE
{ {
@ -23,16 +24,20 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHPhysicsObject::SHPhysicsObject() noexcept SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
: entityID { MAX_EID } : entityID { eid }
, isRigidBody { false } , isRigidBody { false }
, hasColliders{ false } , hasColliders{ false }
, factory { physicsFactory }
, world { physicsWorld }
, rp3dBody { nullptr } , rp3dBody { nullptr }
{} {}
SHPhysicsObject::~SHPhysicsObject() noexcept SHPhysicsObject::~SHPhysicsObject() noexcept
{ {
rp3dBody = nullptr; factory = nullptr;
world = nullptr;
rp3dBody = nullptr;
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -44,10 +49,7 @@ namespace SHADE
SHVec3 result; SHVec3 result;
if (rp3dBody) if (rp3dBody)
{ result = SHVec3{ rp3dBody->getTransform().getPosition() };
const auto& RP3D_RESULT = rp3dBody->getTransform().getPosition();
result = SHVec3{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z };
}
return result; return result;
} }
@ -57,10 +59,7 @@ namespace SHADE
SHQuaternion result; SHQuaternion result;
if (rp3dBody) if (rp3dBody)
{ result = SHQuaternion{ rp3dBody->getTransform().getOrientation() };
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w };
}
return result; return result;
} }
@ -70,10 +69,7 @@ namespace SHADE
SHVec3 result; SHVec3 result;
if (rp3dBody) if (rp3dBody)
{ result = SHQuaternion{ rp3dBody->getTransform().getOrientation() }.ToEuler();
const auto& RP3D_RESULT = rp3dBody->getTransform().getOrientation();
result = SHQuaternion{ RP3D_RESULT.x, RP3D_RESULT.y, RP3D_RESULT.z, RP3D_RESULT.w }.ToEuler();
}
return result; return result;
} }
@ -84,10 +80,14 @@ namespace SHADE
void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept void SHPhysicsObject::SetPosition(const SHVec3& position) noexcept
{ {
const rp3d::Vector3 RP3D_POS { position.x, position.y, position.z }; if (!rp3dBody)
{
SHLOG_ERROR("Cannot set position of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF; rp3d::Transform rp3dTF;
rp3dTF.setPosition(RP3D_POS); rp3dTF.setPosition(position);
rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation()); rp3dTF.setOrientation(rp3dBody->getTransform().getOrientation());
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
@ -96,11 +96,15 @@ namespace SHADE
void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept void SHPhysicsObject::SetOrientation(const SHQuaternion& orientation) noexcept
{ {
const rp3d::Quaternion RP3D_ORIENTATION { orientation.x, orientation.y, orientation.z, orientation.w }; if (!rp3dBody)
{
SHLOG_ERROR("Cannot set orientation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF; rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(RP3D_ORIENTATION); rp3dTF.setOrientation(orientation);
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF; prevTransform = rp3dTF;
@ -108,14 +112,253 @@ namespace SHADE
void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept void SHPhysicsObject::SetRotation(const SHVec3& rotation) noexcept
{ {
const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles( rotation.x, rotation.y, rotation.z ); if (!rp3dBody)
{
SHLOG_ERROR("Cannot set rotation of a non-existent physics body for Entity {}", entityID)
return;
}
rp3d::Transform rp3dTF; rp3d::Transform rp3dTF;
rp3dTF.setPosition(rp3dBody->getTransform().getPosition()); rp3dTF.setPosition(rp3dBody->getTransform().getPosition());
rp3dTF.setOrientation(RP3D_ORIENTATION); rp3dTF.setOrientation(rotation);
rp3dBody->setTransform(rp3dTF); rp3dBody->setTransform(rp3dTF);
prevTransform = rp3dTF; prevTransform = rp3dTF;
} }
/*-----------------------------------------------------------------------------------*/
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c)
{
// If collider already exists, recreate the collision body as a rigid body
if (hasColliders)
world->destroyCollisionBody(rp3dBody);
rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
isRigidBody = true;
rb->position = tf->GetWorldPosition();
rb->orientation = tf->GetWorldRotation();
if (hasColliders)
{
c->position = tf->GetWorldPosition();
c->orientation = tf->GetWorldRotation();
// Get array of colliders and add them back into the rigidbody
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
}
void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c)
{
if (rp3dBody == nullptr)
rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
hasColliders = true;
c->position = tf->GetWorldPosition();
c->orientation = tf->GetWorldRotation();
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
int SHPhysicsObject::AddCollider(SHCollider* collider)
{
switch (collider->GetType())
{
case SHCollider::Type::BOX:
{
const auto* box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents());
rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
break;
}
case SHCollider::Type::SPHERE:
{
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
rp3d::SphereShape* newSphere = factory->createSphereShape(sphere->GetRadius());
rp3dBody->addCollider(newSphere, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity });
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
return static_cast<int>(rp3dBody->getNbColliders()) - 1;
}
void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept
{
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(rp3dBody));
if (hasColliders)
{
// Preserve colliders as a collision body
rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation });
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
isRigidBody = false;
}
void SHPhysicsObject::DestroyCollisionBody() noexcept
{
// Remove all colliders
for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i)
{
auto* collider = rp3dBody->getCollider(i);
rp3dBody->removeCollider(collider);
}
}
void SHPhysicsObject::RemoveCollider(int index)
{
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());
if (NUM_COLLIDERS == 0)
return;
if (index < 0 || index >= NUM_COLLIDERS)
throw std::invalid_argument("Index out of range!");
auto* collider = rp3dBody->getCollider(index);
rp3dBody->removeCollider(collider);
}
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept
{
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
if (rb->dirtyFlags == 0)
return;
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
const uint16_t RB_FLAGS = rb->dirtyFlags;
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
{
// Check if current dirty flag has been set to true
if (RB_FLAGS & 1U << i)
{
switch (i)
{
case 0: // Gravity
{
rigidBody->enableGravity(rb->IsGravityEnabled());
break;
}
case 1: // Sleeping
{
rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep());
break;
}
case 2: // Linear Constraints
{
const rp3d::Vector3 CONSTRAINTS
{
rb->flags & 1U << 2 ? 0.0f : 1.0f,
rb->flags & 1U << 3 ? 0.0f : 1.0f,
rb->flags & 1U << 4 ? 0.0f : 1.0f
};
rigidBody->setLinearLockAxisFactor(CONSTRAINTS);
break;
}
case 3: // Angular Constraints
{
const rp3d::Vector3 CONSTRAINTS
{
rb->flags & 1U << 5 ? 0.0f : 1.0f,
rb->flags & 1U << 6 ? 0.0f : 1.0f,
rb->flags & 1U << 7 ? 0.0f : 1.0f
};
rigidBody->setAngularLockAxisFactor(CONSTRAINTS);
break;
}
case 4: // Type
{
rigidBody->setType(static_cast<rp3d::BodyType>(rb->GetType()));
break;
}
case 5: // Mass
{
rigidBody->setMass(rb->GetMass());
break;
}
case 6: // Drag
{
rigidBody->setLinearDamping(rb->GetDrag());
break;
}
case 7: // Angular Drag
{
rigidBody->setAngularDamping(rb->GetAngularDrag());
break;
}
case 8: // Linear Velocity
{
rigidBody->setLinearVelocity(rb->GetLinearVelocity());
break;
}
case 9: // Angular Velocity
{
rigidBody->setAngularVelocity(rb->GetAngularVelocity());
break;
}
default: break;
}
}
}
rb->dirtyFlags = 0;
}
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
{
int index = 0;
for (auto& [collider, dirty] : c->colliders)
{
if (!dirty)
continue;
// Update offsets
auto* rp3dCollider = rp3dBody->getCollider(index);
rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity));
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
const auto* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape());
rp3dBoxShape->setHalfExtents(box->GetHalfExtents());
break;
}
case SHCollider::Type::SPHERE:
{
const auto* sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape());
auto* rp3dSphereShape = reinterpret_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape());
rp3dSphereShape->setRadius(sphere->GetRadius());
break;
}
default: break;
}
dirty = false;
++index;
}
}
} // namespace SHADE } // namespace SHADE

View File

@ -13,9 +13,9 @@
#include <reactphysics3d/reactphysics3d.h> #include <reactphysics3d/reactphysics3d.h>
// Project Headers // Project Headers
#include "Math/Vector/SHVec3.h" #include "Math/Transform/SHTransformComponent.h"
#include "Math/SHQuaternion.h" #include "Components/SHRigidBodyComponent.h"
#include "ECS_Base/Entity/SHEntity.h" #include "Components/SHColliderComponent.h"
namespace SHADE namespace SHADE
{ {
@ -31,15 +31,13 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem; friend class SHPhysicsSystem;
friend class SHRigidBodyComponent;
friend class SHColliderComponent;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHPhysicsObject () noexcept; SHPhysicsObject (EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept;
SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default; SHPhysicsObject (const SHPhysicsObject& rhs) noexcept = default;
SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default; SHPhysicsObject (SHPhysicsObject&& rhs) noexcept = default;
virtual ~SHPhysicsObject () noexcept; virtual ~SHPhysicsObject () noexcept;
@ -63,9 +61,24 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetPosition (const SHVec3& position) noexcept; void SetPosition (const SHVec3& position) noexcept;
void SetOrientation (const SHQuaternion& orientation) noexcept; void SetOrientation (const SHQuaternion& orientation) noexcept;
void SetRotation (const SHVec3& rotation) noexcept; void SetRotation (const SHVec3& rotation) noexcept;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c);
void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c);
int AddCollider (SHCollider* collider);
void DestroyRigidBody (SHColliderComponent* c) noexcept;
void RemoveCollider (int index);
void DestroyCollisionBody () noexcept;
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
void SyncColliders (SHColliderComponent* c) const noexcept;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -76,14 +89,9 @@ namespace SHADE
bool isRigidBody; bool isRigidBody;
bool hasColliders; bool hasColliders;
rp3d::PhysicsCommon* factory;
rp3d::PhysicsWorld* world;
rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body rp3d::CollisionBody* rp3dBody; // Can be either a collision body or a rigid body
rp3d::Transform prevTransform; // Cached transform for interpolation rp3d::Transform prevTransform; // Cached transform for interpolation
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
}; };
} // namespace SHADE } // namespace SHADE

View File

@ -68,10 +68,7 @@ namespace SHADE
if (world) if (world)
{ {
const auto RP3D_GRAVITY = world->getGravity(); result = world->getGravity();
result.x = RP3D_GRAVITY.x;
result.y = RP3D_GRAVITY.y;
result.z = RP3D_GRAVITY.z;
} }
else else
{ {
@ -112,8 +109,7 @@ namespace SHADE
{ {
if (world) if (world)
{ {
const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z }; world->setGravity(gravity);
world->setGravity(G);
} }
else else
{ {
@ -161,8 +157,7 @@ namespace SHADE
{ {
if (world) if (world)
{ {
const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z }; world->setGravity(settings.gravity);
world->setGravity(G);
world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations); world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations);
world->setNbIterationsPositionSolver(settings.numPositionSolverIterations); world->setNbIterationsPositionSolver(settings.numPositionSolverIterations);
world->enableSleeping(settings.sleepingEnabled); world->enableSleeping(settings.sleepingEnabled);
@ -207,69 +202,14 @@ namespace SHADE
SHLOG_INFO("Adding a Rigidbody to the Physics World.") SHLOG_INFO("Adding a Rigidbody to the Physics World.")
#endif #endif
// Check if entity is already a physics object auto* physicsObject = CreatePhysicsObject(entityID);
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
// Get entity transform physicsObject->CreateRigidBody
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); (
EnsureTransform(entityID),
// Possibly redundant SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID),
if (!SHADE_TF) SHComponentManager::GetComponent_s<SHColliderComponent>(entityID)
{ );
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
// If collider already exists
if (physicsObject->hasColliders)
world->destroyCollisionBody(physicsObject->rp3dBody);
physicsObject->rp3dBody = world->createRigidBody(RP3D_TF);
physicsObject->isRigidBody = true;
// Recreate colliders
if (physicsObject->hasColliders)
{
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
}
} }
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept
@ -278,63 +218,13 @@ namespace SHADE
SHLOG_INFO("Adding a Collider to the Physics World.") SHLOG_INFO("Adding a Collider to the Physics World.")
#endif #endif
// Check if entity is already a physics object auto* physicsObject = CreatePhysicsObject(entityID);
auto* physicsObject = GetPhysicsObject(entityID);
if (!physicsObject)
{
physicsObject = &(map.emplace(entityID, SHPhysicsObject{}).first->second);
physicsObject->entityID = entityID;
}
// Get entity transform physicsObject->CreateCollisionBody
auto const* SHADE_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); (
EnsureTransform(entityID),
// Possibly redundant SHComponentManager::GetComponent<SHColliderComponent>(entityID)
if (!SHADE_TF) );
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
SHADE_TF = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
}
const SHVec3& SHADE_POS = SHADE_TF->GetWorldPosition();
const SHVec3& SHADE_ROT = SHADE_TF->GetWorldRotation();
const rp3d::Vector3 RP3D_POS { SHADE_POS.x, SHADE_POS.y, SHADE_POS.z };
const rp3d::Quaternion RP3D_ROT = rp3d::Quaternion::fromEulerAngles( SHADE_ROT.x, SHADE_ROT.y, SHADE_ROT.z );
const rp3d::Transform RP3D_TF { RP3D_POS, RP3D_ROT };
// No rb
if (!physicsObject->isRigidBody)
physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF);
const auto& COLLIDERS = SHComponentManager::GetComponent<SHColliderComponent>(entityID)->GetColliders();
for (const auto& collider : COLLIDERS | std::views::keys)
{
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
physicsObject->rp3dBody->addCollider(newBox, RP3D_TF);
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
}
physicsObject->hasColliders = true;
} }
void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept
@ -343,6 +233,13 @@ namespace SHADE
SHLOG_INFO("Removing a Rigidbody from the Physics World.") SHLOG_INFO("Removing a Rigidbody from the Physics World.")
#endif #endif
auto* physicsObject = GetPhysicsObject(entityID);
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s<SHColliderComponent>(entityID));
if (physicsObject->rp3dBody == nullptr)
DestroyPhysicsObject(entityID);
} }
void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept
@ -392,33 +289,10 @@ namespace SHADE
} }
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape) void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
{ {
auto* physicsObject = GetPhysicsObject(entityID); auto* physicsObject = GetPhysicsObject(entityID);
physicsObject->AddCollider(collider);
switch (shape->GetType())
{
case SHShape::Type::BOUNDING_BOX:
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
rp3d::BoxShape* newBox = factory.createBoxShape(RP3D_EXTENTS);
// TODO(Diren): Handle offsets
rp3d::Transform tf = rp3d::Transform::identity();
physicsObject->rp3dBody->addCollider(newBox, tf);
break;
}
case SHShape::Type::SPHERE:
{
break;
}
// TODO(Diren): Add more collider shapes
default: break;
}
} }
void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index) void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index)
@ -475,6 +349,7 @@ namespace SHADE
if (system->worldUpdated) if (system->worldUpdated)
{ {
system->SyncTransforms(); system->SyncTransforms();
// TODO(Diren): Handle trigger messages for scripting // TODO(Diren): Handle trigger messages for scripting
} }
} }
@ -483,6 +358,18 @@ namespace SHADE
/* Private Function Member Definitions */ /* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept
{
const auto it = map.find(entityID);
if (it == map.end())
{
auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second;
return newPhysicsObject;
}
return &(it->second);
}
SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept
{ {
const auto it = map.find(entityID); const auto it = map.find(entityID);
@ -495,6 +382,19 @@ namespace SHADE
return &(it->second); return &(it->second);
} }
void SHPhysicsSystem::DestroyPhysicsObject(EntityID entityID) noexcept
{
map.erase(entityID);
}
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
{
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
if (RP3D_ACTIVE != componentActive)
physicsObject->rp3dBody->setIsActive(componentActive);
}
void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept void SHPhysicsSystem::SyncRigidBodyComponents(std::vector<SHRigidBodyComponent>& denseArray) noexcept
{ {
if (denseArray.empty()) if (denseArray.empty())
@ -505,23 +405,16 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID(); const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject // Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID); auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy // TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive; const bool COMPONENT_ACTIVE = comp.isActive;
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE) if (!COMPONENT_ACTIVE)
continue; continue;
if (comp.dirtyFlags > 0) physicsObject->SyncRigidBody(&comp);
{
SyncRigidBody(physicsObject, &comp);
comp.dirtyFlags = 0;
}
} }
} }
@ -535,29 +428,23 @@ namespace SHADE
const EntityID ENTITY_ID = comp.GetEID(); const EntityID ENTITY_ID = comp.GetEID();
// Get physicsObject // Get physicsObject
auto const* physicsObject = GetPhysicsObject(ENTITY_ID); auto* physicsObject = GetPhysicsObject(ENTITY_ID);
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
// TODO(Diren): Check if active in hierarchy // TODO(Diren): Check if active in hierarchy
const bool COMPONENT_ACTIVE = comp.isActive; const bool COMPONENT_ACTIVE = comp.isActive;
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
if (RP3D_ACTIVE != COMPONENT_ACTIVE)
physicsObject->rp3dBody->setIsActive(COMPONENT_ACTIVE);
if (!COMPONENT_ACTIVE) if (!COMPONENT_ACTIVE)
continue; continue;
SyncCollider(physicsObject, &comp); physicsObject->SyncColliders(&comp);
} }
} }
void SHPhysicsSystem::SyncTransforms() noexcept void SHPhysicsSystem::SyncTransforms() noexcept
{ {
for (auto& pair : map) for (auto& [entityID, physicsObject] : map)
{ {
const EntityID ENTITY_ID = pair.first;
SHPhysicsObject& physicsObject = pair.second;
rp3d::Vector3 rp3dPos; rp3d::Vector3 rp3dPos;
rp3d::Quaternion rp3dRot; rp3d::Quaternion rp3dRot;
@ -567,7 +454,7 @@ namespace SHADE
if (physicsObject.isRigidBody) if (physicsObject.isRigidBody)
{ {
auto const* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(ENTITY_ID); auto* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID);
if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC) if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
continue; continue;
@ -585,6 +472,16 @@ namespace SHADE
rp3dPos = CURRENT_TF.getPosition(); rp3dPos = CURRENT_TF.getPosition();
rp3dRot = CURRENT_TF.getOrientation(); rp3dRot = CURRENT_TF.getOrientation();
} }
rbComponent->position = CURRENT_TF.getPosition();
rbComponent->orientation = CURRENT_TF.getOrientation();
if (physicsObject.hasColliders)
{
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
} }
else else
{ {
@ -593,155 +490,29 @@ namespace SHADE
} }
// Convert RP3D Transform to SHADE // Convert RP3D Transform to SHADE
const SHVec3 SHADE_POS = SHVec3{ rp3dPos.x, rp3dPos.y, rp3dPos.z }; auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
const SHVec3 SHADE_ROT = SHQuaternion{ rp3dRot.x, rp3dRot.y, rp3dRot.z, rp3dRot.w }.ToEuler(); tfComponent->SetWorldPosition(rp3dPos);
tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler());
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(ENTITY_ID);
tfComponent->SetWorldPosition(SHADE_POS);
tfComponent->SetWorldRotation(SHADE_ROT);
// Cache transforms // Cache transforms
physicsObject.prevTransform = CURRENT_TF; physicsObject.prevTransform = CURRENT_TF;
} }
} }
void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID)
{ {
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody); auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
const uint16_t RB_FLAGS = comp->dirtyFlags; // Possibly redundant
const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U; if (!tf)
for (size_t i = 0; i < NUM_FLAGS; ++i)
{ {
// Check if current dirty flag has been set to true SHComponentManager::AddComponent<SHTransformComponent>(entityID);
if (RB_FLAGS & 1U << i) tf = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
{
switch (i)
{
case 0: // Gravity
{
rigidBody->enableGravity(comp->IsGravityEnabled());
break;
}
case 1: // Sleeping
{
rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep());
break;
}
case 2: // Linear Constraints
{
SetRP3DLinearConstraints(rigidBody, comp->flags);
break;
}
case 3: // Angular Constraints
{
SetRP3DAngularConstraints(rigidBody, comp->flags);
break;
}
case 4: // Type
{
rigidBody->setType(static_cast<rp3d::BodyType>(comp->GetType()));
break;
}
case 5: // Mass
{
rigidBody->setMass(comp->GetMass());
break;
}
case 6: // Drag
{
rigidBody->setLinearDamping(comp->GetDrag());
break;
}
case 7: // Angular Drag
{
rigidBody->setAngularDamping(comp->GetAngularDrag());
break;
}
case 8: // Linear Velocity
{
const SHVec3& SHADE_VEL = comp->GetLinearVelocity();
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
rigidBody->setLinearVelocity(RP3D_VEL);
break;
}
case 9: // Angular Velocity
{
const SHVec3& SHADE_VEL = comp->GetAngularVelocity();
rp3d::Vector3 RP3D_VEL { SHADE_VEL.x, SHADE_VEL.y, SHADE_VEL.z };
rigidBody->setAngularVelocity(RP3D_VEL);
break;
}
default: break;
}
}
} }
return tf;
} }
void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
{
const rp3d::Vector3 CONSTRAINTS
{
rbFlags & 1U << 2 ? 0.0f : 1.0f,
rbFlags & 1U << 3 ? 0.0f : 1.0f,
rbFlags & 1U << 4 ? 0.0f : 1.0f
};
rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS);
}
void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept
{
const rp3d::Vector3 CONSTRAINTS
{
rbFlags & 1U << 5 ? 0.0f : 1.0f,
rbFlags & 1U << 6 ? 0.0f : 1.0f,
rbFlags & 1U << 7 ? 0.0f : 1.0f
};
rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS);
}
void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept
{
int index = 0;
for (auto& [collider, dirty] : comp->colliders)
{
if (!dirty)
continue;
switch (collider.GetType())
{
case SHCollider::Type::BOX:
{
SHBoundingBox* box = reinterpret_cast<SHBoundingBox*>(collider.GetShape());
const SHVec3& SHADE_EXTENTS = box->GetHalfExtents();
rp3d::Vector3 RP3D_EXTENTS { SHADE_EXTENTS.x, SHADE_EXTENTS.y, SHADE_EXTENTS.z };
auto* rp3dBoxShape = reinterpret_cast<rp3d::BoxShape*>(physicsObject->rp3dBody->getCollider(index)->getCollisionShape());
rp3dBoxShape->setHalfExtents(RP3D_EXTENTS);
if (rp3dBoxShape)
{
SHLOG_INFO("Updating box things")
}
break;
}
case SHCollider::Type::SPHERE:
{
break;
}
default: break;
}
dirty = false;
++index;
}
}
} // namespace SHADE } // namespace SHADE

View File

@ -19,6 +19,7 @@
#include "SHPhysicsObject.h" #include "SHPhysicsObject.h"
#include "Components/SHRigidBodyComponent.h" #include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h" #include "Components/SHColliderComponent.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h" #include "Scene/SHSceneGraph.h"
#include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHSystemRoutine.h"
@ -81,8 +82,8 @@ namespace SHADE
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Init () override; void Init () override;
void Exit () override; void Exit () override;
void AddRigidBody (EntityID entityID) noexcept; void AddRigidBody (EntityID entityID) noexcept;
void AddCollider (EntityID entityID) noexcept; void AddCollider (EntityID entityID) noexcept;
@ -100,7 +101,7 @@ namespace SHADE
void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept;
void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept;
void AddCollisionShape (EntityID entityID, SHShape* shape); void AddCollisionShape (EntityID entityID, SHCollider* collider);
void RemoveCollisionShape (EntityID entityID, int index); void RemoveCollisionShape (EntityID entityID, int index);
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -185,18 +186,18 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void DestroyPhysicsObject (EntityID entityID) noexcept;
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept; void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncTransforms () noexcept; void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
// TODO(Diren): Trigger handling // TODO(Diren): Trigger handling
static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; // TODO(Diren): Remove when responsibility shifted to editor
static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; SHTransformComponent* EnsureTransform (EntityID entityID);
static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept;
static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept;
}; };

View File

@ -30,8 +30,9 @@ project "SHADE_Managed"
"%{IncludeDir.imguizmo}", "%{IncludeDir.imguizmo}",
"%{IncludeDir.imnodes}", "%{IncludeDir.imnodes}",
"%{IncludeDir.yamlcpp}", "%{IncludeDir.yamlcpp}",
"%{IncludeDir.RTTR}/include", "%{IncludeDir.RTTR}/include",
"%{IncludeDir.dotnet}\\include", "%{IncludeDir.dotnet}\\include",
"%{IncludeDir.reactphysics3d}\\include",
"%{wks.location}/SHADE_Engine/src" "%{wks.location}/SHADE_Engine/src"
} }