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


why collision not detection not happened in Two Sphere

Updated January 13, 2017 01:05 AM