Added Physics System
This commit is contained in:
parent
658054bc14
commit
097b1be3f7
|
@ -86,7 +86,6 @@ namespace Sandbox
|
||||||
|
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHTransformComponent>();
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRenderable>();
|
||||||
SHADE::SHComponentManager::CreateComponentSparseSet<SHADE::SHRigidBodyComponent>();
|
|
||||||
|
|
||||||
//TODO: REMOVE AFTER PRESENTATION
|
//TODO: REMOVE AFTER PRESENTATION
|
||||||
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
SHADE::SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
|
||||||
|
|
|
@ -8,23 +8,19 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
class SHFixedSystemRoutine: public SHSystemRoutine
|
class SHFixedSystemRoutine: public SHSystemRoutine
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
double accumulatedTime;
|
double accumulatedTime;
|
||||||
double fixedTimeStep;
|
double fixedTimeStep;
|
||||||
|
|
||||||
protected:
|
|
||||||
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
SHFixedSystemRoutine(double timeStep = DEFAULT_FIXED_STEP, std::string routineName = "Default Fixed Routine Name", bool editorPause = false)
|
||||||
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
:SHSystemRoutine(routineName, editorPause), accumulatedTime(0.0), fixedTimeStep(timeStep){}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~SHFixedSystemRoutine() = default;
|
~SHFixedSystemRoutine() = default;
|
||||||
|
|
||||||
virtual void Execute(double dt) noexcept;
|
virtual void Execute(double dt) noexcept override;
|
||||||
|
|
||||||
virtual void FixedExecute(double dt) noexcept {};
|
|
||||||
|
|
||||||
|
virtual void FixedExecute(double dt) noexcept {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -465,6 +465,21 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* Private Function Member Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SHRigidBodyComponent::SyncRP3DAndSHADE()
|
||||||
|
{
|
||||||
|
rigidBody->setType(static_cast<rp3d::BodyType>(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)
|
void SHRigidBodyComponent::SetFlag(bool flagState, int flagPos)
|
||||||
{
|
{
|
||||||
flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos);
|
flagState ? flags |= (1U << flagPos) : flags &= ~(1U << flagPos);
|
||||||
|
|
|
@ -21,6 +21,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
class SH_API SHRigidBodyComponent : public SHComponent
|
class SH_API SHRigidBodyComponent : public SHComponent
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Friends */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
friend class SHPhysicsSystem;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Type Definitions */
|
/* Type Definitions */
|
||||||
|
@ -129,8 +136,6 @@ namespace SHADE
|
||||||
float drag;
|
float drag;
|
||||||
float angularDrag;
|
float angularDrag;
|
||||||
|
|
||||||
SHMatrix inertiaTensor;
|
|
||||||
|
|
||||||
// rX rY rZ pX pY pZ slp g
|
// rX rY rZ pX pY pZ slp g
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
|
|
||||||
|
@ -138,6 +143,7 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void SyncRP3DAndSHADE ();
|
||||||
void SetFlag (bool flagState, int flagPos);
|
void SetFlag (bool flagState, int flagPos);
|
||||||
void SetRP3DLinearConstraints () const ;
|
void SetRP3DLinearConstraints () const ;
|
||||||
void SetRP3DAngularConstraints () const ;
|
void SetRP3DAngularConstraints () const ;
|
||||||
|
|
|
@ -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 <SHpch.h>
|
||||||
|
|
||||||
|
// 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<SHADE::SHRigidBodyComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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<SHPhysicsSystem*>(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<SHRigidBodyComponent>(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<SHPhysicsSystem*>(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<SHPhysicsSystem*>(GetSystem());
|
||||||
|
system->world->update(static_cast<rp3d::decimal>(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<SHRigidBodyComponent>(ENTITY_ID); rb)
|
||||||
|
{
|
||||||
|
// TODO(Diren): Interpolate transforms for rendering
|
||||||
|
if (node->IsActive() && rb->isActive)
|
||||||
|
{
|
||||||
|
// Get SHADE transform
|
||||||
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(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<SHTransformComponent>(entityID);
|
||||||
|
if (!transformComponent)
|
||||||
|
{
|
||||||
|
// NOTE: This should already be handled by the editor.
|
||||||
|
|
||||||
|
SHLOG_INFO("Automatically adding a transform to Entity {}", entityID)
|
||||||
|
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
|
||||||
|
transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(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<SHRigidBodyComponent>(entityID);
|
||||||
|
if (!rigidBodyComponent)
|
||||||
|
{
|
||||||
|
// NOTE: This should already be handled by the editor.
|
||||||
|
|
||||||
|
SHLOG_INFO("Automatically adding a rigidbody to Entity {}", entityID)
|
||||||
|
SHComponentManager::AddComponent<SHRigidBodyComponent>(entityID);
|
||||||
|
rigidBodyComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(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<SHRigidBodyComponent>(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
|
|
@ -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 <queue>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <reactphysics3d/reactphysics3d.h>
|
||||||
|
|
||||||
|
// 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<UpdateCommand> updateQueue;
|
||||||
|
std::unordered_map<EntityID, CachedTransform> 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
|
Loading…
Reference in New Issue