Bullet Physics DebugDraw Unexpected Results

by nullReference   Last Updated June 12, 2019 01:13 AM

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):

enter image description here

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. Also...Does anyone know of any good resources for Bullet as far as examples / documentation?? I have been working from random form posts, the doxygen api, and user manual .pdf file.



Related Questions


Updated January 13, 2017 01:05 AM

Updated January 03, 2019 15:13 PM

Updated March 31, 2019 12:13 PM

Updated August 05, 2019 15:13 PM

Updated April 27, 2015 00:05 AM