I'm integrating Bullet Physics into my project for collision detection and have just gotten some debug draw functionality to work. However, the results are not what I'm expecting. I have tried to draw a sphere and box shape, but each time they turn out looking like below (this specific screenshot is how a btBoxShape is being rendered):
Relevant code is as follows:
//From CollisionWorld.h
class CollisionWorld {
private:
btCollisionConfiguration* bt_collision_configuration;
btCollisionDispatcher* bt_dispatcher;
btBroadphaseInterface* bt_broadphase;
btCollisionWorld* bt_collision_world;
btScalar scene_size = 500;
unsigned int max_objects = 1000;
CollisionDebugDrawer collision_debug_drawer;
public:
CollisionWorld(bool debug = false);
~CollisionWorld();
void draw();
CollisionDebugDrawer& getCollisionDebugDrawer();
};
//From CollisionWorld.cpp
CollisionWorld::CollisionWorld(bool debug){
bt_collision_configuration = new btDefaultCollisionConfiguration();
bt_dispatcher = new btCollisionDispatcher(bt_collision_configuration);
btVector3 worldAabbMin(-scene_size, -scene_size, -scene_size);
btVector3 worldAabbMax(scene_size, scene_size, scene_size);
bt_broadphase = new bt32BitAxisSweep3(worldAabbMin, worldAabbMax, max_objects, 0, true);
bt_collision_world = new btCollisionWorld(bt_dispatcher, bt_broadphase, bt_collision_configuration);
if (debug) {
bt_collision_world->setDebugDrawer(&collision_debug_drawer);
}
/*btCollisionObject* sphere = new btCollisionObject();
sphere->getWorldTransform().setOrigin(btVector3((btScalar)0, (btScalar)2, (btScalar)0));
btSphereShape* sphere_shape = new btSphereShape(2);
sphere->setCollisionShape(sphere_shape);
bt_collision_world->addCollisionObject(sphere);*/
btCollisionObject* box = new btCollisionObject();
box->getWorldTransform().setOrigin(btVector3((btScalar)0, (btScalar)2, (btScalar)4));
btBoxShape* box_shape = new btBoxShape(btVector3((btScalar)1, (btScalar)1, (btScalar)1));
box->setCollisionShape(box_shape);
bt_collision_world->addCollisionObject(box);
}
CollisionWorld::~CollisionWorld(){}
CollisionDebugDrawer& CollisionWorld::getCollisionDebugDrawer() {
return this->collision_debug_drawer;
}
void CollisionWorld::draw() {
this->bt_collision_world->debugDrawWorld();
}
//From CollisionDebugDrawer.h
class CollisionDebugDrawer : public btIDebugDraw {
private:
Shader debug_shader;
public:
CollisionDebugDrawer();
~CollisionDebugDrawer();
Shader& getDebugShader();
void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) override;
void drawContactPoint(const btVector3 &, const btVector3 &, btScalar, int, const btVector3 &) override;
void reportErrorWarning(const char *) override;
void draw3dText(const btVector3 &, const char *) override;
void setDebugMode(int p) override;
int getDebugMode(void) const override;
};
//From CollisionDebugDrawer.cpp
CollisionDebugDrawer::CollisionDebugDrawer() :
debug_shader(GlobalConstants::DEBUG_VERTEX_SHADER,
GlobalConstants::DEBUG_FRAGMENT_SHADER) {};
CollisionDebugDrawer::~CollisionDebugDrawer() {};
Shader& CollisionDebugDrawer::getDebugShader() {
return this->debug_shader;
}
void CollisionDebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color) {
// I know this is highly inefficient, but this is just to insure everything is working as expected,
// I plan on implementing a better solution once everything clicks
unsigned int VBO2, VAO2;
GLfloat points[6];
points[0] = from.x();
points[1] = from.y();
points[2] = from.z();
points[3] = to.x();
points[4] = to.y();
points[5] = to.z();
glGenVertexArrays(1, &VAO2);
glGenBuffers(1, &VBO2);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), &points, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDrawArrays(GL_LINES, 0, 2);
glBindVertexArray(0);
glDeleteBuffers(1, &VBO2);
glDeleteVertexArrays(1, &VAO2);
}
void CollisionDebugDrawer::drawContactPoint(const btVector3&, const btVector3&, btScalar, int, const btVector3&) {}
void CollisionDebugDrawer::reportErrorWarning(const char*) {}
void CollisionDebugDrawer::draw3dText(const btVector3&, const char *) {}
void CollisionDebugDrawer::setDebugMode(int p) {}
int CollisionDebugDrawer::getDebugMode(void) const { return 3; } // TF is 3?
//From Scene.cpp (where all of this is called)
void Scene::render(float alpha) {
GameState lerp_render_state = lerpRenderState(alpha);
// Set player_actor point (debug only)
player_actor.getModel().setTranslation(lerp_render_state.player_point.position + glm::vec3(0.0f, 0.0f, -3.0f));
// Select a color to clear the screen with and clear screen
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Same shader used for all models (collision_world uses it's own shader)
shader.use();
// Draw the stage
shader.setMat4("mvp", camera.getProjectionMatrix() * camera.getViewMatrix() * stage.getModel().getModelMatrix());
stage.getModel().draw(shader);
// Draw the player capsule (wouldn't normally do this as capsule is for collision only)
shader.setMat4("mvp", camera.getProjectionMatrix() * camera.getViewMatrix() * player_actor.getModel().getModelMatrix());
player_actor.getModel().draw(shader);
// Debug draw for collision world
collision_world.getCollisionDebugDrawer().getDebugShader().use();
collision_world.getCollisionDebugDrawer().getDebugShader().setMat4("vp", camera.getProjectionMatrix() * camera.getViewMatrix());
collision_world.draw();
}
Does anything stick out as being horribly incorrect? I feel like this is probably something simple I've missed.