From 371ffc52dabe294600505026694d8d15cf21911d Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 27 Oct 2022 03:14:46 +0800 Subject: [PATCH] Colliders now use relative sizes --- SHADE_Application/src/Scenes/SBTestScene.cpp | 6 +- .../Inspector/SHEditorComponentView.hpp | 35 ++++-- SHADE_Engine/src/Math/Geometry/SHShape.cpp | 3 +- SHADE_Engine/src/Math/Geometry/SHShape.h | 4 +- .../Components/SHColliderComponent.cpp | 21 ++-- .../Physics/Components/SHColliderComponent.h | 3 +- SHADE_Engine/src/Physics/SHCollider.cpp | 85 ++++++++++--- SHADE_Engine/src/Physics/SHCollider.h | 55 +++++---- .../src/Physics/SHPhysicsMaterial.cpp | 104 ++++++++++++++++ SHADE_Engine/src/Physics/SHPhysicsMaterial.h | 113 ++++++++++++++++++ SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 6 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 6 +- SHADE_Engine/src/Scene/SHSceneGraph.cpp | 10 +- SHADE_Engine/src/Scene/SHSceneGraph.h | 2 +- 14 files changed, 369 insertions(+), 84 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsMaterial.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsMaterial.h diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index a06e68c2..d0d64c73 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -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.SetWorldScale(TEST_OBJ_SCALE); - //if (const bool IS_EVEN = (y * NUM_ROWS + x) % 2; IS_EVEN) - collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero); - //else - // collider.AddBoundingSphere(0.5f, SHVec3::Zero); - + collider.AddBoundingBox(SHVec3::One, SHVec3::Zero); stressTestObjects.emplace_back(entity); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 7fa39d74..4645bf52 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -207,6 +207,10 @@ namespace SHADE { if (!component) return; + + // Get transform component for extrapolating relative sizes + auto* transformComponent = SHComponentManager::GetComponent(component->GetEID()); + const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }); ImGui::SameLine(); @@ -221,28 +225,41 @@ namespace SHADE for (int i{}; i < size; ++i) { ImGui::PushID(i); - SHCollider& collider = component->GetCollider(i); + SHCollider* collider = &component->GetCollider(i); 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 }); - auto box = reinterpret_cast(collider.GetShape()); - SHEditorWidgets::DragVec3("Half Extents", { "X", "Y", "Z" }, [box] {return box->GetHalfExtents(); }, [box](SHVec3 const& vec) {box->SetHalfExtents(vec);}); + auto box = reinterpret_cast(collider->GetShape()); + 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 }); - auto sphere = reinterpret_cast(collider.GetShape()); - SHEditorWidgets::DragFloat("Radius", [sphere] {return sphere->GetRadius(); }, [sphere](float const& value) {sphere->SetRadius(value);}); + auto sphere = reinterpret_cast(collider->GetShape()); + 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::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(); } if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data())) diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.cpp b/SHADE_Engine/src/Math/Geometry/SHShape.cpp index 3fc5775d..2f869029 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.cpp +++ b/SHADE_Engine/src/Math/Geometry/SHShape.cpp @@ -27,10 +27,9 @@ namespace SHADE /* Getter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - SHShape::Type SHShape::GetType() const + SHShape::Type SHShape::GetType() const noexcept { return type; } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Geometry/SHShape.h b/SHADE_Engine/src/Math/Geometry/SHShape.h index 18f54fe6..62198897 100644 --- a/SHADE_Engine/src/Math/Geometry/SHShape.h +++ b/SHADE_Engine/src/Math/Geometry/SHShape.h @@ -63,7 +63,7 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] Type GetType() const; + [[nodiscard]] Type GetType () const noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ @@ -77,6 +77,6 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - Type type; + Type type; }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index 75a00491..fb999847 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -58,7 +58,7 @@ namespace SHADE if (index < 0 || static_cast(index) >= colliders.size()) 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; - auto boxPair = std::make_pair(SHCollider{ TYPE }, true); - auto& collider = colliders.emplace_back(boxPair).first; - - const auto* tf = SHComponentManager::GetComponent(GetEID()); + auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); - collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); + collider.SetBoundingBox(halfExtents); // Notify Physics System system->AddCollisionShape(GetEID(), &collider); @@ -109,16 +107,11 @@ namespace SHADE static constexpr auto TYPE = SHCollider::Type::SPHERE; - auto spherePair = std::make_pair(SHCollider{ TYPE }, true); - auto& collider = colliders.emplace_back(spherePair).first; - - const auto* tf = SHComponentManager::GetComponent(GetEID()); + auto& collider = colliders.emplace_back(SHCollider{ GetEID(), TYPE }); + collider.entityID = GetEID(); collider.SetPositionOffset(posOffset); - - const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale(); - const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z }); - collider.SetAsBoundingSphere(MAX_SCALE * 0.5f * radius); + collider.SetBoundingSphere(radius); // Notify Physics System system->AddCollisionShape(GetEID(), &collider); diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index 4ecd0e93..af726b51 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -43,8 +43,7 @@ namespace SHADE /* Type Definitions */ /*---------------------------------------------------------------------------------*/ - using ColliderDirtyPair = std::pair; - using Colliders = std::vector; + using Colliders = std::vector; public: diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollider.cpp index f5899cfc..6e929a17 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollider.cpp @@ -15,6 +15,8 @@ // Project Headers #include "Math/Geometry/SHBoundingBox.h" #include "Math/Geometry/SHBoundingSphere.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Math/SHMathHelpers.h" namespace SHADE { @@ -22,22 +24,24 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHCollider::SHCollider(Type colliderType) + SHCollider::SHCollider(EntityID eid, Type colliderType, const SHPhysicsMaterial& physicsMaterial) : type { colliderType } + , entityID { eid } , isTrigger { false } , dirty { true } , shape { nullptr } + , material { physicsMaterial } { switch (type) { case Type::BOX: { - SetAsBoundingBox(SHVec3::One); + shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One }; break; } case Type::SPHERE: { - SetAsBoundingSphere(1.0f); + shape = new SHBoundingSphere{ SHVec3::Zero, 0.5f }; break; } default: break; @@ -46,17 +50,21 @@ namespace SHADE SHCollider::SHCollider(const SHCollider& rhs) noexcept : type { rhs.type} + , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } , dirty { true } , shape { rhs.shape } + , material { rhs.material } , positionOffset { rhs.positionOffset } {} SHCollider::SHCollider(SHCollider&& rhs) noexcept : type { rhs.type} + , entityID { rhs.entityID } , isTrigger { rhs.isTrigger } , dirty { true } , shape { rhs.shape } + , material { rhs.material } , positionOffset { rhs.positionOffset } {} @@ -75,9 +83,11 @@ namespace SHADE return *this; type = rhs.type; + entityID = rhs.entityID; isTrigger = rhs.isTrigger; dirty = true; shape = rhs.shape; + material = rhs.material; positionOffset = rhs.positionOffset; return *this; @@ -86,9 +96,11 @@ namespace SHADE SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept { type = rhs.type; + entityID = rhs.entityID; isTrigger = rhs.isTrigger; dirty = true; shape = rhs.shape; + material = rhs.material; positionOffset = rhs.positionOffset; return *this; @@ -115,19 +127,16 @@ namespace SHADE float SHCollider::GetFriction() const noexcept { - // TODO(Diren): Fix after implementing materials - return 0.0f; + return material.GetFriction(); } float SHCollider::GetBounciness() const noexcept { - // TODO(Diren): Fix after implementing materials - return 0.0f; + return material.GetBounciness(); } float SHCollider::GetDensity() const noexcept { - // TODO(Diren): Fix after implementing materials - return 0.0f; + return material.GetDensity(); } const SHVec3& SHCollider::GetPositionOffset() const noexcept @@ -145,22 +154,60 @@ namespace SHADE /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents) + void SHCollider::SetBoundingBox(const SHVec3& halfExtents) { dirty = true; - type = Type::BOX; - delete shape; - shape = new SHBoundingBox{ positionOffset, halfExtents }; + // Set the half extents relative to transform + SHVec3 worldHalfExtents = halfExtents; + + const auto* transformComponent = SHComponentManager::GetComponent_s(entityID); + if (transformComponent != nullptr) + worldHalfExtents *= (transformComponent->GetWorldScale() * 0.5f); + + if (type == Type::BOX) + { + auto* box = reinterpret_cast(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; - type = Type::SPHERE; - delete shape; - shape = new SHBoundingSphere{ positionOffset, radius }; + // Set the radius relative to transform + float worldRadius = radius; + + const auto* transformComponent = SHComponentManager::GetComponent_s(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(shape); + sphere->SetRadius(worldRadius); + } + else + { + type = Type::SPHERE; + + delete shape; + shape = new SHBoundingSphere{ positionOffset, worldRadius }; + } + } void SHCollider::SetIsTrigger(bool trigger) noexcept @@ -172,16 +219,19 @@ namespace SHADE void SHCollider::SetFriction(float friction) noexcept { dirty = true; + material.SetFriction(friction); } void SHCollider::SetBounciness(float bounciness) noexcept { dirty = true; + material.SetBounciness(bounciness); } void SHCollider::SetDensity(float density) noexcept { dirty = true; + material.SetDensity(density); } void SHCollider::SetPositionOffset(const SHVec3& posOffset) noexcept @@ -205,5 +255,4 @@ RTTR_REGISTRATION registration::class_("Collider") .property("Position Offset", &SHCollider::GetPositionOffset, &SHCollider::SetPositionOffset); - // TODO(Diren): Add Physics Materials } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index 0e024f09..4fa483c9 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -13,8 +13,10 @@ #include // Project Headers +#include "ECS_Base/Entity/SHEntity.h" #include "Math/Geometry/SHShape.h" #include "Math/SHQuaternion.h" +#include "SHPhysicsMaterial.h" namespace SHADE { @@ -24,6 +26,15 @@ namespace SHADE class SH_API SHCollider { + private: + + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHColliderComponent; + friend class SHPhysicsObject; + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -40,7 +51,7 @@ namespace SHADE /* 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 (SHCollider&& rhs) noexcept; @@ -57,31 +68,33 @@ namespace SHADE /* 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 GetBounciness () const noexcept; - [[nodiscard]] float GetDensity () const noexcept; + [[nodiscard]] float GetFriction () const noexcept; + [[nodiscard]] float GetBounciness () 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 */ /*---------------------------------------------------------------------------------*/ - void SetAsBoundingBox (const SHVec3& halfExtents); - void SetAsBoundingSphere (float radius); + void SetBoundingBox (const SHVec3& halfExtents); + void SetBoundingSphere (float radius); - void SetIsTrigger (bool isTrigger) noexcept; - void SetFriction (float friction) noexcept; - void SetBounciness (float bounciness) noexcept; - void SetDensity (float density) noexcept; + void SetIsTrigger (bool isTrigger) noexcept; + void SetFriction (float friction) noexcept; + void SetBounciness (float bounciness) noexcept; + void SetDensity (float density) noexcept; + void SetMaterial (const SHPhysicsMaterial& newMaterial) noexcept; void SetPositionOffset (const SHVec3& positionOffset) noexcept; @@ -90,11 +103,13 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - Type type; - bool isTrigger; - bool dirty; - SHShape* shape; - SHVec3 positionOffset; + Type type; + EntityID entityID; // The entity this collider belongs to + bool isTrigger; + bool dirty; + SHShape* shape; + SHPhysicsMaterial material; + SHVec3 positionOffset; RTTR_ENABLE() }; diff --git a/SHADE_Engine/src/Physics/SHPhysicsMaterial.cpp b/SHADE_Engine/src/Physics/SHPhysicsMaterial.cpp new file mode 100644 index 00000000..677e448f --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsMaterial.cpp @@ -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 + +// 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 \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsMaterial.h b/SHADE_Engine/src/Physics/SHPhysicsMaterial.h new file mode 100644 index 00000000..b3db1655 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsMaterial.h @@ -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].
+ * 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].
+ * 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; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index 986ce503..4d4d8cd7 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -261,9 +261,9 @@ namespace SHADE void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { int index = 0; - for (auto& [collider, dirty] : c->colliders) + for (auto& collider : c->colliders) { - if (!dirty) + if (!collider.dirty) continue; // Update offsets @@ -293,7 +293,7 @@ namespace SHADE default: break; } - dirty = false; + collider.dirty = false; ++index; } } diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index 1c6e79d7..c3cd5ebc 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -517,7 +517,7 @@ namespace SHADE // Add collision shapes back into the body if (colliderComponent != nullptr) { - for (auto& collider : colliderComponent->colliders | std::views::keys) + for (auto& collider : colliderComponent->colliders) physicsObject->AddCollider(&collider); } } @@ -538,7 +538,7 @@ namespace SHADE } // Add Collision Shapes - for (auto& collider : colliderComponent->colliders | std::views::keys) + for (auto& collider : colliderComponent->colliders) physicsObject->AddCollider(&collider); } } @@ -576,7 +576,7 @@ namespace SHADE rp3d::Transform{ colliderComponent->position, colliderComponent->orientation } ); - for (auto& collider : colliderComponent->colliders | std::views::keys) + for (auto& collider : colliderComponent->colliders) physicsObject->AddCollider(&collider); } diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.cpp b/SHADE_Engine/src/Scene/SHSceneGraph.cpp index 950fd6a0..df46b3fb 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.cpp +++ b/SHADE_Engine/src/Scene/SHSceneGraph.cpp @@ -582,9 +582,9 @@ namespace SHADE 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; } - void SHSceneGraph::TraverseAndInvokePredicate(const SHSceneNode* node, const UnaryFunction& predicate) + void SHSceneGraph::TraverseAndInvokeFunction(const SHSceneNode* node, const UnaryFunction& function) { for (auto* child : node->children) { - predicate(child); - TraverseAndInvokePredicate(child, predicate); + function(child); + TraverseAndInvokeFunction(child, function); } } diff --git a/SHADE_Engine/src/Scene/SHSceneGraph.h b/SHADE_Engine/src/Scene/SHSceneGraph.h index b52fd1ff..45ab48e5 100644 --- a/SHADE_Engine/src/Scene/SHSceneGraph.h +++ b/SHADE_Engine/src/Scene/SHSceneGraph.h @@ -142,7 +142,7 @@ namespace SHADE bool RemoveNode (SHSceneNode* nodeToRemove) noexcept; void Reset () noexcept; - void Traverse (const UnaryFunction& predicate) const; + void Traverse (const UnaryFunction& function) const; private: /*---------------------------------------------------------------------------------*/