Added a forced update to the physics system
This commit is contained in:
parent
c98693c6bc
commit
d36d70e3eb
|
@ -16,6 +16,7 @@
|
||||||
// Project Headers
|
// Project Headers
|
||||||
#include "ECS_Base/Managers/SHSystemManager.h"
|
#include "ECS_Base/Managers/SHSystemManager.h"
|
||||||
#include "ECS_Base/Managers/SHComponentManager.h"
|
#include "ECS_Base/Managers/SHComponentManager.h"
|
||||||
|
#include "Scene/SHSceneManager.h"
|
||||||
|
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
|
@ -148,6 +149,10 @@ namespace SHADE
|
||||||
|
|
||||||
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent& component) const noexcept
|
void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent& component) const noexcept
|
||||||
{
|
{
|
||||||
|
// This state is synced in the pre-update routine
|
||||||
|
if (!rp3dBody->isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
if (component.dirtyFlags == 0)
|
if (component.dirtyFlags == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -267,6 +272,10 @@ namespace SHADE
|
||||||
|
|
||||||
void SHPhysicsObject::SyncColliders(SHColliderComponent& component) const noexcept
|
void SHPhysicsObject::SyncColliders(SHColliderComponent& component) const noexcept
|
||||||
{
|
{
|
||||||
|
// This state is synced in the pre-update routine
|
||||||
|
if (!rp3dBody->isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto& collisionShape : component.collisionShapes)
|
for (auto& collisionShape : component.collisionShapes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,6 +167,7 @@ namespace SHADE
|
||||||
if (!COMPONENT_GROUP.rigidBodyComponent && !COMPONENT_GROUP.colliderComponent)
|
if (!COMPONENT_GROUP.rigidBodyComponent && !COMPONENT_GROUP.colliderComponent)
|
||||||
{
|
{
|
||||||
destroyPhysicsObject(COMMAND.eid);
|
destroyPhysicsObject(COMMAND.eid);
|
||||||
|
wakeAllObjects();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +177,10 @@ namespace SHADE
|
||||||
physicsObject = createPhysicsObject(COMMAND.eid);
|
physicsObject = createPhysicsObject(COMMAND.eid);
|
||||||
|
|
||||||
componentFunc[SHUtilities::ConvertEnum(COMMAND.command)][SHUtilities::ConvertEnum(COMMAND.component)](COMMAND, physicsObject, COMPONENT_GROUP);
|
componentFunc[SHUtilities::ConvertEnum(COMMAND.command)][SHUtilities::ConvertEnum(COMMAND.component)](COMMAND, physicsObject, COMPONENT_GROUP);
|
||||||
|
|
||||||
|
// If any removal was done, wake all objects
|
||||||
|
if (COMMAND.command == QueueCommand::Command::REMOVE)
|
||||||
|
wakeAllObjects();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,5 +302,11 @@ namespace SHADE
|
||||||
physicsObject->RemoveCollisionShape(command.shapeIndex);
|
physicsObject->RemoveCollisionShape(command.shapeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsObjectManager::wakeAllObjects() noexcept
|
||||||
|
{
|
||||||
|
for (auto& physicsObject : physicsObjects | std::views::values)
|
||||||
|
physicsObject.GetRigidBody()->setIsSleeping(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -165,6 +165,8 @@ namespace SHADE
|
||||||
SHPhysicsObject* createPhysicsObject (EntityID eid) noexcept;
|
SHPhysicsObject* createPhysicsObject (EntityID eid) noexcept;
|
||||||
void destroyPhysicsObject (EntityID eid) noexcept;
|
void destroyPhysicsObject (EntityID eid) noexcept;
|
||||||
|
|
||||||
|
void wakeAllObjects () noexcept;
|
||||||
|
|
||||||
static void addRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
static void addRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
||||||
static void addCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
static void addCollider (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
||||||
static void removeRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
static void removeRigidBody (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
||||||
|
@ -172,6 +174,8 @@ namespace SHADE
|
||||||
|
|
||||||
static void addCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
static void addCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
||||||
static void removeCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
static void removeCollisionShape (const QueueCommand& command, SHPhysicsObject* physicsObject, const PhysicsComponentGroup& componentGroup);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Editor/SHEditor.h"
|
#include "Editor/SHEditor.h"
|
||||||
#include "Physics/SHPhysicsEvents.h"
|
#include "Physics/SHPhysicsEvents.h"
|
||||||
#include "Scene/SHSceneManager.h"
|
#include "Scene/SHSceneManager.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------*/
|
||||||
/* Local Helper Functions */
|
/* Local Helper Functions */
|
||||||
|
@ -34,16 +35,16 @@ namespace SHADE
|
||||||
SHPhysicsSystem::SHPhysicsSystem()
|
SHPhysicsSystem::SHPhysicsSystem()
|
||||||
: worldUpdated { false }
|
: worldUpdated { false }
|
||||||
, interpolationFactor { 0.0 }
|
, interpolationFactor { 0.0 }
|
||||||
, fixedDT { 60.0 }
|
, fixedDT { DEFAULT_FIXED_STEP }
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Getter Function Definitions */
|
/* Getter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
double SHPhysicsSystem::GetFixedDT() const noexcept
|
double SHPhysicsSystem::GetFixedUpdateRate() const noexcept
|
||||||
{
|
{
|
||||||
return fixedDT;
|
return 1.0 / fixedDT;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SHPhysicsWorldState::WorldSettings& SHPhysicsSystem::GetWorldSettings() const noexcept
|
const SHPhysicsWorldState::WorldSettings& SHPhysicsSystem::GetWorldSettings() const noexcept
|
||||||
|
@ -76,9 +77,9 @@ namespace SHADE
|
||||||
/* Setter Function Definitions */
|
/* Setter Function Definitions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SHPhysicsSystem::SetFixedDT(double fixedUpdateRate) noexcept
|
void SHPhysicsSystem::SetFixedUpdateRate(double fixedUpdateRate) noexcept
|
||||||
{
|
{
|
||||||
fixedDT = fixedUpdateRate;
|
fixedDT = 1.0 / fixedUpdateRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::SetWorldSettings(const SHPhysicsWorldState::WorldSettings& settings) noexcept
|
void SHPhysicsSystem::SetWorldSettings(const SHPhysicsWorldState::WorldSettings& settings) noexcept
|
||||||
|
@ -126,6 +127,45 @@ namespace SHADE
|
||||||
worldState.DestroyWorld(factory);
|
worldState.DestroyWorld(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::ForceUpdate()
|
||||||
|
{
|
||||||
|
if (!worldState.world)
|
||||||
|
{
|
||||||
|
SHLOGV_ERROR("Unable to force update without a Physics world!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* scriptingSystem = SHSystemManager::GetSystem<SHScriptEngine>();
|
||||||
|
if (scriptingSystem == nullptr)
|
||||||
|
{
|
||||||
|
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force the physics world to update once
|
||||||
|
if (scriptingSystem != nullptr)
|
||||||
|
scriptingSystem->ExecuteFixedUpdates();
|
||||||
|
|
||||||
|
worldState.world->update(static_cast<rp3d::decimal>(fixedDT));
|
||||||
|
|
||||||
|
// Sync transforms. No interpolation applied here
|
||||||
|
for (auto& [entityID, physicsObject] : objectManager.physicsObjects)
|
||||||
|
{
|
||||||
|
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||||
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||||
|
|
||||||
|
postUpdateSyncTransforms
|
||||||
|
(
|
||||||
|
physicsObject
|
||||||
|
, transformComponent
|
||||||
|
, rigidBodyComponent
|
||||||
|
, colliderComponent
|
||||||
|
, 1.0 // We use 1.0 here to avoid any interpolation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHPhysicsSystem::AddCollisionShape(EntityID eid, int shapeIndex)
|
void SHPhysicsSystem::AddCollisionShape(EntityID eid, int shapeIndex)
|
||||||
{
|
{
|
||||||
static const auto ADD_SHAPE = [&](EntityID entityID, int index)
|
static const auto ADD_SHAPE = [&](EntityID entityID, int index)
|
||||||
|
@ -339,5 +379,92 @@ namespace SHADE
|
||||||
return onStopEvent->handle;
|
return onStopEvent->handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::preUpdateSyncTransform
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
) noexcept
|
||||||
|
{
|
||||||
|
if (!transformComponent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const SHVec3& WORLD_POS = transformComponent->GetWorldPosition();
|
||||||
|
const SHQuaternion& WORLD_ROT = transformComponent->GetWorldOrientation();
|
||||||
|
const SHVec3& WORLD_SCL = transformComponent->GetWorldScale();
|
||||||
|
|
||||||
|
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
|
||||||
|
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
|
||||||
|
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
{
|
||||||
|
rigidBodyComponent->position = WORLD_POS;
|
||||||
|
rigidBodyComponent->orientation = WORLD_ROT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colliderComponent)
|
||||||
|
{
|
||||||
|
colliderComponent->position = WORLD_POS;
|
||||||
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
colliderComponent->scale = WORLD_SCL;
|
||||||
|
|
||||||
|
colliderComponent->RecomputeCollisionShapes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::postUpdateSyncTransforms
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
, double interpolationFactor
|
||||||
|
) noexcept
|
||||||
|
{
|
||||||
|
const rp3d::Transform& CURRENT_TF = physicsObject.rp3dBody->getTransform();
|
||||||
|
auto renderPos = CURRENT_TF.getPosition();
|
||||||
|
auto renderRot = CURRENT_TF.getOrientation();
|
||||||
|
|
||||||
|
// Cache transforms
|
||||||
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
|
|
||||||
|
// Sync with rigid bodies
|
||||||
|
if (rigidBodyComponent)
|
||||||
|
{
|
||||||
|
// Skip static bodies
|
||||||
|
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check if transform should be interpolated
|
||||||
|
if (rigidBodyComponent->IsInterpolating())
|
||||||
|
{
|
||||||
|
// Interpolate transforms between current and predicted next transform
|
||||||
|
|
||||||
|
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
|
||||||
|
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
|
||||||
|
|
||||||
|
renderPos = INTERPOLATED_TF.getPosition();
|
||||||
|
renderRot = INTERPOLATED_TF.getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
rigidBodyComponent->position = CURRENT_TF.getPosition();
|
||||||
|
rigidBodyComponent->orientation = CURRENT_TF.getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync with colliders
|
||||||
|
if (colliderComponent)
|
||||||
|
{
|
||||||
|
colliderComponent->position = CURRENT_TF.getPosition();
|
||||||
|
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set transform for rendering
|
||||||
|
if (transformComponent)
|
||||||
|
{
|
||||||
|
transformComponent->SetWorldPosition(renderPos);
|
||||||
|
transformComponent->SetWorldOrientation(renderRot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -55,7 +55,7 @@ namespace SHADE
|
||||||
/* Getter Functions */
|
/* Getter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
[[nodiscard]] double GetFixedDT () const noexcept;
|
[[nodiscard]] double GetFixedUpdateRate () const noexcept;
|
||||||
[[nodiscard]] const SHPhysicsWorldState::WorldSettings& GetWorldSettings () const noexcept;
|
[[nodiscard]] const SHPhysicsWorldState::WorldSettings& GetWorldSettings () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] const std::vector<SHCollisionInfo>& GetAllCollisionInfo () const noexcept;
|
[[nodiscard]] const std::vector<SHCollisionInfo>& GetAllCollisionInfo () const noexcept;
|
||||||
|
@ -67,7 +67,7 @@ namespace SHADE
|
||||||
/* Setter Functions */
|
/* Setter Functions */
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void SetFixedDT (double fixedUpdateRate) noexcept;
|
void SetFixedUpdateRate (double fixedUpdateRate) noexcept;
|
||||||
void SetWorldSettings (const SHPhysicsWorldState::WorldSettings& settings) noexcept;
|
void SetWorldSettings (const SHPhysicsWorldState::WorldSettings& settings) noexcept;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
@ -77,6 +77,8 @@ namespace SHADE
|
||||||
void Init () override;
|
void Init () override;
|
||||||
void Exit () override;
|
void Exit () override;
|
||||||
|
|
||||||
|
void ForceUpdate ();
|
||||||
|
|
||||||
// Specific Handling for Collision Shapes as they are not under the Component System
|
// Specific Handling for Collision Shapes as they are not under the Component System
|
||||||
|
|
||||||
void AddCollisionShape (EntityID eid, int shapeIndex);
|
void AddCollisionShape (EntityID eid, int shapeIndex);
|
||||||
|
@ -121,14 +123,6 @@ namespace SHADE
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void syncOnPlay(EntityID eid, SHPhysicsObject& physicsObject) noexcept;
|
static void syncOnPlay(EntityID eid, SHPhysicsObject& physicsObject) noexcept;
|
||||||
|
|
||||||
static void preUpdateSyncTransform
|
|
||||||
(
|
|
||||||
SHPhysicsObject& physicsObject
|
|
||||||
, SHTransformComponent& transformComponent
|
|
||||||
, SHRigidBodyComponent* rigidBodyComponent
|
|
||||||
, SHColliderComponent* colliderComponent
|
|
||||||
) noexcept;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
||||||
|
@ -161,20 +155,6 @@ namespace SHADE
|
||||||
/*-------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void Execute(double dt) noexcept override;
|
void Execute(double dt) noexcept override;
|
||||||
|
|
||||||
private:
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
/* Function Members */
|
|
||||||
/*-------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void postUpdateSyncTransforms
|
|
||||||
(
|
|
||||||
SHPhysicsObject& physicsObject
|
|
||||||
, SHTransformComponent& transformComponent
|
|
||||||
, SHRigidBodyComponent* rigidBodyComponent
|
|
||||||
, SHColliderComponent* colliderComponent
|
|
||||||
, double interpolationFactor
|
|
||||||
) noexcept;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -208,5 +188,24 @@ namespace SHADE
|
||||||
SHEventHandle onPlay (SHEventPtr onPlayEvent);
|
SHEventHandle onPlay (SHEventPtr onPlayEvent);
|
||||||
SHEventHandle onStop (SHEventPtr onStopEvent);
|
SHEventHandle onStop (SHEventPtr onStopEvent);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void preUpdateSyncTransform
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
|
static void postUpdateSyncTransforms
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
, double interpolationFactor
|
||||||
|
) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
|
@ -55,7 +55,7 @@ namespace SHADE
|
||||||
auto phySystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
auto phySystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
|
||||||
if (phySystem)
|
if (phySystem)
|
||||||
{
|
{
|
||||||
return phySystem->GetFixedDT();
|
return phySystem->GetFixedUpdateRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get fixed delta time. 0.0 returned instead.");
|
SHLOG_WARNING("[SHPhysicsSystemInterface] Failed to get fixed delta time. 0.0 returned instead.");
|
||||||
|
|
|
@ -125,18 +125,18 @@ namespace SHADE
|
||||||
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
SHLOGV_ERROR("Unable to invoke FixedUpdate() on scripts due to missing SHScriptEngine!");
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedTimeStep = 1.0 / physicsSystem->fixedDT;
|
const double FIXED_DT = physicsSystem->fixedDT;
|
||||||
accumulatedTime += dt;
|
accumulatedTime += dt;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (accumulatedTime > fixedTimeStep)
|
while (accumulatedTime > FIXED_DT)
|
||||||
{
|
{
|
||||||
if (scriptingSystem != nullptr)
|
if (scriptingSystem != nullptr)
|
||||||
scriptingSystem->ExecuteFixedUpdates();
|
scriptingSystem->ExecuteFixedUpdates();
|
||||||
|
|
||||||
physicsSystem->worldState.world->update(static_cast<rp3d::decimal>(fixedTimeStep));
|
physicsSystem->worldState.world->update(static_cast<rp3d::decimal>(FIXED_DT));
|
||||||
|
|
||||||
accumulatedTime -= fixedTimeStep;
|
accumulatedTime -= FIXED_DT;
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,18 +165,15 @@ namespace SHADE
|
||||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||||
|
|
||||||
if (transformComponent)
|
|
||||||
{
|
|
||||||
postUpdateSyncTransforms
|
postUpdateSyncTransforms
|
||||||
(
|
(
|
||||||
physicsObject
|
physicsObject
|
||||||
, *transformComponent
|
, transformComponent
|
||||||
, rigidBodyComponent
|
, rigidBodyComponent
|
||||||
, colliderComponent
|
, colliderComponent
|
||||||
, physicsSystem->interpolationFactor
|
, physicsSystem->interpolationFactor
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Collision & Trigger messages
|
// Collision & Trigger messages
|
||||||
if (scriptingSystem != nullptr)
|
if (scriptingSystem != nullptr)
|
||||||
|
@ -203,7 +200,7 @@ namespace SHADE
|
||||||
preUpdateSyncTransform
|
preUpdateSyncTransform
|
||||||
(
|
(
|
||||||
physicsObject
|
physicsObject
|
||||||
, *transformComponent
|
, transformComponent
|
||||||
, rigidBodyComponent
|
, rigidBodyComponent
|
||||||
, colliderComponent
|
, colliderComponent
|
||||||
);
|
);
|
||||||
|
@ -217,99 +214,4 @@ namespace SHADE
|
||||||
if (colliderComponent)
|
if (colliderComponent)
|
||||||
physicsObject.SyncColliders(*colliderComponent);
|
physicsObject.SyncColliders(*colliderComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsPreUpdate::preUpdateSyncTransform
|
|
||||||
(
|
|
||||||
SHPhysicsObject& physicsObject
|
|
||||||
, SHTransformComponent& transformComponent
|
|
||||||
, SHRigidBodyComponent* rigidBodyComponent
|
|
||||||
, SHColliderComponent* colliderComponent
|
|
||||||
) noexcept
|
|
||||||
{
|
|
||||||
const SHVec3& WORLD_POS = transformComponent.GetWorldPosition();
|
|
||||||
const SHQuaternion& WORLD_ROT = transformComponent.GetWorldOrientation();
|
|
||||||
const SHVec3& WORLD_SCL = transformComponent.GetWorldScale();
|
|
||||||
|
|
||||||
const rp3d::Transform RP3D_TRANSFORM { WORLD_POS, WORLD_ROT };
|
|
||||||
physicsObject.GetRigidBody()->setTransform(RP3D_TRANSFORM);
|
|
||||||
|
|
||||||
if (rigidBodyComponent)
|
|
||||||
{
|
|
||||||
rigidBodyComponent->position = WORLD_POS;
|
|
||||||
rigidBodyComponent->orientation = WORLD_ROT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colliderComponent)
|
|
||||||
{
|
|
||||||
colliderComponent->position = WORLD_POS;
|
|
||||||
colliderComponent->orientation = WORLD_ROT;
|
|
||||||
colliderComponent->scale = WORLD_SCL;
|
|
||||||
|
|
||||||
colliderComponent->RecomputeCollisionShapes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SHPhysicsSystem::PhysicsPostUpdate::postUpdateSyncTransforms
|
|
||||||
(
|
|
||||||
SHPhysicsObject& physicsObject
|
|
||||||
, SHTransformComponent& transformComponent
|
|
||||||
, SHRigidBodyComponent* rigidBodyComponent
|
|
||||||
, SHColliderComponent* colliderComponent
|
|
||||||
, double interpolationFactor
|
|
||||||
) noexcept
|
|
||||||
{
|
|
||||||
rp3d::Vector3 rp3dPos;
|
|
||||||
rp3d::Quaternion rp3dRot;
|
|
||||||
|
|
||||||
const rp3d::Transform CURRENT_TF = physicsObject.rp3dBody->getTransform();
|
|
||||||
|
|
||||||
// Check if transform should be interpolated
|
|
||||||
|
|
||||||
if (rigidBodyComponent)
|
|
||||||
{
|
|
||||||
// Skip static bodies
|
|
||||||
if (rigidBodyComponent->GetType() == SHRigidBodyComponent::Type::STATIC)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (rigidBodyComponent->IsInterpolating())
|
|
||||||
{
|
|
||||||
// Interpolate transforms between current and predicted next transform
|
|
||||||
|
|
||||||
const rp3d::Transform PREV_TF = physicsObject.prevTransform;
|
|
||||||
const rp3d::Transform INTERPOLATED_TF = rp3d::Transform::interpolateTransforms(PREV_TF, CURRENT_TF, static_cast<rp3d::decimal>(interpolationFactor));
|
|
||||||
|
|
||||||
rp3dPos = INTERPOLATED_TF.getPosition();
|
|
||||||
rp3dRot = INTERPOLATED_TF.getOrientation();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rp3dPos = CURRENT_TF.getPosition();
|
|
||||||
rp3dRot = CURRENT_TF.getOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
rigidBodyComponent->position = CURRENT_TF.getPosition();
|
|
||||||
rigidBodyComponent->orientation = CURRENT_TF.getOrientation();
|
|
||||||
|
|
||||||
if (colliderComponent)
|
|
||||||
{
|
|
||||||
// Sync with colliders
|
|
||||||
|
|
||||||
colliderComponent->position = CURRENT_TF.getPosition();
|
|
||||||
colliderComponent->orientation = CURRENT_TF.getOrientation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rp3dPos = CURRENT_TF.getPosition();
|
|
||||||
rp3dRot = CURRENT_TF.getOrientation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert RP3D Transform to SHADE
|
|
||||||
transformComponent.SetWorldPosition(rp3dPos);
|
|
||||||
transformComponent.SetWorldOrientation(rp3dRot);
|
|
||||||
|
|
||||||
// Cache transforms
|
|
||||||
physicsObject.prevTransform = CURRENT_TF;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace SHADE
|
} // namespace SHADE
|
Loading…
Reference in New Issue