diff --git a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp index 2edca110..e63895d5 100644 --- a/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHCollisionShape.cpp @@ -177,9 +177,21 @@ namespace SHADE { dirty = true; - const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + const auto* COLLIDER = SHComponentManager::GetComponent(entityID); + auto* box = reinterpret_cast(shape); + + SHVec3 correctedHalfExtents = halfExtents; + + // Get current relative halfExtents for error checking. 0 is ignored + const SHVec3& CURRENT_RELATIVE_EXTENTS = box->GetRelativeExtents(); + for (size_t i = 0; i < SHVec3::SIZE; ++i) + { + if (SHMath::CompareFloat(halfExtents[i], 0.0f)) + correctedHalfExtents[i] = CURRENT_RELATIVE_EXTENTS[i]; + } + // Set the half extents relative to world scale - const SHVec3 WORLD_EXTENTS = halfExtents * colliderComponent->GetScale() * 0.5f; + const SHVec3 WORLD_EXTENTS = correctedHalfExtents * COLLIDER->GetScale() * 0.5f; if (type != Type::BOX) { @@ -189,18 +201,24 @@ namespace SHADE shape = new SHBox{ positionOffset, WORLD_EXTENTS }; } - auto* box = reinterpret_cast(shape); box->SetWorldExtents(WORLD_EXTENTS); - box->SetRelativeExtents(halfExtents); + box->SetRelativeExtents(correctedHalfExtents); } void SHCollisionShape::SetBoundingSphere(float radius) { dirty = true; - const auto* colliderComponent = SHComponentManager::GetComponent(entityID); + auto* sphere = reinterpret_cast(shape); + const auto* COLLIDER = SHComponentManager::GetComponent(entityID); + + // Get current relative halfExtents for error checking. 0 is ignored + const float CURRENT_RELATIVE_RADIUS = sphere->GetRelativeRadius(); + if (SHMath::CompareFloat(radius, 0.0f)) + radius = CURRENT_RELATIVE_RADIUS; + // Set the radius relative to world scale - const SHVec3 WORLD_SCALE = colliderComponent->GetScale(); + const SHVec3 WORLD_SCALE = COLLIDER->GetScale(); const float MAX_SCALE = SHMath::Max({ WORLD_SCALE.x, WORLD_SCALE.y, WORLD_SCALE.z }); const float WORLD_RADIUS = radius * MAX_SCALE * 0.5f; @@ -212,8 +230,8 @@ namespace SHADE shape = new SHSphere{ positionOffset, WORLD_RADIUS }; } - auto* sphere = reinterpret_cast(shape); sphere->SetWorldRadius(WORLD_RADIUS); + sphere->SetRelativeRadius(radius); } void SHCollisionShape::SetIsTrigger(bool trigger) noexcept diff --git a/SHADE_Engine/src/Physics/Interface/SHPhysicsMaterial.cpp b/SHADE_Engine/src/Physics/Interface/SHPhysicsMaterial.cpp index 677e448f..95141501 100644 --- a/SHADE_Engine/src/Physics/Interface/SHPhysicsMaterial.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHPhysicsMaterial.cpp @@ -44,7 +44,7 @@ namespace SHADE && SHMath::CompareFloat(density, rhs.density); } - bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept + bool SHPhysicsMaterial::operator!=(const SHPhysicsMaterial& rhs) const noexcept { return !SHMath::CompareFloat(friction, rhs.friction) || !SHMath::CompareFloat(bounciness, rhs.bounciness) diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp index 5fe1e55e..765decd8 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.cpp @@ -302,6 +302,9 @@ namespace SHADE { static constexpr int FLAG_POS = 9; + if (newMass < 0.0f) + return; + if (type != Type::DYNAMIC) { SHLOG_WARNING("Cannot set mass of a non-dynamic object {}", GetEID()) @@ -385,42 +388,62 @@ namespace SHADE void SHRigidBodyComponent::AddForce(const SHVec3& force) const noexcept { - system->AddForce(GetEID(), force); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyWorldForceAtCenterOfMass(force); } void SHRigidBodyComponent::AddForceAtLocalPos(const SHVec3& force, const SHVec3& localPos) const noexcept { - system->AddForceAtLocalPos(GetEID(), force, localPos); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyWorldForceAtLocalPosition(force, localPos); } void SHRigidBodyComponent::AddForceAtWorldPos(const SHVec3& force, const SHVec3& worldPos) const noexcept { - system->AddForceAtWorldPos(GetEID(), force, worldPos); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyWorldForceAtWorldPosition(force, worldPos); } void SHRigidBodyComponent::AddRelativeForce(const SHVec3& relativeForce) const noexcept { - system->AddRelativeForce(GetEID(), relativeForce); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyLocalForceAtCenterOfMass(relativeForce); } void SHRigidBodyComponent::AddRelativeForceAtLocalPos(const SHVec3& relativeForce, const SHVec3& localPos) const noexcept { - system->AddRelativeForceAtLocalPos(GetEID(), relativeForce, localPos); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyLocalForceAtLocalPosition(relativeForce, localPos); } void SHRigidBodyComponent::AddRelativeForceAtWorldPos(const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept { - system->AddRelativeForceAtWorldPos(GetEID(), relativeForce, worldPos); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyLocalForceAtWorldPosition(relativeForce, worldPos); } void SHRigidBodyComponent::AddTorque(const SHVec3& torque) const noexcept { - system->AddTorque(GetEID(), torque); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyWorldTorque(torque); } void SHRigidBodyComponent::AddRelativeTorque(const SHVec3& relativeTorque) const noexcept { - system->AddRelativeTorque(GetEID(), relativeTorque); + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->applyLocalTorque(relativeTorque); + } + + void SHRigidBodyComponent::ClearForces() const noexcept + { + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->resetForce(); + } + + void SHRigidBodyComponent::ClearTorque() const noexcept + { + if (auto* physicsObject = system->GetPhysicsObject(GetEID()); physicsObject) + physicsObject->GetRigidBody()->resetTorque(); } } // namespace SHADE diff --git a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h index 48a5d723..f7062f96 100644 --- a/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h +++ b/SHADE_Engine/src/Physics/Interface/SHRigidBodyComponent.h @@ -125,14 +125,15 @@ namespace SHADE void AddForce (const SHVec3& force) const noexcept; void AddForceAtLocalPos (const SHVec3& force, const SHVec3& localPos) const noexcept; void AddForceAtWorldPos (const SHVec3& force, const SHVec3& worldPos) const noexcept; - void AddRelativeForce (const SHVec3& relativeForce) const noexcept; void AddRelativeForceAtLocalPos (const SHVec3& relativeForce, const SHVec3& localPos) const noexcept; void AddRelativeForceAtWorldPos (const SHVec3& relativeForce, const SHVec3& worldPos) const noexcept; - void AddTorque (const SHVec3& torque) const noexcept; void AddRelativeTorque (const SHVec3& relativeTorque) const noexcept; + void ClearForces () const noexcept; + void ClearTorque () const noexcept; + private: /*---------------------------------------------------------------------------------*/ /* Data Members */ diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp index 346ab4cb..a52d3899 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.cpp @@ -277,23 +277,24 @@ namespace SHADE if (!rp3dBody->isActive()) return; - int index = 0; - for (auto& collisionShape : component.collisionShapes) + const int NUM_SHAPES = static_cast(component.collisionShapes.size()); + for (int i = 0; i < NUM_SHAPES; ++i) { + auto& collisionShape = component.collisionShapes[i]; + if (!collisionShape.dirty) continue; switch (collisionShape.GetType()) { - case SHCollisionShape::Type::BOX: syncBoxShape(index, collisionShape); break; - case SHCollisionShape::Type::SPHERE: syncSphereShape(index, collisionShape); break; + case SHCollisionShape::Type::BOX: syncBoxShape(i, collisionShape); break; + case SHCollisionShape::Type::SPHERE: syncSphereShape(i, collisionShape); break; default: break; } - // TODO(Diren): Update Material + syncMaterial(i, collisionShape); collisionShape.dirty = false; - ++index; } } @@ -301,6 +302,14 @@ namespace SHADE /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + void SHPhysicsObject::syncMaterial(int colliderIndex, SHCollisionShape& collisionShape) const noexcept + { + auto& rp3dMaterial = rp3dBody->getCollider(colliderIndex)->getMaterial(); + rp3dMaterial.setFrictionCoefficient(collisionShape.GetFriction()); + rp3dMaterial.setBounciness(collisionShape.GetBounciness()); + rp3dMaterial.setMassDensity(collisionShape.GetDensity()); + } + void SHPhysicsObject::addBoxShape(SHCollisionShape& boxShape) const noexcept { const rp3d::Transform OFFSETS diff --git a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h index fefc983f..5a0e62ac 100644 --- a/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h +++ b/SHADE_Engine/src/Physics/PhysicsObject/SHPhysicsObject.h @@ -96,6 +96,8 @@ namespace SHADE /* Function Members */ /*---------------------------------------------------------------------------------*/ + void syncMaterial (int colliderIndex, SHCollisionShape& collisionShape) const noexcept; + // Box Shapes void addBoxShape (SHCollisionShape& boxShape) const noexcept; diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp index 5f679655..33ba88e7 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.cpp @@ -62,7 +62,7 @@ namespace SHADE return collisionListener.GetTriggerInfoContainer(); } - const SHPhysicsObject* const SHPhysicsSystem::GetPhysicsObject(EntityID eid) noexcept + const SHPhysicsObject* SHPhysicsSystem::GetPhysicsObject(EntityID eid) noexcept { return objectManager.GetPhysicsObject(eid); } @@ -223,55 +223,6 @@ namespace SHADE #endif } - void SHPhysicsSystem::AddForce(EntityID eid, const SHVec3& force) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtCenterOfMass(force); - } - - void SHPhysicsSystem::AddForceAtLocalPos(EntityID eid, const SHVec3& force, const SHVec3& localPos) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtLocalPosition(force, localPos); - } - - void SHPhysicsSystem::AddForceAtWorldPos(EntityID eid, const SHVec3& force, const SHVec3& worldPos) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyWorldForceAtWorldPosition(force, worldPos); - } - - void SHPhysicsSystem::AddRelativeForce(EntityID eid, const SHVec3& relativeForce) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtCenterOfMass(relativeForce); - } - - void SHPhysicsSystem::AddRelativeForceAtLocalPos(EntityID eid, const SHVec3& relativeForce, const SHVec3& localPos) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtLocalPosition(relativeForce, localPos); - } - - - void SHPhysicsSystem::AddRelativeForceAtWorldPos(EntityID eid, const SHVec3& relativeForce, const SHVec3& worldPos) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyLocalForceAtWorldPosition(relativeForce, worldPos); - } - - void SHPhysicsSystem::AddTorque(EntityID eid, const SHVec3& torque) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyWorldTorque(torque); - } - - void SHPhysicsSystem::AddRelativeTorque(EntityID eid, const SHVec3& relativeTorque) noexcept - { - const auto* PHYSICS_OBJECT = objectManager.GetPhysicsObject(eid); - PHYSICS_OBJECT->GetRigidBody()->applyLocalTorque(relativeTorque); - } - /*-----------------------------------------------------------------------------------*/ /* Private Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h index 3891ff48..3da7094b 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystem.h @@ -61,7 +61,7 @@ namespace SHADE [[nodiscard]] const std::vector& GetAllCollisionInfo () const noexcept; [[nodiscard]] const std::vector& GetAllTriggerInfo () const noexcept; - [[nodiscard]] const SHPhysicsObject* const GetPhysicsObject (EntityID eid) noexcept; + [[nodiscard]] const SHPhysicsObject* GetPhysicsObject (EntityID eid) noexcept; [[nodiscard]] const SHPhysicsObjectManager::PhysicsObjectEntityMap& GetPhysicsObjects () const noexcept; /*---------------------------------------------------------------------------------*/ /* Setter Functions */ @@ -79,25 +79,13 @@ namespace SHADE 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. + // This is done as events need to be sent out. + // TODO(Diren): Consider using a static method through the ColliderComponent. void AddCollisionShape (EntityID eid, int shapeIndex); void RemoveCollisionShape (EntityID eid, int shapeIndex); - // Forces are applied from components here. These functions should only be invoked during play (through scripts) - // Thus there is no need to check for an editor. - - void AddForce (EntityID eid, const SHVec3& force) noexcept; - void AddForceAtLocalPos (EntityID eid, const SHVec3& force, const SHVec3& localPos) noexcept; - void AddForceAtWorldPos (EntityID eid, const SHVec3& force, const SHVec3& worldPos) noexcept; - - void AddRelativeForce (EntityID eid, const SHVec3& relativeForce) noexcept; - void AddRelativeForceAtLocalPos (EntityID eid, const SHVec3& relativeForce, const SHVec3& localPos) noexcept; - void AddRelativeForceAtWorldPos (EntityID eid, const SHVec3& relativeForce, const SHVec3& worldPos) noexcept; - - void AddTorque (EntityID eid, const SHVec3& torque) noexcept; - void AddRelativeTorque (EntityID eid, const SHVec3& relativeTorque) noexcept; - /*---------------------------------------------------------------------------------*/ /* System Routines */ /*---------------------------------------------------------------------------------*/ diff --git a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp index a42da3a6..3e56ca14 100644 --- a/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp +++ b/SHADE_Engine/src/Physics/System/SHPhysicsSystemRoutines.cpp @@ -13,11 +13,14 @@ // Primary Header #include "SHPhysicsSystem.h" // Project Headers +#include "ECS_Base/Managers/SHEntityManager.h" #include "ECS_Base/Managers/SHSystemManager.h" #include "Editor/SHEditor.h" #include "Scene/SHSceneManager.h" #include "Scripting/SHScriptEngine.h" +#include "Input/SHInputManager.h" + namespace SHADE { /*-----------------------------------------------------------------------------------*/ @@ -136,16 +139,8 @@ namespace SHADE { if (scriptingSystem != nullptr) scriptingSystem->ExecuteFixedUpdates(); - - physicsSystem->worldState.world->update(static_cast(FIXED_DT)); - // Clear all forces of every body in the scene after each update - for (auto& physicsObject : physicsSystem->objectManager.physicsObjects | std::views::values) - { - auto* rp3dRigidBody = physicsObject.GetRigidBody(); - rp3dRigidBody->resetForce(); - rp3dRigidBody->resetTorque(); - } + physicsSystem->worldState.world->update(static_cast(FIXED_DT)); accumulatedTime -= FIXED_DT; ++count; diff --git a/SHADE_Managed/src/Components/RigidBody.cxx b/SHADE_Managed/src/Components/RigidBody.cxx index a88a2503..cdaa296a 100644 --- a/SHADE_Managed/src/Components/RigidBody.cxx +++ b/SHADE_Managed/src/Components/RigidBody.cxx @@ -194,6 +194,12 @@ namespace SHADE { return Convert::ToCLI(GetNativeComponent()->GetForce()); } + + void RigidBody::ClearForces() + { + GetNativeComponent()->ClearForces(); + } + /*---------------------------------------------------------------------------------*/ /* Torque Functions */ /*---------------------------------------------------------------------------------*/ @@ -212,4 +218,9 @@ namespace SHADE return Convert::ToCLI(GetNativeComponent()->GetTorque()); } + void RigidBody::ClearTorque() + { + GetNativeComponent()->ClearTorque(); + } + } \ No newline at end of file diff --git a/SHADE_Managed/src/Components/RigidBody.hxx b/SHADE_Managed/src/Components/RigidBody.hxx index 50147033..8bfe34aa 100644 --- a/SHADE_Managed/src/Components/RigidBody.hxx +++ b/SHADE_Managed/src/Components/RigidBody.hxx @@ -146,6 +146,7 @@ namespace SHADE void AddRelativeForceAtWorldPos(Vector3 relativeForce, Vector3 worldPos); Vector3 GetForce(); + void ClearForces(); /*-----------------------------------------------------------------------------*/ /* Torque Functions */ @@ -154,6 +155,7 @@ namespace SHADE void AddRelativeTorque(Vector3 relativeForce); Vector3 GetTorque(); + void ClearTorque(); }; } \ No newline at end of file