Partial implementation of syncing SHADE and ReactPhysics active states

This commit is contained in:
Diren D Bharwani 2022-11-14 00:25:24 +08:00
parent d36d70e3eb
commit fe1b9d14f5
7 changed files with 129 additions and 79 deletions

View File

@ -223,9 +223,4 @@
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0.5, z: 0}
Scripts:
- Type: Item
currCategory: 0
- Type: PickAndThrow
throwForce: [100, 200, 100]
item: 51000
Scripts: ~

View File

@ -27,6 +27,7 @@ namespace SHADE
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
: entityID { eid }
, collidersActive { true }
, factory { physicsFactory }
, world { physicsWorld }
, rp3dBody { nullptr }

View File

@ -84,6 +84,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
EntityID entityID;
bool collidersActive; // Only used to sync with SHADE components
rp3d::PhysicsCommon* factory;
rp3d::PhysicsWorld* world;

View File

@ -16,6 +16,7 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
#include "Scene/SHSceneManager.h"
namespace SHADE
{
@ -122,6 +123,10 @@ namespace SHADE
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
for (const auto& COLLIDER : COLLIDER_SET)
{
// Skip inactive colliders
//if (!SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(COLLIDER.GetEID()))
// continue;
for (auto& collisionShape : COLLIDER.GetCollisionShapes())
{
switch (collisionShape.GetType())

View File

@ -387,7 +387,7 @@ namespace SHADE
, SHColliderComponent* colliderComponent
) noexcept
{
if (!transformComponent)
if (!transformComponent || !SHSceneManager::CheckNodeAndComponentsActive<SHTransformComponent>(physicsObject.entityID))
return;
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
@ -397,13 +397,13 @@ namespace SHADE
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
if (rigidBodyComponent)
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
rigidBodyComponent->position = WORLD_POS;
rigidBodyComponent->orientation = WORLD_ROT;
}
if (colliderComponent)
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = WORLD_POS;
colliderComponent->orientation = WORLD_ROT;
@ -422,15 +422,16 @@ namespace SHADE
, double interpolationFactor
) noexcept
{
const rp3d::Transform& CURRENT_TF = physicsObject.rp3dBody->getTransform();
const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
auto renderPos = CURRENT_TF.getPosition();
auto renderRot = CURRENT_TF.getOrientation();
// Cache transforms
if (physicsObject.GetRigidBody()->isActive())
physicsObject.prevTransform = CURRENT_TF;
// Sync with rigid bodies
if (rigidBodyComponent)
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
{
// Skip static bodies
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
@ -453,14 +454,14 @@ namespace SHADE
}
// Sync with colliders
if (colliderComponent)
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
{
colliderComponent->position = CURRENT_TF.getPosition();
colliderComponent->orientation = CURRENT_TF.getOrientation();
}
// Set transform for rendering
if (transformComponent)
if (transformComponent && SHSceneManager::CheckNodeAndComponentsActive<SHTransformComponent>(physicsObject.entityID))
{
transformComponent->SetWorldPosition(renderPos);
transformComponent->SetWorldOrientation(renderRot);

View File

@ -122,7 +122,9 @@ namespace SHADE
/* Function Members */
/*-------------------------------------------------------------------------------*/
static void syncOnPlay(EntityID eid, SHPhysicsObject& physicsObject) noexcept;
void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
static void syncOnPlay (EntityID eid, SHPhysicsObject& physicsObject) noexcept;
};
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine

View File

@ -15,6 +15,7 @@
// Project Headers
#include "ECS_Base/Managers/SHSystemManager.h"
#include "Editor/SHEditor.h"
#include "Scene/SHSceneManager.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE
@ -45,14 +46,10 @@ namespace SHADE
#ifdef SHEDITOR
auto* editor = SHSystemManager::GetSystem<SHEditor>();
// Only Sync on Play.
// Otherwise, Components are only holding data until the world is built on play.
if (editor)
{
if (editor->editorState != SHEditor::State::STOP)
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
{
physicsSystem->objectManager.UpdateCommands();
@ -62,6 +59,10 @@ namespace SHADE
if (physicsObject.rp3dBody == nullptr)
continue;
// Sync active states between SHADE & RP3D
syncRigidBodyActive(entityID, physicsObject);
syncColliderActive(entityID, physicsObject);
syncOnPlay(entityID, physicsObject);
}
}
@ -95,7 +96,6 @@ namespace SHADE
}
}
}
}
#else
@ -110,6 +110,9 @@ namespace SHADE
if (physicsObject.rp3dBody == nullptr)
continue;
syncRigidBodyActive(entityID, physicsObject);
syncColliderActive(entityID, physicsObject);
syncOnPlay(entityID, physicsObject);
}
@ -188,6 +191,48 @@ namespace SHADE
/* Private Function Member Definitions */
/*-----------------------------------------------------------------------------------*/
void SHPhysicsSystem::PhysicsPreUpdate::syncRigidBodyActive(EntityID eid, SHPhysicsObject& physicsObject) const noexcept
{
if (!SHComponentManager::HasComponent<SHRigidBodyComponent>(eid))
return;
const bool IS_ACTIVE_IN_SCENE = SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(eid);
const bool IS_RP3D_BODY_ACTIVE = physicsObject.GetRigidBody()->isActive();
if (IS_ACTIVE_IN_SCENE != IS_RP3D_BODY_ACTIVE)
physicsObject.GetRigidBody()->setIsActive(IS_ACTIVE_IN_SCENE);
}
void SHPhysicsSystem::PhysicsPreUpdate::syncColliderActive(EntityID eid, SHPhysicsObject& physicsObject) const noexcept
{
const auto* COLLIDER = SHComponentManager::GetComponent_s<SHColliderComponent>(eid);
if (!COLLIDER)
return;
const bool IS_ACTIVE_IN_SCENE = SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(eid);
const bool IS_RP3D_COLLIDER_ACTIVE = physicsObject.collidersActive;
if (IS_ACTIVE_IN_SCENE != IS_RP3D_COLLIDER_ACTIVE)
{
// HACK: If active state turned off, remove all collision shapes. If turned on, add them back.
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
const int NUM_SHAPES = static_cast<int>(COLLIDER->GetCollisionShapes().size());
if (IS_ACTIVE_IN_SCENE)
{
for (int i = 0; i < NUM_SHAPES; ++i)
physicsSystem->objectManager.AddCollisionShape(eid, i);
}
else
{
for (int i = NUM_SHAPES - 1; i >= 0; --i)
physicsSystem->objectManager.RemoveCollisionShape(eid, i);
}
physicsObject.collidersActive = IS_ACTIVE_IN_SCENE;
}
}
void SHPhysicsSystem::PhysicsPreUpdate::syncOnPlay(EntityID eid, SHPhysicsObject& physicsObject) noexcept
{
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);