SP3-2 Colliders use relative size #127

Merged
direnbharwani merged 7 commits from SP3-2-Physics into main 2022-10-28 16:38:44 +08:00
18 changed files with 512 additions and 163 deletions

View File

@ -96,11 +96,7 @@ namespace Sandbox
transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f)); transform.SetWorldRotation(SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f), SHMath::GenerateRandomNumber(0.0f, 360.0f));
transform.SetWorldScale(TEST_OBJ_SCALE); transform.SetWorldScale(TEST_OBJ_SCALE);
//if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) collider.AddBoundingBox(SHVec3::One, SHVec3::Zero);
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

@ -207,6 +207,10 @@ namespace SHADE
{ {
if (!component) if (!component)
return; return;
// Get transform component for extrapolating relative sizes
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(component->GetEID());
const auto componentType = rttr::type::get(*component); const auto componentType = rttr::type::get(*component);
SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
ImGui::SameLine(); ImGui::SameLine();
@ -221,28 +225,41 @@ namespace SHADE
for (int i{}; i < size; ++i) for (int i{}; i < size; ++i)
{ {
ImGui::PushID(i); ImGui::PushID(i);
SHCollider& collider = component->GetCollider(i); SHCollider* collider = &component->GetCollider(i);
auto cursorPos = ImGui::GetCursorPos(); auto cursorPos = ImGui::GetCursorPos();
if (collider.GetType() == SHCollider::Type::BOX) if (collider->GetType() == SHCollider::Type::BOX)
{ {
SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel( std::format("{} Box Collider #{}", ICON_FA_CUBE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto box = reinterpret_cast<SHBoundingBox*>(collider.GetShape()); auto box = reinterpret_cast<SHBoundingBox*>(collider->GetShape());
SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); SHEditorWidgets::DragVec3
(
"Half Extents", { "X", "Y", "Z" },
[box, transformComponent] { return (transformComponent->GetWorldScale() * 2.0f) * box->GetHalfExtents(); },
[collider](SHVec3 const& vec) { collider->SetBoundingBox(vec); });
} }
else if (collider.GetType() == SHCollider::Type::SPHERE) else if (collider->GetType() == SHCollider::Type::SPHERE)
{ {
SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y }); SHEditorWidgets::BeginPanel(std::format("{} Sphere Collider #{}", ICON_MD_CIRCLE, i).data(), { ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y });
auto sphere = reinterpret_cast<SHBoundingSphere*>(collider.GetShape()); auto sphere = reinterpret_cast<SHBoundingSphere*>(collider->GetShape());
SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);}); SHEditorWidgets::DragFloat
(
"Radius",
[sphere, transformComponent]
{
const SHVec3& TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
return sphere->GetRadius() / MAX_SCALE;
},
[collider](float const& value) { collider->SetBoundingSphere(value);});
} }
else if (collider.GetType() == SHCollider::Type::CAPSULE) else if (collider->GetType() == SHCollider::Type::CAPSULE)
{ {
} }
{ {
SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f }); SHEditorWidgets::BeginPanel("Offset", { ImGui::GetContentRegionAvail().x, 30.0f });
SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider.GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider.SetPositionOffset(vec); }); SHEditorWidgets::DragVec3("Position", { "X", "Y", "Z" }, [&collider] {return collider->GetPositionOffset(); }, [&collider](SHVec3 const& vec) {collider->SetPositionOffset(vec); });
SHEditorWidgets::EndPanel(); SHEditorWidgets::EndPanel();
} }
if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))

View File

@ -27,10 +27,9 @@ namespace SHADE
/* Getter Function Definitions */ /* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHShape::Type SHShape::GetType() const SHShape::Type SHShape::GetType() const noexcept
{ {
return type; return type;
} }
} // namespace SHADE } // namespace SHADE

View File

@ -63,7 +63,7 @@ namespace SHADE
/* Getter Functions */ /* Getter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
[[nodiscard]] Type GetType() const; [[nodiscard]] Type GetType () const noexcept;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Function Members */ /* Function Members */

View File

@ -58,7 +58,7 @@ namespace SHADE
if (index < 0 || static_cast<size_t>(index) >= colliders.size()) if (index < 0 || static_cast<size_t>(index) >= colliders.size())
throw std::invalid_argument("Out-of-range access!"); throw std::invalid_argument("Out-of-range access!");
return colliders[index].first; return colliders[index];
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -85,13 +85,11 @@ namespace SHADE
static constexpr auto TYPE = SHCollider::Type::BOX; static constexpr auto TYPE = SHCollider::Type::BOX;
auto boxPair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
auto& collider = colliders.emplace_back(boxPair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.entityID = GetEID();
collider.SetPositionOffset(posOffset); collider.SetPositionOffset(posOffset);
collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); collider.SetBoundingBox(halfExtents);
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);
@ -109,16 +107,11 @@ namespace SHADE
static constexpr auto TYPE = SHCollider::Type::SPHERE; static constexpr auto TYPE = SHCollider::Type::SPHERE;
auto spherePair = std::make_pair(SHCollider{ TYPE }, true); auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE });
auto& collider = colliders.emplace_back(spherePair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
collider.entityID = GetEID();
collider.SetPositionOffset(posOffset); collider.SetPositionOffset(posOffset);
collider.SetBoundingSphere(radius);
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 * radius);
// Notify Physics System // Notify Physics System
system->AddCollisionShape(GetEID(), &collider); system->AddCollisionShape(GetEID(), &collider);

View File

@ -43,8 +43,7 @@ namespace SHADE
/* Type Definitions */ /* Type Definitions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
using ColliderDirtyPair = std::pair<SHCollider, bool>; using Colliders = std::vector<SHCollider>;
using Colliders = std::vector<ColliderDirtyPair>;
public: public:

View File

@ -15,6 +15,8 @@
// Project Headers // Project Headers
#include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingBox.h"
#include "Math/Geometry/SHBoundingSphere.h" #include "Math/Geometry/SHBoundingSphere.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Math/SHMathHelpers.h"
namespace SHADE namespace SHADE
{ {
@ -22,22 +24,24 @@ namespace SHADE
/* Constructors & Destructor Definitions */ /* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
SHCollider::SHCollider(Type colliderType) SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial)
: type { colliderType } : type { colliderType }
, entityID { eid }
, isTrigger { false } , isTrigger { false }
, dirty { true } , dirty { true }
, shape { nullptr } , shape { nullptr }
, material { physicsMaterial }
{ {
switch (type) switch (type)
{ {
case Type::BOX: case Type::BOX:
{ {
SetAsBoundingBox(SHVec3::One); shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One };
break; break;
} }
case Type::SPHERE: case Type::SPHERE:
{ {
SetAsBoundingSphere(1.0f); shape = new SHBoundingSphere{ SHVec3::Zero, 0.5f };
break; break;
} }
default: break; default: break;
@ -46,19 +50,27 @@ namespace SHADE
SHCollider::SHCollider(const SHCollider& rhs) noexcept SHCollider::SHCollider(const SHCollider& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, entityID { rhs.entityID }
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { rhs.shape } , shape { nullptr }
, material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
{} {
CopyShape(rhs.shape);
}
SHCollider::SHCollider(SHCollider&& rhs) noexcept SHCollider::SHCollider(SHCollider&& rhs) noexcept
: type { rhs.type} : type { rhs.type}
, entityID { rhs.entityID }
, isTrigger { rhs.isTrigger } , isTrigger { rhs.isTrigger }
, dirty { true } , dirty { true }
, shape { rhs.shape } , shape { nullptr }
, material { rhs.material }
, positionOffset { rhs.positionOffset } , positionOffset { rhs.positionOffset }
{} {
CopyShape(rhs.shape);
}
SHCollider::~SHCollider() noexcept SHCollider::~SHCollider() noexcept
{ {
@ -75,22 +87,30 @@ namespace SHADE
return *this; return *this;
type = rhs.type; type = rhs.type;
entityID = rhs.entityID;
isTrigger = rhs.isTrigger; isTrigger = rhs.isTrigger;
dirty = true; dirty = true;
shape = rhs.shape; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
delete shape;
CopyShape(rhs.shape);
return *this; return *this;
} }
SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept
{ {
type = rhs.type; type = rhs.type;
entityID = rhs.entityID;
isTrigger = rhs.isTrigger; isTrigger = rhs.isTrigger;
dirty = true; dirty = true;
shape = rhs.shape; material = rhs.material;
positionOffset = rhs.positionOffset; positionOffset = rhs.positionOffset;
delete shape;
CopyShape(rhs.shape);
return *this; return *this;
} }
@ -115,19 +135,22 @@ namespace SHADE
float SHCollider::GetFriction() const noexcept float SHCollider::GetFriction() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetFriction();
return 0.0f;
} }
float SHCollider::GetBounciness() const noexcept float SHCollider::GetBounciness() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetBounciness();
return 0.0f;
} }
float SHCollider::GetDensity() const noexcept float SHCollider::GetDensity() const noexcept
{ {
// TODO(Diren): Fix after implementing materials return material.GetDensity();
return 0.0f; }
const SHPhysicsMaterial& SHCollider::GetMaterial() const noexcept
{
return material;
} }
const SHVec3& SHCollider::GetPositionOffset() const noexcept const SHVec3& SHCollider::GetPositionOffset() const noexcept
@ -145,22 +168,60 @@ namespace SHADE
/* Setter Function Definitions */ /* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents) void SHCollider::SetBoundingBox(const SHVec3& halfExtents)
{ {
dirty = true; dirty = true;
// Set the half extents relative to transform
SHVec3 worldHalfExtents = halfExtents;
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent != nullptr)
worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f);
if (type == Type::BOX)
{
auto* box = reinterpret_cast<SHBoundingBox*>(shape);
box->SetHalfExtents(worldHalfExtents);
}
else
{
type = Type::BOX; type = Type::BOX;
delete shape; delete shape;
shape = new SHBoundingBox{ positionOffset, halfExtents }; shape = new SHBoundingBox{ positionOffset, worldHalfExtents };
}
} }
void SHCollider::SetAsBoundingSphere(float radius) void SHCollider::SetBoundingSphere(float radius)
{ {
dirty = true; dirty = true;
// Set the radius relative to transform
float worldRadius = radius;
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent != nullptr)
{
const SHVec3 TF_WORLD_SCALE = transformComponent->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
worldRadius *= MAX_SCALE;
}
if (type == Type::SPHERE)
{
auto* sphere = reinterpret_cast<SHBoundingSphere*>(shape);
sphere->SetRadius(worldRadius);
}
else
{
type = Type::SPHERE; type = Type::SPHERE;
delete shape; delete shape;
shape = new SHBoundingSphere{ positionOffset, radius }; shape = new SHBoundingSphere{ positionOffset, worldRadius };
}
} }
void SHCollider::SetIsTrigger(bool trigger) noexcept void SHCollider::SetIsTrigger(bool trigger) noexcept
@ -172,23 +233,74 @@ namespace SHADE
void SHCollider::SetFriction(float friction) noexcept void SHCollider::SetFriction(float friction) noexcept
{ {
dirty = true; dirty = true;
material.SetFriction(friction);
} }
void SHCollider::SetBounciness(float bounciness) noexcept void SHCollider::SetBounciness(float bounciness) noexcept
{ {
dirty = true; dirty = true;
material.SetBounciness(bounciness);
} }
void SHCollider::SetDensity(float density) noexcept void SHCollider::SetDensity(float density) noexcept
{ {
dirty = true; dirty = true;
material.SetDensity(density);
}
void SHCollider::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
{
dirty = true;
material = newMaterial;
} }
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
{ {
dirty = true; dirty = true;
positionOffset = posOffset; positionOffset = posOffset;
switch (type)
{
case Type::BOX:
{
reinterpret_cast<SHBoundingBox*>(shape)->SetCenter(positionOffset);
break;
} }
case Type::SPHERE:
{
reinterpret_cast<SHBoundingSphere*>(shape)->SetCenter(positionOffset);
break;
}
default: break;
}
}
/*-----------------------------------------------------------------------------------*/
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHCollider::CopyShape(const SHShape* rhs)
{
switch (type)
{
case Type::BOX:
{
const auto* RHS_BOX = reinterpret_cast<const SHBoundingBox*>(rhs);
shape = new SHBoundingBox{ positionOffset, RHS_BOX->GetHalfExtents() };
break;
}
case Type::SPHERE:
{
const auto* RHS_SPHERE = reinterpret_cast<const SHBoundingSphere*>(rhs);
shape = new SHBoundingSphere{ positionOffset, RHS_SPHERE->GetRadius() };
break;
}
default: break;
}
}
} // namespace SHADE } // namespace SHADE
RTTR_REGISTRATION RTTR_REGISTRATION
@ -205,5 +317,4 @@ RTTR_REGISTRATION
registration::class_<SHCollider>("Collider") registration::class_<SHCollider>("Collider")
.property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset); .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset);
// TODO(Diren): Add Physics Materials
} }

View File

@ -13,8 +13,10 @@
#include <rttr/registration> #include <rttr/registration>
// Project Headers // Project Headers
#include "ECS_Base/Entity/SHEntity.h"
#include "Math/Geometry/SHShape.h" #include "Math/Geometry/SHShape.h"
#include "Math/SHQuaternion.h" #include "Math/SHQuaternion.h"
#include "SHPhysicsMaterial.h"
namespace SHADE namespace SHADE
{ {
@ -24,6 +26,15 @@ namespace SHADE
class SH_API SHCollider class SH_API SHCollider
{ {
private:
/*---------------------------------------------------------------------------------*/
/* Friends */
/*---------------------------------------------------------------------------------*/
friend class SHColliderComponent;
friend class SHPhysicsObject;
public: public:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
@ -40,7 +51,7 @@ namespace SHADE
/* Constructors & Destructor */ /* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SHCollider (Type colliderType = Type::BOX); SHCollider (EntityID eid, Type colliderType = Type::BOX, const SHPhysicsMaterial& physicsMaterial = SHPhysicsMaterial::DEFAULT);
SHCollider (const SHCollider& rhs) noexcept; SHCollider (const SHCollider& rhs) noexcept;
SHCollider (SHCollider&& rhs) noexcept; SHCollider (SHCollider&& rhs) noexcept;
@ -66,6 +77,7 @@ namespace SHADE
[[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]] const SHPhysicsMaterial& GetMaterial () const noexcept;
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
@ -75,13 +87,14 @@ namespace SHADE
/* Setter Functions */ /* Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SetAsBoundingBox (const SHVec3& halfExtents); void SetBoundingBox (const SHVec3& halfExtents);
void SetAsBoundingSphere (float radius); void SetBoundingSphere (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 SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept;
void SetPositionOffset (const SHVec3& positionOffset) noexcept; void SetPositionOffset (const SHVec3& positionOffset) noexcept;
@ -91,11 +104,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Type type; Type type;
EntityID entityID; // The entity this collider belongs to
bool isTrigger; bool isTrigger;
bool dirty; bool dirty;
SHShape* shape; SHShape* shape;
SHPhysicsMaterial material;
SHVec3 positionOffset; SHVec3 positionOffset;
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CopyShape(const SHShape* rhs);
RTTR_ENABLE() RTTR_ENABLE()
}; };

View File

@ -0,0 +1,104 @@
/****************************************************************************************
* \file SHPhysicsMaterial.cpp
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Implementation for a Physics Material.
*
* \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 "SHPhysicsMaterial.h"
// Project Headers
#include "Math/SHMathHelpers.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Static Data Member Definitions */
/*-----------------------------------------------------------------------------------*/
const SHPhysicsMaterial SHPhysicsMaterial::DEFAULT { 0.4f, 0.0f, 1.0f };
/*-----------------------------------------------------------------------------------*/
/* Constructors & Destructor Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsMaterial::SHPhysicsMaterial(float _friction, float _bounciness, float _density) noexcept
: friction { std::clamp(_friction, 0.0f, 1.0f) }
, bounciness{ std::clamp(_bounciness, 0.0f, 1.0f) }
, density { std::fabs(_density) }
{}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */
/*-----------------------------------------------------------------------------------*/
bool SHPhysicsMaterial::operator==(const SHPhysicsMaterial& rhs) const noexcept
{
return SHMath::CompareFloat(friction, rhs.friction)
&& SHMath::CompareFloat(bounciness, rhs.bounciness)
&& SHMath::CompareFloat(density, rhs.density);
}
bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept
{
return !SHMath::CompareFloat(friction, rhs.friction)
|| !SHMath::CompareFloat(bounciness, rhs.bounciness)
|| !SHMath::CompareFloat(density, rhs.density);
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
float SHPhysicsMaterial::GetFriction() const noexcept
{
return friction;
}
float SHPhysicsMaterial::GetBounciness() const noexcept
{
return bounciness;
}
float SHPhysicsMaterial::GetDensity() const noexcept
{
return density;
}
/*-----------------------------------------------------------------------------------*/
/* Setter Function Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsMaterial::SetFriction(float newFriction) noexcept
{
if (newFriction < 0.0f || newFriction > 1.0f)
{
SHLOG_WARNING("Clamping friction of Physics Material between [0,1].")
}
friction = std::clamp(newFriction, 0.0f, 1.0f);
}
void SHPhysicsMaterial::SetBounciness(float newBounciness) noexcept
{
if (newBounciness < 0.0f || newBounciness > 1.0f)
{
SHLOG_WARNING("Clamping bounciness of Physics Material between [0,1].")
}
bounciness = std::clamp(newBounciness, 0.0f, 1.0f);
}
void SHPhysicsMaterial::SetDensity(float newDensity) noexcept
{
if (newDensity < 0.0f)
{
SHLOG_WARNING("Setting negative density of Physics Material to positive.")
}
density = std::fabs(newDensity);
}
} // namespace SHADE

View File

@ -0,0 +1,113 @@
/****************************************************************************************
* \file SHPhysicsMaterial.h
* \author Diren D Bharwani, diren.dbharwani, 390002520
* \brief Interface for a Physics Material.
*
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
* disclosure of this file or its contents without the prior written consent
* of DigiPen Institute of Technology is prohibited.
****************************************************************************************/
#pragma once
// Project Headers
#include "SH_API.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHPhysicsMaterial
{
public:
/*---------------------------------------------------------------------------------*/
/* Static Data Members */
/*---------------------------------------------------------------------------------*/
static const SHPhysicsMaterial DEFAULT;
/*---------------------------------------------------------------------------------*/
/* Constructors & Destructor */
/*---------------------------------------------------------------------------------*/
SHPhysicsMaterial (const SHPhysicsMaterial&) noexcept = default;
SHPhysicsMaterial (SHPhysicsMaterial&&) noexcept = default;
~SHPhysicsMaterial() = default;
/**
* @brief Default constructor for a physics material.
* @param friction The friction of the material. Clamped between [0,1]. Defaults to 0.4.
* @param bounciness The bounciness of the material. Clamped between [0,1].
* @param density The mass density of the material. Always made positive.
*/
SHPhysicsMaterial (float friction = 0.4f, float bounciness = 0.0f, float density = 1.0f) noexcept;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */
/*---------------------------------------------------------------------------------*/
SHPhysicsMaterial& operator= (const SHPhysicsMaterial&) noexcept = default;
SHPhysicsMaterial& operator= (SHPhysicsMaterial&&) noexcept = default;
bool operator==(const SHPhysicsMaterial& rhs) const noexcept;
bool operator!=(const SHPhysicsMaterial& rhs) const noexcept;
/*---------------------------------------------------------------------------------*/
/* Getter Functions */
/*---------------------------------------------------------------------------------*/
[[nodiscard]] float GetFriction () const noexcept;
[[nodiscard]] float GetBounciness () const noexcept;
[[nodiscard]] float GetDensity () const noexcept;
/*---------------------------------------------------------------------------------*/
/* Setter Functions */
/*---------------------------------------------------------------------------------*/
/**
* @brief Sets the friction coefficient of the physics material.
* @param newFriction The friction value to set. Clamped between [0,1].
*/
void SetFriction (float newFriction) noexcept;
/**
* @brief Sets the bounciness factor of the physics material.
* @param newBounciness The bounciness value to set. Clamped between [0,1].
*/
void SetBounciness (float newBounciness) noexcept;
/**
* @brief Sets the mass density of the physics material.
* @param newDensity The density value to set. Always made positive.
*/
void SetDensity (float newDensity) noexcept;
private:
/*---------------------------------------------------------------------------------*/
/* Data Members */
/*---------------------------------------------------------------------------------*/
/**
* @brief The friction coefficient of the physics object., clamped between [0,1].<br/>
* 0 means the object will never experience friction.
* 1 means the friction force against the object is equal to the applied force.
*/
float friction;
/**
* @brief The bounciness factor of the physics object., clamped between [0,1].<br/>
* 0 means the object will never bounce.
* 1 means the object never loses energy on a bounce.
*/
float bounciness;
/**
* @brief The density of the collider that determines the mass of the collision shape
* if it is automatically computed. Must be a positive number.
*/
float density;
};
}

View File

@ -261,9 +261,9 @@ namespace SHADE
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
{ {
int index = 0; int index = 0;
for (auto& [collider, dirty] : c->colliders) for (auto& collider : c->colliders)
{ {
if (!dirty) if (!collider.dirty)
continue; continue;
// Update offsets // Update offsets
@ -293,7 +293,7 @@ namespace SHADE
default: break; default: break;
} }
dirty = false; collider.dirty = false;
++index; ++index;
} }
} }

View File

@ -246,21 +246,6 @@ namespace SHADE
if (physicsObject.rp3dBody == nullptr) if (physicsObject.rp3dBody == nullptr)
continue; continue;
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
// Clear all forces and velocities if editor is not in play
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
{
if (rigidBodyComponent)
{
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
}
}
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID); const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent && transformComponent->HasChanged()) if (transformComponent && transformComponent->HasChanged())
{ {
@ -270,10 +255,21 @@ namespace SHADE
physicsObject.SetPosition(WORLD_POS); physicsObject.SetPosition(WORLD_POS);
physicsObject.SetOrientation(WORLD_ROT); physicsObject.SetOrientation(WORLD_ROT);
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
if (rigidBodyComponent) if (rigidBodyComponent)
{ {
rigidBodyComponent->position = WORLD_POS; rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT; rigidBodyComponent->orientation = WORLD_ROT;
// Clear all forces and velocities if editor is stopped
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
{
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
}
} }
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
@ -517,7 +513,7 @@ namespace SHADE
// Add collision shapes back into the body // Add collision shapes back into the body
if (colliderComponent != nullptr) if (colliderComponent != nullptr)
{ {
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }
} }
@ -538,7 +534,7 @@ namespace SHADE
} }
// Add Collision Shapes // Add Collision Shapes
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }
} }
@ -576,7 +572,7 @@ namespace SHADE
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
); );
for (auto& collider : colliderComponent->colliders | std::views::keys) for (auto& collider : colliderComponent->colliders)
physicsObject->AddCollider(&collider); physicsObject->AddCollider(&collider);
} }

View File

@ -582,9 +582,9 @@ namespace SHADE
ReleaseNode(node); ReleaseNode(node);
} }
void SHSceneGraph::Traverse (const UnaryFunction& predicate) const void SHSceneGraph::Traverse (const UnaryFunction& function) const
{ {
TraverseAndInvokeFunction(root, predicate); TraverseAndInvokeFunction(root, function);
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -621,7 +621,7 @@ namespace SHADE
delete node; delete node;
} }
void SHSceneGraph::TraverseAndInvokeFunction (const SHSceneNode* node, const UnaryFunction& function) void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
{ {
for (auto* child : node->children) for (auto* child : node->children)
{ {

View File

@ -142,7 +142,7 @@ namespace SHADE
bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; bool RemoveNode (SHSceneNode* nodeToRemove) noexcept;
void Reset () noexcept; void Reset () noexcept;
void Traverse (const UnaryFunction& predicate) const; void Traverse (const UnaryFunction& function) const;
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -417,13 +417,13 @@ namespace SHADE
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Collider", DEFAULT_CSHARP_NAMESPACE + ".Collider",
"OnColliderBoundChanged" "OnCollisionShapeChanged"
); );
csColliderOnRemoved = dotNet.GetFunctionPtr<CsEventRelayFuncPtr> csColliderOnRemoved = dotNet.GetFunctionPtr<CsEventRelayFuncPtr>
( (
DEFAULT_CSHARP_LIB_NAME, DEFAULT_CSHARP_LIB_NAME,
DEFAULT_CSHARP_NAMESPACE + ".Collider", DEFAULT_CSHARP_NAMESPACE + ".Collider",
"OnColliderRemoved" "OnCollisionShapeRemoved"
); );
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr> csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
( (

View File

@ -22,7 +22,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ColliderBound - Constructors */ /* ColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ColliderBound::ColliderBound(int arrayIdx, Entity attachedEntity) CollisionShape::CollisionShape(int arrayIdx, Entity attachedEntity)
: arrayIndex { arrayIdx } : arrayIndex { arrayIdx }
, entity { attachedEntity } , entity { attachedEntity }
{} {}
@ -30,7 +30,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ColliderBound - Setter Functions */ /* ColliderBound - Setter Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void ColliderBound::updateArrayIndex(int index) void CollisionShape::updateArrayIndex(int index)
{ {
arrayIndex = index; arrayIndex = index;
} }
@ -38,42 +38,42 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Constructors */ /* BoxColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
BoxColliderBound::BoxColliderBound(int arrayIdx, Entity attachedEntity) BoxCollider::BoxCollider(int arrayIdx, Entity attachedEntity)
: ColliderBound { arrayIndex, attachedEntity } : CollisionShape { arrayIndex, attachedEntity }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Properties */ /* BoxColliderBound - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Vector3 BoxColliderBound::Center::get() Vector3 BoxCollider::Center::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetCenter()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetCenter());
} }
void BoxColliderBound::Center::set(Vector3 value) void BoxCollider::Center::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetCenter(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetCenter(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::HalfExtents::get() Vector3 BoxCollider::HalfExtents::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetHalfExtents());
} }
void BoxColliderBound::HalfExtents::set(Vector3 value) void BoxCollider::HalfExtents::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetHalfExtents(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::Min::get() Vector3 BoxCollider::Min::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMin()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMin());
} }
void BoxColliderBound::Min::set(Vector3 value) void BoxCollider::Min::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetMin(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetMin(Convert::ToNative(value));
} }
Vector3 BoxColliderBound::Max::get() Vector3 BoxCollider::Max::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMax()); return Convert::ToCLI(getNativeBoundObject<SHBoundingBox>().GetMax());
} }
void BoxColliderBound::Max::set(Vector3 value) void BoxCollider::Max::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingBox>().SetMax(Convert::ToNative(value)); getNativeBoundObject<SHBoundingBox>().SetMax(Convert::ToNative(value));
} }
@ -81,11 +81,11 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Usage Functions */ /* BoxColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool BoxColliderBound::TestPoint(Vector3 point) bool BoxCollider::TestPoint(Vector3 point)
{ {
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point)); return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
} }
bool BoxColliderBound::Raycast(Ray ray, float maxDistance) bool BoxCollider::Raycast(Ray ray, float maxDistance)
{ {
return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance); return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance);
} }
@ -93,19 +93,19 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* BoxColliderBound - Properties */ /* BoxColliderBound - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Vector3 SphereColliderBound::Center::get() Vector3 SphereCollider::Center::get()
{ {
return Convert::ToCLI(getNativeBoundObject<SHBoundingSphere>().GetCenter()); return Convert::ToCLI(getNativeBoundObject<SHBoundingSphere>().GetCenter());
} }
void SphereColliderBound::Center::set(Vector3 value) void SphereCollider::Center::set(Vector3 value)
{ {
getNativeBoundObject<SHBoundingSphere>().SetCenter(Convert::ToNative(value)); getNativeBoundObject<SHBoundingSphere>().SetCenter(Convert::ToNative(value));
} }
float SphereColliderBound::Radius::get() float SphereCollider::Radius::get()
{ {
return getNativeBoundObject<SHBoundingSphere>().GetRadius(); return getNativeBoundObject<SHBoundingSphere>().GetRadius();
} }
void SphereColliderBound::Radius::set(float value) void SphereCollider::Radius::set(float value)
{ {
getNativeBoundObject<SHBoundingSphere>().SetRadius(value); getNativeBoundObject<SHBoundingSphere>().SetRadius(value);
} }
@ -113,11 +113,11 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SphereColliderBound - Usage Functions */ /* SphereColliderBound - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
bool SphereColliderBound::TestPoint(Vector3 point) bool SphereCollider::TestPoint(Vector3 point)
{ {
return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point)); return getNativeBoundObject<SHBoundingBox>().TestPoint(Convert::ToNative(point));
} }
bool SphereColliderBound::Raycast(Ray ray, float maxDistance) bool SphereCollider::Raycast(Ray ray, float maxDistance)
{ {
return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance); return getNativeBoundObject<SHBoundingBox>().Raycast(Convert::ToNative(ray), maxDistance);
} }
@ -125,8 +125,8 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* SphereColliderBound - Constructors */ /* SphereColliderBound - Constructors */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
SphereColliderBound::SphereColliderBound(int arrayIndex, Entity attachedEntity) SphereCollider::SphereCollider(int arrayIndex, Entity attachedEntity)
: ColliderBound{ arrayIndex, attachedEntity } : CollisionShape{ arrayIndex, attachedEntity }
{} {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -137,7 +137,7 @@ namespace SHADE
{ {
// Create lists if they don't exist // Create lists if they don't exist
if (colliders == nullptr) if (colliders == nullptr)
colliders = gcnew CollidersMap; colliders = gcnew ColliderMap;
if (!colliders->ContainsKey(entity)) if (!colliders->ContainsKey(entity))
colliders->Add(entity, gcnew WeakReferenceList()); colliders->Add(entity, gcnew WeakReferenceList());
@ -148,7 +148,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Collider - Properties */ /* Collider - Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
int Collider::ColliderBoundsCount::get() int Collider::CollisionShapeCount::get()
{ {
return static_cast<int>(GetNativeComponent()->GetColliders().size()); return static_cast<int>(GetNativeComponent()->GetColliders().size());
} }
@ -156,7 +156,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Collider - ColliderBound Functions */ /* Collider - ColliderBound Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
ColliderBound^ Collider::GetColliderBound(int index) CollisionShape^ Collider::GetCollisionShape(int index)
{ {
// Populate the list if it hasn't been // Populate the list if it hasn't been
if (subColliderList == nullptr) if (subColliderList == nullptr)
@ -172,15 +172,15 @@ namespace SHADE
return subColliderList[index]; return subColliderList[index];
} }
generic<typename T> generic<typename T>
T Collider::GetColliderBound(int index) T Collider::GetCollisionShape(int index)
{ {
return safe_cast<T>(GetColliderBound(index)); return safe_cast<T>(GetCollisionShape(index));
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Event Handling Functions */ /* Event Handling Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Collider::OnColliderRemoved(EntityID entity) void Collider::OnCollisionShapeRemoved(EntityID entity)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Check if there are any colliders to update // Check if there are any colliders to update
@ -192,7 +192,7 @@ namespace SHADE
SAFE_NATIVE_CALL_END("Collider.OnColliderRemoved") SAFE_NATIVE_CALL_END("Collider.OnColliderRemoved")
} }
void Collider::OnColliderBoundChanged(EntityID entity) void Collider::OnCollisionShapeChanged(EntityID entity)
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
// Check if there are any colliders to update // Check if there are any colliders to update
@ -226,20 +226,20 @@ namespace SHADE
if (subColliderList) if (subColliderList)
subColliderList->Clear(); subColliderList->Clear();
else else
subColliderList = gcnew System::Collections::Generic::List<ColliderBound^>(); subColliderList = gcnew System::Collections::Generic::List<CollisionShape^>();
// Populate the list // Populate the list
int i = 0; int i = 0;
for (const auto& collider : GetNativeComponent()->GetColliders()) for (const auto& collider : GetNativeComponent()->GetColliders())
{ {
ColliderBound^ bound = nullptr; CollisionShape^ bound = nullptr;
switch (collider.first.GetType()) switch (collider.GetType())
{ {
case SHCollider::Type::BOX: case SHCollider::Type::BOX:
bound = gcnew BoxColliderBound(i, Owner.GetEntity()); bound = gcnew BoxCollider(i, Owner.GetEntity());
break; break;
case SHCollider::Type::SPHERE: case SHCollider::Type::SPHERE:
bound = gcnew SphereColliderBound(i, Owner.GetEntity()); bound = gcnew SphereCollider(i, Owner.GetEntity());
break; break;
case SHCollider::Type::CAPSULE: case SHCollider::Type::CAPSULE:
// TODO // TODO

View File

@ -18,8 +18,8 @@ of DigiPen Institute of Technology is prohibited.
#include "Component.hxx" #include "Component.hxx"
namespace SHADE namespace SHADE
{ {
template<typename ColliderBoundType> template<typename CollisionShapeType>
ColliderBoundType& SHADE::ColliderBound::getNativeBoundObject() CollisionShapeType& SHADE::CollisionShape::getNativeBoundObject()
{ {
SHColliderComponent* collider = SHComponentManager::GetComponent_s<SHColliderComponent>(entity); SHColliderComponent* collider = SHComponentManager::GetComponent_s<SHColliderComponent>(entity);
if (!collider) if (!collider)
@ -31,7 +31,7 @@ namespace SHADE
if (bounds.GetType() != SHCollider::Type::BOX) if (bounds.GetType() != SHCollider::Type::BOX)
throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound."); throw gcnew System::InvalidOperationException("Attempted to retrieve invalid ColliderBound.");
return reinterpret_cast<ColliderBoundType&>(bounds); return reinterpret_cast<CollisionShapeType&>(bounds);
} }
catch (std::invalid_argument&) catch (std::invalid_argument&)
{ {

View File

@ -27,7 +27,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Base interface for all Collider Shapes. /// Base interface for all Collider Shapes.
/// </summary> /// </summary>
public ref class ColliderBound public ref class CollisionShape
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -51,7 +51,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
ColliderBound(int arrayIdx, Entity attachedEntity); CollisionShape(int arrayIdx, Entity attachedEntity);
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -62,8 +62,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
template<typename ColliderBoundType> template<typename CollisionShapeType>
ColliderBoundType& getNativeBoundObject(); CollisionShapeType& getNativeBoundObject();
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -75,7 +75,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Box-shaped Collider Bound. /// Box-shaped Collider Bound.
/// </summary> /// </summary>
public ref class BoxColliderBound : public ColliderBound public ref class BoxCollider : public CollisionShape
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -128,13 +128,13 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
BoxColliderBound(int arrayIndex, Entity attachedEntity); BoxCollider(int arrayIndex, Entity attachedEntity);
}; };
/// <summary> /// <summary>
/// Sphere-shaped Collider Bound. /// Sphere-shaped Collider Bound.
/// </summary> /// </summary>
public ref class SphereColliderBound : public ColliderBound public ref class SphereCollider : public CollisionShape
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -169,7 +169,7 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors */ /* Constructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
SphereColliderBound(int arrayIndex, Entity attachedEntity); SphereCollider(int arrayIndex, Entity attachedEntity);
}; };
/// <summary> /// <summary>
@ -196,7 +196,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Total number of ColliderBounds in the Collider component. /// Total number of ColliderBounds in the Collider component.
/// </summary> /// </summary>
property int ColliderBoundsCount property int CollisionShapeCount
{ {
int get(); int get();
} }
@ -209,7 +209,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <param name="index">Index to retrieve a ColliderBound from.</param> /// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns> /// <returns>ColliderBound for the specified index.</returns>
ColliderBound^ GetColliderBound(int index); CollisionShape^ GetCollisionShape(int index);
/// <summary> /// <summary>
/// Retrieves a ColliderBound at the specified index in the ColliderBound list /// Retrieves a ColliderBound at the specified index in the ColliderBound list
/// and casts it to the appropriate type. /// and casts it to the appropriate type.
@ -217,42 +217,42 @@ namespace SHADE
/// <typeparam name="T">Type of the ColliderBound to cast to.</typeparam> /// <typeparam name="T">Type of the ColliderBound to cast to.</typeparam>
/// <param name="index">Index to retrieve a ColliderBound from.</param> /// <param name="index">Index to retrieve a ColliderBound from.</param>
/// <returns>ColliderBound for the specified index.</returns> /// <returns>ColliderBound for the specified index.</returns>
generic<typename T> where T:ColliderBound generic<typename T> where T:CollisionShape
T GetColliderBound(int index); T GetCollisionShape(int index);
internal: internal:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Event Handling Functions */ /* Event Handling Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// To be called from native code when a collider has been removed. /// To be called from native code when a collision shape has been removed.
/// </summary> /// </summary>
/// <param name="entity">The entity which has it's collider removed.</param> /// <param name="entity">The entity which has it's collision shape removed.</param>
static void OnColliderRemoved(EntityID entity); static void OnCollisionShapeRemoved(EntityID entity);
/// <summary> /// <summary>
/// To be called from native code when a Collider bound has been removed. /// To be called from native code when a Collision Shape has been changed.
/// </summary> /// </summary>
/// <param name="entity"> /// <param name="entity">
/// The entity which has it's collider bounds changed. /// The entity which has it's collision shape changed.
/// </param> /// </param>
static void OnColliderBoundChanged(EntityID entity); static void OnCollisionShapeChanged(EntityID entity);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Type Definitions */ /* Type Definitions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
using WeakReferenceList = System::Collections::Generic::List<System::WeakReference^>; using WeakReferenceList = System::Collections::Generic::List<System::WeakReference^>;
using CollidersMap = System::Collections::Generic::Dictionary<EntityID, WeakReferenceList^>; using ColliderMap = System::Collections::Generic::Dictionary<EntityID, WeakReferenceList^>;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Static Data Members */ /* Static Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
static CollidersMap^ colliders; static ColliderMap^ colliders;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
System::Collections::Generic::List<ColliderBound^>^ subColliderList; System::Collections::Generic::List<CollisionShape^>^ subColliderList;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */