Files
SDL3CPlusPlus/src/services/impl/bullet_physics_service.cpp
johndoe6345789 cb5b58ca9e feat(physics): Enhance physics bridge service with new functionalities
- Added SetGravity method to adjust the gravity in the physics world.
- Introduced AddSphereRigidBody method for creating sphere rigid bodies.
- Implemented RemoveRigidBody method to delete existing rigid bodies.
- Added SetRigidBodyTransform method to update the position and rotation of rigid bodies.
- Included ApplyForce and ApplyImpulse methods for applying forces and impulses to rigid bodies.
- Added SetLinearVelocity method to set the linear velocity of rigid bodies.
- Enhanced StepSimulation method to accept a maxSubSteps parameter.
- Implemented GetBodyCount method to retrieve the number of rigid bodies in the world.
- Added Clear method to remove all rigid bodies from the physics world.
- Updated the script engine service to bind new physics methods to Lua.
- Enhanced material configuration handling in shader script service.
- Introduced MaterialXMaterialConfig structure for better material management.
- Added texture binding support in ShaderPaths structure.
- Included stb_image implementation for image loading support.
2026-01-07 00:20:19 +00:00

250 lines
8.3 KiB
C++

#include "bullet_physics_service.hpp"
#include "../interfaces/i_logger.hpp"
#include <stdexcept>
namespace sdl3cpp::services::impl {
BulletPhysicsService::BulletPhysicsService(std::shared_ptr<ILogger> logger)
: logger_(std::move(logger)) {
if (logger_) {
logger_->Trace("BulletPhysicsService", "BulletPhysicsService");
}
}
BulletPhysicsService::~BulletPhysicsService() {
if (logger_) {
logger_->Trace("BulletPhysicsService", "~BulletPhysicsService");
}
if (initialized_) {
Shutdown();
}
}
void BulletPhysicsService::Initialize(const btVector3& gravity) {
logger_->Trace("BulletPhysicsService", "Initialize",
"gravity.x=" + std::to_string(gravity.getX()) +
", gravity.y=" + std::to_string(gravity.getY()) +
", gravity.z=" + std::to_string(gravity.getZ()));
gravity_ = gravity;
bool wasInitialized = initialized_;
if (!initialized_) {
physicsBridge_ = std::make_unique<PhysicsBridgeService>(logger_);
initialized_ = true;
}
if (physicsBridge_) {
std::string error;
if (!physicsBridge_->SetGravity(gravity_, error)) {
logger_->Warn("SetGravity failed: " + error);
}
}
if (!wasInitialized && initialized_) {
logger_->Info("Physics service initialized");
}
}
void BulletPhysicsService::Shutdown() noexcept {
logger_->Trace("BulletPhysicsService", "Shutdown");
if (!initialized_) {
return;
}
physicsBridge_.reset();
initialized_ = false;
logger_->Info("Physics service shutdown");
}
bool BulletPhysicsService::AddBoxRigidBody(const std::string& name,
const btVector3& halfExtents,
float mass,
const btTransform& transform) {
logger_->Trace("BulletPhysicsService", "AddBoxRigidBody",
"name=" + name +
", halfExtents.x=" + std::to_string(halfExtents.getX()) +
", halfExtents.y=" + std::to_string(halfExtents.getY()) +
", halfExtents.z=" + std::to_string(halfExtents.getZ()) +
", mass=" + std::to_string(mass) +
", origin.x=" + std::to_string(transform.getOrigin().getX()) +
", origin.y=" + std::to_string(transform.getOrigin().getY()) +
", origin.z=" + std::to_string(transform.getOrigin().getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string 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,
float radius,
float mass,
const btTransform& transform) {
logger_->Trace("BulletPhysicsService", "AddSphereRigidBody",
"name=" + name +
", radius=" + std::to_string(radius) +
", mass=" + std::to_string(mass) +
", origin.x=" + std::to_string(transform.getOrigin().getX()) +
", origin.y=" + std::to_string(transform.getOrigin().getY()) +
", origin.z=" + std::to_string(transform.getOrigin().getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->AddSphereRigidBody(name, radius, mass, transform, error)) {
logger_->Error("AddSphereRigidBody failed: " + error);
return false;
}
return true;
}
bool BulletPhysicsService::RemoveRigidBody(const std::string& name) {
logger_->Trace("BulletPhysicsService", "RemoveRigidBody", "name=" + name);
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->RemoveRigidBody(name, error)) {
logger_->Error("RemoveRigidBody failed: " + error);
return false;
}
return true;
}
void BulletPhysicsService::StepSimulation(float deltaTime, int maxSubSteps) {
logger_->Trace("BulletPhysicsService", "StepSimulation",
"deltaTime=" + std::to_string(deltaTime) +
", maxSubSteps=" + std::to_string(maxSubSteps));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
physicsBridge_->StepSimulation(deltaTime, maxSubSteps);
}
bool BulletPhysicsService::GetTransform(const std::string& name, btTransform& outTransform) const {
logger_->Trace("BulletPhysicsService", "GetTransform", "name=" + name);
if (!physicsBridge_) {
return false;
}
std::string 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_->Trace("BulletPhysicsService", "SetTransform",
"name=" + name +
", origin.x=" + std::to_string(transform.getOrigin().getX()) +
", origin.y=" + std::to_string(transform.getOrigin().getY()) +
", origin.z=" + std::to_string(transform.getOrigin().getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->SetRigidBodyTransform(name, transform, error)) {
logger_->Error("SetTransform failed: " + error);
return false;
}
return true;
}
bool BulletPhysicsService::ApplyForce(const std::string& name, const btVector3& force) {
logger_->Trace("BulletPhysicsService", "ApplyForce",
"name=" + name +
", force.x=" + std::to_string(force.getX()) +
", force.y=" + std::to_string(force.getY()) +
", force.z=" + std::to_string(force.getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->ApplyForce(name, force, error)) {
logger_->Error("ApplyForce failed: " + error);
return false;
}
return true;
}
bool BulletPhysicsService::ApplyImpulse(const std::string& name, const btVector3& impulse) {
logger_->Trace("BulletPhysicsService", "ApplyImpulse",
"name=" + name +
", impulse.x=" + std::to_string(impulse.getX()) +
", impulse.y=" + std::to_string(impulse.getY()) +
", impulse.z=" + std::to_string(impulse.getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->ApplyImpulse(name, impulse, error)) {
logger_->Error("ApplyImpulse failed: " + error);
return false;
}
return true;
}
bool BulletPhysicsService::SetLinearVelocity(const std::string& name, const btVector3& velocity) {
logger_->Trace("BulletPhysicsService", "SetLinearVelocity",
"name=" + name +
", velocity.x=" + std::to_string(velocity.getX()) +
", velocity.y=" + std::to_string(velocity.getY()) +
", velocity.z=" + std::to_string(velocity.getZ()));
if (!physicsBridge_) {
throw std::runtime_error("Physics service not initialized");
}
std::string error;
if (!physicsBridge_->SetLinearVelocity(name, velocity, error)) {
logger_->Error("SetLinearVelocity failed: " + error);
return false;
}
return true;
}
size_t BulletPhysicsService::GetBodyCount() const {
logger_->Trace("BulletPhysicsService", "GetBodyCount");
if (!physicsBridge_) {
return 0;
}
return physicsBridge_->GetBodyCount();
}
void BulletPhysicsService::Clear() {
logger_->Trace("BulletPhysicsService", "Clear");
if (!physicsBridge_) {
return;
}
physicsBridge_->Clear();
}
} // namespace sdl3cpp::services::impl