From 097b1be3f7e23924fc5f562cf0ee802491aca171 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Wed, 28 Sep 2022 16:15:36 +0800 Subject: [PATCH] Added Physics System --- .../src/Application/SBApplication.cpp | 1 - .../ECS_Base/System/SHFixedSystemRoutine.h | 16 +- .../Components/SHRigidBodyComponent.cpp | 15 + .../Physics/Components/SHRigidBodyComponent.h | 10 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 446 ++++++++++++++++++ SHADE_Engine/src/Physics/SHPhysicsSystem.h | 237 ++++++++++ 6 files changed, 712 insertions(+), 13 deletions(-) create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.cpp create mode 100644 SHADE_Engine/src/Physics/SHPhysicsSystem.h diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp index 82ca0f1c..fdc933b9 100644 --- a/SHADE_Application/src/Application/SBApplication.cpp +++ b/SHADE_Application/src/Application/SBApplication.cpp @@ -86,7 +86,6 @@ namespace Sandbox SHADE::SHComponentManager::CreateComponentSparseSet(); SHADE::SHComponentManager::CreateComponentSparseSet(); - SHADE::SHComponentManager::CreateComponentSparseSet(); //TODO: REMOVE AFTER PRESENTATION SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf"); diff --git a/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h b/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h index d9a2b510..d54d9441 100644 --- a/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h +++ b/SHADE_Engine/src/ECS_Base/System/SHFixedSystemRoutine.h @@ -8,23 +8,19 @@ namespace SHADE { class SHFixedSystemRoutine: public SHSystemRoutine { - private: - double accumulatedTime; - double fixedTimeStep; - protected: - SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false) + double accumulatedTime; + double fixedTimeStep; + + SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false) :SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){} - - public: ~SHFixedSystemRoutine() = default; - virtual void Execute(double dt) noexcept; - - virtual void FixedExecute(double dt) noexcept {}; + virtual void Execute(double dt) noexcept override; + virtual void FixedExecute(double dt) noexcept {} }; diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp index 2de6e52a..e3989d6e 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.cpp @@ -465,6 +465,21 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHRigidBodyComponent::SyncRP3DAndSHADE() + { + rigidBody->setType(static_cast(type)); + + rigidBody->setMass(mass); + rigidBody->setLinearDamping(drag); + rigidBody->setAngularDamping(angularDrag); + + rigidBody->enableGravity(flags & (1U << 0)); + rigidBody->setIsAllowedToSleep(flags & (1U << 1)); + SetRP3DLinearConstraints(); + SetRP3DAngularConstraints(); + } + + void SHRigidBodyComponent::SetFlag(bool flagState, int flagPos) { flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos); diff --git a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h index 69338b1e..668ab6bd 100644 --- a/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHRigidBodyComponent.h @@ -21,6 +21,13 @@ namespace SHADE { class SH_API SHRigidBodyComponent : public SHComponent { + private: + /*---------------------------------------------------------------------------------*/ + /* Friends */ + /*---------------------------------------------------------------------------------*/ + + friend class SHPhysicsSystem; + public: /*---------------------------------------------------------------------------------*/ /* Type Definitions */ @@ -128,8 +135,6 @@ namespace SHADE float mass; float drag; float angularDrag; - - SHMatrix inertiaTensor; // rX rY rZ pX pY pZ slp g uint8_t flags; @@ -138,6 +143,7 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ + void SyncRP3DAndSHADE (); void SetFlag (bool flagState, int flagPos); void SetRP3DLinearConstraints () const ; void SetRP3DAngularConstraints () const ; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp new file mode 100644 index 00000000..537c2c70 --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -0,0 +1,446 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for the Physics System + * + * \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 "SHPhysicsSystem.h" + +// Project Headers +#include "Math/Transform/SHTransformComponent.h" +#include "Scene/SHSceneManager.h" +#include "ECS_Base/Managers/SHComponentManager.h" +#include "ECS_Base/Managers/SHEntityManager.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHPhysicsSystem::PhysicsPreUpdate::PhysicsPreUpdate() + : SHSystemRoutine { "Physics PreUpdate", true } + {} + + SHPhysicsSystem::PhysicsFixedUpdate::PhysicsFixedUpdate() + : SHFixedSystemRoutine { DEFAULT_FIXED_STEP, "Physics FixedUpdate", true } + {} + + SHPhysicsSystem::PhysicsPostUpdate::PhysicsPostUpdate() + : SHSystemRoutine { "Physics PostUpdate", true } + {} + + /*-----------------------------------------------------------------------------------*/ + /* Getter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + bool SHPhysicsSystem::IsSleepingEnabled() const noexcept + { + if (world) + return world->isSleepingEnabled(); + + SHLOGV_WARNING("No physics world has been initialised!") + return false; + } + + //double SHPhysicsSystem::GetFixedUpdate() const noexcept + //{ + // return fixedUpdate; + //} + + SHVec3 SHPhysicsSystem::GetWorldGravity() const noexcept + { + SHVec3 result; + + if (world) + { + const auto RP3D_GRAVITY = world->getGravity(); + result.x = RP3D_GRAVITY.x; + result.y = RP3D_GRAVITY.y; + result.z = RP3D_GRAVITY.z; + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + + return result; + } + + uint16_t SHPhysicsSystem::GetNumberVelocityIterations() const noexcept + { + if (world) + return world->getNbIterationsVelocitySolver(); + + SHLOGV_WARNING("No physics world has been initialised!") + return 0; + } + + uint16_t SHPhysicsSystem::GetNumberPositionIterations() const noexcept + { + if (world) + return world->getNbIterationsPositionSolver(); + + SHLOGV_WARNING("No physics world has been initialised!") + return 0; + } + + /*-----------------------------------------------------------------------------------*/ + /* Setter Function Definitions */ + /*-----------------------------------------------------------------------------------*/ + + //void SHPhysicsSystem::SetFixedUpdate(double fixedUpdateRate) noexcept + //{ + // fixedUpdate = fixedUpdateRate; + // SHLOG_INFO("Setting Physics update rate to {}", 1.0 / fixedUpdate) + //} + + void SHPhysicsSystem::SetWorldGravity(const SHVec3& gravity) const noexcept + { + if (world) + { + const rp3d::Vector3 G { gravity.x, gravity.y, gravity.z }; + world->setGravity(G); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetNumberVelocityIterations(uint16_t numVelIterations) const noexcept + { + if (world) + { + world->setNbIterationsVelocitySolver(numVelIterations); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetNumberPositionIterations(uint16_t numPosIterations) const noexcept + { + if (world) + { + world->setNbIterationsPositionSolver(numPosIterations); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetSleepingEnabled(bool enableSleeping) const noexcept + { + if (world) + { + world->enableSleeping(enableSleeping); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + void SHPhysicsSystem::SetWorldSettings(const WorldSettings& settings) const noexcept + { + if (world) + { + const rp3d::Vector3 G { settings.gravity.x, settings.gravity.y, settings.gravity.z }; + world->setGravity(G); + world->setNbIterationsVelocitySolver(settings.numVelocitySolverIterations); + world->setNbIterationsPositionSolver(settings.numPositionSolverIterations); + world->enableSleeping(settings.sleepingEnabled); + } + else + { + SHLOGV_WARNING("No physics world has been initialised!") + } + } + + /*-----------------------------------------------------------------------------------*/ + /* Public Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::Init() + { + using namespace rp3d; + + // Create a physics world with the default settings + PhysicsWorld::WorldSettings settings; + settings.gravity = Vector3{ 0, -9.81, 0 }; + settings.isSleepingEnabled = true; + settings.defaultVelocitySolverNbIterations = 8; + settings.defaultPositionSolverNbIterations = 3; + + world = factory.createPhysicsWorld(settings); + + // Create component sparse sets + SHADE::SHComponentManager::CreateComponentSparseSet(); + } + + void SHPhysicsSystem::Exit() + { + factory.destroyPhysicsWorld(world); + } + + void SHPhysicsSystem::AddRigidBodyComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::RIGID_BODY, + .type = UpdateType::ADD, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::AddColliderComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::COLLIDER, + .type = UpdateType::ADD, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::RemoveRigidBodyComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::RIGID_BODY, + .type = UpdateType::REMOVE, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::RemoveColliderComponent(EntityID id) noexcept + { + const UpdateCommand NEW_CMD + { + .component = UpdateComponent::COLLIDER, + .type = UpdateType::REMOVE, + .entityID = id + }; + + updateQueue.push(NEW_CMD); + } + + void SHPhysicsSystem::PhysicsPreUpdate::Execute([[maybe_unused]]double dt) noexcept + { + auto* system = reinterpret_cast(GetSystem()); + system->ClearUpdateQueue(); + + // Sync active states: if node or component is not active, set rp3d to inactive + static const auto SYNC_ACTIVE = [](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + auto const* rigidBodyComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + if(rigidBodyComponent) + { + const bool RP3D_ACTIVE = rigidBodyComponent->rigidBody->isActive(); + const bool SHADE_ACTIVE = node->IsActive() && rigidBodyComponent->isActive; + + if (RP3D_ACTIVE != SHADE_ACTIVE) + rigidBodyComponent->rigidBody->setIsActive(SHADE_ACTIVE); + } + else // Check for a collider + { + + } + }; + + const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + sceneGraph.Traverse(SYNC_ACTIVE); + } + + //void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept + //{ + // // I had to override this anyway due to needing to calculate the + // // interpolation factor right after the fixed update was done + + // auto* system = reinterpret_cast(GetSystem()); + // fixedTimeStep = 1.0 / system->fixedUpdate; + + // accumulatedTime += dt; + // int counter = 0; + + // while (accumulatedTime > fixedTimeStep) + // { + // FixedExecute(fixedTimeStep); + + // accumulatedTime -= fixedTimeStep; + // ++counter; + // } + + // stats.numSteps = counter; + + // system->interpolationFactor = accumulatedTime / fixedTimeStep; + //} + + void SHPhysicsSystem::PhysicsFixedUpdate::FixedExecute(double dt) noexcept + { + auto* system = reinterpret_cast(GetSystem()); + system->world->update(static_cast(dt)); + + system->fixedDT = fixedTimeStep; + system->accumulatedTime = accumulatedTime; + } + + void SHPhysicsSystem::PhysicsPostUpdate::Execute(double dt) noexcept + { + // Interpolate transforms for rendering + const auto& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); + sceneGraph.Traverse([](SHSceneNode* node) + { + const EntityID ENTITY_ID = node->GetEntityID(); + + // Check if has rigid body + if (auto* rb = SHComponentManager::GetComponent_s(ENTITY_ID); rb) + { + // TODO(Diren): Interpolate transforms for rendering + if (node->IsActive() && rb->isActive) + { + // Get SHADE transform + auto* transformComponent = SHComponentManager::GetComponent_s(ENTITY_ID); + SHASSERT(transformComponent != nullptr, "Transform Component missing from Entity " + std::to_string(ENTITY_ID)) + + const auto& RP3D_POS = rb->GetPosition(); + const SHVec3 SHADE_POS{ RP3D_POS.x, RP3D_POS.y, RP3D_POS.z }; + + const auto& SHADE_ROT = rb->GetOrientation().ToEuler(); + + transformComponent->SetWorldPosition(SHADE_POS); + transformComponent->SetWorldRotation(SHADE_ROT); + } + else // Check for a collider + { + + } + } + }); + + // TODO(Diren): Handle trigger messages for scripting + } + + /*-----------------------------------------------------------------------------------*/ + /* Private Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHPhysicsSystem::ClearUpdateQueue() noexcept + { + while (!updateQueue.empty()) + { + const auto& CMD = updateQueue.front(); + switch (CMD.type) + { + case UpdateType::ADD: + { + switch (CMD.component) + { + case UpdateComponent::RIGID_BODY: AddRigidBody(CMD.entityID); break; + //case UpdateComponent::COLLIDER: AddCollider(CMD.entityID); break; + default: break; + } + } + case UpdateType::REMOVE: + { + switch (CMD.component) + { + case UpdateComponent::RIGID_BODY: RemoveRigidBody(CMD.entityID); break; + //case UpdateComponent::COLLIDER: RemoveCollider(CMD.entityID); break; + default: break; + } + } + default: break; + } + + updateQueue.pop(); + } + } + + + void SHPhysicsSystem::AddRigidBody(EntityID entityID) const noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Adding a Rigidbody to the Physics World.") + #endif + + // Rigid Bodies need a transform. + auto const* transformComponent = SHComponentManager::GetComponent_s(entityID); + if (!transformComponent) + { + // NOTE: This should already be handled by the editor. + + SHLOG_INFO("Automatically adding a transform to Entity {}", entityID) + SHComponentManager::AddComponent(entityID); + transformComponent = SHComponentManager::GetComponent(entityID); + } + + const SHVec3& SHADE_WORLD_POSITION = transformComponent->GetWorldPosition(); + const rp3d::Vector3 RP3D_POSITION { SHADE_WORLD_POSITION.x, SHADE_WORLD_POSITION.y, SHADE_WORLD_POSITION.z }; + + const SHVec3& SHADE_WORLD_ROTATION = transformComponent->GetWorldRotation(); + const rp3d::Quaternion RP3D_ORIENTATION = rp3d::Quaternion::fromEulerAngles(SHADE_WORLD_ROTATION.x, SHADE_WORLD_ROTATION.y, SHADE_WORLD_ROTATION.z); + + const rp3d::Transform RP3D_TF { RP3D_POSITION, RP3D_ORIENTATION }; + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (!rigidBodyComponent) + { + // NOTE: This should already be handled by the editor. + + SHLOG_INFO("Automatically adding a rigidbody to Entity {}", entityID) + SHComponentManager::AddComponent(entityID); + rigidBodyComponent = SHComponentManager::GetComponent(entityID); + } + + rigidBodyComponent->rigidBody = world->createRigidBody(RP3D_TF); + rigidBodyComponent->SyncRP3DAndSHADE(); + + // Reassign collider + //if (collider) + //{ + // collider. + //} + } + + void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) const noexcept + { + #ifdef _DEBUG + SHLOG_INFO("Removing a Rigidbody from the Physics World.") + #endif + + auto* rigidBodyComponent = SHComponentManager::GetComponent_s(entityID); + if (rigidBodyComponent == nullptr) + { + SHLOG_ERROR("Entity {} does not have a rigidbody component to remove!", entityID) + return; + } + + // If a collider exists, remake the colliders with a collision body + + world->destroyRigidBody(rigidBodyComponent->rigidBody); + rigidBodyComponent->rigidBody = nullptr; // this should be redundant + } + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h new file mode 100644 index 00000000..dac6836a --- /dev/null +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -0,0 +1,237 @@ +/**************************************************************************************** + * \file SHPhysicsSystem.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for the Physics System + * + * \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 +#include + +#include + +// Project Headers +#include "Math/SHQuaternion.h" +#include "Components/SHRigidBodyComponent.h" + +#include "Scene/SHSceneGraph.h" +#include "ECS_Base/System/SHSystemRoutine.h" +#include "ECS_Base/System/SHFixedSystemRoutine.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SH_API SHPhysicsSystem : public SHSystem + { + public: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + struct WorldSettings + { + SHVec3 gravity; + uint16_t numVelocitySolverIterations; + uint16_t numPositionSolverIterations; + bool sleepingEnabled; + }; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsSystem () = default; + ~SHPhysicsSystem () override = default; + + SHPhysicsSystem (const SHPhysicsSystem&) = delete; + SHPhysicsSystem (SHPhysicsSystem&&) = delete; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHPhysicsSystem& operator= (const SHPhysicsSystem&) = delete; + SHPhysicsSystem& operator= (SHPhysicsSystem&&) = delete; + + /*---------------------------------------------------------------------------------*/ + /* Getter Functions */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] bool IsSleepingEnabled () const noexcept; + + //[[nodiscard]] double GetFixedUpdate () const noexcept; + [[nodiscard]] SHVec3 GetWorldGravity () const noexcept; + [[nodiscard]] uint16_t GetNumberVelocityIterations () const noexcept; + [[nodiscard]] uint16_t GetNumberPositionIterations () const noexcept; + + + /*---------------------------------------------------------------------------------*/ + /* Setter Functions */ + /*---------------------------------------------------------------------------------*/ + + //void SetFixedUpdate (double fixedUpdateRate) noexcept; + void SetWorldGravity (const SHVec3& gravity) const noexcept; + void SetNumberVelocityIterations (uint16_t numVelIterations) const noexcept; + void SetNumberPositionIterations (uint16_t numPosIterations) const noexcept; + void SetSleepingEnabled (bool enableSleeping) const noexcept; + + void SetWorldSettings (const WorldSettings& settings) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Init () override; + void Exit () override; + + void AddRigidBodyComponent (EntityID id) noexcept; + void AddColliderComponent (EntityID id) noexcept; + void RemoveRigidBodyComponent (EntityID id) noexcept; + void RemoveColliderComponent (EntityID id) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* System Routines */ + /*---------------------------------------------------------------------------------*/ + + class SH_API PhysicsPreUpdate : public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPreUpdate(); + ~PhysicsPreUpdate() = default; + + PhysicsPreUpdate(const PhysicsPreUpdate&) = delete; + PhysicsPreUpdate(PhysicsPreUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPreUpdate& operator= (const PhysicsPreUpdate&) = delete; + PhysicsPreUpdate& operator= (PhysicsPreUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + class SH_API PhysicsFixedUpdate : public SHFixedSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsFixedUpdate(); + ~PhysicsFixedUpdate() = default; + + PhysicsFixedUpdate(const PhysicsFixedUpdate&) = delete; + PhysicsFixedUpdate(PhysicsFixedUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsFixedUpdate& operator= (const PhysicsFixedUpdate&) = delete; + PhysicsFixedUpdate& operator= (PhysicsFixedUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + //void Execute (double dt) noexcept override; + void FixedExecute (double dt) noexcept override; + }; + + class SH_API PhysicsPostUpdate : public SHSystemRoutine + { + public: + /*-------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPostUpdate(); + ~PhysicsPostUpdate() = default; + + PhysicsPostUpdate(const PhysicsPostUpdate&) = delete; + PhysicsPostUpdate(PhysicsPostUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*-------------------------------------------------------------------------------*/ + + PhysicsPostUpdate& operator= (const PhysicsPostUpdate&) = delete; + PhysicsPostUpdate& operator= (PhysicsPostUpdate&&) = delete; + + /*-------------------------------------------------------------------------------*/ + /* Function Members */ + /*-------------------------------------------------------------------------------*/ + + void Execute(double dt) noexcept override; + }; + + + private: + /*---------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*---------------------------------------------------------------------------------*/ + + enum class UpdateComponent { RIGID_BODY, COLLIDER }; + enum class UpdateType { ADD, REMOVE }; + + struct UpdateCommand + { + UpdateComponent component; + UpdateType type; + EntityID entityID; + }; + + struct CachedTransform + { + SHVec3 position; + SHQuaternion orientation; + }; + + /*---------------------------------------------------------------------------------*/ + /* Data Members */ + /*---------------------------------------------------------------------------------*/ + + //double interpolationFactor; + //double fixedUpdate; + + double accumulatedTime; + double fixedDT; + + rp3d::PhysicsCommon factory; + rp3d::PhysicsWorld* world; + + std::queue updateQueue; + std::unordered_map prevTransforms; // used for interpolation + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void ClearUpdateQueue () noexcept; + + void AddRigidBody (EntityID entityID) const noexcept; + void AddCollider (EntityID entityID) const noexcept; + void RemoveRigidBody (EntityID entityID) const noexcept; + void RemoveCollider (EntityID entityID) const noexcept; + }; + + +} // namespace SHADE \ No newline at end of file