Partial implementation of syncing SHADE and ReactPhysics active states
This commit is contained in:
parent
d36d70e3eb
commit
fe1b9d14f5
|
@ -223,9 +223,4 @@
|
||||||
Bounciness: 0
|
Bounciness: 0
|
||||||
Density: 1
|
Density: 1
|
||||||
Position Offset: {x: 0, y: 0.5, z: 0}
|
Position Offset: {x: 0, y: 0.5, z: 0}
|
||||||
Scripts:
|
Scripts: ~
|
||||||
- Type: Item
|
|
||||||
currCategory: 0
|
|
||||||
- Type: PickAndThrow
|
|
||||||
throwForce: [100, 200, 100]
|
|
||||||
item: 51000
|
|
|
@ -26,10 +26,11 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
|
SHPhysicsObject::SHPhysicsObject(EntityID eid, rp3d::PhysicsCommon* physicsFactory, rp3d::PhysicsWorld* physicsWorld) noexcept
|
||||||
: entityID { eid }
|
: entityID { eid }
|
||||||
, factory { physicsFactory }
|
, collidersActive { true }
|
||||||
, world { physicsWorld }
|
, factory { physicsFactory }
|
||||||
, rp3dBody { nullptr }
|
, world { physicsWorld }
|
||||||
|
, rp3dBody { nullptr }
|
||||||
{
|
{
|
||||||
// Implicitly create a static body.
|
// Implicitly create a static body.
|
||||||
|
|
||||||
|
|
|
@ -84,12 +84,13 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
EntityID entityID;
|
EntityID entityID;
|
||||||
|
bool collidersActive; // Only used to sync with SHADE components
|
||||||
|
|
||||||
rp3d::PhysicsCommon* factory;
|
rp3d::PhysicsCommon* factory;
|
||||||
rp3d::PhysicsWorld* world;
|
rp3d::PhysicsWorld* world;
|
||||||
|
|
||||||
rp3d::RigidBody* rp3dBody;
|
rp3d::RigidBody* rp3dBody;
|
||||||
rp3d::Transform prevTransform; // Cached transform for interpolation
|
rp3d::Transform prevTransform; // Cached transform for interpolation
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
/* Function Members */
|
/* Function Members */
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
#include "Graphics/MiddleEnd/Interface/SHDebugDrawSystem.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -122,6 +123,10 @@ namespace SHADE
|
||||||
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
|
const auto& COLLIDER_SET = SHComponentManager::GetDense<SHColliderComponent>();
|
||||||
for (const auto& COLLIDER : COLLIDER_SET)
|
for (const auto& COLLIDER : COLLIDER_SET)
|
||||||
{
|
{
|
||||||
|
// Skip inactive colliders
|
||||||
|
//if (!SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(COLLIDER.GetEID()))
|
||||||
|
// continue;
|
||||||
|
|
||||||
for (auto& collisionShape : COLLIDER.GetCollisionShapes())
|
for (auto& collisionShape : COLLIDER.GetCollisionShapes())
|
||||||
{
|
{
|
||||||
switch (collisionShape.GetType())
|
switch (collisionShape.GetType())
|
||||||
|
|
|
@ -387,7 +387,7 @@ namespace SHADE
|
||||||
, SHColliderComponent* colliderComponent
|
, SHColliderComponent* colliderComponent
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
if (!transformComponent)
|
if (!transformComponent || !SHSceneManager::CheckNodeAndComponentsActive<SHTransformComponent>(physicsObject.entityID))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
|
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
|
@ -397,13 +397,13 @@ namespace SHADE
|
||||||
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
|
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
|
||||||
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
|
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
|
||||||
|
|
||||||
if (rigidBodyComponent)
|
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
rigidBodyComponent->position = WORLD_POS;
|
rigidBodyComponent->position = WORLD_POS;
|
||||||
rigidBodyComponent->orientation = WORLD_ROT;
|
rigidBodyComponent->orientation = WORLD_ROT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colliderComponent)
|
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
colliderComponent->position = WORLD_POS;
|
colliderComponent->position = WORLD_POS;
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
@ -422,15 +422,16 @@ namespace SHADE
|
||||||
, double interpolationFactor
|
, double interpolationFactor
|
||||||
) noexcept
|
) noexcept
|
||||||
{
|
{
|
||||||
const rp3d::Transform& CURRENT_TF = physicsObject.rp3dBody->getTransform();
|
const rp3d::Transform& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
|
||||||
auto renderPos = CURRENT_TF.getPosition();
|
auto renderPos = CURRENT_TF.getPosition();
|
||||||
auto renderRot = CURRENT_TF.getOrientation();
|
auto renderRot = CURRENT_TF.getOrientation();
|
||||||
|
|
||||||
// Cache transforms
|
// Cache transforms
|
||||||
physicsObject.prevTransform = CURRENT_TF;
|
if (physicsObject.GetRigidBody()->isActive())
|
||||||
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
|
|
||||||
// Sync with rigid bodies
|
// Sync with rigid bodies
|
||||||
if (rigidBodyComponent)
|
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
// Skip static bodies
|
// Skip static bodies
|
||||||
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||||
|
@ -453,14 +454,14 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync with colliders
|
// Sync with colliders
|
||||||
if (colliderComponent)
|
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
colliderComponent->position = CURRENT_TF.getPosition();
|
colliderComponent->position = CURRENT_TF.getPosition();
|
||||||
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set transform for rendering
|
// Set transform for rendering
|
||||||
if (transformComponent)
|
if (transformComponent && SHSceneManager::CheckNodeAndComponentsActive<SHTransformComponent>(physicsObject.entityID))
|
||||||
{
|
{
|
||||||
transformComponent->SetWorldPosition(renderPos);
|
transformComponent->SetWorldPosition(renderPos);
|
||||||
transformComponent->SetWorldOrientation(renderRot);
|
transformComponent->SetWorldOrientation(renderRot);
|
||||||
|
|
|
@ -122,7 +122,9 @@ namespace SHADE
|
||||||
/* Function Members */
|
/* 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
|
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
#include "Scripting/SHScriptEngine.h"
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -43,65 +44,13 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||||
|
|
||||||
#ifdef SHEDITOR
|
#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)
|
|
||||||
{
|
|
||||||
physicsSystem->objectManager.UpdateCommands();
|
|
||||||
|
|
||||||
for (auto& [entityID, physicsObject] : physicsSystem->objectManager.physicsObjects)
|
|
||||||
{
|
|
||||||
// Ensure a valid physics Object
|
|
||||||
if (physicsObject.rp3dBody == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
syncOnPlay(entityID, physicsObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto& rigidBodyDense = SHComponentManager::GetDense<SHRigidBodyComponent>();
|
|
||||||
auto& colliderDense = SHComponentManager::GetDense<SHColliderComponent>();
|
|
||||||
|
|
||||||
for (auto& rigidBodyComponent : rigidBodyDense)
|
|
||||||
{
|
|
||||||
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(rigidBodyComponent.GetEID());
|
|
||||||
|
|
||||||
if (TRANSFORM && TRANSFORM->HasChanged())
|
|
||||||
{
|
|
||||||
rigidBodyComponent.position = TRANSFORM->GetWorldPosition();
|
|
||||||
rigidBodyComponent.orientation = TRANSFORM->GetWorldOrientation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& colliderComponent : colliderDense)
|
|
||||||
{
|
|
||||||
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(colliderComponent.GetEID());
|
|
||||||
|
|
||||||
if (TRANSFORM && TRANSFORM->HasChanged())
|
|
||||||
{
|
|
||||||
colliderComponent.position = TRANSFORM->GetWorldPosition();
|
|
||||||
colliderComponent.orientation = TRANSFORM->GetWorldOrientation();
|
|
||||||
colliderComponent.scale = TRANSFORM->GetWorldScale();
|
|
||||||
|
|
||||||
colliderComponent.RecomputeCollisionShapes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Always sync Rigid Body & Collider Components with Physics Objects
|
|
||||||
// Do not check for an editor here
|
|
||||||
|
|
||||||
|
// Only Sync on Play.
|
||||||
|
// Otherwise, Components are only holding data until the world is built on play.
|
||||||
|
const auto* EDITOR = SHSystemManager::GetSystem<SHEditor>();
|
||||||
|
if (EDITOR && EDITOR->editorState != SHEditor::State::STOP)
|
||||||
|
{
|
||||||
physicsSystem->objectManager.UpdateCommands();
|
physicsSystem->objectManager.UpdateCommands();
|
||||||
|
|
||||||
for (auto& [entityID, physicsObject] : physicsSystem->objectManager.physicsObjects)
|
for (auto& [entityID, physicsObject] : physicsSystem->objectManager.physicsObjects)
|
||||||
|
@ -110,10 +59,64 @@ namespace SHADE
|
||||||
if (physicsObject.rp3dBody == nullptr)
|
if (physicsObject.rp3dBody == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Sync active states between SHADE & RP3D
|
||||||
|
syncRigidBodyActive(entityID, physicsObject);
|
||||||
|
syncColliderActive(entityID, physicsObject);
|
||||||
|
|
||||||
syncOnPlay(entityID, physicsObject);
|
syncOnPlay(entityID, physicsObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto& rigidBodyDense = SHComponentManager::GetDense<SHRigidBodyComponent>();
|
||||||
|
auto& colliderDense = SHComponentManager::GetDense<SHColliderComponent>();
|
||||||
|
|
||||||
#endif
|
for (auto& rigidBodyComponent : rigidBodyDense)
|
||||||
|
{
|
||||||
|
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(rigidBodyComponent.GetEID());
|
||||||
|
|
||||||
|
if (TRANSFORM && TRANSFORM->HasChanged())
|
||||||
|
{
|
||||||
|
rigidBodyComponent.position = TRANSFORM->GetWorldPosition();
|
||||||
|
rigidBodyComponent.orientation = TRANSFORM->GetWorldOrientation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& colliderComponent : colliderDense)
|
||||||
|
{
|
||||||
|
const auto* TRANSFORM = SHComponentManager::GetComponent_s<SHTransformComponent>(colliderComponent.GetEID());
|
||||||
|
|
||||||
|
if (TRANSFORM && TRANSFORM->HasChanged())
|
||||||
|
{
|
||||||
|
colliderComponent.position = TRANSFORM->GetWorldPosition();
|
||||||
|
colliderComponent.orientation = TRANSFORM->GetWorldOrientation();
|
||||||
|
colliderComponent.scale = TRANSFORM->GetWorldScale();
|
||||||
|
|
||||||
|
colliderComponent.RecomputeCollisionShapes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Always sync Rigid Body & Collider Components with Physics Objects
|
||||||
|
// Do not check for an editor here
|
||||||
|
|
||||||
|
physicsSystem->objectManager.UpdateCommands();
|
||||||
|
|
||||||
|
for (auto& [entityID, physicsObject] : physicsSystem->objectManager.physicsObjects)
|
||||||
|
{
|
||||||
|
// Ensure a valid physics Object
|
||||||
|
if (physicsObject.rp3dBody == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
syncRigidBodyActive(entityID, physicsObject);
|
||||||
|
syncColliderActive(entityID, physicsObject);
|
||||||
|
|
||||||
|
syncOnPlay(entityID, physicsObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
void SHPhysicsSystem::PhysicsFixedUpdate::Execute(double dt) noexcept
|
||||||
|
@ -188,6 +191,48 @@ namespace SHADE
|
||||||
/* Private Function Member Definitions */
|
/* 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
|
void SHPhysicsSystem::PhysicsPreUpdate::syncOnPlay(EntityID eid, SHPhysicsObject& physicsObject) noexcept
|
||||||
{
|
{
|
||||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(eid);
|
||||||
|
|
Loading…
Reference in New Issue