1#include "physics/PhysicsManager.h"
3#include <btBulletCollisionCommon.h>
4#include <btBulletDynamicsCommon.h>
7#include "physics/CollisionObject.h"
9#include "physics/RigidBody.h"
19 m_broadphase = std::make_unique<btDbvtBroadphase>();
20 m_collisionConfig = std::make_unique<btDefaultCollisionConfiguration>();
21 m_dispatcher = std::make_unique<btCollisionDispatcher>(m_collisionConfig.get());
22 m_solver = std::make_unique<btSequentialImpulseConstraintSolver>();
23 m_world = std::make_unique<btDiscreteDynamicsWorld>(
24 m_dispatcher.get(), m_broadphase.get(), m_solver.get(), m_collisionConfig.get()
27 m_world->setGravity(btVector3(0,
kGravity, 0));
34 auto dispatcher = m_world->getDispatcher();
35 const auto numManifolds = dispatcher->getNumManifolds();
37 for (
int i = 0; i < numManifolds; ++i)
39 auto manifold = dispatcher->getManifoldByIndexInternal(i);
46 auto bodyA =
reinterpret_cast<CollisionObject *
>(manifold->getBody0()->getUserPointer());
47 auto bodyB =
reinterpret_cast<CollisionObject *
>(manifold->getBody1()->getUserPointer());
54 const auto numContacts = manifold->getNumContacts();
55 for (
int j = 0; j < numContacts; ++j)
57 const auto &point = manifold->getContactPoint(j);
58 const vec3 pos(point.m_positionWorldOnB.x(), point.m_positionWorldOnB.y(), point.m_positionWorldOnB.z());
59 const vec3 norm(point.m_normalWorldOnB.x(), point.m_normalWorldOnB.y(), point.m_normalWorldOnB.z());
61 bodyA->DispatchContactEvent(bodyB, pos, norm);
62 bodyB->DispatchContactEvent(bodyA, pos, norm);
69 if (!body || !m_world)
74 if (
auto rigidBody = body->
GetBody())
76 m_world->addRigidBody(rigidBody, btBroadphaseProxy::StaticFilter, btBroadphaseProxy::AllFilter);
83 if (!body || !m_world)
88 if (
auto rigidBody = body->
GetBody())
90 m_world->removeRigidBody(rigidBody);
107 const btVector3 btFrom(btScalar(from.x), btScalar(from.y), btScalar(from.z));
108 const btVector3 btTo(btScalar(to.x), btScalar(to.y), btScalar(to.z));
110 btCollisionWorld::ClosestRayResultCallback cb(btFrom, btTo);
111 m_world->rayTest(btFrom, btTo, cb);
118 out.
point =
vec3(cb.m_hitPointWorld.x(), cb.m_hitPointWorld.y(), cb.m_hitPointWorld.z());
119 out.
normal =
vec3(cb.m_hitNormalWorld.x(), cb.m_hitNormalWorld.y(), cb.m_hitNormalWorld.z());
120 out.
fraction = cb.m_closestHitFraction;
123 if (cb.m_collisionObject)
125 if (
auto *co =
reinterpret_cast<CollisionObject *
>(cb.m_collisionObject->getUserPointer()))
127 out.
object = co->GetOwner();
Engine-wide compile-time tunables and ANSI colour codes.
constexpr mnd::f32 kGravity
constexpr mnd::f32 kFixedTimeStep
constexpr mnd::i32 kMaxSubSteps
Result struct for PhysicsManager::Raycast.
bool Raycast(const vec3 &from, const vec3 &to, RayHit &out)
void AddRigidBody(RigidBody *body)
Register a rigid body so it participates in simulation and collision.
btDiscreteDynamicsWorld * GetWorld()
Raw pointer to the underlying Bullet world (for advanced/internal use).
void Update(float deltaTime)
Step the simulation by deltaTime seconds.
void Init()
Allocate broadphase, dispatcher, solver, and dynamics world. Call once.
void RemoveRigidBody(RigidBody *body)
Unregister a rigid body (e.g. when its owning component is destroyed).
Owning wrapper around btRigidBody; holds a shared Collider, mass, friction, and body type.
btRigidBody * GetBody()
Underlying Bullet body (borrowed, do not delete).
void SetAddedToWorld(bool added)
Track whether this body is currently registered with a PhysicsManager.
glm::vec3 vec3
3-component float vector (e.g. world position, RGB colour, normals).
Hit information returned by PhysicsManager::Raycast.
vec3 point
World-space hit point.
vec3 normal
Surface normal at the hit.
float fraction
Fraction along the ray segment in [0, 1].