mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-24 21:55:09 +00:00
refactor: Replace PhysicsBridge with PhysicsBridgeService and update related implementations
This commit is contained in:
@@ -148,7 +148,6 @@ if(BUILD_SDL3_APP)
|
||||
src/services/impl/gui_renderer_service.cpp
|
||||
src/services/impl/vulkan_gui_service.cpp
|
||||
src/services/impl/bullet_physics_service.cpp
|
||||
src/services/impl/physics_bridge.cpp
|
||||
src/services/impl/scene_service.cpp
|
||||
src/services/impl/graphics_service.cpp
|
||||
src/app/service_based_app.cpp
|
||||
|
||||
@@ -21,7 +21,7 @@ void BulletPhysicsService::Initialize(const btVector3& gravity) {
|
||||
return;
|
||||
}
|
||||
|
||||
physicsBridge_ = std::make_unique<PhysicsBridge>(logger_);
|
||||
physicsBridge_ = std::make_unique<PhysicsBridgeService>(logger_);
|
||||
initialized_ = true;
|
||||
|
||||
logger_->Info("Physics service initialized");
|
||||
@@ -51,7 +51,11 @@ bool BulletPhysicsService::AddBoxRigidBody(const std::string& name,
|
||||
}
|
||||
|
||||
std::string error;
|
||||
return physicsBridge_->addBoxRigidBody(name, halfExtents, mass, transform, error);
|
||||
if (!physicsBridge_->AddBoxRigidBody(name, halfExtents, mass, transform, error)) {
|
||||
logger_->Error("AddBoxRigidBody failed: " + error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::AddSphereRigidBody(const std::string& name,
|
||||
@@ -60,16 +64,16 @@ bool BulletPhysicsService::AddSphereRigidBody(const std::string& name,
|
||||
const btTransform& transform) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support sphere rigid bodies in current implementation
|
||||
logger_->Warn("AddSphereRigidBody not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support sphere rigid bodies in current implementation
|
||||
logger_->Warn("AddSphereRigidBody not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::RemoveRigidBody(const std::string& name) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support removing bodies in current implementation
|
||||
logger_->Warn("RemoveRigidBody not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support removing bodies in current implementation
|
||||
logger_->Warn("RemoveRigidBody not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -80,7 +84,7 @@ void BulletPhysicsService::StepSimulation(float deltaTime, int maxSubSteps) {
|
||||
throw std::runtime_error("Physics service not initialized");
|
||||
}
|
||||
|
||||
physicsBridge_->stepSimulation(deltaTime);
|
||||
physicsBridge_->StepSimulation(deltaTime);
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::GetTransform(const std::string& name, btTransform& outTransform) const {
|
||||
@@ -89,43 +93,49 @@ bool BulletPhysicsService::GetTransform(const std::string& name, btTransform& ou
|
||||
}
|
||||
|
||||
std::string error;
|
||||
return physicsBridge_->getRigidBodyTransform(name, outTransform, error);
|
||||
if (!physicsBridge_->GetRigidBodyTransform(name, outTransform, error)) {
|
||||
if (logger_) {
|
||||
logger_->Warn("GetTransform failed: " + error);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::SetTransform(const std::string& name, const btTransform& transform) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support setting transforms in current implementation
|
||||
logger_->Warn("SetTransform not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support setting transforms in current implementation
|
||||
logger_->Warn("SetTransform not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::ApplyForce(const std::string& name, const btVector3& force) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support applying forces in current implementation
|
||||
logger_->Warn("ApplyForce not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support applying forces in current implementation
|
||||
logger_->Warn("ApplyForce not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::ApplyImpulse(const std::string& name, const btVector3& impulse) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support applying impulses in current implementation
|
||||
logger_->Warn("ApplyImpulse not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support applying impulses in current implementation
|
||||
logger_->Warn("ApplyImpulse not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BulletPhysicsService::SetLinearVelocity(const std::string& name, const btVector3& velocity) {
|
||||
logger_->TraceFunction(__func__);
|
||||
|
||||
// PhysicsBridge doesn't support setting velocity in current implementation
|
||||
logger_->Warn("SetLinearVelocity not supported by PhysicsBridge");
|
||||
// PhysicsBridgeService doesn't support setting velocity in current implementation
|
||||
logger_->Warn("SetLinearVelocity not supported by PhysicsBridgeService");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t BulletPhysicsService::GetBodyCount() const {
|
||||
// PhysicsBridge doesn't expose GetBodyCount in current implementation
|
||||
// PhysicsBridgeService doesn't expose GetBodyCount in current implementation
|
||||
// Returning 0 as stub - could track bodies in wrapper if needed
|
||||
return 0;
|
||||
}
|
||||
@@ -137,10 +147,10 @@ void BulletPhysicsService::Clear() {
|
||||
return;
|
||||
}
|
||||
|
||||
// PhysicsBridge doesn't expose Clear in current implementation
|
||||
// PhysicsBridgeService doesn't expose Clear in current implementation
|
||||
// Shutdown and reinitialize to clear all bodies
|
||||
physicsBridge_.reset();
|
||||
physicsBridge_ = std::make_unique<PhysicsBridge>(logger_);
|
||||
physicsBridge_ = std::make_unique<PhysicsBridgeService>(logger_);
|
||||
}
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "../interfaces/i_physics_service.hpp"
|
||||
#include "../interfaces/i_logger.hpp"
|
||||
#include "physics_bridge.hpp"
|
||||
#include "physics_bridge_service.hpp"
|
||||
#include "../../di/lifecycle.hpp"
|
||||
#include <memory>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace sdl3cpp::services::impl {
|
||||
/**
|
||||
* @brief Bullet physics service implementation.
|
||||
*
|
||||
* Small wrapper service (~120 lines) around PhysicsBridge.
|
||||
* Small wrapper service (~120 lines) around PhysicsBridgeService.
|
||||
* Provides rigid body physics simulation using Bullet Physics.
|
||||
*/
|
||||
class BulletPhysicsService : public IPhysicsService,
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
std::shared_ptr<ILogger> logger_;
|
||||
std::unique_ptr<PhysicsBridge> physicsBridge_;
|
||||
std::unique_ptr<PhysicsBridgeService> physicsBridge_;
|
||||
bool initialized_ = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
#include "physics_bridge.hpp"
|
||||
#include "../interfaces/i_logger.hpp"
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
|
||||
PhysicsBridge::PhysicsBridge(std::shared_ptr<services::ILogger> logger)
|
||||
: collisionConfig_(std::make_unique<btDefaultCollisionConfiguration>()),
|
||||
dispatcher_(std::make_unique<btCollisionDispatcher>(collisionConfig_.get())),
|
||||
broadphase_(std::make_unique<btDbvtBroadphase>()),
|
||||
solver_(std::make_unique<btSequentialImpulseConstraintSolver>()),
|
||||
world_(std::make_unique<btDiscreteDynamicsWorld>(
|
||||
dispatcher_.get(),
|
||||
broadphase_.get(),
|
||||
solver_.get(),
|
||||
collisionConfig_.get())),
|
||||
logger_(std::move(logger)) {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridge", "PhysicsBridge");
|
||||
}
|
||||
world_->setGravity(btVector3(0.0f, -9.81f, 0.0f));
|
||||
}
|
||||
|
||||
PhysicsBridge::~PhysicsBridge() {
|
||||
if (world_) {
|
||||
for (auto& [name, entry] : bodies_) {
|
||||
if (entry.body) {
|
||||
world_->removeRigidBody(entry.body.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsBridge::addBoxRigidBody(const std::string& name,
|
||||
const btVector3& halfExtents,
|
||||
float mass,
|
||||
const btTransform& transform,
|
||||
std::string& error) {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridge", "addBoxRigidBody", "name=" + name);
|
||||
}
|
||||
if (name.empty()) {
|
||||
error = "Rigid body name must not be empty";
|
||||
return false;
|
||||
}
|
||||
if (!world_) {
|
||||
error = "Physics world is not initialized";
|
||||
return false;
|
||||
}
|
||||
if (bodies_.count(name)) {
|
||||
error = "Rigid body already exists: " + name;
|
||||
return false;
|
||||
}
|
||||
auto shape = std::make_unique<btBoxShape>(halfExtents);
|
||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||
if (mass > 0.0f) {
|
||||
shape->calculateLocalInertia(mass, inertia);
|
||||
}
|
||||
auto motionState = std::make_unique<btDefaultMotionState>(transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo constructionInfo(
|
||||
mass,
|
||||
motionState.get(),
|
||||
shape.get(),
|
||||
inertia);
|
||||
auto body = std::make_unique<btRigidBody>(constructionInfo);
|
||||
world_->addRigidBody(body.get());
|
||||
bodies_.emplace(name, BodyRecord{
|
||||
std::move(shape),
|
||||
std::move(motionState),
|
||||
std::move(body),
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
int PhysicsBridge::stepSimulation(float deltaTime) {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridge", "stepSimulation", "deltaTime=" + std::to_string(deltaTime));
|
||||
}
|
||||
if (!world_) {
|
||||
return 0;
|
||||
}
|
||||
return static_cast<int>(world_->stepSimulation(deltaTime, 10, 1.0f / 60.0f));
|
||||
}
|
||||
|
||||
bool PhysicsBridge::getRigidBodyTransform(const std::string& name,
|
||||
btTransform& outTransform,
|
||||
std::string& error) const {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridge", "getRigidBodyTransform", "name=" + name);
|
||||
}
|
||||
auto it = bodies_.find(name);
|
||||
if (it == bodies_.end()) {
|
||||
error = "Rigid body not found: " + name;
|
||||
return false;
|
||||
}
|
||||
if (!it->second.motionState) {
|
||||
error = "Rigid body motion state is missing";
|
||||
return false;
|
||||
}
|
||||
it->second.motionState->getWorldTransform(outTransform);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
@@ -1,58 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace sdl3cpp::services {
|
||||
class ILogger;
|
||||
}
|
||||
|
||||
class btVector3;
|
||||
class btTransform;
|
||||
class btCollisionShape;
|
||||
class btMotionState;
|
||||
class btRigidBody;
|
||||
class btDefaultCollisionConfiguration;
|
||||
class btCollisionDispatcher;
|
||||
class btBroadphaseInterface;
|
||||
class btSequentialImpulseConstraintSolver;
|
||||
class btDiscreteDynamicsWorld;
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
|
||||
class PhysicsBridge {
|
||||
public:
|
||||
explicit PhysicsBridge(std::shared_ptr<services::ILogger> logger);
|
||||
~PhysicsBridge();
|
||||
|
||||
PhysicsBridge(const PhysicsBridge&) = delete;
|
||||
PhysicsBridge& operator=(const PhysicsBridge&) = delete;
|
||||
|
||||
bool addBoxRigidBody(const std::string& name,
|
||||
const btVector3& halfExtents,
|
||||
float mass,
|
||||
const btTransform& transform,
|
||||
std::string& error);
|
||||
int stepSimulation(float deltaTime);
|
||||
bool getRigidBodyTransform(const std::string& name,
|
||||
btTransform& outTransform,
|
||||
std::string& error) const;
|
||||
|
||||
private:
|
||||
struct BodyRecord {
|
||||
std::unique_ptr<btCollisionShape> shape;
|
||||
std::unique_ptr<btMotionState> motionState;
|
||||
std::unique_ptr<btRigidBody> body;
|
||||
};
|
||||
|
||||
std::unique_ptr<btDefaultCollisionConfiguration> collisionConfig_;
|
||||
std::unique_ptr<btCollisionDispatcher> dispatcher_;
|
||||
std::unique_ptr<btBroadphaseInterface> broadphase_;
|
||||
std::unique_ptr<btSequentialImpulseConstraintSolver> solver_;
|
||||
std::unique_ptr<btDiscreteDynamicsWorld> world_;
|
||||
std::unordered_map<std::string, BodyRecord> bodies_;
|
||||
std::shared_ptr<services::ILogger> logger_;
|
||||
};
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
@@ -1,14 +1,36 @@
|
||||
#include "physics_bridge_service.hpp"
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
|
||||
PhysicsBridgeService::PhysicsBridgeService(std::shared_ptr<ILogger> logger)
|
||||
: bridge_(std::make_unique<PhysicsBridge>(logger)),
|
||||
: collisionConfig_(std::make_unique<btDefaultCollisionConfiguration>()),
|
||||
dispatcher_(std::make_unique<btCollisionDispatcher>(collisionConfig_.get())),
|
||||
broadphase_(std::make_unique<btDbvtBroadphase>()),
|
||||
solver_(std::make_unique<btSequentialImpulseConstraintSolver>()),
|
||||
world_(std::make_unique<btDiscreteDynamicsWorld>(
|
||||
dispatcher_.get(),
|
||||
broadphase_.get(),
|
||||
solver_.get(),
|
||||
collisionConfig_.get())),
|
||||
logger_(std::move(logger)) {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridgeService", "PhysicsBridgeService");
|
||||
}
|
||||
world_->setGravity(btVector3(0.0f, -9.81f, 0.0f));
|
||||
}
|
||||
|
||||
PhysicsBridgeService::~PhysicsBridgeService() {
|
||||
if (world_) {
|
||||
for (auto& [name, entry] : bodies_) {
|
||||
if (entry.body) {
|
||||
world_->removeRigidBody(entry.body.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsBridgeService::AddBoxRigidBody(const std::string& name,
|
||||
@@ -19,21 +41,47 @@ bool PhysicsBridgeService::AddBoxRigidBody(const std::string& name,
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridgeService", "AddBoxRigidBody", "name=" + name);
|
||||
}
|
||||
if (!bridge_) {
|
||||
error = "Physics bridge not initialized";
|
||||
if (name.empty()) {
|
||||
error = "Rigid body name must not be empty";
|
||||
return false;
|
||||
}
|
||||
return bridge_->addBoxRigidBody(name, halfExtents, mass, transform, error);
|
||||
if (!world_) {
|
||||
error = "Physics world is not initialized";
|
||||
return false;
|
||||
}
|
||||
if (bodies_.count(name)) {
|
||||
error = "Rigid body already exists: " + name;
|
||||
return false;
|
||||
}
|
||||
auto shape = std::make_unique<btBoxShape>(halfExtents);
|
||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||
if (mass > 0.0f) {
|
||||
shape->calculateLocalInertia(mass, inertia);
|
||||
}
|
||||
auto motionState = std::make_unique<btDefaultMotionState>(transform);
|
||||
btRigidBody::btRigidBodyConstructionInfo constructionInfo(
|
||||
mass,
|
||||
motionState.get(),
|
||||
shape.get(),
|
||||
inertia);
|
||||
auto body = std::make_unique<btRigidBody>(constructionInfo);
|
||||
world_->addRigidBody(body.get());
|
||||
bodies_.emplace(name, BodyRecord{
|
||||
std::move(shape),
|
||||
std::move(motionState),
|
||||
std::move(body),
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
int PhysicsBridgeService::StepSimulation(float deltaTime) {
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridgeService", "StepSimulation", "deltaTime=" + std::to_string(deltaTime));
|
||||
}
|
||||
if (!bridge_) {
|
||||
if (!world_) {
|
||||
return 0;
|
||||
}
|
||||
return bridge_->stepSimulation(deltaTime);
|
||||
return static_cast<int>(world_->stepSimulation(deltaTime, 10, 1.0f / 60.0f));
|
||||
}
|
||||
|
||||
bool PhysicsBridgeService::GetRigidBodyTransform(const std::string& name,
|
||||
@@ -42,11 +90,17 @@ bool PhysicsBridgeService::GetRigidBodyTransform(const std::string& name,
|
||||
if (logger_) {
|
||||
logger_->Trace("PhysicsBridgeService", "GetRigidBodyTransform", "name=" + name);
|
||||
}
|
||||
if (!bridge_) {
|
||||
error = "Physics bridge not initialized";
|
||||
auto it = bodies_.find(name);
|
||||
if (it == bodies_.end()) {
|
||||
error = "Rigid body not found: " + name;
|
||||
return false;
|
||||
}
|
||||
return bridge_->getRigidBodyTransform(name, outTransform, error);
|
||||
if (!it->second.motionState) {
|
||||
error = "Rigid body motion state is missing";
|
||||
return false;
|
||||
}
|
||||
it->second.motionState->getWorldTransform(outTransform);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace sdl3cpp::services::impl
|
||||
|
||||
@@ -2,8 +2,20 @@
|
||||
|
||||
#include "../interfaces/i_physics_bridge_service.hpp"
|
||||
#include "../interfaces/i_logger.hpp"
|
||||
#include "physics_bridge.hpp"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class btVector3;
|
||||
class btTransform;
|
||||
class btCollisionShape;
|
||||
class btMotionState;
|
||||
class btRigidBody;
|
||||
class btDefaultCollisionConfiguration;
|
||||
class btCollisionDispatcher;
|
||||
class btBroadphaseInterface;
|
||||
class btSequentialImpulseConstraintSolver;
|
||||
class btDiscreteDynamicsWorld;
|
||||
|
||||
namespace sdl3cpp::services::impl {
|
||||
|
||||
@@ -13,6 +25,7 @@ namespace sdl3cpp::services::impl {
|
||||
class PhysicsBridgeService : public IPhysicsBridgeService {
|
||||
public:
|
||||
explicit PhysicsBridgeService(std::shared_ptr<ILogger> logger);
|
||||
~PhysicsBridgeService() override;
|
||||
|
||||
bool AddBoxRigidBody(const std::string& name,
|
||||
const btVector3& halfExtents,
|
||||
@@ -25,7 +38,18 @@ public:
|
||||
std::string& error) const override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<PhysicsBridge> bridge_;
|
||||
struct BodyRecord {
|
||||
std::unique_ptr<btCollisionShape> shape;
|
||||
std::unique_ptr<btMotionState> motionState;
|
||||
std::unique_ptr<btRigidBody> body;
|
||||
};
|
||||
|
||||
std::unique_ptr<btDefaultCollisionConfiguration> collisionConfig_;
|
||||
std::unique_ptr<btCollisionDispatcher> dispatcher_;
|
||||
std::unique_ptr<btBroadphaseInterface> broadphase_;
|
||||
std::unique_ptr<btSequentialImpulseConstraintSolver> solver_;
|
||||
std::unique_ptr<btDiscreteDynamicsWorld> world_;
|
||||
std::unordered_map<std::string, BodyRecord> bodies_;
|
||||
std::shared_ptr<ILogger> logger_;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace sdl3cpp::services {
|
||||
* @brief Physics simulation service interface.
|
||||
*
|
||||
* Provides rigid body physics simulation using Bullet Physics.
|
||||
* Wraps the PhysicsBridge class with a clean service interface.
|
||||
* Wraps the physics bridge service with a clean simulation interface.
|
||||
*/
|
||||
class IPhysicsService {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user