Fixed various Physics bugs #217
|
@ -29,7 +29,6 @@ namespace SHADE
|
||||||
|
|
||||||
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
SHRigidBodyComponent::SHRigidBodyComponent() noexcept
|
||||||
: type { Type::DYNAMIC }
|
: type { Type::DYNAMIC }
|
||||||
, interpolate { true }
|
|
||||||
, flags { 0 }
|
, flags { 0 }
|
||||||
, dirtyFlags { std::numeric_limits<uint16_t>::max() }
|
, dirtyFlags { std::numeric_limits<uint16_t>::max() }
|
||||||
, mass { 1.0f }
|
, mass { 1.0f }
|
||||||
|
@ -40,6 +39,7 @@ namespace SHADE
|
||||||
// Initialise default flags
|
// Initialise default flags
|
||||||
flags |= 1U << 0; // Gravity set to true
|
flags |= 1U << 0; // Gravity set to true
|
||||||
flags |= 1U << 1; // Sleeping allowed
|
flags |= 1U << 1; // Sleeping allowed
|
||||||
|
flags |= 1U << 8; // Interpolate by default
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -60,7 +60,16 @@ namespace SHADE
|
||||||
|
|
||||||
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
bool SHRigidBodyComponent::IsInterpolating() const noexcept
|
||||||
{
|
{
|
||||||
return interpolate;
|
static constexpr int FLAG_POS = 8;
|
||||||
|
return flags & (1U << FLAG_POS);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SHRigidBodyComponent::GetIsSleeping() const noexcept
|
||||||
|
{
|
||||||
|
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
|
||||||
|
return physicsObject->GetRigidBody()->isSleeping();
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept
|
SHRigidBodyComponent::Type SHRigidBodyComponent::GetType() const noexcept
|
||||||
|
@ -68,21 +77,6 @@ namespace SHADE
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetMass() const noexcept
|
|
||||||
{
|
|
||||||
return mass;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetDrag() const noexcept
|
|
||||||
{
|
|
||||||
return drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
|
||||||
{
|
|
||||||
return angularDrag;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
bool SHRigidBodyComponent::GetFreezePositionX() const noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 2;
|
static constexpr int FLAG_POS = 2;
|
||||||
|
@ -119,6 +113,27 @@ namespace SHADE
|
||||||
return flags & (1U << FLAG_POS);
|
return flags & (1U << FLAG_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SHRigidBodyComponent::GetAutoMass() const noexcept
|
||||||
|
{
|
||||||
|
static constexpr int FLAG_POS = 9;
|
||||||
|
return flags & (1U << FLAG_POS);
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHRigidBodyComponent::GetMass() const noexcept
|
||||||
|
{
|
||||||
|
return mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHRigidBodyComponent::GetDrag() const noexcept
|
||||||
|
{
|
||||||
|
return drag;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SHRigidBodyComponent::GetAngularDrag() const noexcept
|
||||||
|
{
|
||||||
|
return angularDrag;
|
||||||
|
}
|
||||||
|
|
||||||
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
|
SHVec3 SHRigidBodyComponent::GetForce() const noexcept
|
||||||
{
|
{
|
||||||
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
|
if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject)
|
||||||
|
@ -295,9 +310,19 @@ namespace SHADE
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
void SHRigidBodyComponent::SetInterpolate(bool allowInterpolation) noexcept
|
||||||
{
|
{
|
||||||
interpolate = allowInterpolation;
|
static constexpr int FLAG_POS = 8;
|
||||||
|
allowInterpolation ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHRigidBodyComponent::SetAutoMass(bool autoMass) noexcept
|
||||||
|
{
|
||||||
|
static constexpr int FLAG_POS = 9;
|
||||||
|
autoMass ? flags |= 1U << FLAG_POS : flags &= ~(1U << FLAG_POS);
|
||||||
|
|
||||||
|
dirtyFlags |= 1U << FLAG_POS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetMass(float newMass) noexcept
|
void SHRigidBodyComponent::SetMass(float newMass) noexcept
|
||||||
{
|
{
|
||||||
static constexpr int FLAG_POS = 9;
|
static constexpr int FLAG_POS = 9;
|
||||||
|
@ -313,6 +338,9 @@ namespace SHADE
|
||||||
|
|
||||||
dirtyFlags |= 1U << FLAG_POS;
|
dirtyFlags |= 1U << FLAG_POS;
|
||||||
mass = newMass;
|
mass = newMass;
|
||||||
|
|
||||||
|
// Turn off automass
|
||||||
|
flags &= ~(1U << FLAG_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
void SHRigidBodyComponent::SetDrag(float newDrag) noexcept
|
||||||
|
@ -467,6 +495,8 @@ RTTR_REGISTRATION
|
||||||
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
|
.property("Angular Drag" , &SHRigidBodyComponent::GetAngularDrag , &SHRigidBodyComponent::SetAngularDrag )
|
||||||
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
|
.property("Use Gravity" , &SHRigidBodyComponent::IsGravityEnabled , &SHRigidBodyComponent::SetGravityEnabled )
|
||||||
.property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate )
|
.property("Interpolate" , &SHRigidBodyComponent::IsInterpolating , &SHRigidBodyComponent::SetInterpolate )
|
||||||
|
.property("Sleeping Enabled" , &SHRigidBodyComponent::IsAllowedToSleep , &SHRigidBodyComponent::SetIsAllowedToSleep)
|
||||||
|
.property("Auto Mass" , &SHRigidBodyComponent::GetAutoMass , &SHRigidBodyComponent::SetAutoMass )
|
||||||
.property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX )
|
.property("Freeze Position X" , &SHRigidBodyComponent::GetFreezePositionX , &SHRigidBodyComponent::SetFreezePositionX )
|
||||||
.property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY )
|
.property("Freeze Position Y" , &SHRigidBodyComponent::GetFreezePositionY , &SHRigidBodyComponent::SetFreezePositionY )
|
||||||
.property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ )
|
.property("Freeze Position Z" , &SHRigidBodyComponent::GetFreezePositionZ , &SHRigidBodyComponent::SetFreezePositionZ )
|
||||||
|
|
|
@ -71,19 +71,23 @@ namespace SHADE
|
||||||
[[nodiscard]] bool IsAllowedToSleep () const noexcept;
|
[[nodiscard]] bool IsAllowedToSleep () const noexcept;
|
||||||
[[nodiscard]] bool IsInterpolating () const noexcept;
|
[[nodiscard]] bool IsInterpolating () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool GetIsSleeping () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] Type GetType () const noexcept;
|
[[nodiscard]] Type GetType () const noexcept;
|
||||||
[[nodiscard]] float GetMass () const noexcept;
|
|
||||||
[[nodiscard]] float GetDrag () const noexcept;
|
|
||||||
[[nodiscard]] float GetAngularDrag () const noexcept;
|
|
||||||
|
|
||||||
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
[[nodiscard]] bool GetFreezePositionX () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
[[nodiscard]] bool GetFreezePositionY () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
[[nodiscard]] bool GetFreezePositionZ () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] bool GetFreezeRotationX () const noexcept;
|
[[nodiscard]] bool GetFreezeRotationX () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
[[nodiscard]] bool GetFreezeRotationY () const noexcept;
|
||||||
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
[[nodiscard]] bool GetFreezeRotationZ () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool GetAutoMass () const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] float GetMass () const noexcept;
|
||||||
|
[[nodiscard]] float GetDrag () const noexcept;
|
||||||
|
[[nodiscard]] float GetAngularDrag () const noexcept;
|
||||||
|
|
||||||
[[nodiscard]] SHVec3 GetForce () const noexcept;
|
[[nodiscard]] SHVec3 GetForce () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetTorque () const noexcept;
|
[[nodiscard]] SHVec3 GetTorque () const noexcept;
|
||||||
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
|
[[nodiscard]] SHVec3 GetLinearVelocity () const noexcept;
|
||||||
|
@ -108,6 +112,7 @@ namespace SHADE
|
||||||
void SetFreezeRotationY (bool freezeRotationY) noexcept;
|
void SetFreezeRotationY (bool freezeRotationY) noexcept;
|
||||||
void SetFreezeRotationZ (bool freezeRotationZ) noexcept;
|
void SetFreezeRotationZ (bool freezeRotationZ) noexcept;
|
||||||
void SetInterpolate (bool allowInterpolation) noexcept;
|
void SetInterpolate (bool allowInterpolation) noexcept;
|
||||||
|
void SetAutoMass (bool autoMass) noexcept;
|
||||||
|
|
||||||
void SetMass (float newMass) noexcept;
|
void SetMass (float newMass) noexcept;
|
||||||
void SetDrag (float newDrag) noexcept;
|
void SetDrag (float newDrag) noexcept;
|
||||||
|
@ -144,8 +149,7 @@ namespace SHADE
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
bool interpolate;
|
uint16_t flags; // 0 0 0 0 0 0 am ip aZ aY aX lZ lY lX slp g
|
||||||
uint8_t flags; // aZ aY aX lZ lY lX slp g
|
|
||||||
uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g
|
uint16_t dirtyFlags; // 0 0 0 0 aD d m t aZ aY aX lZ lY lX slp g
|
||||||
|
|
||||||
float mass;
|
float mass;
|
||||||
|
|
|
@ -245,9 +245,17 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
case 9: // Mass
|
case 9: // Mass
|
||||||
{
|
{
|
||||||
rp3dBody->setMass(component.mass);
|
if (component.GetAutoMass())
|
||||||
rp3dBody->updateLocalCenterOfMassFromColliders();
|
{
|
||||||
rp3dBody->updateLocalInertiaTensorFromColliders();
|
rp3dBody->updateMassPropertiesFromColliders();
|
||||||
|
component.mass = rp3dBody->getMass();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rp3dBody->setMass(component.mass);
|
||||||
|
rp3dBody->updateLocalCenterOfMassFromColliders();
|
||||||
|
rp3dBody->updateLocalInertiaTensorFromColliders();
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,14 +154,32 @@ 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);
|
||||||
|
|
||||||
postUpdateSyncTransforms
|
const auto& CURRENT_TF = physicsObject.GetRigidBody()->getTransform();
|
||||||
(
|
const auto& RENDER_POS = CURRENT_TF.getPosition();
|
||||||
physicsObject
|
const auto& RENDER_ROT = CURRENT_TF.getOrientation();
|
||||||
, transformComponent
|
|
||||||
, rigidBodyComponent
|
// Cache transform
|
||||||
, colliderComponent
|
physicsObject.prevTransform = CURRENT_TF;
|
||||||
, 1.0 // We use 1.0 here to avoid any interpolation
|
|
||||||
);
|
// Sync with physics components
|
||||||
|
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(entityID))
|
||||||
|
{
|
||||||
|
rigidBodyComponent->position = RENDER_POS;
|
||||||
|
rigidBodyComponent->orientation = RENDER_ROT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(entityID))
|
||||||
|
{
|
||||||
|
colliderComponent->position = RENDER_POS;
|
||||||
|
colliderComponent->orientation = RENDER_ROT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set transform for rendering
|
||||||
|
if (transformComponent)
|
||||||
|
{
|
||||||
|
transformComponent->SetWorldPosition(RENDER_POS);
|
||||||
|
transformComponent->SetWorldOrientation(RENDER_ROT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,93 +355,4 @@ 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 && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
|
||||||
{
|
|
||||||
rigidBodyComponent->position = WORLD_POS;
|
|
||||||
rigidBodyComponent->orientation = WORLD_ROT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
|
||||||
{
|
|
||||||
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.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 && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
|
||||||
{
|
|
||||||
// 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 && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
|
||||||
{
|
|
||||||
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
|
|
@ -113,6 +113,23 @@ namespace SHADE
|
||||||
void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
|
void syncRigidBodyActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
|
||||||
void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
|
void syncColliderActive (EntityID eid, SHPhysicsObject& physicsObject) const noexcept;
|
||||||
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;
|
||||||
|
|
||||||
|
static void postUpdateSyncTransforms
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
, double interpolationFactor
|
||||||
|
) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
class SH_API PhysicsFixedUpdate final : public SHFixedSystemRoutine
|
||||||
|
@ -178,24 +195,5 @@ 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
|
|
@ -262,4 +262,94 @@ 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
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
physicsObject.prevTransform = RP3D_TRANSFORM;
|
||||||
|
|
||||||
|
if (rigidBodyComponent && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
||||||
|
{
|
||||||
|
rigidBodyComponent->position = WORLD_POS;
|
||||||
|
rigidBodyComponent->orientation = WORLD_ROT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colliderComponent && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
||||||
|
{
|
||||||
|
colliderComponent->position = WORLD_POS;
|
||||||
|
colliderComponent->orientation = WORLD_ROT;
|
||||||
|
colliderComponent->scale = WORLD_SCL;
|
||||||
|
|
||||||
|
colliderComponent->RecomputeCollisionShapes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHPhysicsSystem::PhysicsPreUpdate::postUpdateSyncTransforms
|
||||||
|
(
|
||||||
|
SHPhysicsObject& physicsObject
|
||||||
|
, SHTransformComponent* transformComponent
|
||||||
|
, SHRigidBodyComponent* rigidBodyComponent
|
||||||
|
, SHColliderComponent* colliderComponent
|
||||||
|
, double interpolationFactor
|
||||||
|
) noexcept
|
||||||
|
{
|
||||||
|
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 && SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(physicsObject.entityID))
|
||||||
|
{
|
||||||
|
// 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 && SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(physicsObject.entityID))
|
||||||
|
{
|
||||||
|
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
|
Loading…
Reference in New Issue