Merge pull request #140 from SHADE-DP/SP3-2-Physics
SP3-2 Physics Bugfixes BUGFIXES Fixed the same velocity bug from before :< Trigger Info are now stored in the correct container
This commit is contained in:
commit
13c8928828
|
@ -173,93 +173,93 @@ namespace SHADE
|
|||
SHASSERT(rp3dBody != nullptr, "ReactPhysics body does not exist!")
|
||||
|
||||
auto* rigidBody = reinterpret_cast<rp3d::RigidBody*>(rp3dBody);
|
||||
|
||||
// Sync velocities
|
||||
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||
|
||||
if (rb->dirtyFlags == 0)
|
||||
return;
|
||||
|
||||
const uint16_t RB_FLAGS = rb->dirtyFlags;
|
||||
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
|
||||
if (rb->dirtyFlags != 0)
|
||||
{
|
||||
// Check if current dirty flag has been set to true
|
||||
if (RB_FLAGS & 1U << i)
|
||||
const uint16_t RB_FLAGS = rb->dirtyFlags;
|
||||
for (size_t i = 0; i < SHRigidBodyComponent::NUM_DIRTY_FLAGS; ++i)
|
||||
{
|
||||
switch (i)
|
||||
// Check if current dirty flag has been set to true
|
||||
if (RB_FLAGS & 1U << i)
|
||||
{
|
||||
case 0: // Gravity
|
||||
switch (i)
|
||||
{
|
||||
rigidBody->enableGravity(rb->IsGravityEnabled());
|
||||
break;
|
||||
}
|
||||
case 1: // Sleeping
|
||||
{
|
||||
rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep());
|
||||
break;
|
||||
}
|
||||
case 2: // Linear Constraints
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
case 0: // Gravity
|
||||
{
|
||||
rb->flags & 1U << 2 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 3 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 4 ? 0.0f : 1.0f
|
||||
};
|
||||
rigidBody->enableGravity(rb->IsGravityEnabled());
|
||||
break;
|
||||
}
|
||||
case 1: // Sleeping
|
||||
{
|
||||
rigidBody->setIsAllowedToSleep(rb->IsAllowedToSleep());
|
||||
break;
|
||||
}
|
||||
case 2: // Linear Constraints
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rb->flags & 1U << 2 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 3 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 4 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
|
||||
rigidBody->setLinearLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
}
|
||||
case 3: // Angular Constraints
|
||||
{
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
rigidBody->setLinearLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
}
|
||||
case 3: // Angular Constraints
|
||||
{
|
||||
rb->flags & 1U << 5 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 6 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 7 ? 0.0f : 1.0f
|
||||
};
|
||||
const rp3d::Vector3 CONSTRAINTS
|
||||
{
|
||||
rb->flags & 1U << 5 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 6 ? 0.0f : 1.0f,
|
||||
rb->flags & 1U << 7 ? 0.0f : 1.0f
|
||||
};
|
||||
|
||||
rigidBody->setAngularLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
rigidBody->setAngularLockAxisFactor(CONSTRAINTS);
|
||||
break;
|
||||
}
|
||||
case 4: // Type
|
||||
{
|
||||
rigidBody->setType(static_cast<rp3d::BodyType>(rb->GetType()));
|
||||
break;
|
||||
}
|
||||
case 5: // Mass
|
||||
{
|
||||
rigidBody->setMass(rb->GetMass());
|
||||
break;
|
||||
}
|
||||
case 6: // Drag
|
||||
{
|
||||
rigidBody->setLinearDamping(rb->GetDrag());
|
||||
break;
|
||||
}
|
||||
case 7: // Angular Drag
|
||||
{
|
||||
rigidBody->setAngularDamping(rb->GetAngularDrag());
|
||||
break;
|
||||
}
|
||||
case 8: // Linear Velocity
|
||||
{
|
||||
rigidBody->setLinearVelocity(rb->GetLinearVelocity());
|
||||
break;
|
||||
}
|
||||
case 9: // Angular Velocity
|
||||
{
|
||||
rigidBody->setAngularVelocity(rb->GetAngularVelocity());
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
case 4: // Type
|
||||
{
|
||||
rigidBody->setType(static_cast<rp3d::BodyType>(rb->GetType()));
|
||||
break;
|
||||
}
|
||||
case 5: // Mass
|
||||
{
|
||||
rigidBody->setMass(rb->GetMass());
|
||||
break;
|
||||
}
|
||||
case 6: // Drag
|
||||
{
|
||||
rigidBody->setLinearDamping(rb->GetDrag());
|
||||
break;
|
||||
}
|
||||
case 7: // Angular Drag
|
||||
{
|
||||
rigidBody->setAngularDamping(rb->GetAngularDrag());
|
||||
break;
|
||||
}
|
||||
case 8: // Linear Velocity
|
||||
{
|
||||
rigidBody->setLinearVelocity(rb->GetLinearVelocity());
|
||||
break;
|
||||
}
|
||||
case 9: // Angular Velocity
|
||||
{
|
||||
rigidBody->setAngularVelocity(rb->GetAngularVelocity());
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rb->dirtyFlags = 0;
|
||||
rb->dirtyFlags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rb->linearVelocity = rigidBody->getLinearVelocity();
|
||||
rb->angularVelocity = rigidBody->getAngularVelocity();
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept
|
||||
|
|
|
@ -257,7 +257,10 @@ namespace SHADE
|
|||
if (physicsObject.rp3dBody == nullptr)
|
||||
continue;
|
||||
|
||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
const auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||
|
||||
if (transformComponent && transformComponent->HasChanged())
|
||||
{
|
||||
const auto WORLD_POS = transformComponent->GetWorldPosition();
|
||||
|
@ -266,46 +269,57 @@ namespace SHADE
|
|||
physicsObject.SetPosition(WORLD_POS);
|
||||
physicsObject.SetOrientation(WORLD_ROT);
|
||||
|
||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||
// Sync physics component transforms
|
||||
|
||||
if (rigidBodyComponent)
|
||||
{
|
||||
rigidBodyComponent->position = WORLD_POS;
|
||||
rigidBodyComponent->orientation = WORLD_ROT;
|
||||
|
||||
// Clear all forces and velocities if editor is stopped
|
||||
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
||||
{
|
||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||
rp3dRigidBody->resetForce();
|
||||
rp3dRigidBody->resetTorque();
|
||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||
}
|
||||
|
||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncRigidBody(rigidBodyComponent);
|
||||
}
|
||||
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||
if (colliderComponent)
|
||||
{
|
||||
colliderComponent->position = WORLD_POS;
|
||||
colliderComponent->orientation = WORLD_ROT;
|
||||
|
||||
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
||||
system->SyncActiveStates(&physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncColliders(colliderComponent);
|
||||
}
|
||||
}
|
||||
|
||||
// Sync rigid bodies
|
||||
|
||||
if (rigidBodyComponent)
|
||||
{
|
||||
// Clear all forces and velocities if editor is stopped
|
||||
if (SHSystemManager::GetSystem<SHEditor>()->editorState == SHEditor::State::STOP)
|
||||
{
|
||||
auto* rp3dRigidBody = reinterpret_cast<rp3d::RigidBody*>(physicsObject.rp3dBody);
|
||||
rp3dRigidBody->resetForce();
|
||||
rp3dRigidBody->resetTorque();
|
||||
rp3dRigidBody->setLinearVelocity(SHVec3::Zero);
|
||||
rp3dRigidBody->setAngularVelocity(SHVec3::Zero);
|
||||
}
|
||||
|
||||
// Sync active states
|
||||
const bool COMPONENT_ACTIVE = rigidBodyComponent->isActive;
|
||||
SyncActiveStates(physicsObject, COMPONENT_ACTIVE);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncRigidBody(rigidBodyComponent);
|
||||
}
|
||||
|
||||
// Sync colliders
|
||||
|
||||
if (colliderComponent)
|
||||
{
|
||||
const bool COMPONENT_ACTIVE = colliderComponent->isActive;
|
||||
SyncActiveStates(physicsObject, colliderComponent->isActive);
|
||||
|
||||
if (!COMPONENT_ACTIVE)
|
||||
continue;
|
||||
|
||||
physicsObject.SyncColliders(colliderComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,26 +363,10 @@ namespace SHADE
|
|||
{
|
||||
for (uint32_t i = 0; i < callbackData.getNbContactPairs(); ++i)
|
||||
{
|
||||
auto contactPair = callbackData.getContactPair(i);
|
||||
SHCollisionEvent newCollisionEvent = GenerateCollisionEvent(contactPair);
|
||||
const auto CONTACT_PAIR = callbackData.getContactPair(i);
|
||||
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(CONTACT_PAIR);
|
||||
|
||||
// Find contact pair in container
|
||||
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
|
||||
{
|
||||
const bool ENTITY_MATCH = e.value[0] == newCollisionEvent.value[0];
|
||||
const bool COLLIDERS_MATCH = e.value[1] == newCollisionEvent.value[1];
|
||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||
});
|
||||
|
||||
if (existingEvent == collisionInfo.end())
|
||||
{
|
||||
// Add new event
|
||||
collisionInfo.emplace_back(newCollisionEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingEvent->collisionState = newCollisionEvent.collisionState;
|
||||
}
|
||||
UpdateEventContainers(NEW_EVENT, collisionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,26 +374,10 @@ namespace SHADE
|
|||
{
|
||||
for (uint32_t i = 0; i < callbackData.getNbOverlappingPairs(); ++i)
|
||||
{
|
||||
auto contactPair = callbackData.getOverlappingPair(i);
|
||||
SHCollisionEvent newTriggerEvent = GenerateCollisionEvent(contactPair);
|
||||
const auto& OVERLAP_PAIR = callbackData.getOverlappingPair(i);
|
||||
const SHCollisionEvent NEW_EVENT = GenerateCollisionEvent(OVERLAP_PAIR);
|
||||
|
||||
// Find contact pair in container
|
||||
auto existingEvent = std::ranges::find_if(collisionInfo.begin(), collisionInfo.end(), [&](const SHCollisionEvent& e)
|
||||
{
|
||||
const bool ENTITY_MATCH = e.value[0] == newTriggerEvent.value[0];
|
||||
const bool COLLIDERS_MATCH = e.value[1] == newTriggerEvent.value[1];
|
||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||
});
|
||||
|
||||
if (existingEvent == collisionInfo.end())
|
||||
{
|
||||
// Add new event
|
||||
triggerInfo.emplace_back(newTriggerEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
existingEvent->collisionState = newTriggerEvent.collisionState;
|
||||
}
|
||||
UpdateEventContainers(NEW_EVENT, triggerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,11 +414,11 @@ namespace SHADE
|
|||
map.erase(entityID);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept
|
||||
void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject& physicsObject, bool componentActive) noexcept
|
||||
{
|
||||
const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive();
|
||||
const bool RP3D_ACTIVE = physicsObject.rp3dBody->isActive();
|
||||
if (RP3D_ACTIVE != componentActive)
|
||||
physicsObject->rp3dBody->setIsActive(componentActive);
|
||||
physicsObject.rp3dBody->setIsActive(componentActive);
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::SyncTransforms() noexcept
|
||||
|
@ -491,155 +473,54 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Convert RP3D Transform to SHADE
|
||||
auto* transformComponent = SHComponentManager::GetComponent<SHTransformComponent>(entityID);
|
||||
transformComponent->SetWorldPosition(rp3dPos);
|
||||
transformComponent->SetWorldOrientation(rp3dRot);
|
||||
auto* transformComponent = SHComponentManager::GetComponent_s<SHTransformComponent>(entityID);
|
||||
|
||||
if (transformComponent != nullptr)
|
||||
{
|
||||
transformComponent->SetWorldPosition(rp3dPos);
|
||||
transformComponent->SetWorldOrientation(rp3dRot);
|
||||
}
|
||||
|
||||
// Cache transforms
|
||||
physicsObject.prevTransform = CURRENT_TF;
|
||||
}
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::UpdateEventContainers(const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept
|
||||
{
|
||||
const auto IT = std::ranges::find_if(container.begin(), container.end(), [&](const SHCollisionEvent& e)
|
||||
{
|
||||
const bool ENTITY_MATCH = e.value[0] == collisionEvent.value[0];
|
||||
const bool COLLIDERS_MATCH = e.value[1] == collisionEvent.value[1];
|
||||
return ENTITY_MATCH && COLLIDERS_MATCH;
|
||||
});
|
||||
|
||||
if (IT == container.end())
|
||||
container.emplace_back(collisionEvent);
|
||||
else
|
||||
IT->collisionState = collisionEvent.collisionState;
|
||||
}
|
||||
|
||||
void SHPhysicsSystem::ClearInvalidCollisions() noexcept
|
||||
{
|
||||
for (auto collisionInfoIter = collisionInfo.begin(); collisionInfoIter != collisionInfo.end();)
|
||||
static const auto CLEAR = [](CollisionEvents& container)
|
||||
{
|
||||
if (collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| collisionInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
|
||||
for (auto eventIter = container.begin(); eventIter != container.end();)
|
||||
{
|
||||
collisionInfoIter = collisionInfo.erase(collisionInfoIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
++collisionInfoIter;
|
||||
}
|
||||
}
|
||||
const bool CLEAR_EVENT = eventIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| eventIter->GetCollisionState() == SHCollisionEvent::State::INVALID;
|
||||
|
||||
for (auto triggerInfoIter = triggerInfo.begin(); triggerInfoIter != triggerInfo.end();)
|
||||
{
|
||||
if (triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::EXIT
|
||||
|| triggerInfoIter->GetCollisionState() == SHCollisionEvent::State::INVALID)
|
||||
{
|
||||
triggerInfoIter = triggerInfo.erase(triggerInfoIter);
|
||||
if (CLEAR_EVENT)
|
||||
eventIter = container.erase(eventIter);
|
||||
else
|
||||
++eventIter;
|
||||
}
|
||||
else
|
||||
{
|
||||
++triggerInfoIter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::CollisionCallback::ContactPair& cp) noexcept
|
||||
{
|
||||
static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
|
||||
{
|
||||
const auto* collider = physicsObject.rp3dBody->getCollider(i);
|
||||
if (collider->getEntity() == colliderID)
|
||||
return i;
|
||||
}
|
||||
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
};
|
||||
|
||||
SHCollisionEvent cInfo;
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
// Match body and collider for collision event
|
||||
const rp3d::Entity body1 = cp.getBody1()->getEntity();
|
||||
const rp3d::Entity body2 = cp.getBody2()->getEntity();
|
||||
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
|
||||
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
|
||||
|
||||
// Find and match both ids
|
||||
bool matched[2] = { false, false };
|
||||
|
||||
for (auto& [entityID, physicsObject] : map)
|
||||
{
|
||||
// Match body 1
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_A] = true;
|
||||
}
|
||||
|
||||
// Match body 2
|
||||
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_B] = true;
|
||||
}
|
||||
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
|
||||
return cInfo;
|
||||
}
|
||||
|
||||
return cInfo;
|
||||
CLEAR(collisionInfo);
|
||||
CLEAR(triggerInfo);
|
||||
}
|
||||
|
||||
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const rp3d::OverlapCallback::OverlapPair& cp) noexcept
|
||||
{
|
||||
static const auto MATCH_COLLIDER = [](const SHPhysicsObject& physicsObject, const rp3d::Entity colliderID)->uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
|
||||
{
|
||||
const auto* collider = physicsObject.rp3dBody->getCollider(i);
|
||||
if (collider->getEntity() == colliderID)
|
||||
return i;
|
||||
}
|
||||
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
};
|
||||
|
||||
SHCollisionEvent cInfo;
|
||||
|
||||
// Match body and collider for collision event
|
||||
const rp3d::Entity body1 = cp.getBody1()->getEntity();
|
||||
const rp3d::Entity body2 = cp.getBody2()->getEntity();
|
||||
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
|
||||
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
|
||||
|
||||
// Find and match both ids
|
||||
bool matched[2] = { false, false };
|
||||
|
||||
|
||||
for (auto& [entityID, physicsObject] : map)
|
||||
{
|
||||
// Match body 1
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_A] = true;
|
||||
}
|
||||
|
||||
// Match body 2
|
||||
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_B] = true;
|
||||
}
|
||||
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
|
||||
return cInfo;
|
||||
}
|
||||
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
return cInfo;
|
||||
}
|
||||
|
||||
|
||||
SHEventHandle SHPhysicsSystem::AddPhysicsComponent(SHEventPtr addComponentEvent)
|
||||
{
|
||||
const auto& EVENT_DATA = reinterpret_cast<const SHEventSpec<SHComponentAddedEvent>*>(addComponentEvent.get());
|
||||
|
@ -728,6 +609,9 @@ namespace SHADE
|
|||
const EntityID ENTITY_ID = EVENT_DATA->data->eid;
|
||||
auto* physicsObject = GetPhysicsObject(ENTITY_ID);
|
||||
|
||||
auto* rigidBodyComponent = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ENTITY_ID);
|
||||
auto* colliderComponent = SHComponentManager::GetComponent_s<SHColliderComponent>(ENTITY_ID);
|
||||
|
||||
SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!")
|
||||
|
||||
if (REMOVED_ID == RIGID_BODY_ID)
|
||||
|
@ -735,7 +619,6 @@ namespace SHADE
|
|||
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
|
||||
|
@ -766,6 +649,10 @@ namespace SHADE
|
|||
auto* collider = physicsObject->rp3dBody->getCollider(i);
|
||||
physicsObject->rp3dBody->removeCollider(collider);
|
||||
}
|
||||
|
||||
// Check for a rigidbody component
|
||||
if (rigidBodyComponent == nullptr)
|
||||
physicsObject->rp3dBody = nullptr;
|
||||
}
|
||||
|
||||
if (physicsObject->rp3dBody == nullptr)
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Concepts */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -176,22 +182,24 @@ namespace SHADE
|
|||
/* Function Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
SHPhysicsObject* EnsurePhysicsObject (EntityID entityID) noexcept;
|
||||
SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept;
|
||||
void DestroyPhysicsObject (EntityID entityID) noexcept;
|
||||
|
||||
void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept;
|
||||
static void SyncActiveStates (SHPhysicsObject& physicsObject, bool componentActive) noexcept;
|
||||
void SyncTransforms () noexcept;
|
||||
void ClearInvalidCollisions () noexcept;
|
||||
|
||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::CollisionCallback::ContactPair& cp) noexcept;
|
||||
SHCollisionEvent GenerateCollisionEvent (const rp3d::OverlapCallback::OverlapPair& cp) noexcept;
|
||||
static void UpdateEventContainers (const SHCollisionEvent& collisionEvent, CollisionEvents& container) noexcept;
|
||||
void ClearInvalidCollisions () noexcept;
|
||||
|
||||
SHEventHandle AddPhysicsComponent (SHEventPtr addComponentEvent);
|
||||
SHEventHandle RemovePhysicsComponent (SHEventPtr removeComponentEvent);
|
||||
|
||||
template <typename RP3DCollisionPair, typename = std::enable_if_t
|
||||
<std::is_same_v<RP3DCollisionPair, rp3d::CollisionCallback::ContactPair>
|
||||
|| std::is_same_v<RP3DCollisionPair, rp3d::OverlapCallback::OverlapPair>>>
|
||||
SHCollisionEvent GenerateCollisionEvent (const RP3DCollisionPair& cp) noexcept;
|
||||
};
|
||||
} // namespace SHADE
|
||||
|
||||
|
||||
|
||||
} // namespace SHADE
|
||||
#include "SHPhysicsSystem.hpp"
|
|
@ -0,0 +1,84 @@
|
|||
/****************************************************************************************
|
||||
* \file SHPhysicsSystem.hpp
|
||||
* \author Diren D Bharwani, diren.dbharwani, 390002520
|
||||
* \brief Implementation for templated functions the Physics System
|
||||
*
|
||||
* \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or
|
||||
* disclosure of this file or its contents without the prior written consent
|
||||
* of DigiPen Institute of Technology is prohibited.
|
||||
****************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
// Primary Header
|
||||
#include "SHPhysicsSystem.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Private Function Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
template <typename RP3DCollisionPair, typename Condition>
|
||||
SHCollisionEvent SHPhysicsSystem::GenerateCollisionEvent(const RP3DCollisionPair& cp) noexcept
|
||||
{
|
||||
static const auto MATCH_COLLIDER = []
|
||||
(
|
||||
const SHPhysicsObject& physicsObject
|
||||
, const rp3d::Entity colliderID
|
||||
)->uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < physicsObject.rp3dBody->getNbColliders(); ++i)
|
||||
{
|
||||
const auto* collider = physicsObject.rp3dBody->getCollider(i);
|
||||
if (collider->getEntity() == colliderID)
|
||||
return i;
|
||||
}
|
||||
|
||||
return std::numeric_limits<uint32_t>::max();
|
||||
};
|
||||
|
||||
SHCollisionEvent cInfo;
|
||||
|
||||
// Match body and collider for collision event
|
||||
const rp3d::Entity body1 = cp.getBody1()->getEntity();
|
||||
const rp3d::Entity body2 = cp.getBody2()->getEntity();
|
||||
const rp3d::Entity collider1 = cp.getCollider1()->getEntity();
|
||||
const rp3d::Entity collider2 = cp.getCollider2()->getEntity();
|
||||
|
||||
// Find and match both ids
|
||||
bool matched[2] = { false, false };
|
||||
|
||||
|
||||
for (auto& [entityID, physicsObject] : map)
|
||||
{
|
||||
// Match body 1
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == false && physicsObject.rp3dBody->getEntity() == body1)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_A] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_A] = MATCH_COLLIDER(physicsObject, collider1);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_A] = true;
|
||||
}
|
||||
|
||||
// Match body 2
|
||||
if (matched[SHCollisionEvent::ENTITY_B] == false && physicsObject.rp3dBody->getEntity() == body2)
|
||||
{
|
||||
cInfo.ids[SHCollisionEvent::ENTITY_B] = entityID;
|
||||
cInfo.ids[SHCollisionEvent::COLLIDER_B] = MATCH_COLLIDER(physicsObject, collider2);
|
||||
|
||||
matched[SHCollisionEvent::ENTITY_B] = true;
|
||||
}
|
||||
|
||||
if (matched[SHCollisionEvent::ENTITY_A] == true && matched[SHCollisionEvent::ENTITY_B] == true)
|
||||
return cInfo;
|
||||
}
|
||||
|
||||
// Update collision state
|
||||
cInfo.collisionState = static_cast<SHCollisionEvent::State>(cp.getEventType());
|
||||
|
||||
return cInfo;
|
||||
}
|
||||
} // namespace SHADE
|
Loading…
Reference in New Issue