From 36341bb5e02993237917987b8d083ab5010bcc93 Mon Sep 17 00:00:00 2001 From: Bram Verhulst Date: Mon, 19 Oct 2026 00:44:29 +0200 Subject: [PATCH] feat: remove SimplePhysicsWorld --- destrum/CMakeLists.txt | 1 - .../destrum/Physics/PhysicsSceneBridge.h | 10 - .../destrum/Physics/SimplePhysicsWorld.h | 89 ------ destrum/src/Physics/SimplePhysicsWorld.cpp | 291 ------------------ tests/destrum_tests.cpp | 6 +- 5 files changed, 4 insertions(+), 393 deletions(-) delete mode 100644 destrum/include/destrum/Physics/SimplePhysicsWorld.h delete mode 100644 destrum/src/Physics/SimplePhysicsWorld.cpp diff --git a/destrum/CMakeLists.txt b/destrum/CMakeLists.txt index aec80db..72b36ce 100644 --- a/destrum/CMakeLists.txt +++ b/destrum/CMakeLists.txt @@ -127,7 +127,6 @@ set(SRC_FILES "src/Util/SceneInspector.cpp" "src/Physics/PhysicsWorld.cpp" - "src/Physics/SimplePhysicsWorld.cpp" "src/Physics/PhysicsSceneBridge.cpp" "src/Physics/JoltPhysicsWorld.cpp" ) diff --git a/destrum/include/destrum/Physics/PhysicsSceneBridge.h b/destrum/include/destrum/Physics/PhysicsSceneBridge.h index 314a8d9..696756f 100644 --- a/destrum/include/destrum/Physics/PhysicsSceneBridge.h +++ b/destrum/include/destrum/Physics/PhysicsSceneBridge.h @@ -4,19 +4,9 @@ #include #include -#include class GameObject; -// Small helper you can store inside Scene. -// -// Example: -// class Scene { -// public: -// PhysicsSceneBridge& GetPhysics() { return m_Physics; } -// private: -// PhysicsSceneBridge m_Physics{std::make_unique()}; -// }; class PhysicsSceneBridge final { public: explicit PhysicsSceneBridge(std::unique_ptr world); diff --git a/destrum/include/destrum/Physics/SimplePhysicsWorld.h b/destrum/include/destrum/Physics/SimplePhysicsWorld.h deleted file mode 100644 index 26da7da..0000000 --- a/destrum/include/destrum/Physics/SimplePhysicsWorld.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once - -#include -#include - -#include - -class Rigidbody; - -// Simple CPU placeholder backend. -// -// This is NOT a replacement for Jolt/PhysX/Bullet. -// It exists so your component/scene/render sync can be implemented and tested -// before the real backend is added. -// -// It supports: -// - static, dynamic, kinematic bodies -// - gravity -// - force/impulse integration -// - very simple sphere/box/capsule raycasts using bounding spheres -// -// It does NOT support: -// - collision response -// - contacts -// - friction -// - constraints -// - real character controllers -class SimplePhysicsWorld final : public PhysicsWorld { -public: - explicit SimplePhysicsWorld(const glm::vec3& gravity = glm::vec3{0.0f, -9.81f, 0.0f}); - - void Step(float fixedDt) override; - - PhysicsBodyHandle CreateBody(const PhysicsBodyDesc& desc) override; - void DestroyBody(PhysicsBodyHandle body) override; - - void SetBodyTransform(PhysicsBodyHandle body, const PhysicsTransform& transform) override; - PhysicsTransform GetBodyTransform(PhysicsBodyHandle body) const override; - - void SetLinearVelocity(PhysicsBodyHandle body, const glm::vec3& velocity) override; - glm::vec3 GetLinearVelocity(PhysicsBodyHandle body) const override; - - void AddForce(PhysicsBodyHandle body, const glm::vec3& force) override; - void AddImpulse(PhysicsBodyHandle body, const glm::vec3& impulse) override; - - bool Raycast(const glm::vec3& origin, - const glm::vec3& direction, - float maxDistance, - PhysicsRaycastHit& hit, - PhysicsBodyHandle ignoreBody = {}) const override; - - void SyncKinematicBodiesToPhysics(float fixedDt) override; - void SyncDynamicBodiesToTransforms(); - - [[nodiscard]] const glm::vec3& GetGravity() const { return m_Gravity; } - void SetGravity(const glm::vec3& gravity) { m_Gravity = gravity; } - -private: - struct BodyRecord { - bool alive{false}; - - PhysicsBodyHandle handle{}; - PhysicsBodyDesc desc{}; - - PhysicsTransform previousTransform{}; - PhysicsTransform currentTransform{}; - - glm::vec3 linearVelocity{0.0f}; - glm::vec3 accumulatedForce{0.0f}; - - Rigidbody* rigidbody{nullptr}; - }; - - [[nodiscard]] BodyRecord* FindBody(PhysicsBodyHandle body); - [[nodiscard]] const BodyRecord* FindBody(PhysicsBodyHandle body) const; - - [[nodiscard]] float GetApproxBoundingRadius(const BodyRecord& body) const; - [[nodiscard]] static bool RaySphere(const glm::vec3& origin, - const glm::vec3& dirNormalized, - const glm::vec3& center, - float radius, - float maxDistance, - float& outDistance); - - glm::vec3 m_Gravity{0.0f, -9.81f, 0.0f}; - - std::vector m_Bodies; - std::uint32_t m_NextId{0}; -}; diff --git a/destrum/src/Physics/SimplePhysicsWorld.cpp b/destrum/src/Physics/SimplePhysicsWorld.cpp deleted file mode 100644 index 0c9bd48..0000000 --- a/destrum/src/Physics/SimplePhysicsWorld.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#include - -#include -#include -#include - -#include -#include -#include - -SimplePhysicsWorld::SimplePhysicsWorld(const glm::vec3& gravity) - : m_Gravity(gravity) { -} - -PhysicsBodyHandle SimplePhysicsWorld::CreateBody(const PhysicsBodyDesc& desc) { - BodyRecord record{}; - record.alive = true; - record.handle = PhysicsBodyHandle{m_NextId++}; - record.desc = desc; - record.previousTransform = desc.transform; - record.currentTransform = desc.transform; - - if (desc.owner) { - record.rigidbody = desc.owner->GetComponent(); - } - - m_Bodies.emplace_back(record); - return record.handle; -} - -void SimplePhysicsWorld::DestroyBody(PhysicsBodyHandle body) { - if (BodyRecord* record = FindBody(body)) { - record->alive = false; - record->rigidbody = nullptr; - record->desc.owner = nullptr; - } -} - -void SimplePhysicsWorld::SetBodyTransform(PhysicsBodyHandle body, const PhysicsTransform& transform) { - BodyRecord* record = FindBody(body); - if (!record) { - return; - } - - record->previousTransform = record->currentTransform; - record->currentTransform = transform; -} - -PhysicsTransform SimplePhysicsWorld::GetBodyTransform(PhysicsBodyHandle body) const { - const BodyRecord* record = FindBody(body); - if (!record) { - return {}; - } - - return record->currentTransform; -} - -void SimplePhysicsWorld::SetLinearVelocity(PhysicsBodyHandle body, const glm::vec3& velocity) { - BodyRecord* record = FindBody(body); - if (!record) { - return; - } - - record->linearVelocity = velocity; -} - -glm::vec3 SimplePhysicsWorld::GetLinearVelocity(PhysicsBodyHandle body) const { - const BodyRecord* record = FindBody(body); - if (!record) { - return glm::vec3{0.0f}; - } - - return record->linearVelocity; -} - -void SimplePhysicsWorld::AddForce(PhysicsBodyHandle body, const glm::vec3& force) { - BodyRecord* record = FindBody(body); - if (!record || record->desc.type != RigidbodyType::Dynamic) { - return; - } - - record->accumulatedForce += force; -} - -void SimplePhysicsWorld::AddImpulse(PhysicsBodyHandle body, const glm::vec3& impulse) { - BodyRecord* record = FindBody(body); - if (!record || record->desc.type != RigidbodyType::Dynamic) { - return; - } - - const float invMass = record->desc.mass > 0.0f ? 1.0f / record->desc.mass : 0.0f; - record->linearVelocity += impulse * invMass; -} - -void SimplePhysicsWorld::Step(float fixedDt) { - if (fixedDt <= 0.0f) { - return; - } - - for (BodyRecord& body : m_Bodies) { - if (!body.alive || !body.desc.owner || - body.desc.owner->IsBeingDestroyed() || - !body.desc.owner->IsActiveInHierarchy()) { - continue; - } - - body.previousTransform = body.currentTransform; - - if (body.desc.type != RigidbodyType::Dynamic) { - continue; - } - - const float invMass = body.desc.mass > 0.0f ? 1.0f / body.desc.mass : 0.0f; - - glm::vec3 acceleration{0.0f}; - - if (body.desc.useGravity) { - acceleration += m_Gravity; - } - - acceleration += body.accumulatedForce * invMass; - - // Semi-implicit Euler. - body.linearVelocity += acceleration * fixedDt; - body.currentTransform.position += body.linearVelocity * fixedDt; - - body.accumulatedForce = glm::vec3{0.0f}; - } - - // Compact dead records occasionally. - m_Bodies.erase( - std::remove_if(m_Bodies.begin(), m_Bodies.end(), - [](const BodyRecord& body) { return !body.alive; }), - m_Bodies.end()); -} - -void SimplePhysicsWorld::SyncKinematicBodiesToPhysics(float fixedDt) { - for (BodyRecord& body : m_Bodies) { - if (!body.alive || body.desc.type != RigidbodyType::Kinematic || !body.desc.owner || - body.desc.owner->IsBeingDestroyed() || !body.desc.owner->IsActiveInHierarchy()) { - continue; - } - - Transform& transform = body.desc.owner->GetTransform(); - - body.previousTransform = body.currentTransform; - body.currentTransform.position = transform.GetWorldPosition(); - body.currentTransform.rotation = transform.GetWorldRotation(); - body.linearVelocity = fixedDt > 0.0f - ? (body.currentTransform.position - body.previousTransform.position) / fixedDt - : glm::vec3{0.0f}; - } -} - -void SimplePhysicsWorld::SyncDynamicBodiesToTransforms() { - for (BodyRecord& body : m_Bodies) { - if (!body.alive || body.desc.type != RigidbodyType::Dynamic || !body.desc.owner || - body.desc.owner->IsBeingDestroyed() || !body.desc.owner->IsActiveInHierarchy()) { - continue; - } - - Transform& transform = body.desc.owner->GetTransform(); - transform.SetWorldPosition(body.currentTransform.position); - transform.SetWorldRotation(body.currentTransform.rotation); - } -} - -bool SimplePhysicsWorld::Raycast(const glm::vec3& origin, - const glm::vec3& direction, - float maxDistance, - PhysicsRaycastHit& hit, - PhysicsBodyHandle ignoreBody) const { - if (maxDistance <= 0.0f) { - return false; - } - - const float len = glm::length(direction); - if (len <= 0.00001f) { - return false; - } - - const glm::vec3 dir = direction / len; - - bool found = false; - float bestDistance = std::numeric_limits::max(); - - for (const BodyRecord& body : m_Bodies) { - if (!body.alive || body.desc.shape.type == PhysicsShapeType::None || - !body.desc.owner || body.desc.owner->IsBeingDestroyed() || - !body.desc.owner->IsActiveInHierarchy() || - body.desc.shape.isTrigger || - (ignoreBody.IsValid() && body.handle.id == ignoreBody.id)) { - continue; - } - - float distance = 0.0f; - const float radius = GetApproxBoundingRadius(body); - const glm::vec3 center = body.currentTransform.position - + body.currentTransform.rotation * body.desc.shape.centerOffset; - - if (RaySphere(origin, dir, center, radius, maxDistance, distance)) { - if (distance < bestDistance) { - bestDistance = distance; - found = true; - - hit.object = body.desc.owner; - hit.body = body.handle; - hit.distance = distance; - hit.point = origin + dir * distance; - - const glm::vec3 n = hit.point - center; - hit.normal = glm::length(n) > 0.00001f ? glm::normalize(n) : glm::vec3{0.0f, 1.0f, 0.0f}; - } - } - } - - return found; -} - -SimplePhysicsWorld::BodyRecord* SimplePhysicsWorld::FindBody(PhysicsBodyHandle body) { - for (BodyRecord& record : m_Bodies) { - if (record.alive && record.handle == body) { - return &record; - } - } - - return nullptr; -} - -const SimplePhysicsWorld::BodyRecord* SimplePhysicsWorld::FindBody(PhysicsBodyHandle body) const { - for (const BodyRecord& record : m_Bodies) { - if (record.alive && record.handle == body) { - return &record; - } - } - - return nullptr; -} - -float SimplePhysicsWorld::GetApproxBoundingRadius(const BodyRecord& body) const { - const PhysicsShapeDesc& shape = body.desc.shape; - - switch (shape.type) { - case PhysicsShapeType::Box: - return glm::length(shape.halfExtents); - - case PhysicsShapeType::Sphere: - return shape.radius; - - case PhysicsShapeType::Capsule: - return shape.height * 0.5f; - - case PhysicsShapeType::None: - default: - return 0.0f; - } -} - -bool SimplePhysicsWorld::RaySphere(const glm::vec3& origin, - const glm::vec3& dirNormalized, - const glm::vec3& center, - float radius, - float maxDistance, - float& outDistance) { - const glm::vec3 oc = origin - center; - - const float a = glm::dot(dirNormalized, dirNormalized); - const float b = 2.0f * glm::dot(oc, dirNormalized); - const float c = glm::dot(oc, oc) - radius * radius; - - const float discriminant = b * b - 4.0f * a * c; - if (discriminant < 0.0f) { - return false; - } - - const float sqrtDisc = std::sqrt(discriminant); - const float t0 = (-b - sqrtDisc) / (2.0f * a); - const float t1 = (-b + sqrtDisc) / (2.0f * a); - - float t = t0; - if (t < 0.0f) { - t = t1; - } - - if (t < 0.0f || t > maxDistance) { - return false; - } - - outDistance = t; - return true; -} diff --git a/tests/destrum_tests.cpp b/tests/destrum_tests.cpp index 7204647..e5a68ff 100644 --- a/tests/destrum_tests.cpp +++ b/tests/destrum_tests.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -384,7 +383,10 @@ namespace { void testPhysicsWorldUnits() { - SimplePhysicsWorld world{glm::vec3{0.0f}}; + JoltPhysicsWorld world{{ + .workerThreadCount = 1, + .gravity = glm::vec3{0.0f} + }}; GameObject object{"scaled-physics"}; object.GetTransform().SetLocalScale(glm::vec3{0.5f}); object.AddComponent(1.0f);