Colliders now use relative sizes
This commit is contained in:
parent
19ceab84df
commit
371ffc52da
|
@ -95,11 +95,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()))
|
||||||
|
|
|
@ -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
|
|
@ -63,7 +63,7 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] Type GetType() const;
|
[[nodiscard]] Type GetType () const noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
@ -77,6 +77,6 @@ namespace SHADE
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -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);
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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,17 +50,21 @@ 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 { rhs.shape }
|
||||||
|
, material { rhs.material }
|
||||||
, positionOffset { rhs.positionOffset }
|
, positionOffset { rhs.positionOffset }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
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 { rhs.shape }
|
||||||
|
, material { rhs.material }
|
||||||
, positionOffset { rhs.positionOffset }
|
, positionOffset { rhs.positionOffset }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -75,9 +83,11 @@ 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;
|
shape = rhs.shape;
|
||||||
|
material = rhs.material;
|
||||||
positionOffset = rhs.positionOffset;
|
positionOffset = rhs.positionOffset;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -86,9 +96,11 @@ namespace SHADE
|
||||||
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;
|
shape = rhs.shape;
|
||||||
|
material = rhs.material;
|
||||||
positionOffset = rhs.positionOffset;
|
positionOffset = rhs.positionOffset;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -115,19 +127,16 @@ 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 SHVec3& SHCollider::GetPositionOffset() const noexcept
|
const SHVec3& SHCollider::GetPositionOffset() const noexcept
|
||||||
|
@ -145,22 +154,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;
|
||||||
type = Type::BOX;
|
|
||||||
|
|
||||||
delete shape;
|
// Set the half extents relative to transform
|
||||||
shape = new SHBoundingBox{ positionOffset, halfExtents };
|
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;
|
||||||
|
|
||||||
|
delete shape;
|
||||||
|
shape = new SHBoundingBox{ positionOffset, worldHalfExtents };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetAsBoundingSphere(float radius)
|
void SHCollider::SetBoundingSphere(float radius)
|
||||||
{
|
{
|
||||||
dirty = true;
|
dirty = true;
|
||||||
type = Type::SPHERE;
|
|
||||||
|
|
||||||
delete shape;
|
// Set the radius relative to transform
|
||||||
shape = new SHBoundingSphere{ positionOffset, radius };
|
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;
|
||||||
|
|
||||||
|
delete shape;
|
||||||
|
shape = new SHBoundingSphere{ positionOffset, worldRadius };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHCollider::SetIsTrigger(bool trigger) noexcept
|
void SHCollider::SetIsTrigger(bool trigger) noexcept
|
||||||
|
@ -172,16 +219,19 @@ 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::SetPositionOffset(const SHVec3& posOffset) noexcept
|
void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept
|
||||||
|
@ -205,5 +255,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
|
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
@ -57,31 +68,33 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] bool HasChanged () const noexcept;
|
[[nodiscard]] bool HasChanged () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] bool IsTrigger () const noexcept;
|
[[nodiscard]] bool IsTrigger () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] Type GetType () const noexcept;
|
[[nodiscard]] Type GetType () 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]] const SHPhysicsMaterial& GetMaterial () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
[[nodiscard]] const SHVec3& GetPositionOffset () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] SHShape* GetShape () noexcept;
|
[[nodiscard]] SHShape* GetShape () noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* 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;
|
||||||
|
|
||||||
|
@ -90,11 +103,13 @@ namespace SHADE
|
||||||
/* Data Members */
|
/* Data Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
bool isTrigger;
|
EntityID entityID; // The entity this collider belongs to
|
||||||
bool dirty;
|
bool isTrigger;
|
||||||
SHShape* shape;
|
bool dirty;
|
||||||
SHVec3 positionOffset;
|
SHShape* shape;
|
||||||
|
SHPhysicsMaterial material;
|
||||||
|
SHVec3 positionOffset;
|
||||||
|
|
||||||
RTTR_ENABLE()
|
RTTR_ENABLE()
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -517,7 +517,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 +538,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 +576,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -582,9 +582,9 @@ namespace SHADE
|
||||||
ReleaseNode(node);
|
ReleaseNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::Traverse (const UnaryFunction& predicate) const
|
void SHSceneGraph::Traverse (const UnaryFunction& function) const
|
||||||
{
|
{
|
||||||
TraverseAndInvokePredicate(root, predicate);
|
TraverseAndInvokeFunction(root, function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -621,12 +621,12 @@ namespace SHADE
|
||||||
delete node;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryFunction& predicate)
|
void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function)
|
||||||
{
|
{
|
||||||
for (auto* child : node->children)
|
for (auto* child : node->children)
|
||||||
{
|
{
|
||||||
predicate(child);
|
function(child);
|
||||||
TraverseAndInvokePredicate(child, predicate);
|
TraverseAndInvokeFunction(child, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
Loading…
Reference in New Issue