Merge pull request #120 from SHADE-DP/SP3-2-Physics

SP3-2 Physics Bugfixes
NEW

Forces can be added to the rigid body.
BUGFIXES

Rigidbody transforms can be modified while the editor is in play.
Deleting a rigid body no longer causes a crash (please let me know if it does happen again and how to replicate it)
Deleting a collider actually gets rid of the collider
On editor stop, forces and velocities are cleared from rigid bodies.
This commit is contained in:
XiaoQiDigipen 2022-10-26 16:40:31 +08:00 committed by GitHub
commit 29dccf77b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 432 additions and 420 deletions

View File

@ -35,6 +35,23 @@ namespace SHADE
return selected;
}
template <typename ComponentType, typename EnforcedComponent, std::enable_if_t<std::is_base_of_v<SHComponent, ComponentType>, bool> = true, std::enable_if_t<std::is_base_of_v<SHComponent, EnforcedComponent>, bool> = true>
bool DrawAddComponentWithEnforcedComponentButton(EntityID const& eid)
{
bool selected = false;
if (!SHComponentManager::HasComponent<ComponentType>(eid))
{
if(selected = ImGui::Selectable(std::format("Add {}", rttr::type::get<ComponentType>().get_name().data()).data()); selected)
{
if(SHComponentManager::GetComponent_s<EnforcedComponent>(eid) == nullptr)
SHComponentManager::AddComponent<EnforcedComponent>(eid);
SHComponentManager::AddComponent<ComponentType>(eid);
}
}
return selected;
}
SHEditorInspector::SHEditorInspector()
:SHEditorWindow("Inspector", ImGuiWindowFlags_MenuBar)
{
@ -90,15 +107,13 @@ namespace SHADE
if(ImGui::BeginMenu(std::format("{} Add Component", ICON_MD_LIBRARY_ADD).data()))
{
DrawAddComponentButton<SHTransformComponent>(eid);
DrawAddComponentButton<SHRenderable>(eid);
DrawAddComponentButton<SHColliderComponent>(eid);
if(DrawAddComponentButton<SHRigidBodyComponent>(eid))
{
if(SHComponentManager::GetComponent_s<SHTransformComponent>(eid) == nullptr)
{
SHComponentManager::AddComponent<SHTransformComponent>(eid);
}
}
// Components that require Transforms
DrawAddComponentWithEnforcedComponentButton<SHRenderable, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHRigidBodyComponent, SHTransformComponent>(eid);
DrawAddComponentWithEnforcedComponentButton<SHColliderComponent, SHTransformComponent>(eid);
ImGui::EndMenu();
}

View File

@ -12,6 +12,7 @@
#include "SHpch.h"
#include "SHEvent.h"
#include "SHEventReceiver.h"
#include "SH_API.h"
/******************************************************************************
INSTRUCTIONS FOR USE:
@ -67,7 +68,7 @@ namespace SHADE
using EventManagerListener = std::function<void(SHEvent)>;
class SHEventManager
class SH_API SHEventManager
{
private:

View File

@ -61,9 +61,9 @@ namespace SHADE
void SHTransformSystem::Init()
{
std::shared_ptr thisReceiver { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
ReceiverPtr receiver = std::dynamic_pointer_cast<SHEventReceiver>(thisReceiver);
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, receiver);
const std::shared_ptr CHANGE_PARENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHTransformSystem>>(this, &SHTransformSystem::ChangeParent) };
const ReceiverPtr CHANGE_PARENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(CHANGE_PARENT_RECEIVER);
SHEventManager::SubscribeTo(SH_SCENEGRAPH_CHANGE_PARENT_EVENT, CHANGE_PARENT_RECEIVER_PTR);
}
void SHTransformSystem::Exit()
@ -75,50 +75,6 @@ namespace SHADE
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent)
{
const auto& eventData = reinterpret_cast<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
auto* node = eventData->data->node;
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
// Recompute local transform and store localToWorld Matrix
SHMatrix localToWorld = SHMatrix::Identity;
SHMatrix worldToLocal = SHMatrix::Identity;
auto* newParent = eventData->data->newParent;
const auto* PARENT_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(newParent->GetEntityID());
if (PARENT_TF != nullptr) // Not the root
{
localToWorld = PARENT_TF->GetTRS();
worldToLocal = SHMatrix::Inverse(localToWorld);
}
// Maintain World Transform and recompute Local Transform
// Compute Local Position
tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal);
tf->localRotation = tf->worldRotation;
tf->local.scale = tf->world.scale;
if (PARENT_TF != nullptr)
{
// Compute Local Rotation
tf->localRotation -= PARENT_TF->GetLocalRotation();
// Compute Local Scale
tf->local.scale /= PARENT_TF->GetLocalScale();
}
tf->local.trs = localToWorld;
// Propagate maintaining world transform down the branch
UpdateChildrenLocalTransforms(node);
return eventData->handle;
}
void SHTransformSystem::UpdateChildrenLocalTransforms(SHSceneNode* node)
{
// Structure is similar to update entity, albeit without a queue to do being a forced update
@ -300,4 +256,49 @@ namespace SHADE
tf.world.ComputeTRS();
}
SHEventHandle SHTransformSystem::ChangeParent(SHEventPtr changeParentEvent)
{
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHSceneGraphChangeParentEvent>*>(changeParentEvent.get());
auto* node = EVENT_DATA->data->node;
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(node->GetEntityID());
// Recompute local transform and store localToWorld Matrix
SHMatrix localToWorld = SHMatrix::Identity;
SHMatrix worldToLocal = SHMatrix::Identity;
auto* newParent = EVENT_DATA->data->newParent;
const auto* PARENT_TF = SHComponentManager::GetComponent_s<SHTransformComponent>(newParent->GetEntityID());
if (PARENT_TF != nullptr) // Not the root
{
localToWorld = PARENT_TF->GetTRS();
worldToLocal = SHMatrix::Inverse(localToWorld);
}
// Maintain World Transform and recompute Local Transform
// Compute Local Position
tf->local.position = SHVec3::Transform(tf->world.position, worldToLocal);
tf->localRotation = tf->worldRotation;
tf->local.scale = tf->world.scale;
if (PARENT_TF != nullptr)
{
// Compute Local Rotation
tf->localRotation -= PARENT_TF->GetLocalRotation();
// Compute Local Scale
tf->local.scale /= PARENT_TF->GetLocalScale();
}
tf->local.trs = localToWorld;
// Propagate maintaining world transform down the branch
UpdateChildrenLocalTransforms(node);
return EVENT_DATA->handle;
}
} // namespace SHADE

View File

@ -11,9 +11,9 @@
#pragma once
// Project Headers
#include "SHTransformComponent.h"
#include "Scene/SHSceneGraph.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "Scene/SHSceneGraph.h"
#include "SHTransformComponent.h"
namespace SHADE
{
@ -53,17 +53,6 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/
TransformPostLogicUpdate ();
~TransformPostLogicUpdate () = default;
TransformPostLogicUpdate (const TransformPostLogicUpdate&) = delete;
TransformPostLogicUpdate (TransformPostLogicUpdate&&) = delete;
/*-------------------------------------------------------------------------------*/
/* Operator Overloads */
/*-------------------------------------------------------------------------------*/
TransformPostLogicUpdate& operator= (const TransformPostLogicUpdate&) = delete;
TransformPostLogicUpdate& operator= (TransformPostLogicUpdate&&) = delete;
/*-------------------------------------------------------------------------------*/
/* Function Members */
@ -80,17 +69,6 @@ namespace SHADE
/*-------------------------------------------------------------------------------*/
TransformPostPhysicsUpdate ();
~TransformPostPhysicsUpdate () = default;
TransformPostPhysicsUpdate (const TransformPostPhysicsUpdate&) = delete;
TransformPostPhysicsUpdate (TransformPostPhysicsUpdate&&) = delete;
/*-------------------------------------------------------------------------------*/
/* Operator Overloads */
/*-------------------------------------------------------------------------------*/
TransformPostPhysicsUpdate& operator= (const TransformPostPhysicsUpdate&) = delete;
TransformPostPhysicsUpdate& operator= (TransformPostPhysicsUpdate&&) = delete;
/*-------------------------------------------------------------------------------*/
/* Function Members */
@ -111,11 +89,14 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
static void UpdateChildrenLocalTransforms (SHSceneNode* node);
static void UpdateEntity (const SHSceneNode* node, bool clearDirtyFlag);
static void UpdateTransform (SHTransformComponent& tf, const SHTransformComponent* parent = nullptr);
// Event Handlers
SHEventHandle ChangeParent (SHEventPtr changeParentEvent);
};

View File

@ -26,7 +26,6 @@ namespace SHADE
SHColliderComponent::SHColliderComponent() noexcept
: system { nullptr }
, colliders {}
{}
/*-----------------------------------------------------------------------------------*/
@ -69,31 +68,24 @@ namespace SHADE
void SHColliderComponent::OnCreate()
{
system = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (!system)
{
SHLOG_ERROR("Physics system does not exist, Collider Component not added!")
return;
}
system->AddCollider(GetEID());
}
void SHColliderComponent::OnDestroy()
{
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to remove Collider component!")
return;
}
system->RemoveCollider(GetEID());
}
SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept
{
const auto TYPE = SHCollider::Type::BOX;
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
return nullptr;
}
auto boxPair = std::make_pair(SHCollider{TYPE}, true);
static constexpr auto TYPE = SHCollider::Type::BOX;
auto boxPair = std::make_pair(SHCollider{ TYPE }, true);
auto& collider = colliders.emplace_back(boxPair).first;
const auto* tf = SHComponentManager::GetComponent<SHTransformComponent>(GetEID());
@ -101,12 +93,6 @@ namespace SHADE
collider.SetPositionOffset(posOffset);
collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents);
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Box Collider!")
return nullptr;
}
// Notify Physics System
system->AddCollisionShape(GetEID(), &collider);
@ -115,7 +101,13 @@ namespace SHADE
SHBoundingSphere* SHColliderComponent::AddBoundingSphere(float radius, const SHVec3& posOffset) noexcept
{
const auto TYPE = SHCollider::Type::SPHERE;
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
return nullptr;
}
static constexpr auto TYPE = SHCollider::Type::SPHERE;
auto spherePair = std::make_pair(SHCollider{ TYPE }, true);
auto& collider = colliders.emplace_back(spherePair).first;
@ -126,13 +118,7 @@ namespace SHADE
const SHVec3 TF_WORLD_SCALE = tf->GetWorldScale();
const float MAX_SCALE = SHMath::Max({ TF_WORLD_SCALE.x, TF_WORLD_SCALE.y, TF_WORLD_SCALE.z });
collider.SetAsBoundingSphere(MAX_SCALE * 0.5f);
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to add Sphere Collider!")
return nullptr;
}
collider.SetAsBoundingSphere(MAX_SCALE * 0.5f * radius);
// Notify Physics System
system->AddCollisionShape(GetEID(), &collider);

View File

@ -44,7 +44,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
using ColliderDirtyPair = std::pair<SHCollider, bool>;
using Colliders = std::vector<ColliderDirtyPair>;
using Colliders = std::vector<ColliderDirtyPair>;
public:
@ -81,10 +81,10 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
void OnCreate () override;
void OnDestroy () override;
void OnCreate () override;
void OnDestroy () override;
void RemoveCollider (int index);
void RemoveCollider (int index);
SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept;
SHBoundingSphere* AddBoundingSphere (float radius = 1.0f, const SHVec3& posOffset = SHVec3::Zero) noexcept;

View File

@ -28,11 +28,10 @@ namespace SHADE
, flags { 0 }
, dirtyFlags { 0 }
, interpolate { true }
, system { nullptr }
, rp3dBody { nullptr }
, mass { 1.0f }
, drag { 0.01f }
, angularDrag { 0.01f }
{
// Set default flags: Gravity & Sleeping enabled
flags |= 1U << 0;
@ -161,7 +160,13 @@ namespace SHADE
void SHRigidBodyComponent::SetGravityEnabled(bool enableGravity) noexcept
{
constexpr int FLAG_POS = 0;
static constexpr int FLAG_POS = 0;
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot enable gravity of a non-dynamic object {}", GetEID())
return;
}
dirtyFlags |= 1U << FLAG_POS;
enableGravity ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -169,7 +174,13 @@ namespace SHADE
void SHRigidBodyComponent::SetIsAllowedToSleep(bool isAllowedToSleep) noexcept
{
constexpr int FLAG_POS = 1;
static constexpr int FLAG_POS = 1;
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot enable sleeping of a non-dynamic object {}", GetEID())
return;
}
dirtyFlags |= 1U << 1;
isAllowedToSleep ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -177,7 +188,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezePositionX(bool freezePositionX) noexcept
{
constexpr int FLAG_POS = 2;
static constexpr int FLAG_POS = 2;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 2;
freezePositionX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -185,7 +202,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezePositionY(bool freezePositionY) noexcept
{
constexpr int FLAG_POS = 3;
static constexpr int FLAG_POS = 3;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 2;
freezePositionY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -193,7 +216,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezePositionZ(bool freezePositionZ) noexcept
{
constexpr int FLAG_POS = 4;
static constexpr int FLAG_POS = 4;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set linear constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 2;
freezePositionZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -201,7 +230,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezeRotationX(bool freezeRotationX) noexcept
{
constexpr int FLAG_POS = 5;
static constexpr int FLAG_POS = 5;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 3;
freezeRotationX ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -209,7 +244,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezeRotationY(bool freezeRotationY) noexcept
{
constexpr int FLAG_POS = 6;
static constexpr int FLAG_POS = 6;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 3;
freezeRotationY ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -217,7 +258,13 @@ namespace SHADE
void SHRigidBodyComponent::SetFreezeRotationZ(bool freezeRotationZ) noexcept
{
constexpr int FLAG_POS = 7;
static constexpr int FLAG_POS = 7;
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set angular constraints of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 3;
freezeRotationZ ? flags |= (1U << FLAG_POS) : flags &= ~(1U << FLAG_POS);
@ -230,30 +277,60 @@ namespace SHADE
void SHRigidBodyComponent::SetMass(float newMass) noexcept
{
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID())
return;
}
dirtyFlags |= 1U << 5;
mass = newMass;
}
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
{
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot set drag of a non-dynamic object {}", GetEID())
return;
}
dirtyFlags |= 1U << 6;
drag = newDrag;
}
void SHRigidBodyComponent::SetAngularDrag(float newAngularDrag) noexcept
{
if (type != Type::DYNAMIC)
{
SHLOG_WARNING("Cannot set angular drag of a non-dynamic object {}", GetEID())
return;
}
dirtyFlags |= 1U << 7;
angularDrag = newAngularDrag;
}
void SHRigidBodyComponent::SetLinearVelocity(const SHVec3& newLinearVelocity) noexcept
{
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set linear velocity of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 8;
linearVelocity = newLinearVelocity;
}
void SHRigidBodyComponent::SetAngularVelocity(const SHVec3& newAngularVelocity) noexcept
{
if (type == Type::STATIC)
{
SHLOG_WARNING("Cannot set angular velocity of a static object {}", GetEID())
return;
}
dirtyFlags |= 1U << 9;
angularVelocity = newAngularVelocity;
}
@ -262,125 +339,92 @@ namespace SHADE
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHRigidBodyComponent::OnCreate()
{
system = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (!system)
{
SHLOG_ERROR("Physics system does not exist, Rigid Body Component not added!")
return;
}
// Notify Physics System
system->AddRigidBody(GetEID());
}
void SHRigidBodyComponent::OnDestroy()
{
// Notify Physics System
if (!system)
{
SHLOG_ERROR("Physics system does not exist, unable to remove Rigid Body Component!")
return;
}
system->RemoveRigidBody(GetEID());
}
void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddForce(GetEID(), force);
rp3dBody->applyWorldForceAtCenterOfMass(force);
}
void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddForceAtLocalPos(GetEID(), force, localPos);
rp3dBody->applyWorldForceAtLocalPosition(force, localPos);
}
void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddForceAtWorldPos(GetEID(), force, worldPos);
rp3dBody->applyWorldForceAtWorldPosition(force, worldPos);
}
void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddRelativeForce(GetEID(), force);
rp3dBody->applyLocalForceAtCenterOfMass(relativeForce);
}
void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddRelativeForceAtLocalPos(GetEID(), force, localPos);
rp3dBody->applyLocalForceAtLocalPosition(relativeForce, localPos);
}
void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddRelativeForceAtWorldPos(GetEID(), force, worldPos);
rp3dBody->applyLocalForceAtWorldPosition(relativeForce, worldPos);
}
void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddTorque(GetEID(), torque);
rp3dBody->applyWorldTorque(torque);
}
void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept
{
if (!system)
if (rp3dBody == nullptr)
{
SHLOG_ERROR("Physics system does not exist, unable to Add Force to a body!")
SHLOGV_ERROR("Entity {} is missing an rp3dBody!", GetEID())
return;
}
// Notify Physics Systems
system->AddRelativeTorque(GetEID(), relativeTorque);
rp3dBody->applyLocalTorque(relativeTorque);
}
} // namespace SHADE

View File

@ -10,6 +10,7 @@
#pragma once
#include <reactphysics3d/reactphysics3d.h>
#include <rttr/registration>
// Project Headers
@ -125,9 +126,6 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
void OnCreate () override;
void OnDestroy () override;
void AddForce (const SHVec3& force) const noexcept;
void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept;
void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept;
@ -155,7 +153,7 @@ namespace SHADE
uint16_t dirtyFlags;
bool interpolate;
SHPhysicsSystem* system;
rp3d::RigidBody* rp3dBody;
float mass;
float drag;
@ -167,8 +165,6 @@ namespace SHADE
SHVec3 torque;
SHVec3 angularVelocity;
// TODO(Diren): Once quaternions have replaced euler angles in transforms, store it for the rigidbody.
SHVec3 position;
SHQuaternion orientation;

View File

@ -26,8 +26,6 @@ namespace SHADE
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
: entityID { eid }
, isRigidBody { false }
, hasColliders{ false }
, factory { physicsFactory }
, world { physicsWorld }
, rp3dBody { nullptr }
@ -130,42 +128,6 @@ namespace SHADE
/* Public Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c)
{
// If collider already exists, recreate the collision body as a rigid body
if (hasColliders)
world->destroyCollisionBody(rp3dBody);
rp3dBody = world->createRigidBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
isRigidBody = true;
rb->position = tf->GetWorldPosition();
rb->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
if (hasColliders)
{
c->position = tf->GetWorldPosition();
c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
// Get array of colliders and add them back into the rigidbody
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
}
void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c)
{
if (rp3dBody == nullptr)
rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() });
hasColliders = true;
c->position = tf->GetWorldPosition();
c->orientation = SHQuaternion::FromEuler(tf->GetWorldRotation());
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
int SHPhysicsObject::AddCollider(SHCollider* collider)
{
switch (collider->GetType())
@ -193,31 +155,6 @@ namespace SHADE
return static_cast<int>(rp3dBody->getNbColliders()) - 1;
}
void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept
{
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(rp3dBody));
if (hasColliders)
{
// Preserve colliders as a collision body
rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation });
for (auto& collider : c->colliders | std::views::keys)
AddCollider(&collider);
}
isRigidBody = false;
}
void SHPhysicsObject::DestroyCollisionBody() noexcept
{
// Remove all colliders
for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i)
{
auto* collider = rp3dBody->getCollider(i);
rp3dBody->removeCollider(collider);
}
}
void SHPhysicsObject::RemoveCollider(int index)
{
const int NUM_COLLIDERS = static_cast<int>(rp3dBody->getNbColliders());

View File

@ -69,13 +69,8 @@ namespace SHADE
/* Function Members */
/*---------------------------------------------------------------------------------*/
void CreateRigidBody (const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c);
void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c);
int AddCollider (SHCollider* collider);
void DestroyRigidBody (SHColliderComponent* c) noexcept;
void RemoveCollider (int index);
void DestroyCollisionBody () noexcept;
void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept;
void SyncColliders (SHColliderComponent* c) const noexcept;
@ -86,8 +81,6 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
EntityID entityID;
bool isRigidBody;
bool hasColliders;
rp3d::PhysicsCommon* factory;
rp3d::PhysicsWorld* world;

View File

@ -16,6 +16,8 @@
// Project Headers
#include "ECS_Base/Managers/SHComponentManager.h"
#include "ECS_Base/Managers/SHEntityManager.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.hpp"
#include "Math/SHMathHelpers.h"
#include "Scene/SHSceneManager.h"
#include "Math/Transform/SHTransformComponent.h"
@ -175,11 +177,9 @@ namespace SHADE
void SHPhysicsSystem::Init()
{
using namespace rp3d;
// Create a physics world with the default settings
PhysicsWorld::WorldSettings settings;
settings.gravity = Vector3{ 0.0f, -9.81f, 0.0f };
rp3d::PhysicsWorld::WorldSettings settings;
settings.gravity = SHVec3{ 0.0f, -9.81f, 0.0f };
settings.isSleepingEnabled = true;
settings.defaultVelocitySolverNbIterations = 8;
settings.defaultPositionSolverNbIterations = 3;
@ -190,6 +190,16 @@ namespace SHADE
// Set up solvers
world->setContactsPositionCorrectionTechnique(rp3d::ContactsPositionCorrectionTechnique::SPLIT_IMPULSES);
// Subscribe to component events
const std::shared_ptr ADD_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::AddPhysicsComponent) };
const ReceiverPtr ADD_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(ADD_COMPONENT_RECEIVER);
SHEventManager::SubscribeTo(SH_COMPONENT_ADDED_EVENT, ADD_COMPONENT_RECEIVER_PTR);
const std::shared_ptr REMOVE_COMPONENT_RECEIVER { std::make_shared<SHEventReceiverSpec<SHPhysicsSystem>>(this, &SHPhysicsSystem::RemovePhysicsComponent) };
const ReceiverPtr REMOVE_COMPONENT_RECEIVER_PTR = std::dynamic_pointer_cast<SHEventReceiver>(REMOVE_COMPONENT_RECEIVER);
SHEventManager::SubscribeTo(SH_COMPONENT_REMOVED_EVENT, REMOVE_COMPONENT_RECEIVER_PTR);
}
void SHPhysicsSystem::Exit()
@ -197,99 +207,6 @@ namespace SHADE
factory.destroyPhysicsWorld(world);
}
void SHPhysicsSystem::AddRigidBody(EntityID entityID) noexcept
{
//#ifdef _DEBUG
// SHLOG_INFO("Adding a Rigidbody to the Physics World.")
//#endif
auto* physicsObject = CreatePhysicsObject(entityID);
physicsObject->CreateRigidBody
(
EnsureTransform(entityID),
SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID),
SHComponentManager::GetComponent_s<SHColliderComponent>(entityID)
);
}
void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept
{
//#ifdef _DEBUG
// SHLOG_INFO("Adding a Collider to the Physics World.")
//#endif
auto* physicsObject = CreatePhysicsObject(entityID);
physicsObject->CreateCollisionBody
(
EnsureTransform(entityID),
SHComponentManager::GetComponent<SHColliderComponent>(entityID)
);
}
void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept
{
#ifdef _DEBUG
SHLOG_INFO("Removing a Rigidbody from the Physics World.")
#endif
auto* physicsObject = GetPhysicsObject(entityID);
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s<SHColliderComponent>(entityID));
if (physicsObject->rp3dBody == nullptr)
DestroyPhysicsObject(entityID);
}
void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept
{
#ifdef _DEBUG
SHLOG_INFO("Removing a Collider from the Physics World.")
#endif
}
void SHPhysicsSystem::AddForce(EntityID entityID, const SHVec3& force) const noexcept
{
}
void SHPhysicsSystem::AddForceAtLocalPos(EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept
{
}
void SHPhysicsSystem::AddForceAtWorldPos(EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept
{
}
void SHPhysicsSystem::AddRelativeForce(EntityID entityID, const SHVec3& relativeForce) const noexcept
{
}
void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept
{
}
void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept
{
}
void SHPhysicsSystem::AddTorque(EntityID entityID, const SHVec3& torque) const noexcept
{
}
void SHPhysicsSystem::AddRelativeTorque(EntityID entityID, const SHVec3& relativeTorque) const noexcept
{
}
void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider)
{
auto* physicsObject = GetPhysicsObject(entityID);
@ -298,27 +215,63 @@ namespace SHADE
void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index)
{
auto* physicsObject = GetPhysicsObject(entityID);
physicsObject->RemoveCollider(index);
}
void SHPhysicsSystem::PhysicsPreUpdate::Execute(double) noexcept
{
auto* system = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
// Sync transforms
for (auto& [entityID, physicsObject] : system->map)
{
// Ensure a valid physics Object
if (physicsObject.rp3dBody == nullptr)
continue;
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
// Clear all forces and velocities if editor is not in play
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
{
if (rigidBodyComponent)
{
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
rp3dRigidBody->resetForce();
rp3dRigidBody->resetTorque();
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
}
}
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
if (transformComponent && transformComponent->HasChanged())
{
const auto WORLD_POS = transformComponent->GetWorldPosition();
const auto WORLD_ROT = transformComponent->GetWorldOrientation();
physicsObject.SetPosition(WORLD_POS);
physicsObject.SetOrientation(WORLD_ROT);
if (rigidBodyComponent)
{
rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT;
}
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
if (colliderComponent)
{
colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT;
}
}
}
// Update bodies and colliders if component is dirty
system->SyncRigidBodyComponents(SHComponentManager::GetDense<SHRigidBodyComponent>());
system->SyncColliderComponents(SHComponentManager::GetDense<SHColliderComponent>());
// Sync transforms
for (auto& physicsObject : system->map | std::views::values)
{
const auto* TF = SHComponentManager::GetComponent<SHTransformComponent>(physicsObject.entityID);
if (TF->HasChanged())
{
physicsObject.SetPosition(TF->GetWorldPosition());
physicsObject.SetOrientation(TF->GetWorldOrientation());
}
}
}
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
@ -359,7 +312,7 @@ namespace SHADE
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept
SHPhysicsObject* SHPhysicsSystem::EnsurePhysicsObject(EntityID entityID) noexcept
{
const auto it = map.find(entityID);
if (it == map.end())
@ -451,15 +404,18 @@ namespace SHADE
const rp3d::Transform CURRENT_TF = physicsObject.rp3dBody->getTransform();
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
// Check if transform should be interpolated
if (physicsObject.isRigidBody)
if (rigidBodyComponent != nullptr)
{
auto* rbComponent = SHComponentManager::GetComponent<SHRigidBodyComponent>(entityID);
if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
continue;
if (rbComponent->IsInterpolating())
if (rigidBodyComponent->IsInterpolating())
{
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
@ -474,12 +430,12 @@ namespace SHADE
rp3dRot = CURRENT_TF.getOrientation();
}
rbComponent->position = CURRENT_TF.getPosition();
rbComponent->orientation = CURRENT_TF.getOrientation();
rigidBodyComponent->position = CURRENT_TF.getPosition();
rigidBodyComponent->orientation = CURRENT_TF.getOrientation();
if (physicsObject.hasColliders)
if (colliderComponent != nullptr)
{
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
@ -491,28 +447,146 @@ namespace SHADE
}
// Convert RP3D Transform to SHADE
auto* tfComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
tfComponent->SetWorldPosition(rp3dPos);
tfComponent->SetWorldOrientation(SHQuaternion{ rp3dRot });
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
transformComponent->SetWorldPosition(rp3dPos);
transformComponent->SetWorldOrientation(rp3dRot);
// Cache transforms
physicsObject.prevTransform = CURRENT_TF;
}
}
SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID)
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
{
auto* tf = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
// Possibly redundant
if (!tf)
static const auto RIGID_BODY_ID = ComponentFamily::GetID<SHRigidBodyComponent>();
static const auto COLLIDER_ID = ComponentFamily::GetID<SHColliderComponent>();
const auto ADDED_ID = EVENT_DATA->data->addedComponentType;
const bool IS_PHYSICS_COMPONENT = ADDED_ID == RIGID_BODY_ID || ADDED_ID == COLLIDER_ID;
if (IS_PHYSICS_COMPONENT)
{
SHComponentManager::AddComponent<SHTransformComponent>(entityID);
tf = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
auto* physicsObject = EnsurePhysicsObject(ENTITY_ID);
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(ENTITY_ID);
if (transformComponent == nullptr)
{
SHLOG_ERROR("Entity {} cannot add a Physics Component without a Transform! Component not created!", ENTITY_ID)
return EVENT_DATA->handle;
}
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
if (ADDED_ID == RIGID_BODY_ID)
{
if (colliderComponent != nullptr)
{
world->destroyCollisionBody(physicsObject->rp3dBody);
physicsObject->rp3dBody = nullptr;
}
rigidBodyComponent->position = transformComponent->GetWorldPosition();
rigidBodyComponent->orientation = transformComponent->GetWorldOrientation();
physicsObject->rp3dBody = world->createRigidBody
(
rp3d::Transform{ rigidBodyComponent->position, rigidBodyComponent->orientation }
);
rigidBodyComponent->rp3dBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody);
// Add collision shapes back into the body
if (colliderComponent != nullptr)
{
for (auto& collider : colliderComponent->colliders | std::views::keys)
physicsObject->AddCollider(&collider);
}
}
if (ADDED_ID == COLLIDER_ID)
{
SHASSERT(colliderComponent != nullptr, "Collider Component was not added to Entity " + std::to_string(ENTITY_ID) + "!");
colliderComponent->position = transformComponent->GetWorldPosition();
colliderComponent->orientation = transformComponent->GetWorldOrientation();
if (physicsObject->rp3dBody == nullptr)
{
physicsObject->rp3dBody = world->createCollisionBody
(
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
);
}
// Add Collision Shapes
for (auto& collider : colliderComponent->colliders | std::views::keys)
physicsObject->AddCollider(&collider);
}
}
return tf;
return EVENT_DATA->handle;
}
SHEventHandle SHPhysicsSystem::RemovePhysicsComponent(SHEventPtr removeComponentEvent)
{
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentRemovedEvent>*>(removeComponentEvent.get());
static const auto RIGID_BODY_ID = ComponentFamily::GetID<SHRigidBodyComponent>();
static const auto COLLIDER_ID = ComponentFamily::GetID<SHColliderComponent>();
const auto REMOVED_ID = EVENT_DATA->data->removedComponentType;
const bool IS_PHYSICS_COMPONENT = REMOVED_ID == RIGID_BODY_ID || REMOVED_ID == COLLIDER_ID;
if (IS_PHYSICS_COMPONENT)
{
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
if (REMOVED_ID == RIGID_BODY_ID)
{
world->destroyRigidBody(reinterpret_cast<rp3d::RigidBody*>(physicsObject->rp3dBody));
physicsObject->rp3dBody = nullptr;
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
if (colliderComponent != nullptr)
{
// Preserve colliders as a collision body
physicsObject->rp3dBody = world->createCollisionBody
(
rp3d::Transform{ colliderComponent->position, colliderComponent->orientation }
);
for (auto& collider : colliderComponent->colliders | std::views::keys)
physicsObject->AddCollider(&collider);
}
// Wake up all physics objects
for (auto& [entityID, object] : map)
{
if (SHComponentManager::HasComponent<SHRigidBodyComponent>(entityID))
reinterpret_cast<rp3d::RigidBody*>(object.rp3dBody)->setIsSleeping(false);
}
}
if (REMOVED_ID == COLLIDER_ID)
{
// Remove all colliders
for (uint32_t i = 0; i < physicsObject->rp3dBody->getNbColliders(); ++i)
{
auto* collider = physicsObject->rp3dBody->getCollider(i);
physicsObject->rp3dBody->removeCollider(collider);
}
}
if (physicsObject->rp3dBody == nullptr)
DestroyPhysicsObject(ENTITY_ID);
}
return EVENT_DATA->handle;
}
} // namespace SHADE

View File

@ -16,14 +16,14 @@
#include <reactphysics3d/reactphysics3d.h>
// Project Headers
#include "SHPhysicsObject.h"
#include "Components/SHRigidBodyComponent.h"
#include "Components/SHColliderComponent.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h"
#include "ECS_Base/System/SHSystemRoutine.h"
#include "ECS_Base/System/SHFixedSystemRoutine.h"
#include "Math/Transform/SHTransformComponent.h"
#include "Scene/SHSceneGraph.h"
#include "SHPhysicsObject.h"
namespace SHADE
@ -32,7 +32,7 @@ namespace SHADE
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
class SH_API SHPhysicsSystem : public SHSystem
class SH_API SHPhysicsSystem final : public SHSystem
{
public:
/*---------------------------------------------------------------------------------*/
@ -85,21 +85,10 @@ namespace SHADE
void Init () override;
void Exit () override;
void AddRigidBody (EntityID entityID) noexcept;
void AddCollider (EntityID entityID) noexcept;
void RemoveRigidBody (EntityID entityID) noexcept;
void RemoveCollider (EntityID entityID) noexcept;
void AddForce (EntityID entityID, const SHVec3& force) const noexcept;
void AddForceAtLocalPos (EntityID entityID, const SHVec3& force, const SHVec3& localPos) const noexcept;
void AddForceAtWorldPos (EntityID entityID, const SHVec3& force, const SHVec3& worldPos) const noexcept;
void AddRelativeForce (EntityID entityID, const SHVec3& relativeForce) const noexcept;
void AddRelativeForceAtLocalPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& localPos) const noexcept;
void AddRelativeForceAtWorldPos (EntityID entityID, const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept;
void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept;
void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept;
//void AddRigidBody (EntityID entityID) noexcept;
//void AddCollider (EntityID entityID) noexcept;
//void RemoveRigidBody (EntityID entityID) noexcept;
//void RemoveCollider (EntityID entityID) noexcept;
void AddCollisionShape (EntityID entityID, SHCollider* collider);
void RemoveCollisionShape (EntityID entityID, int index);
@ -108,10 +97,7 @@ namespace SHADE
/* System Routines */
/*---------------------------------------------------------------------------------*/
/**
* @brief Synchronises RP3D with SHADE
*/
class SH_API PhysicsPreUpdate : public SHSystemRoutine
class SH_API PhysicsPreUpdate final : public SHSystemRoutine
{
public:
/*-------------------------------------------------------------------------------*/
@ -127,7 +113,7 @@ namespace SHADE
void Execute(double dt) noexcept override;
};
class SH_API PhysicsFixedUpdate : public SHFixedSystemRoutine
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
{
public:
/*-------------------------------------------------------------------------------*/
@ -143,7 +129,7 @@ namespace SHADE
void Execute (double dt) noexcept override;
};
class SH_API PhysicsPostUpdate : public SHSystemRoutine
class SH_API PhysicsPostUpdate final : public SHSystemRoutine
{
public:
/*-------------------------------------------------------------------------------*/
@ -170,15 +156,14 @@ namespace SHADE
/* Data Members */
/*---------------------------------------------------------------------------------*/
// TODO(Diren): Store interpFactor
bool worldUpdated;
double interpolationFactor;
double fixedDT;
rp3d::PhysicsWorld* world;
rp3d::PhysicsWorld* world;
rp3d::PhysicsCommon factory;
EntityObjectMap map;
@ -186,7 +171,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* Function Members */
/*---------------------------------------------------------------------------------*/
SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
void DestroyPhysicsObject (EntityID entityID) noexcept;
@ -194,10 +179,9 @@ namespace SHADE
void SyncRigidBodyComponents (std::vector<SHRigidBodyComponent>& denseArray) noexcept;
void SyncColliderComponents (std::vector<SHColliderComponent>& denseArray) noexcept;
void SyncTransforms () noexcept;
// TODO(Diren): Trigger handling
// TODO(Diren): Remove when responsibility shifted to editor
SHTransformComponent* EnsureTransform (EntityID entityID);
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
};