Skip to content
Snippets Groups Projects
Commit cfd01c74 authored by Joseph Walton-Rivers's avatar Joseph Walton-Rivers
Browse files

standardise debug draw call

parent 94a4310c
No related branches found
No related tags found
No related merge requests found
......@@ -116,6 +116,9 @@ namespace fggl::phys {
// update
virtual void step() = 0;
// debug
virtual void setDebugDraw(bool enable) = 0;
};
} // namespace fggl::phys
......
......@@ -75,6 +75,14 @@ namespace fggl::phys::bullet {
explicit BulletPhysicsEngine(entity::EntityManager* world);
~BulletPhysicsEngine() override;
// copy is not allowed
BulletPhysicsEngine(const BulletPhysicsEngine&) = delete;
BulletPhysicsEngine& operator=(const BulletPhysicsEngine&) = delete;
// move is not allowed
BulletPhysicsEngine(BulletPhysicsEngine&&) = delete;
BulletPhysicsEngine& operator=(BulletPhysicsEngine&&) = delete;
void step() override;
void onEntityDeath(entity::EntityID entity);
......@@ -83,9 +91,19 @@ namespace fggl::phys::bullet {
std::vector<entity::EntityID> raycastAll(math::vec3 from, math::vec3 to) override;
std::vector<entity::EntityID> sweep(PhyShape& shape, math::Transform& from, math::Transform& to) override;
/**
* Add a rigid body to the physics world.
*
* The body should not currently be in the simulation. Physics position will be synced with the motion
* state prior to it being added to the simulation. This method should not need to be called manually, it
* is called when the entity is decoded.
*
* @param entity the entity the BulletBody is attached to.
* @param body the pre-configured bullet body.
*/
void addBody(entity::EntityID entity, BulletBody& body);
bool debugDraw = false;
void setDebugDraw(bool enabled) override;
private:
entity::EntityManager* m_ecs;
BulletConfiguration m_config;
......@@ -94,14 +112,12 @@ namespace fggl::phys::bullet {
ContactCache m_contactCache;
/**
* Check for ECS components which aren't in the physics world and add them.
*/
void checkForPhys();
/**
* Sync the bullet world state back to the ECS.
* Force position and rotation in the ECS to match those from the physics world.
*
* As FGGL uses motion states, this should not be required. As it iterates all entities in a scene this is
* also a very expensive operation.
*/
void forceSyncToECS();
void syncTransformToECS();
/**
* Deal with physics collisions
......
......@@ -97,7 +97,6 @@ namespace fggl::phys::bullet {
auto& physComp = manager.template get<BulletBody>(entity);
engine->addBody(entity, physComp);
});
engine->debugDraw = true;
return engine;
}
......
......@@ -35,7 +35,7 @@ namespace fggl::phys::bullet {
return {fgglVec.x, fgglVec.y, fgglVec.z};
}
BulletPhysicsEngine::BulletPhysicsEngine(entity::EntityManager* world) : m_ecs(world), m_config(), m_world(nullptr) {
BulletPhysicsEngine::BulletPhysicsEngine(entity::EntityManager* world) : m_ecs(world), m_config(), m_world(nullptr), m_debug(nullptr) {
m_config.broadphase = new btDbvtBroadphase();
m_config.collisionConfiguration = new btDefaultCollisionConfiguration();
m_config.dispatcher = new btCollisionDispatcher(m_config.collisionConfiguration);
......@@ -47,9 +47,6 @@ namespace fggl::phys::bullet {
m_config.solver,
m_config.collisionConfiguration);
m_debug = std::make_unique<debug::BulletDebugDrawList>();
m_world->setDebugDrawer( m_debug.get() );
m_debug->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
// callbacks (for handling bullet -> ecs)
......@@ -78,7 +75,8 @@ namespace fggl::phys::bullet {
//syncToECS();
pollCollisions();
if ( debugDraw ) {
// if debug draw is enabled, trigger a draw call
if ( m_debug != nullptr ) {
m_world->debugDrawWorld();
}
}
......@@ -92,83 +90,26 @@ namespace fggl::phys::bullet {
m_world->addRigidBody(body.body);
}
inline btCollisionShape* shape_to_bullet(const phys::RigidBody& fgglBody) {
if ( fgglBody.shape == nullptr ) {
// they forgot to put a shape, we'll assume a unit sphere to avoid crashes...
return new btSphereShape(0.5F);
}
switch (fgglBody.shape->type) {
case phys::ShapeType::BOX: {
auto extents = ((phys::Box*)fgglBody.shape)->extents;
return new btBoxShape({extents.x, extents.y, extents.z});
}
case phys::ShapeType::SPHERE: {
float radius = ((phys::Sphere*)fgglBody.shape)->radius;
return new btSphereShape(radius);
}
default:
return new btSphereShape(0.5f);
}
}
void BulletPhysicsEngine::checkForPhys() {
// FIXME without reactive-based approaches this is very slow
auto entsWantPhys = m_ecs->find<phys::RigidBody>();
for (auto ent : entsWantPhys) {
auto* btComp = m_ecs->tryGet<BulletBody>(ent);
if ( btComp != nullptr ) {
// they are already in the simulation
continue;
}
// set up the bullet proxy for our object
btComp = &m_ecs->add<BulletBody>(ent);
const auto& fgBody = m_ecs->get<phys::RigidBody>(ent);
btComp->motion = new FgglMotionState(m_ecs, ent);
// collisions
btCollisionShape* colShape = shape_to_bullet(fgBody);
btVector3 localInt(0, 0, 0);
if ( !fgBody.isStatic() ) {
colShape->calculateLocalInertia(fgBody.mass, localInt);
}
// setup the construction information
btRigidBody::btRigidBodyConstructionInfo bodyCI(
fgBody.mass,
btComp->motion,
colShape,
localInt
);
btComp->body = new btRigidBody(bodyCI);
btComp->body->setUserIndex( static_cast<int>(ent) );
if (!fgBody.isStatic()) {
btComp->body->setRestitution(0.5f);
btComp->body->setRollingFriction(0.0f);
}
if ( fgBody.type == BodyType::KINEMATIC ) {
auto flags = btComp->body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT;
btComp->body->setCollisionFlags( flags );
// we don't have a clean way of saying a kinematic object moved, so just prevent sleeping.
// if this turns out to be an issue, we'll need to revisit this.
btComp->body->setActivationState( DISABLE_DEACTIVATION );
}
m_world->addRigidBody( btComp->body );
void BulletPhysicsEngine::setDebugDraw(bool active) {
if ( active ) {
m_debug = std::make_unique<debug::BulletDebugDrawList>();
m_world->setDebugDrawer(m_debug.get());
m_debug->setDebugMode(btIDebugDraw::DBG_DrawWireframe);
} else {
m_debug = nullptr;
}
}
void BulletPhysicsEngine::forceSyncToECS() {
void BulletPhysicsEngine::syncTransformToECS() {
const auto physEnts = m_ecs->find<math::Transform, BulletBody>();
for (const auto& ent : physEnts) {
auto& transform = m_ecs->get<math::Transform>(ent);
auto& physBody = m_ecs->get<BulletBody>(ent);
// don't bother syncing things with motion states, it's not necessary
if ( physBody.motion != nullptr ) {
continue;
}
auto& transform = m_ecs->get<math::Transform>(ent);
if ( physBody.body->isKinematicObject() ) {
continue;
}
......@@ -201,7 +142,6 @@ namespace fggl::phys::bullet {
// release resources and delete
bulletBody.release();
//m_ecs->remove<BulletBody>(ent);
}
// delete the world
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment