diff --git a/Assets/Scenes/PhysicsSandbox.shade b/Assets/Scenes/PhysicsSandbox.shade index 0637a088..a0b3c0c2 100644 --- a/Assets/Scenes/PhysicsSandbox.shade +++ b/Assets/Scenes/PhysicsSandbox.shade @@ -1 +1,28 @@ -[] \ No newline at end of file +- EID: 0 + Name: Default + IsActive: true + NumberOfChildren: 0 + Components: + Transform Component: + Translate: {x: 0, y: 1.77475965, z: 0} + Rotate: {x: -0, y: 0, z: -0} + Scale: {x: 1, y: 1, z: 1} + IsActive: true + RigidBody Component: + Type: Static + Auto Mass: false + Mass: 1 + Drag: 0 + Angular Drag: 0 + Use Gravity: true + Gravity Scale: 1 + Interpolate: true + Sleeping Enabled: true + Freeze Position X: false + Freeze Position Y: false + Freeze Position Z: false + Freeze Rotation X: false + Freeze Rotation Y: false + Freeze Rotation Z: false + IsActive: true + Scripts: ~ \ No newline at end of file diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index ce0a939c..a58839c5 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -109,7 +109,7 @@ namespace Sandbox SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); - SHSystemManager::RegisterRoutine(); + SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); SHSystemManager::RegisterRoutine(); diff --git a/SHADE_Application/src/Scenes/SBMainScene.cpp b/SHADE_Application/src/Scenes/SBMainScene.cpp index 55ce32b0..6c875518 100644 --- a/SHADE_Application/src/Scenes/SBMainScene.cpp +++ b/SHADE_Application/src/Scenes/SBMainScene.cpp @@ -11,7 +11,7 @@ #include "Scripting/SHScriptEngine.h" #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" @@ -44,13 +44,6 @@ namespace Sandbox { sceneName = SHSerialization::DeserializeSceneFromFile(sceneAssetID); - auto* physicsSystem = SHSystemManager::GetSystem(); - if (!physicsSystem) - { - SHLOGV_CRITICAL("Failed to get the physics system for building the scene!") - return; - } - /*-----------------------------------------------------------------------*/ /* TESTING CODE */ /*-----------------------------------------------------------------------*/ diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index bcc7f09d..9e3fa8ab 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -10,7 +10,7 @@ #include "Scripting/SHScriptEngine.h" #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" #include "Graphics/MiddleEnd/Lights/SHLightComponent.h" diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index f70ab889..02614631 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -251,7 +251,7 @@ namespace SHADE if(rbType == SHRigidBodyComponent::Type::DYNAMIC) //Dynamic only fields { - SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetGravityEnabled(value);}, "Gravity"); + SHEditorWidgets::CheckBox("Use Gravity", [component]{return component->IsGravityEnabled();}, [component](bool const& value){component->SetIsGravityEnabled(value);}, "Gravity"); //SHEditorWidgets::DragFloat("Mass", [component] {return component->GetMass(); }, [component](float const& value) {component->SetMass(value); }, "Mass"); } if (rbType == SHRigidBodyComponent::Type::DYNAMIC || rbType == SHRigidBodyComponent::Type::KINEMATIC) //Dynamic or Kinematic only fields @@ -296,7 +296,7 @@ namespace SHADE { SHEditorWidgets::DragVec3("Force", { "X", "Y", "Z" }, [component] {return component->GetForce(); }, [](SHVec3 const& value) {}, false, "Force", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); SHEditorWidgets::DragVec3("Torque", { "X", "Y", "Z" }, [component] {return component->GetTorque(); }, [](SHVec3 const& value) {}, false, "Torque", 0.1f, "%.3f", 0.0f, 0.0f, ImGuiSliderFlags_ReadOnly); - SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->GetIsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep"); + SHEditorWidgets::CheckBox("Is Asleep", [component] {return component->IsSleeping(); }, [](bool value) {}, "If the Rigid Body is asleep"); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index 83647da7..f0d3e3e5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -14,7 +14,7 @@ #include "Scripting/SHScriptEngine.h" #include "ECS_Base/Managers/SHSystemManager.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" #include "Camera/SHCameraComponent.h" #include "Camera/SHCameraArmComponent.h" diff --git a/SHADE_Engine/src/Events/SHEventDefines.h b/SHADE_Engine/src/Events/SHEventDefines.h index d7bbf5f0..7bf82cd5 100644 --- a/SHADE_Engine/src/Events/SHEventDefines.h +++ b/SHADE_Engine/src/Events/SHEventDefines.h @@ -13,9 +13,11 @@ constexpr SHEventIdentifier SH_COMPONENT_REMOVED_EVENT { 4 }; constexpr SHEventIdentifier SH_SCENEGRAPH_CHANGE_PARENT_EVENT { 5 }; constexpr SHEventIdentifier SH_SCENEGRAPH_ADD_CHILD_EVENT { 6 }; constexpr SHEventIdentifier SH_SCENEGRAPH_REMOVE_CHILD_EVENT { 7 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 8 }; -constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 9 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 10 }; -constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 11 }; -constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 12 }; +constexpr SHEventIdentifier SH_SCENE_ON_INIT_EVENT { 8 }; +constexpr SHEventIdentifier SH_SCENE_ON_EXIT_EVENT { 9 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_ADDED_EVENT { 10 }; +constexpr SHEventIdentifier SH_PHYSICS_COLLIDER_REMOVED_EVENT { 11 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PLAY_EVENT { 12 }; +constexpr SHEventIdentifier SH_EDITOR_ON_PAUSE_EVENT { 13 }; +constexpr SHEventIdentifier SH_EDITOR_ON_STOP_EVENT { 14 }; diff --git a/SHADE_Engine/src/Physics/Collision/SHCollisionInfo.h b/SHADE_Engine/src/Physics/Collision/SHCollisionInfo.h index d2dad647..dfcf4f22 100644 --- a/SHADE_Engine/src/Physics/Collision/SHCollisionInfo.h +++ b/SHADE_Engine/src/Physics/Collision/SHCollisionInfo.h @@ -12,7 +12,7 @@ // Project Headers #include "Physics/Interface/SHColliderComponent.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" namespace SHADE diff --git a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.cpp b/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.cpp index ad739847..1867636c 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.cpp +++ b/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.cpp @@ -13,6 +13,9 @@ // Primary Header #include "SHRigidBody.h" +// Project Headers +#include "Tools/Logger/SHLogger.h" + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -93,4 +96,357 @@ namespace SHADE return *this; } + /*-----------------------------------------------------------------------------------*/ + /* Getter Functions Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHRigidBody::Type SHRigidBody::GetType() const noexcept + { + return bodyType; + } + + float SHRigidBody::GetMass() const noexcept + { + return 1.0f/ invMass; + } + + float SHRigidBody::GetLinearDrag() const noexcept + { + return linearDrag; + } + + float SHRigidBody::GetGravityScale() const noexcept + { + return gravityScale; + } + + const SHVec3& SHRigidBody::GetAccumulatedForce() const noexcept + { + return accumulatedForce; + } + + const SHVec3& SHRigidBody::GetLinearVelocity() const noexcept + { + return linearVelocity; + } + + const SHVec3& SHRigidBody::GetAngularVelocity() const noexcept + { + return angularVelocity; + } + + // Flags + + bool SHRigidBody::IsActive() const noexcept + { + static constexpr unsigned int FLAG_POS = 0; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::IsSleeping() const noexcept + { + static constexpr unsigned int FLAG_POS = 1; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::IsSleepingEnabled() const noexcept + { + static constexpr unsigned int FLAG_POS = 2; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::IsGravityEnabled() const noexcept + { + static constexpr unsigned int FLAG_POS = 3; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::IsAutoMassEnabled() const noexcept + { + static constexpr unsigned int FLAG_POS = 4; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezePositionX() const noexcept + { + static constexpr unsigned int FLAG_POS = 10; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezePositionY() const noexcept + { + static constexpr unsigned int FLAG_POS = 11; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezePositionZ() const noexcept + { + static constexpr unsigned int FLAG_POS = 12; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezeRotationX() const noexcept + { + static constexpr unsigned int FLAG_POS = 13; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezeRotationY() const noexcept + { + static constexpr unsigned int FLAG_POS = 14; + return flags & (1U << FLAG_POS); + } + + bool SHRigidBody::GetFreezeRotationZ() const noexcept + { + static constexpr unsigned int FLAG_POS = 15; + return flags & (1U << FLAG_POS); + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Functions Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBody::SetType(Type newType) noexcept + { + if (newType == bodyType) + return; + + bodyType = newType; + invMass = newType == Type::DYNAMIC ? 1.0f : 0.0f; + } + + void SHRigidBody::SetMass(float newMass) noexcept + { + if (bodyType != Type::DYNAMIC) + { + SHLOG_WARNING("Cannot set mass of a non-Dynamic Body {}", entityID) + return; + } + + if (newMass < 0.0f) + { + SHLOG_WARNING("Cannot set mass below 0. Object {}'s mass will remain unchanged.", entityID) + return; + } + + invMass = 1.0f / newMass; + + // TODO: Recompute inertia tensor + } + + void SHRigidBody::SetLinearDrag(float newLinearDrag) noexcept + { + if (bodyType == Type::STATIC) + { + SHLOG_WARNING("Cannot set linear drag of a Static Body {}", entityID) + return; + } + + if (newLinearDrag < 0.0f) + { + SHLOG_WARNING("Cannot set drag below 0. Object {}'s linear drag will remain unchanged.", entityID) + return; + } + + linearDrag = newLinearDrag; + } + + void SHRigidBody::SetGravityScale(float newGravityScale) noexcept + { + gravityScale = newGravityScale; + } + + void SHRigidBody::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept + { + linearVelocity = newLinearVelocity; + } + + void SHRigidBody::SetIsActive(bool isActive) noexcept + { + static constexpr unsigned int FLAG_POS = 0; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + isActive ? flags |= VALUE : flags &= ~VALUE; + } + + void SHRigidBody::SetIsSleeping(bool isSleeping) noexcept + { + static constexpr unsigned int FLAG_POS = 1; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + isSleeping ? flags |= VALUE : flags &= ~VALUE; + } + + void SHRigidBody::SetSleepingEnabled(bool enableSleeping) noexcept + { + static constexpr unsigned int FLAG_POS = 2; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (enableSleeping) + { + flags |= VALUE; + } + else + { + flags &= ~VALUE; + // Wake the body + SetIsSleeping(false); + } + } + + void SHRigidBody::SetGravityEnabled(bool enableGravity) noexcept + { + static constexpr unsigned int FLAG_POS = 3; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + enableGravity ? flags |= VALUE : flags &= ~VALUE; + } + + void SHRigidBody::SetAutoMassEnabled(bool enableAutoMass) noexcept + { + static constexpr unsigned int FLAG_POS = 4; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (enableAutoMass) + { + flags |= VALUE; + // TODO: Compute mass based on collider geometry + } + else + { + flags &= ~VALUE; + // Use default mass of 1 + invMass = 1.0f; + } + } + + void SHRigidBody::SetFreezePositionX(bool freezePositionX) noexcept + { + static constexpr unsigned int FLAG_POS = 10; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezePositionX) + { + flags |= VALUE; + // Reset linear velocity along X-axis + linearVelocity.x = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + void SHRigidBody::SetFreezePositionY(bool freezePositionY) noexcept + { + static constexpr unsigned int FLAG_POS = 11; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezePositionY) + { + flags |= VALUE; + // Reset linear velocity along Y-axis + linearVelocity.y = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + void SHRigidBody::SetFreezePositionZ(bool freezePositionZ) noexcept + { + static constexpr unsigned int FLAG_POS = 12; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezePositionZ) + { + flags |= VALUE; + // Reset linear velocity along Z-axis + linearVelocity.z = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + void SHRigidBody::SetFreezeRotationX(bool freezeRotationX) noexcept + { + static constexpr unsigned int FLAG_POS = 13; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezeRotationX) + { + flags |= VALUE; + // Reset angular velocity along X-axis + angularVelocity.x = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + void SHRigidBody::SetFreezeRotationY(bool freezeRotationY) noexcept + { + static constexpr unsigned int FLAG_POS = 14; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezeRotationY) + { + flags |= VALUE; + // Reset angular velocity along Y-axis + angularVelocity.y = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + void SHRigidBody::SetFreezeRotationZ(bool freezeRotationZ) noexcept + { + static constexpr unsigned int FLAG_POS = 15; + static constexpr uint16_t VALUE = 1U << FLAG_POS; + + if (freezeRotationZ) + { + flags |= VALUE; + // Reset angular velocity along Z-axis + angularVelocity.z = 0.0f; + } + else + { + flags &= ~VALUE; + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Member Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBody::AddForce(const SHVec3& force, const SHVec3& pos) noexcept + { + if (bodyType != Type::DYNAMIC) + return; + + accumulatedForce += force; + // Compute torque when force is offset + } + + void SHRigidBody::AddImpulse(const SHVec3& impulse, const SHVec3& pos) noexcept + { + if (bodyType != Type::DYNAMIC) + return; + + linearVelocity += impulse * invMass; + } + + void SHRigidBody::ClearForces() noexcept + { + accumulatedForce = SHVec3::Zero; + } + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.h b/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.h index 598ed3aa..77b29292 100644 --- a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.h +++ b/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.h @@ -13,22 +13,20 @@ // Project Headers #include "ECS_Base/SHECSMacros.h" #include "Math/Vector/SHVec3.h" +#include "SH_API.h" namespace SHADE { + /*-------------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-------------------------------------------------------------------------------------*/ + /** * @brief * Encapsulates a Rigid Body used in Physics Simulations */ - class SHRigidBody + class SH_API SHRigidBody { - private: - /*-----------------------------------------------------------------------------------*/ - /* Friends */ - /*-----------------------------------------------------------------------------------*/ - - friend class SHRigidBodyComponent; - public: /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -185,5 +183,3 @@ namespace SHADE }; } // namespace SHADE - -#include "SHRigidBody.inl" diff --git a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.inl b/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.inl deleted file mode 100644 index 28f98d12..00000000 --- a/SHADE_Engine/src/Physics/Dynamics/SHRigidBody.inl +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************************** - * \file SHRigidBody.inl - * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Implementation for inlined functions of a Rigid Body. - * - * \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 - -// Primary Header -#include "SHRigidBody.h" - -// Project Headers -#include "Math/SHMathHelpers.h" -#include "Tools/Logger/SHLogger.h" - -namespace SHADE -{ - /*-----------------------------------------------------------------------------------*/ - /* Getter Functions Definitions */ - /*-----------------------------------------------------------------------------------*/ - - inline SHRigidBody::Type SHRigidBody::GetType() const noexcept - { - return bodyType; - } - - inline float SHRigidBody::GetMass() const noexcept - { - return 1.0f/ invMass; - } - - inline float SHRigidBody::GetLinearDrag() const noexcept - { - return linearDrag; - } - - inline float SHRigidBody::GetGravityScale() const noexcept - { - return gravityScale; - } - - inline const SHVec3& SHRigidBody::GetAccumulatedForce() const noexcept - { - return accumulatedForce; - } - - inline const SHVec3& SHRigidBody::GetLinearVelocity() const noexcept - { - return linearVelocity; - } - - inline const SHVec3& SHRigidBody::GetAngularVelocity() const noexcept - { - return angularVelocity; - } - - // Flags - - inline bool SHRigidBody::IsActive() const noexcept - { - static constexpr unsigned int FLAG_POS = 0; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::IsSleeping() const noexcept - { - static constexpr unsigned int FLAG_POS = 1; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::IsSleepingEnabled() const noexcept - { - static constexpr unsigned int FLAG_POS = 2; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::IsGravityEnabled() const noexcept - { - static constexpr unsigned int FLAG_POS = 3; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::IsAutoMassEnabled() const noexcept - { - static constexpr unsigned int FLAG_POS = 4; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezePositionX() const noexcept - { - static constexpr unsigned int FLAG_POS = 10; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezePositionY() const noexcept - { - static constexpr unsigned int FLAG_POS = 11; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezePositionZ() const noexcept - { - static constexpr unsigned int FLAG_POS = 12; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezeRotationX() const noexcept - { - static constexpr unsigned int FLAG_POS = 13; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezeRotationY() const noexcept - { - static constexpr unsigned int FLAG_POS = 14; - return flags & (1U << FLAG_POS); - } - - inline bool SHRigidBody::GetFreezeRotationZ() const noexcept - { - static constexpr unsigned int FLAG_POS = 15; - return flags & (1U << FLAG_POS); - } - - /*-----------------------------------------------------------------------------------*/ - /* Setter Functions Definitions */ - /*-----------------------------------------------------------------------------------*/ - - inline void SHRigidBody::SetType(Type newType) noexcept - { - if (newType == bodyType) - return; - - bodyType = newType; - invMass = newType == Type::DYNAMIC ? 1.0f : 0.0f; - } - - inline void SHRigidBody::SetMass(float newMass) noexcept - { - if (bodyType != Type::DYNAMIC) - { - SHLOG_WARNING("Cannot set mass of a non-Dynamic Body {}", entityID) - return; - } - - if (newMass < 0.0f) - { - SHLOG_WARNING("Cannot set mass below 0. Object {}'s mass will remain unchanged.", entityID) - return; - } - - invMass = 1.0f / newMass; - - // TODO: Recompute inertia tensor - } - - inline void SHRigidBody::SetLinearDrag(float newLinearDrag) noexcept - { - if (bodyType == Type::STATIC) - { - SHLOG_WARNING("Cannot set linear drag of a Static Body {}", entityID) - return; - } - - if (newLinearDrag < 0.0f) - { - SHLOG_WARNING("Cannot set drag below 0. Object {}'s linear drag will remain unchanged.", entityID) - return; - } - - linearDrag = newLinearDrag; - } - - inline void SHRigidBody::SetGravityScale(float newGravityScale) noexcept - { - gravityScale = newGravityScale; - } - - inline void SHRigidBody::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept - { - linearVelocity = newLinearVelocity; - } - - inline void SHRigidBody::SetIsActive(bool isActive) noexcept - { - static constexpr unsigned int FLAG_POS = 0; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - isActive ? flags |= VALUE : flags &= ~VALUE; - } - - inline void SHRigidBody::SetIsSleeping(bool isSleeping) noexcept - { - static constexpr unsigned int FLAG_POS = 1; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - isSleeping ? flags |= VALUE : flags &= ~VALUE; - } - - inline void SHRigidBody::SetSleepingEnabled(bool enableSleeping) noexcept - { - static constexpr unsigned int FLAG_POS = 2; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (enableSleeping) - { - flags |= VALUE; - } - else - { - flags &= ~VALUE; - // Wake the body - SetIsSleeping(false); - } - } - - inline void SHRigidBody::SetGravityEnabled(bool enableGravity) noexcept - { - static constexpr unsigned int FLAG_POS = 3; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - enableGravity ? flags |= VALUE : flags &= ~VALUE; - } - - inline void SHRigidBody::SetAutoMassEnabled(bool enableAutoMass) noexcept - { - static constexpr unsigned int FLAG_POS = 4; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (enableAutoMass) - { - flags |= VALUE; - // TODO: Compute mass based on collider geometry - } - else - { - flags &= ~VALUE; - // Use default mass of 1 - invMass = 1.0f; - } - } - - inline void SHRigidBody::SetFreezePositionX(bool freezePositionX) noexcept - { - static constexpr unsigned int FLAG_POS = 10; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezePositionX) - { - flags |= VALUE; - // Reset linear velocity along X-axis - linearVelocity.x = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - inline void SHRigidBody::SetFreezePositionY(bool freezePositionY) noexcept - { - static constexpr unsigned int FLAG_POS = 11; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezePositionY) - { - flags |= VALUE; - // Reset linear velocity along Y-axis - linearVelocity.y = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - inline void SHRigidBody::SetFreezePositionZ(bool freezePositionZ) noexcept - { - static constexpr unsigned int FLAG_POS = 12; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezePositionZ) - { - flags |= VALUE; - // Reset linear velocity along Z-axis - linearVelocity.z = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - inline void SHRigidBody::SetFreezeRotationX(bool freezeRotationX) noexcept - { - static constexpr unsigned int FLAG_POS = 13; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezeRotationX) - { - flags |= VALUE; - // Reset angular velocity along X-axis - angularVelocity.x = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - inline void SHRigidBody::SetFreezeRotationY(bool freezeRotationY) noexcept - { - static constexpr unsigned int FLAG_POS = 14; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezeRotationY) - { - flags |= VALUE; - // Reset angular velocity along Y-axis - angularVelocity.y = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - inline void SHRigidBody::SetFreezeRotationZ(bool freezeRotationZ) noexcept - { - static constexpr unsigned int FLAG_POS = 15; - static constexpr uint16_t VALUE = 1U << FLAG_POS; - - if (freezeRotationZ) - { - flags |= VALUE; - // Reset angular velocity along Z-axis - angularVelocity.z = 0.0f; - } - else - { - flags &= ~VALUE; - } - } - - /*-----------------------------------------------------------------------------------*/ - /* Member Function Definitions */ - /*-----------------------------------------------------------------------------------*/ - - inline void SHRigidBody::AddForce(const SHVec3& force, const SHVec3& pos) noexcept - { - if (bodyType != Type::DYNAMIC) - return; - - accumulatedForce += force; - // Compute torque when force is offset - } - - inline void SHRigidBody::AddImpulse(const SHVec3& impulse, const SHVec3& pos) noexcept - { - if (bodyType != Type::DYNAMIC) - return; - - linearVelocity += impulse * invMass; - } - - inline void SHRigidBody::ClearForces() noexcept - { - accumulatedForce = SHVec3::Zero; - } - -} // namespace SHADE diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.cpp new file mode 100644 index 00000000..44452868 --- /dev/null +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.cpp @@ -0,0 +1,74 @@ +/**************************************************************************************** + * \file SHPhysicsObject.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Physics Object. + * + * \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 "SHPhysicsObject.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructor & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject::SHPhysicsObject(EntityID eid) noexcept + : entityID { eid } + {} + + SHPhysicsObject::SHPhysicsObject(const SHPhysicsObject& rhs) noexcept + : entityID { rhs.entityID } + { + // Perform a deep copy of the components + *rigidBody = *rhs.rigidBody; + } + + SHPhysicsObject::SHPhysicsObject(SHPhysicsObject&& rhs) noexcept + : entityID { rhs.entityID } + { + // Perform a deep copy of the components + *rigidBody = *rhs.rigidBody; + } + + SHPhysicsObject::~SHPhysicsObject() noexcept + { + entityID = MAX_EID; + + delete rigidBody; + } + + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject& SHPhysicsObject::operator=(const SHPhysicsObject& rhs) noexcept + { + if (this == &rhs) + return *this; + + entityID = rhs.entityID; + + // Perform a deep copy of the components + *rigidBody = *rhs.rigidBody; + + return *this; + } + + SHPhysicsObject& SHPhysicsObject::operator=(SHPhysicsObject&& rhs) noexcept + { + entityID = rhs.entityID; + + // Perform a deep copy of the components + *rigidBody = *rhs.rigidBody; + + return *this; + } +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.h new file mode 100644 index 00000000..2be5844d --- /dev/null +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObject.h @@ -0,0 +1,52 @@ +/**************************************************************************************** + * \file SHPhysicsObject.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Physics Object. + * + * \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 "Physics/Dynamics/SHRigidBody.h" + +namespace SHADE +{ + /*-------------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-------------------------------------------------------------------------------------*/ + + /** + * @brief + * Encapsulates a rigid body and a collider tied to an Entity. + */ + struct SH_API SHPhysicsObject + { + public: + /*-----------------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------------*/ + + EntityID entityID = MAX_EID; + SHRigidBody* rigidBody = nullptr; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject (EntityID eid) noexcept; + SHPhysicsObject (const SHPhysicsObject& rhs) noexcept; + SHPhysicsObject (SHPhysicsObject&& rhs) noexcept; + ~SHPhysicsObject () noexcept; + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject& operator=(const SHPhysicsObject& rhs) noexcept; + SHPhysicsObject& operator=(SHPhysicsObject&& rhs) noexcept; + }; +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp new file mode 100644 index 00000000..dccca97b --- /dev/null +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.cpp @@ -0,0 +1,138 @@ +/**************************************************************************************** + * \file SHPhysicsObjectManager.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Physics Object Manager. + * + * \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 "SHPhysicsObjectManager.h" + +// Project Headers +#include "Physics/Interface/SHColliderComponent.h" +#include "Physics/Interface/SHCollisionShape.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" +#include "Tools/Utilities/SHUtilities.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObjectManager::EntityObjectMap& SHPhysicsObjectManager::GetPhysicsObjects() noexcept + { + return physicsObjects; + } + + const SHPhysicsObject* SHPhysicsObjectManager::GetPhysicsObject(EntityID entityID) noexcept + { + const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID); + if (PHYSICS_OBJECT_ITERATOR == physicsObjects.end()) + { + SHLOG_ERROR("Cannot find physics object for entity {}!", entityID) + return nullptr; + } + + return &PHYSICS_OBJECT_ITERATOR->second; + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Member Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsObjectManager::AddRigidBody(EntityID entityID) noexcept + { + SHPhysicsObject* physicsObject = nullptr; + + const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID); + if (PHYSICS_OBJECT_ITERATOR == physicsObjects.end()) + physicsObject = createPhysicsObject(entityID); + else + physicsObject = &PHYSICS_OBJECT_ITERATOR->second; + + // Get the component + auto* rigidBodyComponent = SHComponentManager::GetComponent(entityID); + + // Create a new rigidbody in the physics object + // We assume none has already been made + + physicsObject->rigidBody = new SHRigidBody + { + entityID + , static_cast(rigidBodyComponent->GetType()) + }; + + // Link with the component + rigidBodyComponent->SetRigidBody(physicsObject->rigidBody); + + // TODO: Broadcast event + } + + void SHPhysicsObjectManager::RemoveRigidBody(EntityID entityID) noexcept + { + const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID); + if (PHYSICS_OBJECT_ITERATOR != physicsObjects.end()) + { + SHPhysicsObject* physicsObject = &PHYSICS_OBJECT_ITERATOR->second; + + delete physicsObject->rigidBody; + physicsObject->rigidBody = nullptr; + + // Destroy empty physics objects + if (physicsObject->rigidBody == nullptr) + destroyPhysicsObject(entityID); + } + + // TODO: Broadcast event + } + + void SHPhysicsObjectManager::AddCollider(EntityID entityID) noexcept + { + // Link with the component + + // TODO: Broadcast event + } + + void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept + { + // Unlink with the component + + // TODO: Broadcast event + } + + void SHPhysicsObjectManager::AddCollisionShape(EntityID entityID, uint8_t shapeID) noexcept + { + // Link with the component + + // TODO: Broadcast event + } + + void SHPhysicsObjectManager::RemoveCollisionShape(EntityID entityID, uint8_t shapeID) noexcept + { + // Unlink with the component + + // TODO: Broadcast event + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Member Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject* SHPhysicsObjectManager::createPhysicsObject(EntityID entityID) + { + const auto& NEW_OBJECT = physicsObjects.emplace(entityID, SHPhysicsObject{entityID}).first; + return &NEW_OBJECT->second; + } + + void SHPhysicsObjectManager::destroyPhysicsObject(EntityID entityID) + { + physicsObjects.erase(entityID); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.h b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.h new file mode 100644 index 00000000..17a1d3a1 --- /dev/null +++ b/SHADE_Engine/src/Physics/Interface/PhysicsObject/SHPhysicsObjectManager.h @@ -0,0 +1,125 @@ +/**************************************************************************************** + * \file SHPhysicsObjectManager.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Physics Object Manager. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include + +// Project Headers +#include "SHPhysicsObject.h" + +namespace SHADE +{ + /*-------------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-------------------------------------------------------------------------------------*/ + + /** + * @brief + * Encapsulates a manager for physics objects that links raw physics components with the + * engine's components. + */ + class SHPhysicsObjectManager + { + private: + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + using EntityObjectMap = std::unordered_map; + + public: + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObjectManager() noexcept = default; + + /*-----------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*-----------------------------------------------------------------------------------*/ + + [[nodiscard]] EntityObjectMap& GetPhysicsObjects () noexcept; + [[nodiscard]] const SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + + /*-----------------------------------------------------------------------------------*/ + /* Member Functions */ + /*-----------------------------------------------------------------------------------*/ + + /** + * @brief + * Creates a rigid body and links it with the rigid body component. + * @param entityID + * The entity to link the new rigid body to. + */ + void AddRigidBody (EntityID entityID) noexcept; + + /** + * @brief + * Destroys a rigid body and removes the link with the rigid body component. + * @param entityID + * The entity to destroy the rigid body of. + */ + void RemoveRigidBody (EntityID entityID) noexcept; + + /** + * @brief + * Creates a collider and links it with the collider component. + * @param entityID + * The entity to link the new collider to. + */ + void AddCollider (EntityID entityID) noexcept; + + /** + * @brief + * Destroys a collider and removes the link with the collider component. + * @param entityID + * The entity to destroy the collider of. + */ + void RemoveCollider (EntityID entityID) noexcept; + + /** + * @brief + * Creates a collision shape for composite colliders and links it with the + * collider component. + * @param eientityIDd + * The entity to create a collision shape for. + * @param shapeID + * The id of the shape being created. + */ + void AddCollisionShape (EntityID entityID, uint8_t shapeID) noexcept; + + /** + * @brief + * Destroys a collision shape for composite colliders and removes the link with the + * collider component. + * @param entityID + * The entity to destroy the collision shape of. + * @param shapeID + * The id of the shape being destroyed. + */ + void RemoveCollisionShape (EntityID entityID, uint8_t shapeID) noexcept; + + private: + /*-----------------------------------------------------------------------------------*/ + /* Data Members */ + /*-----------------------------------------------------------------------------------*/ + + EntityObjectMap physicsObjects; + + /*-----------------------------------------------------------------------------------*/ + /* Member Functions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsObject* createPhysicsObject (EntityID entityID); + void destroyPhysicsObject (EntityID entityID); + }; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.cpp similarity index 59% rename from SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp rename to SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.cpp index 6dad9020..5924c612 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.cpp @@ -18,7 +18,7 @@ // Project Headers #include "ECS_Base/Managers/SHSystemManager.h" -#include "Math/SHMathHelpers.h" +#include "Physics/Dynamics/SHRigidBody.h" #include "Physics/System/SHPhysicsSystem.h" namespace SHADE @@ -28,77 +28,127 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHRigidBodyComponent::SHRigidBodyComponent() noexcept + : type { Type::STATIC } + , interpolate { true } + , rigidBody { nullptr } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Getter Functions Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept { - + return type; } - /*-----------------------------------------------------------------------------------*/ - /* Getter Function Definitions */ - /*-----------------------------------------------------------------------------------*/ - bool SHRigidBodyComponent::IsGravityEnabled() const noexcept { + if (rigidBody) + return rigidBody->IsGravityEnabled(); + return false; } bool SHRigidBodyComponent::IsAllowedToSleep() const noexcept { + if (rigidBody) + return rigidBody->IsSleepingEnabled(); + return false; } bool SHRigidBodyComponent::IsInterpolating() const noexcept { + return interpolate; + } + + bool SHRigidBodyComponent::IsSleeping() const noexcept + { + if (rigidBody) + return rigidBody->IsSleeping(); + return false; } - bool SHRigidBodyComponent::GetIsSleeping() const noexcept + bool SHRigidBodyComponent::GetAutoMass() const noexcept { - return false; - } + if (rigidBody) + return rigidBody->IsAutoMassEnabled(); - SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept - { - return Type::STATIC; + return false; } bool SHRigidBodyComponent::GetFreezePositionX() const noexcept { + if (rigidBody) + return rigidBody->GetFreezePositionX(); + return false; } bool SHRigidBodyComponent::GetFreezePositionY() const noexcept { + if (rigidBody) + return rigidBody->GetFreezePositionY(); + return false; } bool SHRigidBodyComponent::GetFreezePositionZ() const noexcept { + if (rigidBody) + return rigidBody->GetFreezePositionZ(); + return false; } bool SHRigidBodyComponent::GetFreezeRotationX() const noexcept { + if (rigidBody) + return rigidBody->GetFreezeRotationX(); + return false; } bool SHRigidBodyComponent::GetFreezeRotationY() const noexcept { + if (rigidBody) + return rigidBody->GetFreezeRotationY(); + return false; } bool SHRigidBodyComponent::GetFreezeRotationZ() const noexcept { + if (rigidBody) + return rigidBody->GetFreezeRotationZ(); + return false; } - float SHRigidBodyComponent::GetMass() const noexcept + float SHRigidBodyComponent::GetGravityScale() const noexcept { + if (rigidBody) + return rigidBody->GetGravityScale(); + return 0.0f; } + float SHRigidBodyComponent::GetMass() const noexcept + { + if (rigidBody) + return rigidBody->GetMass(); + + return -1.0f; + } + float SHRigidBodyComponent::GetDrag() const noexcept { - return 0.0f; + if (rigidBody) + return rigidBody->GetLinearDrag(); + + return -1.0f; } float SHRigidBodyComponent::GetAngularDrag() const noexcept @@ -108,6 +158,9 @@ namespace SHADE SHVec3 SHRigidBodyComponent::GetForce() const noexcept { + if (rigidBody) + return rigidBody->GetAccumulatedForce(); + return SHVec3::Zero; } @@ -118,6 +171,9 @@ namespace SHADE SHVec3 SHRigidBodyComponent::GetLinearVelocity() const noexcept { + if (rigidBody) + return rigidBody->GetLinearVelocity(); + return SHVec3::Zero; } @@ -127,91 +183,126 @@ namespace SHADE } /*-----------------------------------------------------------------------------------*/ - /* Setter Function Definitions */ + /* Setter Functions Definitions */ /*-----------------------------------------------------------------------------------*/ void SHRigidBodyComponent::SetType(Type newType) noexcept { - + if (newType == type) + return; + + type = newType; + + if (rigidBody) + rigidBody->SetType(static_cast(newType)); } - void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept + void SHRigidBodyComponent::SetRigidBody(SHRigidBody* rb) noexcept { - + rigidBody = rb; + } + + void SHRigidBodyComponent::SetIsGravityEnabled(bool enableGravity) noexcept + { + if (rigidBody) + rigidBody->SetGravityEnabled(enableGravity); } void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept { - + if (rigidBody) + rigidBody->SetSleepingEnabled(isAllowedToSleep); + } + + void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept + { + if (rigidBody) + rigidBody->SetAutoMassEnabled(autoMass); } void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept { - + if (rigidBody) + rigidBody->SetFreezePositionX(freezePositionX); } void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept { - + if (rigidBody) + rigidBody->SetFreezePositionY(freezePositionY); } void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept { - + if (rigidBody) + rigidBody->SetFreezePositionZ(freezePositionZ); } void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept { - + if (rigidBody) + rigidBody->SetFreezeRotationX(freezeRotationX); } void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept { - + if (rigidBody) + rigidBody->SetFreezeRotationY(freezeRotationY); } void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept { - + if (rigidBody) + rigidBody->SetFreezeRotationZ(freezeRotationZ); } void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept { - + interpolate = allowInterpolation; + } + + void SHRigidBodyComponent::SetGravityScale(float gravityScale) noexcept + { + if (rigidBody) + rigidBody->SetGravityScale(gravityScale); + } + + void SHRigidBodyComponent::SetMass(float newMass) noexcept + { + if (rigidBody) + rigidBody->SetMass(newMass); } void SHRigidBodyComponent::SetDrag(float newDrag) noexcept { - + if (rigidBody) + rigidBody->SetLinearDrag(newDrag); } void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept { - + } void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept { - + if (rigidBody) + rigidBody->SetLinearVelocity(newLinearVelocity); } void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept { - + } /*-----------------------------------------------------------------------------------*/ - /* Public Function Member Definitions */ + /* Member Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHRigidBodyComponent::OnCreate() - { - - } - void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - + if (rigidBody) + rigidBody->AddForce(force); } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept @@ -221,12 +312,13 @@ namespace SHADE void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - + if (rigidBody) + rigidBody->AddForce(force, worldPos); } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - + } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept @@ -251,7 +343,8 @@ namespace SHADE void SHRigidBodyComponent::ClearForces() const noexcept { - + if (rigidBody) + rigidBody->ClearForces(); } void SHRigidBodyComponent::ClearTorque() const noexcept @@ -259,6 +352,15 @@ namespace SHADE } + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHRigidBodyComponent::OnCreate() + { + + } + } // namespace SHADE RTTR_REGISTRATION @@ -274,17 +376,19 @@ RTTR_REGISTRATION ); registration::class_("RigidBody Component") - .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) - //.property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) - .property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag ) - .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) - .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled ) - .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) - .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep) - .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) - .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) - .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) - .property("Freeze Rotation X" , &SHRigidBodyComponent::GetFreezeRotationX , &SHRigidBodyComponent::SetFreezeRotationX ) - .property("Freeze Rotation Y" , &SHRigidBodyComponent::GetFreezeRotationY , &SHRigidBodyComponent::SetFreezeRotationY ) - .property("Freeze Rotation Z" , &SHRigidBodyComponent::GetFreezeRotationZ , &SHRigidBodyComponent::SetFreezeRotationZ ); + .property("Type" , &SHRigidBodyComponent::GetType , &SHRigidBodyComponent::SetType ) + .property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass ) + .property("Mass" , &SHRigidBodyComponent::GetMass , &SHRigidBodyComponent::SetMass ) + .property("Drag" , &SHRigidBodyComponent::GetDrag , &SHRigidBodyComponent::SetDrag ) + .property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag ) + .property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetIsGravityEnabled ) + .property("Gravity Scale" , &SHRigidBodyComponent::GetGravityScale , &SHRigidBodyComponent::SetGravityScale ) + .property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate ) + .property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep ) + .property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX ) + .property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY ) + .property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ ) + .property("Freeze Rotation X" , &SHRigidBodyComponent::GetFreezeRotationX , &SHRigidBodyComponent::SetFreezeRotationX ) + .property("Freeze Rotation Y" , &SHRigidBodyComponent::GetFreezeRotationY , &SHRigidBodyComponent::SetFreezeRotationY ) + .property("Freeze Rotation Z" , &SHRigidBodyComponent::GetFreezeRotationZ , &SHRigidBodyComponent::SetFreezeRotationZ ); } \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h similarity index 88% rename from SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h rename to SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h index 021743da..ae0bd3ec 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h @@ -15,10 +15,15 @@ // Project Headers #include "ECS_Base/Components/SHComponent.h" #include "Math/Vector/SHVec3.h" -#include "Math/SHQuaternion.h" namespace SHADE { + /*-------------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-------------------------------------------------------------------------------------*/ + + class SHRigidBody; + /*-----------------------------------------------------------------------------------*/ /* Type Definitions */ /*-----------------------------------------------------------------------------------*/ @@ -67,13 +72,13 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ + [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] bool IsGravityEnabled () const noexcept; [[nodiscard]] bool IsAllowedToSleep () const noexcept; [[nodiscard]] bool IsInterpolating () const noexcept; - - [[nodiscard]] bool GetIsSleeping () const noexcept; - - [[nodiscard]] Type GetType () const noexcept; + [[nodiscard]] bool IsSleeping () const noexcept; + [[nodiscard]] bool GetAutoMass () const noexcept; [[nodiscard]] bool GetFreezePositionX () const noexcept; [[nodiscard]] bool GetFreezePositionY () const noexcept; @@ -82,6 +87,7 @@ namespace SHADE [[nodiscard]] bool GetFreezeRotationY () const noexcept; [[nodiscard]] bool GetFreezeRotationZ () const noexcept; + [[nodiscard]] float GetGravityScale () const noexcept; [[nodiscard]] float GetMass () const noexcept; [[nodiscard]] float GetDrag () const noexcept; [[nodiscard]] float GetAngularDrag () const noexcept; @@ -91,18 +97,18 @@ namespace SHADE [[nodiscard]] SHVec3 GetLinearVelocity () const noexcept; [[nodiscard]] SHVec3 GetAngularVelocity () const noexcept; - //[[nodiscard]] const SHVec3& GetPosition () const noexcept; - //[[nodiscard]] const SHQuaternion& GetOrientation () const noexcept; - //[[nodiscard]] SHVec3 GetRotation () const noexcept; - /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ void SetType (Type newType) noexcept; - void SetGravityEnabled (bool enableGravity) noexcept; + void SetRigidBody (SHRigidBody* rb) noexcept; + + void SetIsGravityEnabled (bool enableGravity) noexcept; void SetIsAllowedToSleep (bool isAllowedToSleep) noexcept; + void SetAutoMass (bool autoMass) noexcept; + void SetFreezePositionX (bool freezePositionX) noexcept; void SetFreezePositionY (bool freezePositionY) noexcept; void SetFreezePositionZ (bool freezePositionZ) noexcept; @@ -110,9 +116,9 @@ namespace SHADE void SetFreezeRotationY (bool freezeRotationY) noexcept; void SetFreezeRotationZ (bool freezeRotationZ) noexcept; void SetInterpolate (bool allowInterpolation) noexcept; - //void SetAutoMass (bool autoMass) noexcept; - //void SetMass (float newMass) noexcept; + void SetGravityScale (float gravityScale) noexcept; + void SetMass (float newMass) noexcept; void SetDrag (float newDrag) noexcept; void SetAngularDrag (float newAngularDrag) noexcept; @@ -142,6 +148,11 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ + Type type; + bool interpolate; + SHRigidBody* rigidBody; + RTTR_ENABLE() }; + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsWorld.cpp b/SHADE_Engine/src/Physics/SHPhysicsWorld.cpp index 85e76702..d54d3f86 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsWorld.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsWorld.cpp @@ -19,53 +19,9 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsWorldState::SHPhysicsWorldState() noexcept - : world { nullptr } - {} /*-----------------------------------------------------------------------------------*/ /* Public Function Members Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsWorldState::CreateWorld(rp3d::PhysicsCommon& factory) - { - rp3d::PhysicsWorld::WorldSettings rp3dWorldSettings; - rp3dWorldSettings.gravity = settings.gravity; - rp3dWorldSettings.defaultVelocitySolverNbIterations = settings.numVelocitySolverIterations; - rp3dWorldSettings.defaultPositionSolverNbIterations = settings.numPositionSolverIterations; - rp3dWorldSettings.isSleepingEnabled = settings.sleepingEnabled; - - // These are my preferred default values. QoL for modifying these. - rp3dWorldSettings.defaultBounciness = 0.0f; - rp3dWorldSettings.defaultFrictionCoefficient = 0.4f; - - world = factory.createPhysicsWorld(rp3dWorldSettings); - world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES); - } - - void SHPhysicsWorldState::DestroyWorld(rp3d::PhysicsCommon& factory) - { - if (!world) - return; - - factory.destroyPhysicsWorld(world); - world = nullptr; - } - - void SHPhysicsWorldState::UpdateSettings() const noexcept - { - if (!world) - { - SHLOGV_ERROR("Unable to update Physics World settings without creating a world!") - return; - } - - world->setGravity(settings.gravity); - world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations); - world->setNbIterationsPositionSolver(settings.numPositionSolverIterations); - world->enableSleeping(settings.sleepingEnabled); - } - - - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsWorld.h b/SHADE_Engine/src/Physics/SHPhysicsWorld.h index c5152c44..e872cd3c 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsWorld.h +++ b/SHADE_Engine/src/Physics/SHPhysicsWorld.h @@ -10,8 +10,6 @@ #pragma once -#include - // Project Headers #include "Math/SHMath.h" #include "SH_API.h" @@ -47,7 +45,6 @@ namespace SHADE /* Data Members */ /*---------------------------------------------------------------------------------*/ - rp3d::PhysicsWorld* world; WorldSettings settings; /*---------------------------------------------------------------------------------*/ @@ -60,14 +57,6 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void CreateWorld (rp3d::PhysicsCommon& factory); - void DestroyWorld (rp3d::PhysicsCommon& factory); - - /** - * @brief Applies the current settings to the physics world. The world must be created - * before this is called. - */ - void UpdateSettings () const noexcept; }; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp similarity index 50% rename from SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp rename to SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp index 0029a8e7..9b1c0015 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPostUpdateRoutine.cpp @@ -1,7 +1,7 @@ /**************************************************************************************** - * \file SHPhysicsSystemRoutines.h + * \file SHPhysicsPostUpdateRoutine.cpp * \author Diren D Bharwani, diren.dbharwani, 390002520 - * \brief Implementation for the Physics System Routines + * \brief Implementation for the Physics Post-Update Routine * * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or * disclosure of this file or its contents without the prior written consent @@ -11,24 +11,12 @@ #include // Primary Header -#include "SHPhysicsSystem.h" +#include "Physics/System/SHPhysicsSystem.h" + // Project Headers -#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" -#include "Editor/SHEditor.h" -#include "Scene/SHSceneManager.h" #include "Scripting/SHScriptEngine.h" -#include "Input/SHInputManager.h" -#include "Physics/Collision/SHCollisionTagMatrix.h" - -/*-------------------------------------------------------------------------------------*/ -/* Local Functions */ -/*-------------------------------------------------------------------------------------*/ - -void testFunction(); - -///////////////////////////////////////////////////////////////////////////////////////// namespace SHADE { @@ -36,59 +24,14 @@ namespace SHADE /* Constructors & Destructor Definitions */ /*-----------------------------------------------------------------------------------*/ - SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() - : SHSystemRoutine { "Physics PreUpdate", true } - {} - - SHPhysicsSystem::PhysicsFixedUpdate::PhysicsFixedUpdate() - : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", false } - {} - SHPhysicsSystem::PhysicsPostUpdate::PhysicsPostUpdate() - : SHSystemRoutine { "Physics PostUpdate", false } + : SHSystemRoutine { "Physics Post-Update", false } {} /*-----------------------------------------------------------------------------------*/ /* Public Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept - { - auto* physicsSystem = reinterpret_cast(GetSystem()); - } - - void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept - { - auto* physicsSystem = reinterpret_cast(GetSystem()); - - auto* scriptingSystem = SHSystemManager::GetSystem(); - if (scriptingSystem == nullptr) - { - SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!"); - } - - const double FIXED_DT = physicsSystem->fixedDT; - - accumulatedTime += dt; - - int count = 0; - while (accumulatedTime > FIXED_DT) - { - if (scriptingSystem != nullptr) - scriptingSystem->ExecuteFixedUpdates(); - - // TODO: Update World - - accumulatedTime -= FIXED_DT; - ++count; - } - - stats.numSteps = count; - physicsSystem->worldUpdated = count > 0; - - physicsSystem->interpolationFactor = accumulatedTime / fixedTimeStep; - } - void SHPhysicsSystem::PhysicsPostUpdate::Execute(double) noexcept { auto* physicsSystem = reinterpret_cast(GetSystem()); @@ -110,6 +53,10 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ -} // namespace SHADE + void SHPhysicsSystem::PhysicsPostUpdate::syncTransforms(SHRigidBodyComponent* rbComponent) const noexcept + { + + } +} diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp new file mode 100644 index 00000000..a0f348f4 --- /dev/null +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsPreUpdateRoutine.cpp @@ -0,0 +1,62 @@ +/**************************************************************************************** + * \file SHPhysicsPreUpdateRoutine.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Physics Pre-Update Routine + * + * \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 "Physics/System/SHPhysicsSystem.h" + +// Project Headers +#include "ECS_Base/Managers/SHComponentManager.h" +#include "Math/Transform/SHTransformComponent.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() + : SHSystemRoutine { "Physics Pre-Update", true } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept + { + auto* physicsSystem = reinterpret_cast(GetSystem()); + + // Get all physics objects & sync transforms + for (auto& physicsObject : physicsSystem->physicsObjectManager.GetPhysicsObjects() | std::views::values) + syncTransforms(&physicsObject); + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::PhysicsPreUpdate::syncTransforms(SHPhysicsObject* physicsObject) const noexcept + { + const EntityID EID = physicsObject->entityID; + + // Get relevant components: Transform, Rigidbody & Collider + const auto* TRANSFORM_COMPONENT = SHComponentManager::GetComponent_s(EID); + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(EID); + auto* colliderComponent = SHComponentManager::GetComponent_s(EID); + + if (TRANSFORM_COMPONENT && TRANSFORM_COMPONENT->HasChanged()) + { + // Sync the objects transforms + } + } +} diff --git a/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp new file mode 100644 index 00000000..77da8706 --- /dev/null +++ b/SHADE_Engine/src/Physics/System/Routines/SHPhysicsUpdateRoutine.cpp @@ -0,0 +1,62 @@ +/**************************************************************************************** + * \file SHPhysicsUpdateRoutine.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Physics Update Routine + * + * \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 "Physics/System/SHPhysicsSystem.h" + +// Project Headers +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Scripting/SHScriptEngine.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsSystem::PhysicsUpdate::PhysicsUpdate() + : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics Update", false } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::PhysicsUpdate::Execute(double dt) noexcept + { + auto* physicsSystem = reinterpret_cast(GetSystem()); + + auto* scriptEngine = SHSystemManager::GetSystem(); + if (!scriptEngine) + { + SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing ScriptEngine!") + } + + const double FIXED_DT = physicsSystem->fixedDT; + accumulatedTime += dt; + + int count = 0; + while (accumulatedTime > FIXED_DT) + { + + + accumulatedTime -= FIXED_DT; + ++count; + } + + stats.numSteps = count; + physicsSystem->worldUpdated = count > 0; + + physicsSystem->interpolationFactor = physicsSystem->worldUpdated ? accumulatedTime / FIXED_DT : 0.0; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index eacd6ac9..98a69087 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -20,9 +20,7 @@ #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" #include "Physics/Collision/SHCollisionTagMatrix.h" -#include "Physics/SHPhysicsEvents.h" -#include "Scene/SHSceneManager.h" -#include "Scripting/SHScriptEngine.h" +#include "Physics/Interface/SHColliderComponent.h" namespace SHADE { @@ -34,7 +32,18 @@ namespace SHADE : worldUpdated { false } , interpolationFactor { 0.0 } , fixedDT { DEFAULT_FIXED_STEP } - {} + { + // Add more events here to register them + + eventFunctions[0] = { &SHPhysicsSystem::onComponentAdded , SH_COMPONENT_ADDED_EVENT }; + eventFunctions[1] = { &SHPhysicsSystem::onComponentRemoved, SH_COMPONENT_REMOVED_EVENT }; + eventFunctions[2] = { &SHPhysicsSystem::onSceneInit , SH_SCENE_ON_INIT_EVENT }; + eventFunctions[3] = { &SHPhysicsSystem::onSceneExit , SH_SCENE_ON_EXIT_EVENT }; + + #ifdef SHEDITOR + eventFunctions[4] = { &SHPhysicsSystem::onEditorPlay , SH_EDITOR_ON_PLAY_EVENT }; + #endif + } /*-----------------------------------------------------------------------------------*/ /* Getter Function Definitions */ @@ -45,13 +54,48 @@ namespace SHADE return 1.0 / fixedDT; } + double SHPhysicsSystem::GetFixedDT() const noexcept + { + return fixedDT; + } + /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHPhysicsSystem::SetFixedUpdateRate(double fixedUpdateRate) noexcept + void SHPhysicsSystem::SetFixedUpdateRate(double fixedUpdateRate) noexcept { + // Handle invalid input + if (fixedUpdateRate <= 0.0) + { + SHLOGV_WARNING("Invalid value for setting fixed update rate! Fixed update rate unchanged.") + return; + } + fixedDT = 1.0 / fixedUpdateRate; + + // Handle potential incorrect / unintended input + if (fixedDT > 1.0) + { + SHLOGV_WARNING("Fixed Update Rate Time is set below 1. This may result in undesirable behaviour.") + } + } + + void SHPhysicsSystem::SetFixedDT(double fixedDt) noexcept + { + if (fixedDt <= 0.0) + { + SHLOGV_WARNING("Invalid value for setting fixed delta time! Fixed delta time unchanged.") + return; + } + + fixedDT = fixedDt; + + // Handle potential incorrect / unintended input + if (fixedDT > 1.0) + { + SHLOGV_WARNING("Fixed Delta Time is set above 1. This may result in undesirable behaviour.") + } } /*-----------------------------------------------------------------------------------*/ @@ -64,11 +108,21 @@ namespace SHADE std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); SHCollisionTagMatrix::Init(defaultCollisionTagNameFilePath); + + // Link Managers to system + + // Register Events + for (int i = 0; i < NUM_EVENT_FUNCTIONS; ++i) + { + const std::shared_ptr EVENT_RECEIVER = std::make_shared>(this, eventFunctions[i].first); + const ReceiverPtr EVENT_RECEIVER_PTR = std::dynamic_pointer_cast(EVENT_RECEIVER); + + SHEventManager::SubscribeTo(eventFunctions[i].second, EVENT_RECEIVER_PTR); + } } void SHPhysicsSystem::Exit() { - // Write collision tag names to file std::filesystem::path defaultCollisionTagNameFilePath { ASSET_ROOT }; defaultCollisionTagNameFilePath.append("CollisionTags.SHConfig"); @@ -84,4 +138,98 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHEventHandle SHPhysicsSystem::onSceneInit(SHEventPtr onSceneInitEvent) + { + /* + * TODO: + * If a world already exists, destroy it + * Recreate the world + * + * If there is an editor and editor mode is already playing, link all entities with the world immediately. + */ + + return onSceneInitEvent.get()->handle; + } + + SHEventHandle SHPhysicsSystem::onSceneExit(SHEventPtr onSceneExitEvent) + { + /* + * TODO: + * Destroy the physics world. + * Destroy all physics objects. + */ + + return onSceneExitEvent.get()->handle; + } + + SHEventHandle SHPhysicsSystem::onComponentAdded(SHEventPtr onComponentAddedEvent) + { + static const auto RIGID_BODY_COMPONENT_ID = ComponentFamily::GetID(); + static const auto COLLIDER_COMPONENT_ID = ComponentFamily::GetID(); + + const auto& EVENT_DATA = reinterpret_cast*>(onComponentAddedEvent.get())->data; + + const auto ADDED_ID = EVENT_DATA->addedComponentType; + + const bool IS_RIGID_BODY = ADDED_ID == RIGID_BODY_COMPONENT_ID; + const bool IS_COLLIDER = ADDED_ID == COLLIDER_COMPONENT_ID; + + // Check if its a physics component + if (IS_RIGID_BODY || IS_COLLIDER) + { + const EntityID EID = EVENT_DATA->eid; + + // Link engine components with physics object component + if (IS_RIGID_BODY) + physicsObjectManager.AddRigidBody(EID); + + if (IS_COLLIDER) + physicsObjectManager.AddCollider(EID); + } + + return onComponentAddedEvent.get()->handle; + } + + SHEventHandle SHPhysicsSystem::onComponentRemoved(SHEventPtr onComponentRemovedEvent) + { + static const auto RIGID_BODY_COMPONENT_ID = ComponentFamily::GetID(); + static const auto COLLIDER_COMPONENT_ID = ComponentFamily::GetID(); + + const auto& EVENT_DATA = reinterpret_cast*>(onComponentRemovedEvent.get())->data; + + const auto REMOVED_DATA = EVENT_DATA->removedComponentType; + + const bool IS_RIGID_BODY = REMOVED_DATA == RIGID_BODY_COMPONENT_ID; + const bool IS_COLLIDER = REMOVED_DATA == COLLIDER_COMPONENT_ID; + + // Check if its a physics component + if (IS_RIGID_BODY || IS_COLLIDER) + { + const EntityID EID = EVENT_DATA->eid; + + // Link engine components with physics object component + if (IS_RIGID_BODY) + physicsObjectManager.RemoveRigidBody(EID); + + if (IS_COLLIDER) + physicsObjectManager.RemoveCollider(EID); + } + + return onComponentRemovedEvent.get()->handle; + } + +#ifdef SHEDITOR + + SHEventHandle SHPhysicsSystem::onEditorPlay(SHEventPtr onEditorPlayEvent) + { + /* + * TODO: + * Link all entities with the world. + */ + + return onEditorPlayEvent.get()->handle; + } + +#endif + } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3fe05c09..1562241f 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -11,14 +11,15 @@ #pragma once // Project Headers +#include "ECS_Base/System/SHSystem.h" #include "ECS_Base/System/SHSystemRoutine.h" #include "ECS_Base/System/SHFixedSystemRoutine.h" +#include "Events/SHEvent.h" -#include "Math/Transform/SHTransformComponent.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/PhysicsObject/SHPhysicsObjectManager.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "Physics/Interface/SHColliderComponent.h" -#include "Physics/SHPhysicsWorld.h" -#include "Scene/SHSceneGraph.h" + namespace SHADE { @@ -28,13 +29,6 @@ namespace SHADE class SH_API SHPhysicsSystem final : public SHSystem { - private: - /*---------------------------------------------------------------------------------*/ - /* Friends */ - /*---------------------------------------------------------------------------------*/ - - friend class SHPhysicsDebugDrawSystem; - public: /*---------------------------------------------------------------------------------*/ /* Constructors & Destructor */ @@ -46,104 +40,121 @@ namespace SHADE /* Getter Functions */ /*---------------------------------------------------------------------------------*/ - [[nodiscard]] double GetFixedUpdateRate () const noexcept; - [[nodiscard]] const SHPhysicsWorldState::WorldSettings& GetWorldSettings () const noexcept; + [[nodiscard]] double GetFixedUpdateRate() const noexcept; + [[nodiscard]] double GetFixedDT() const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetFixedUpdateRate (double fixedUpdateRate) noexcept; - void SetWorldSettings (const SHPhysicsWorldState::WorldSettings& settings) noexcept; + void SetFixedUpdateRate(double fixedUpdateRate) noexcept; + void SetFixedDT(double fixedDt) noexcept; /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init() override; + void Exit() override; - void ForceUpdate (); + void ForceUpdate(); /*---------------------------------------------------------------------------------*/ /* System Routines */ /*---------------------------------------------------------------------------------*/ + /** + * @brief + * The physics update routine that runs before the simulation is updated. + * This is always running, regardless of the editor state. + *
+ * This update game logic is applied before the simulation runs. + */ class SH_API PhysicsPreUpdate final : public SHSystemRoutine { public: - /*-------------------------------------------------------------------------------*/ - /* Constructors & Destructor */ - /*-------------------------------------------------------------------------------*/ - PhysicsPreUpdate(); - - /*-------------------------------------------------------------------------------*/ - /* Function Members */ - /*-------------------------------------------------------------------------------*/ - void Execute(double dt) noexcept override; private: - /*-------------------------------------------------------------------------------*/ - /* Function Members */ - /*-------------------------------------------------------------------------------*/ - + void syncTransforms(SHPhysicsObject* physicsObject) const noexcept; }; - class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine + /** + * @brief + * The physics update routine that runs at a fixed rate. This is where the main + * simulation runs. If delta time is large enough, this may run more than once per + * frame. If delta time is small enough, this may not run at all. + */ + class SH_API PhysicsUpdate final : public SHFixedSystemRoutine { public: - /*-------------------------------------------------------------------------------*/ - /* Constructors & Destructor */ - /*-------------------------------------------------------------------------------*/ - - PhysicsFixedUpdate(); - - /*-------------------------------------------------------------------------------*/ - /* Function Members */ - /*-------------------------------------------------------------------------------*/ - - void Execute (double dt) noexcept override; + PhysicsUpdate(); + void Execute(double dt) noexcept override; }; + /** + * @brief + * The physics update that runs after the simulation. This sets the rendering + * transforms and sends messages to scripting system for collision & trigger events. + */ class SH_API PhysicsPostUpdate final : public SHSystemRoutine { public: - /*-------------------------------------------------------------------------------*/ - /* Constructors & Destructor */ - /*-------------------------------------------------------------------------------*/ - PhysicsPostUpdate(); - - /*-------------------------------------------------------------------------------*/ - /* Function Members */ - /*-------------------------------------------------------------------------------*/ - void Execute(double dt) noexcept override; private: - - /*-------------------------------------------------------------------------------*/ - /* Function Members */ - /*-------------------------------------------------------------------------------*/ - + void syncTransforms(SHRigidBodyComponent* rbComponent) const noexcept; }; private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + using EventFunctionPair = std::pair; + /*---------------------------------------------------------------------------------*/ /* Data Members */ /*---------------------------------------------------------------------------------*/ + #ifdef SHEDITOR + static constexpr int NUM_EVENT_FUNCTIONS = 5; + #else + static constexpr int NUM_EVENT_FUNCTIONS = 4; + #endif + + // Event function container for cleanly registering to events + EventFunctionPair eventFunctions[NUM_EVENT_FUNCTIONS]; + // System data bool worldUpdated; double interpolationFactor; double fixedDT; + // Sub-systems / managers + + SHPhysicsObjectManager physicsObjectManager; + /*---------------------------------------------------------------------------------*/ /* Function Members */ /*---------------------------------------------------------------------------------*/ + SHEventHandle onSceneInit (SHEventPtr onSceneInitEvent); + SHEventHandle onSceneExit (SHEventPtr onSceneExitEvent); + + SHEventHandle onComponentAdded (SHEventPtr onComponentAddedEvent); + SHEventHandle onComponentRemoved (SHEventPtr onComponentRemovedEvent); + + + #ifdef SHEDITOR + + SHEventHandle onEditorPlay (SHEventPtr onEditorPlayEvent); + // We don't need an onEditorStop because on stop exits the scene, which is already handled above. + + #endif + }; } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index 99e4fa41..9d648185 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -15,7 +15,7 @@ #include "Camera/SHCameraArmComponent.h" #include "Math/Transform/SHTransformComponent.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "UI/SHCanvasComponent.h" #include "UI/SHButtonComponent.h" #include "ECS_Base/Managers/SHSystemManager.h" diff --git a/SHADE_Managed/src/Components/RigidBody.cxx b/SHADE_Managed/src/Components/RigidBody.cxx index a564402f..7b3604f2 100644 --- a/SHADE_Managed/src/Components/RigidBody.cxx +++ b/SHADE_Managed/src/Components/RigidBody.cxx @@ -34,7 +34,7 @@ namespace SHADE } void RigidBody::IsGravityEnabled::set(bool value) { - return GetNativeComponent()->SetGravityEnabled(value); + return GetNativeComponent()->SetIsGravityEnabled(value); } bool RigidBody::IsAllowedToSleep::get() { diff --git a/SHADE_Managed/src/Components/RigidBody.hxx b/SHADE_Managed/src/Components/RigidBody.hxx index 8bfe34aa..6ca39316 100644 --- a/SHADE_Managed/src/Components/RigidBody.hxx +++ b/SHADE_Managed/src/Components/RigidBody.hxx @@ -15,7 +15,7 @@ of DigiPen Institute of Technology is prohibited. #pragma once // External Dependencies -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" // Project Includes #include "Components/Component.hxx" diff --git a/SHADE_Managed/src/Engine/ECS.cxx b/SHADE_Managed/src/Engine/ECS.cxx index c388f0cd..3ace79ab 100644 --- a/SHADE_Managed/src/Engine/ECS.cxx +++ b/SHADE_Managed/src/Engine/ECS.cxx @@ -23,7 +23,7 @@ of DigiPen Institute of Technology is prohibited. #include "ECS_Base/Managers/SHEntityManager.h" #include "Math/Transform/SHTransformComponent.h" #include "Physics/Interface/SHColliderComponent.h" -#include "Physics/Interface/SHRigidBodyComponent.h" +#include "Physics/Interface/RigidBodyComponent/SHRigidBodyComponent.h" #include "Scene/SHSceneManager.h" #include "Scene/SHSceneGraph.h" #include "Tools/Logger/SHLog.h"