mirror of
https://github.com/johndoe6345789/SDL3CPlusPlus.git
synced 2026-04-25 14:15:02 +00:00
- 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.
250 lines
8.3 KiB
C++
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
|