From ff9b504bc5224089726983f7098b19bfd8b226fb Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Tue, 11 Oct 2022 01:26:12 +0800 Subject: [PATCH] Moved collider interface into physics object. Added support for removing rigidbodies --- SHADE_Application/src/Scenes/SBTestScene.cpp | 3 +- .../Components/SHColliderComponent.cpp | 16 +- .../Physics/Components/SHColliderComponent.h | 2 +- SHADE_Engine/src/Physics/SHCollider.cpp | 106 +++---- SHADE_Engine/src/Physics/SHCollider.h | 22 +- SHADE_Engine/src/Physics/SHPhysicsObject.cpp | 108 ++++++- SHADE_Engine/src/Physics/SHPhysicsObject.h | 4 +- SHADE_Engine/src/Physics/SHPhysicsSystem.cpp | 287 ++++-------------- SHADE_Engine/src/Physics/SHPhysicsSystem.h | 13 +- 9 files changed, 227 insertions(+), 334 deletions(-) diff --git a/SHADE_Application/src/Scenes/SBTestScene.cpp b/SHADE_Application/src/Scenes/SBTestScene.cpp index 3b277e6c..36c69386 100644 --- a/SHADE_Application/src/Scenes/SBTestScene.cpp +++ b/SHADE_Application/src/Scenes/SBTestScene.cpp @@ -104,8 +104,7 @@ namespace Sandbox transform.SetWorldRotation(SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber(), SHMath::GenerateRandomNumber()); transform.SetWorldScale(TEST_OBJ_SCALE); - auto* box = collider.AddBoundingBox(); - box->SetHalfExtents(transform.GetWorldScale() * 0.5f); + collider.AddBoundingBox(SHVec3::One * 0.5f, SHVec3::Zero); stressTestObjects.emplace_back(entity); } diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp index 73e7ccbd..ada90eaa 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.cpp @@ -24,7 +24,8 @@ namespace SHADE /*-----------------------------------------------------------------------------------*/ SHColliderComponent::SHColliderComponent() noexcept - : system { nullptr } + : system { nullptr } + , colliders {} {} /*-----------------------------------------------------------------------------------*/ @@ -87,12 +88,17 @@ namespace SHADE system->RemoveCollider(GetEID()); } - SHBoundingBox* SHColliderComponent::AddBoundingBox() noexcept + SHBoundingBox* SHColliderComponent::AddBoundingBox(const SHVec3& halfExtents, const SHVec3& posOffset) noexcept { const auto TYPE = SHCollider::Type::BOX; - const auto BOX_PAIR = std::make_pair(SHCollider{TYPE}, true); - auto& collider = colliders.emplace_back(BOX_PAIR).first; + auto boxPair = std::make_pair(SHCollider{TYPE}, true); + auto& collider = colliders.emplace_back(boxPair).first; + + const auto* tf = SHComponentManager::GetComponent(GetEID()); + + collider.SetPositionOffset(posOffset); + collider.SetAsBoundingBox(tf->GetWorldScale() * halfExtents); if (!system) { @@ -101,7 +107,7 @@ namespace SHADE } // Notify Physics System - system->AddCollisionShape(GetEID(), collider.GetShape()); + system->AddCollisionShape(GetEID(), &collider); return reinterpret_cast(collider.GetShape()); } diff --git a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h index fd4bcb9a..db4cd612 100644 --- a/SHADE_Engine/src/Physics/Components/SHColliderComponent.h +++ b/SHADE_Engine/src/Physics/Components/SHColliderComponent.h @@ -82,7 +82,7 @@ namespace SHADE void OnCreate () override; void OnDestroy () override; - SHBoundingBox* AddBoundingBox () noexcept; + SHBoundingBox* AddBoundingBox (const SHVec3& halfExtents = SHVec3::One, const SHVec3& posOffset = SHVec3::Zero) noexcept; void RemoveCollider (int index); diff --git a/SHADE_Engine/src/Physics/SHCollider.cpp b/SHADE_Engine/src/Physics/SHCollider.cpp index 724db19c..5a3a6ac2 100644 --- a/SHADE_Engine/src/Physics/SHCollider.cpp +++ b/SHADE_Engine/src/Physics/SHCollider.cpp @@ -29,25 +29,23 @@ namespace SHADE } SHCollider::SHCollider(const SHCollider& rhs) noexcept - : type { rhs.type} - , isTrigger { rhs.isTrigger } - , dirty { true } - , shape { nullptr } + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + , positionOffset { rhs.positionOffset } { CreateShape(); - - // TODO(Diren): Copy transform data over } SHCollider::SHCollider(SHCollider&& rhs) noexcept - : type { rhs.type} - , isTrigger { rhs.isTrigger } - , dirty { true } - , shape { nullptr } + : type { rhs.type} + , isTrigger { rhs.isTrigger } + , dirty { true } + , shape { nullptr } + , positionOffset { rhs.positionOffset } { CreateShape(); - - // TODO(Diren): Copy transform data over } SHCollider::~SHCollider() noexcept @@ -61,27 +59,26 @@ namespace SHADE SHCollider& SHCollider::operator=(const SHCollider& rhs) noexcept { - type = rhs.type; - isTrigger = rhs.isTrigger; - dirty = true; + if (this == &rhs) + return *this; + + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + positionOffset = rhs.positionOffset; CreateShape(); - - // TODO(Diren): Copy transform data over - return *this; } SHCollider& SHCollider::operator=(SHCollider&& rhs) noexcept { - type = rhs.type; - isTrigger = rhs.isTrigger; - dirty = true; + type = rhs.type; + isTrigger = rhs.isTrigger; + dirty = true; + positionOffset = rhs.positionOffset; CreateShape(); - - // TODO(Diren): Copy transform data over - return *this; } @@ -104,11 +101,6 @@ namespace SHADE return type; } - SHShape* SHCollider::GetShape() const noexcept - { - return shape; - } - float SHCollider::GetFriction() const noexcept { // TODO(Diren): Fix after implementing materials @@ -126,38 +118,41 @@ namespace SHADE return 0.0f; } - SHVec3 SHCollider::GetPosition() const noexcept - { - // TODO(Diren): Fix after linking transform data - return SHVec3::Zero; - } - const SHVec3& SHCollider::GetPositionOffset() const noexcept { return positionOffset; } - SHQuaternion SHCollider::GetOrientation() const noexcept + SHShape* SHCollider::GetShape() noexcept { - // TODO(Diren): Fix after linking transform data - return SHQuaternion::Identity; + dirty = true; + return shape; } /*-----------------------------------------------------------------------------------*/ /* Setter Function Definitions */ /*-----------------------------------------------------------------------------------*/ - void SHCollider::SetType(Type newType) noexcept + void SHCollider::SetAsBoundingBox(const SHVec3& halfExtents) { - if (type == newType) - return; - dirty = true; + type = Type::BOX; - type = newType; - CreateShape(); + delete shape; + shape = new SHBoundingBox{ positionOffset, halfExtents }; } + void SHCollider::SetAsBoundingSphere(float radius) + { + dirty = true; + type = Type::SPHERE; + + // TODO(Diren): Add Sphere + delete shape; + } + + + void SHCollider::SetIsTrigger(bool trigger) noexcept { dirty = true; @@ -191,25 +186,22 @@ namespace SHADE void SHCollider::CreateShape() { - // Remove current shape delete shape; switch (type) { - case Type::BOX: CreateBoundingBox(); break; - case Type::SPHERE: CreateSphere(); break; + case Type::BOX: + { + SetAsBoundingBox(SHVec3::One); + break; + } + case Type::SPHERE: + { + SetAsBoundingSphere(1.0f); + break; + } default: break; } } - void SHCollider::CreateBoundingBox() - { - shape = new SHBoundingBox{ SHVec3::Zero, SHVec3::One }; - } - - void SHCollider::CreateSphere() - { - - } - } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHCollider.h b/SHADE_Engine/src/Physics/SHCollider.h index fce4a5b2..b53ce58a 100644 --- a/SHADE_Engine/src/Physics/SHCollider.h +++ b/SHADE_Engine/src/Physics/SHCollider.h @@ -32,8 +32,6 @@ namespace SHADE BOX , SPHERE , CAPSULE - , CONVEX_HULL - , CONVEX_MESH }; /*---------------------------------------------------------------------------------*/ @@ -62,28 +60,28 @@ namespace SHADE [[nodiscard]] bool IsTrigger () const noexcept; [[nodiscard]] Type GetType () const noexcept; - [[nodiscard]] SHShape* GetShape () const noexcept; [[nodiscard]] float GetFriction () const noexcept; [[nodiscard]] float GetBounciness () const noexcept; [[nodiscard]] float GetDensity () const noexcept; - [[nodiscard]] SHVec3 GetPosition () const noexcept; [[nodiscard]] const SHVec3& GetPositionOffset () const noexcept; - [[nodiscard]] SHQuaternion GetOrientation () const noexcept; + + [[nodiscard]] SHShape* GetShape () noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ /*---------------------------------------------------------------------------------*/ - void SetType (Type newType) noexcept; + void SetAsBoundingBox (const SHVec3& halfExtents); + void SetAsBoundingSphere (float radius); - void SetIsTrigger (bool isTrigger) noexcept; - void SetFriction (float friction) noexcept; - void SetBounciness (float bounciness) noexcept; - void SetDensity (float density) noexcept; + void SetIsTrigger (bool isTrigger) noexcept; + void SetFriction (float friction) noexcept; + void SetBounciness (float bounciness) noexcept; + void SetDensity (float density) noexcept; - void SetPositionOffset (const SHVec3& positionOffset) noexcept; + void SetPositionOffset (const SHVec3& positionOffset) noexcept; private: /*---------------------------------------------------------------------------------*/ @@ -101,8 +99,6 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ void CreateShape (); - void CreateBoundingBox (); - void CreateSphere (); }; } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp index bbe8c726..eaecc9c0 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.cpp @@ -132,7 +132,7 @@ namespace SHADE void SHPhysicsObject::CreateRigidBody(const SHTransformComponent* tf, SHRigidBodyComponent* rb, SHColliderComponent* c) { - // If collider already exists + // If collider already exists, recreate the collision body as a rigid body if (hasColliders) world->destroyCollisionBody(rp3dBody); @@ -141,31 +141,91 @@ namespace SHADE rb->position = tf->GetWorldPosition(); rb->orientation = tf->GetWorldRotation(); + + if (hasColliders) + { + c->position = tf->GetWorldPosition(); + c->orientation = tf->GetWorldRotation(); + // Get array of colliders and add them back into the rigidbody + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); + } } void SHPhysicsObject::CreateCollisionBody(const SHTransformComponent* tf, SHColliderComponent* c) { - + if (rp3dBody == nullptr) + rp3dBody = world->createCollisionBody(rp3d::Transform{ tf->GetWorldPosition(), tf->GetWorldRotation() }); + + hasColliders = true; + + c->position = tf->GetWorldPosition(); + c->orientation = tf->GetWorldRotation(); + + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); } int SHPhysicsObject::AddCollider(SHCollider* collider) { - return 0; + switch (collider->GetType()) + { + case SHCollider::Type::BOX: + { + const auto* box = reinterpret_cast(collider->GetShape()); + rp3d::BoxShape* newBox = factory->createBoxShape(box->GetHalfExtents()); + + // TODO(Diren): Handle offsets + rp3dBody->addCollider(newBox, rp3d::Transform{ collider->GetPositionOffset(), SHQuaternion::Identity }); + break; + } + case SHCollider::Type::SPHERE: + { + break; + } + // TODO(Diren): Add more collider shapes + default: break; + } + + return static_cast(rp3dBody->getNbColliders()) - 1; } - void SHPhysicsObject::DestroyRigidBody() noexcept + void SHPhysicsObject::DestroyRigidBody(SHColliderComponent* c) noexcept { - + world->destroyRigidBody(reinterpret_cast(rp3dBody)); + + if (hasColliders) + { + // Preserve colliders as a collision body + rp3dBody = world->createCollisionBody(rp3d::Transform{ c->position, c->orientation }); + for (auto& collider : c->colliders | std::views::keys) + AddCollider(&collider); + } + + isRigidBody = false; } void SHPhysicsObject::DestroyCollisionBody() noexcept { - + // Remove all colliders + for (uint32_t i = 0; i < rp3dBody->getNbColliders(); ++i) + { + auto* collider = rp3dBody->getCollider(i); + rp3dBody->removeCollider(collider); + } } - void SHPhysicsObject::RemoveCollider(int index) noexcept + void SHPhysicsObject::RemoveCollider(int index) { - + const int NUM_COLLIDERS = static_cast(rp3dBody->getNbColliders()); + if (NUM_COLLIDERS == 0) + return; + + if (index < 0 || index >= NUM_COLLIDERS) + throw std::invalid_argument("Index out of range!"); + + auto* collider = rp3dBody->getCollider(index); + rp3dBody->removeCollider(collider); } void SHPhysicsObject::SyncRigidBody(SHRigidBodyComponent* rb) const noexcept @@ -260,7 +320,37 @@ namespace SHADE void SHPhysicsObject::SyncColliders(SHColliderComponent* c) const noexcept { - + int index = 0; + for (auto& [collider, dirty] : c->colliders) + { + if (!dirty) + continue; + + // Update offsets + auto* rp3dCollider = rp3dBody->getCollider(index); + rp3dCollider->setLocalToBodyTransform(rp3d::Transform(collider.GetPositionOffset(), SHQuaternion::Identity)); + + switch (collider.GetType()) + { + case SHCollider::Type::BOX: + { + const auto* box = reinterpret_cast(collider.GetShape()); + + auto* rp3dBoxShape = reinterpret_cast(rp3dCollider->getCollisionShape()); + rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); + + break; + } + case SHCollider::Type::SPHERE: + { + break; + } + default: break; + } + + dirty = false; + ++index; + } } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Physics/SHPhysicsObject.h b/SHADE_Engine/src/Physics/SHPhysicsObject.h index 8562a0a1..39a85421 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/SHPhysicsObject.h @@ -73,8 +73,8 @@ namespace SHADE void CreateCollisionBody (const SHTransformComponent* tf, SHColliderComponent* c); int AddCollider (SHCollider* collider); - void DestroyRigidBody () noexcept; - void RemoveCollider (int index) noexcept; + void DestroyRigidBody (SHColliderComponent* c) noexcept; + void RemoveCollider (int index); void DestroyCollisionBody () noexcept; void SyncRigidBody (SHRigidBodyComponent* rb) const noexcept; diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp index b922cdd7..c5a7aa57 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.cpp @@ -202,46 +202,14 @@ namespace SHADE SHLOG_INFO("Adding a Rigidbody to the Physics World.") #endif - // Check if entity is already a physics object - auto* physicsObject = GetPhysicsObject(entityID); + auto* physicsObject = CreatePhysicsObject(entityID); - if (!physicsObject) - physicsObject = CreatePhysicsObject(entityID); - - // Get components transform - auto* transformComponent = EnsureTransform(entityID); - auto* rigidBodyComponent = SHComponentManager::GetComponent(entityID); - - physicsObject->CreateRigidBody(transformComponent, rigidBodyComponent, nullptr); - - // Recreate colliders - const rp3d::Transform RP3D_TF { transformComponent->GetWorldPosition(), transformComponent->GetWorldRotation() }; - if (physicsObject->hasColliders) - { - const auto& COLLIDERS = SHComponentManager::GetComponent(entityID)->GetColliders(); - for (const auto& collider : COLLIDERS | std::views::keys) - { - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } - } - } - + physicsObject->CreateRigidBody + ( + EnsureTransform(entityID), + SHComponentManager::GetComponent(entityID), + SHComponentManager::GetComponent_s(entityID) + ); } void SHPhysicsSystem::AddCollider(EntityID entityID) noexcept @@ -250,43 +218,13 @@ namespace SHADE SHLOG_INFO("Adding a Collider to the Physics World.") #endif - // Check if entity is already a physics object - auto* physicsObject = GetPhysicsObject(entityID); - if (!physicsObject) - physicsObject = CreatePhysicsObject(entityID); + auto* physicsObject = CreatePhysicsObject(entityID); - // Get entity transform - auto const* TF = EnsureTransform(entityID); - const rp3d::Transform RP3D_TF { TF->GetWorldPosition(), TF->GetWorldRotation() }; - - // No rb - if (!physicsObject->isRigidBody) - physicsObject->rp3dBody = world->createCollisionBody(RP3D_TF); - - const auto& COLLIDERS = SHComponentManager::GetComponent(entityID)->GetColliders(); - for (const auto& collider : COLLIDERS | std::views::keys) - { - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - physicsObject->rp3dBody->addCollider(newBox, RP3D_TF); - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } - } - - physicsObject->hasColliders = true; + physicsObject->CreateCollisionBody + ( + EnsureTransform(entityID), + SHComponentManager::GetComponent(entityID) + ); } void SHPhysicsSystem::RemoveRigidBody(EntityID entityID) noexcept @@ -295,6 +233,13 @@ namespace SHADE SHLOG_INFO("Removing a Rigidbody from the Physics World.") #endif + auto* physicsObject = GetPhysicsObject(entityID); + SHASSERT(physicsObject != nullptr, "Physics object has been lost from the world!") + + physicsObject->DestroyRigidBody(SHComponentManager::GetComponent_s(entityID)); + + if (physicsObject->rp3dBody == nullptr) + DestroyPhysicsObject(entityID); } void SHPhysicsSystem::RemoveCollider(EntityID entityID) noexcept @@ -344,30 +289,10 @@ namespace SHADE } - void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHShape* shape) + void SHPhysicsSystem::AddCollisionShape(EntityID entityID, SHCollider* collider) { auto* physicsObject = GetPhysicsObject(entityID); - - switch (shape->GetType()) - { - case SHShape::Type::BOX: - { - auto* box = reinterpret_cast(shape); - rp3d::BoxShape* newBox = factory.createBoxShape(box->GetHalfExtents()); - - // TODO(Diren): Handle offsets - - rp3d::Transform tf = rp3d::Transform::identity(); - physicsObject->rp3dBody->addCollider(newBox, tf); - break; - } - case SHShape::Type::SPHERE: - { - break; - } - // TODO(Diren): Add more collider shapes - default: break; - } + physicsObject->AddCollider(collider); } void SHPhysicsSystem::RemoveCollisionShape(EntityID entityID, int index) @@ -424,6 +349,7 @@ namespace SHADE if (system->worldUpdated) { system->SyncTransforms(); + // TODO(Diren): Handle trigger messages for scripting } } @@ -434,8 +360,14 @@ namespace SHADE SHPhysicsObject* SHPhysicsSystem::CreatePhysicsObject(EntityID entityID) noexcept { - auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second; - return newPhysicsObject; + const auto it = map.find(entityID); + if (it == map.end()) + { + auto* newPhysicsObject = &map.emplace(entityID, SHPhysicsObject{entityID, &factory, world}).first->second; + return newPhysicsObject; + } + + return &(it->second); } SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID entityID) noexcept @@ -450,6 +382,11 @@ namespace SHADE return &(it->second); } + void SHPhysicsSystem::DestroyPhysicsObject(EntityID entityID) noexcept + { + map.erase(entityID); + } + void SHPhysicsSystem::SyncActiveStates(SHPhysicsObject* physicsObject, bool componentActive) noexcept { const bool RP3D_ACTIVE = physicsObject->rp3dBody->isActive(); @@ -500,17 +437,14 @@ namespace SHADE if (!COMPONENT_ACTIVE) continue; - SyncCollider(physicsObject, &comp); + physicsObject->SyncColliders(&comp); } } void SHPhysicsSystem::SyncTransforms() noexcept { - for (auto& pair : map) + for (auto& [entityID, physicsObject] : map) { - const EntityID ENTITY_ID = pair.first; - SHPhysicsObject& physicsObject = pair.second; - rp3d::Vector3 rp3dPos; rp3d::Quaternion rp3dRot; @@ -520,7 +454,7 @@ namespace SHADE if (physicsObject.isRigidBody) { - auto const* rbComponent = SHComponentManager::GetComponent(ENTITY_ID); + auto* rbComponent = SHComponentManager::GetComponent(entityID); if (rbComponent->GetType() == SHRigidBodyComponent::Type::STATIC) continue; @@ -538,6 +472,16 @@ namespace SHADE rp3dPos = CURRENT_TF.getPosition(); rp3dRot = CURRENT_TF.getOrientation(); } + + rbComponent->position = CURRENT_TF.getPosition(); + rbComponent->orientation = CURRENT_TF.getOrientation(); + + if (physicsObject.hasColliders) + { + auto* colliderComponent = SHComponentManager::GetComponent(entityID); + colliderComponent->position = CURRENT_TF.getPosition(); + colliderComponent->orientation = CURRENT_TF.getOrientation(); + } } else { @@ -546,145 +490,16 @@ namespace SHADE } // Convert RP3D Transform to SHADE - auto* tfComponent = SHComponentManager::GetComponent(ENTITY_ID); + auto* tfComponent = SHComponentManager::GetComponent(entityID); tfComponent->SetWorldPosition(rp3dPos); tfComponent->SetWorldRotation(SHQuaternion{ rp3dRot }.ToEuler()); + // Cache transforms physicsObject.prevTransform = CURRENT_TF; } } - void SHPhysicsSystem::SyncRigidBody(SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept - { - auto* rigidBody = reinterpret_cast(physicsObject->rp3dBody); - - const uint16_t RB_FLAGS = comp->dirtyFlags; - const size_t NUM_FLAGS = sizeof(RB_FLAGS) * 8U; - for (size_t i = 0; i < NUM_FLAGS; ++i) - { - // Check if current dirty flag has been set to true - if (RB_FLAGS & 1U << i) - { - switch (i) - { - case 0: // Gravity - { - rigidBody->enableGravity(comp->IsGravityEnabled()); - break; - } - case 1: // Sleeping - { - rigidBody->setIsAllowedToSleep(comp->IsAllowedToSleep()); - break; - } - case 2: // Linear Constraints - { - SetRP3DLinearConstraints(rigidBody, comp->flags); - break; - } - case 3: // Angular Constraints - { - SetRP3DAngularConstraints(rigidBody, comp->flags); - break; - } - case 4: // Type - { - rigidBody->setType(static_cast(comp->GetType())); - break; - } - case 5: // Mass - { - rigidBody->setMass(comp->GetMass()); - break; - } - case 6: // Drag - { - rigidBody->setLinearDamping(comp->GetDrag()); - break; - } - case 7: // Angular Drag - { - rigidBody->setAngularDamping(comp->GetAngularDrag()); - break; - } - case 8: // Linear Velocity - { - rigidBody->setLinearVelocity(comp->GetLinearVelocity()); - break; - } - case 9: // Angular Velocity - { - rigidBody->setAngularVelocity(comp->GetAngularVelocity()); - break; - } - default: break; - } - } - } - } - - void SHPhysicsSystem::SetRP3DLinearConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept - { - const rp3d::Vector3 CONSTRAINTS - { - rbFlags & 1U << 2 ? 0.0f : 1.0f, - rbFlags & 1U << 3 ? 0.0f : 1.0f, - rbFlags & 1U << 4 ? 0.0f : 1.0f - }; - - - rp3dRigidBody->setLinearLockAxisFactor(CONSTRAINTS); - } - - void SHPhysicsSystem::SetRP3DAngularConstraints(rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept - { - const rp3d::Vector3 CONSTRAINTS - { - rbFlags & 1U << 5 ? 0.0f : 1.0f, - rbFlags & 1U << 6 ? 0.0f : 1.0f, - rbFlags & 1U << 7 ? 0.0f : 1.0f - }; - - rp3dRigidBody->setAngularLockAxisFactor(CONSTRAINTS); - } - - void SHPhysicsSystem::SyncCollider(SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept - { - int index = 0; - for (auto& [collider, dirty] : comp->colliders) - { - if (!dirty) - continue; - - switch (collider.GetType()) - { - case SHCollider::Type::BOX: - { - SHBoundingBox* box = reinterpret_cast(collider.GetShape()); - - auto* rp3dBoxShape = reinterpret_cast(physicsObject->rp3dBody->getCollider(index)->getCollisionShape()); - rp3dBoxShape->setHalfExtents(box->GetHalfExtents()); - - if (rp3dBoxShape) - { - SHLOG_INFO("Updating box things") - } - - break; - } - case SHCollider::Type::SPHERE: - { - break; - } - default: break; - } - - dirty = false; - ++index; - } - } - SHTransformComponent* SHPhysicsSystem::EnsureTransform(EntityID entityID) { auto* tf = SHComponentManager::GetComponent_s(entityID); diff --git a/SHADE_Engine/src/Physics/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/SHPhysicsSystem.h index b5ab36bc..bc6a1ba2 100644 --- a/SHADE_Engine/src/Physics/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/SHPhysicsSystem.h @@ -82,8 +82,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ - void Init () override; - void Exit () override; + void Init () override; + void Exit () override; void AddRigidBody (EntityID entityID) noexcept; void AddCollider (EntityID entityID) noexcept; @@ -101,7 +101,7 @@ namespace SHADE void AddTorque (EntityID entityID, const SHVec3& torque) const noexcept; void AddRelativeTorque (EntityID entityID, const SHVec3& relativeTorque) const noexcept; - void AddCollisionShape (EntityID entityID, SHShape* shape); + void AddCollisionShape (EntityID entityID, SHCollider* collider); void RemoveCollisionShape (EntityID entityID, int index); /*---------------------------------------------------------------------------------*/ @@ -188,6 +188,7 @@ namespace SHADE /*---------------------------------------------------------------------------------*/ SHPhysicsObject* CreatePhysicsObject (EntityID entityID) noexcept; SHPhysicsObject* GetPhysicsObject (EntityID entityID) noexcept; + void DestroyPhysicsObject (EntityID entityID) noexcept; void SyncActiveStates (SHPhysicsObject* physicsObject, bool componentActive) noexcept; void SyncRigidBodyComponents (std::vector& denseArray) noexcept; @@ -195,12 +196,6 @@ namespace SHADE void SyncTransforms () noexcept; // TODO(Diren): Trigger handling - static void SyncRigidBody (SHPhysicsObject const* physicsObject, const SHRigidBodyComponent* comp) noexcept; - static void SetRP3DLinearConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - static void SetRP3DAngularConstraints (rp3d::RigidBody const* rp3dRigidBody, uint8_t rbFlags) noexcept; - - static void SyncCollider (SHPhysicsObject const* physicsObject, SHColliderComponent* comp) noexcept; - // TODO(Diren): Remove when responsibility shifted to editor SHTransformComponent* EnsureTransform (EntityID entityID); };