jBullet example

6k views Asked by At

I am trying to learn how to use jBullet in a project that I am working on and I have reviewed the demo that the source provides but I just cannot figure out how these demo get objects display. Does anyone have a good resource they could point me in or provide a basic example that displays one or two objects on screen?

Thank you in advance, I am sorry I don't have any code to show I can quickly write up some if needed but just really looking for a direction to go.

Thank you,

Code for the Cube that I am using, so I am trying to add collision to it, but i am unsure how using jbullet:

    public void  Draw() {
    // center point posX, posY, posZ
    float radius = size / 2;

    //top
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(1.0f,0.0f,0.0f); // red
            glVertex3f(posX + radius, posY + radius, posZ - radius);
            glVertex3f(posX - radius, posY + radius, posZ - radius);
            glVertex3f(posX - radius, posY + radius, posZ + radius);
            glVertex3f(posX + radius, posY + radius, posZ + radius);
        }
    glEnd();
    glPopMatrix();

    //bottom
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(1.0f,1.0f,0.0f); // ?? color
            glVertex3f(posX + radius, posY - radius, posZ + radius);
            glVertex3f(posX - radius, posY - radius, posZ + radius);
            glVertex3f(posX - radius, posY - radius, posZ - radius);
            glVertex3f(posX + radius, posY - radius, posZ - radius);
        }
    glEnd();
    glPopMatrix();

    //right side
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(1.0f,0.0f,1.0f); // ?? color
            glVertex3f(posX + radius, posY + radius, posZ + radius);
            glVertex3f(posX + radius, posY - radius, posZ + radius);
            glVertex3f(posX + radius, posY - radius, posZ - radius);
            glVertex3f(posX + radius, posY + radius, posZ - radius);
        }
    glEnd();
    glPopMatrix();

    //left side
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(0.0f,1.0f,1.0f); // ?? color
            glVertex3f(posX - radius, posY + radius, posZ - radius);
            glVertex3f(posX - radius, posY - radius, posZ - radius);
            glVertex3f(posX - radius, posY - radius, posZ + radius);
            glVertex3f(posX - radius, posY + radius, posZ + radius);
        }
    glEnd();
    glPopMatrix();

    //front side 
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(0.0f,0.0f,1.0f); //blue 
            glVertex3f(posX + radius, posY + radius, posZ + radius);
            glVertex3f(posX - radius, posY + radius, posZ + radius);
            glVertex3f(posX - radius, posY - radius, posZ + radius);
            glVertex3f(posX + radius, posY - radius, posZ + radius);
        }
    glEnd();
    glPopMatrix();

    //back side
    glPushMatrix();
    glBegin(GL_QUADS);
        {
            glColor3f(0.0f,1.0f,0.0f); // green
            glVertex3f(posX + radius, posY - radius, posZ - radius);
            glVertex3f(posX - radius, posY - radius, posZ - radius);
            glVertex3f(posX - radius, posY + radius, posZ - radius);
            glVertex3f(posX + radius, posY + radius, posZ - radius);
        }
    glEnd();
    glPopMatrix();
}

Here is my converted code from the hello world test code, does this look correct to everyone? :

public static void HelloWorld() {

    BroadphaseInterface broadphase = new DbvtBroadphase();
    DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
    CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);

    SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();

    DiscreteDynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

    // set the gravity of our world
    dynamicsWorld.setGravity(new Vector3f(0, -10, 0));

    // setup our collision shapes
    CollisionShape groundShape = new StaticPlaneShape(new Vector3f(0, 1, 0), 1);
    CollisionShape fallShape = new SphereShape(1);

    // setup the motion state
    DefaultMotionState groundMotionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, -1, 0), 1.0f))); 

    RigidBodyConstructionInfo groundRigidBodyCI = new RigidBodyConstructionInfo(0, groundMotionState, groundShape, new Vector3f(0,0,0)); 
    RigidBody groundRigidBody = new RigidBody(groundRigidBodyCI); 

    dynamicsWorld.addRigidBody(groundRigidBody); // add our ground to the dynamic world.. 

    // setup the motion state for the ball
    DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 50, 0), 1.0f)));

    //This we're going to give mass so it responds to gravity 
    int mass = 1;

    Vector3f fallInertia = new Vector3f(0,0,0); 
    fallShape.calculateLocalInertia(mass,fallInertia); 

    RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass,fallMotionState,fallShape,fallInertia); 
    RigidBody fallRigidBody = new RigidBody(fallRigidBodyCI); 

    //now we add it to our physics simulation 
    dynamicsWorld.addRigidBody(fallRigidBody); 

    for (int i=0 ; i<300 ; i++) { 
        dynamicsWorld.stepSimulation(1/60.f, 10); 

        Transform trans = new Transform();
        fallRigidBody.getMotionState().getWorldTransform(trans); 


        System.out.println("sphere height: " + trans.origin.y);
    }

}
3

There are 3 answers

0
AudioBubble On BEST ANSWER

Example code for jBullet HelloWorld:

public static void HelloWorld() {

BroadphaseInterface broadphase = new DbvtBroadphase();
DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);

SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();

DiscreteDynamicsWorld dynamicsWorld = new DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

// set the gravity of our world
dynamicsWorld.setGravity(new Vector3f(0, -10, 0));

// setup our collision shapes
CollisionShape groundShape = new StaticPlaneShape(new Vector3f(0, 1, 0), 1);
CollisionShape fallShape = new SphereShape(1);

// setup the motion state
DefaultMotionState groundMotionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, -1, 0), 1.0f))); 

RigidBodyConstructionInfo groundRigidBodyCI = new RigidBodyConstructionInfo(0, groundMotionState, groundShape, new Vector3f(0,0,0)); 
RigidBody groundRigidBody = new RigidBody(groundRigidBodyCI); 

dynamicsWorld.addRigidBody(groundRigidBody); // add our ground to the dynamic world.. 

// setup the motion state for the ball
DefaultMotionState fallMotionState = new DefaultMotionState(new Transform(new Matrix4f(new Quat4f(0, 0, 0, 1), new Vector3f(0, 50, 0), 1.0f)));

//This we're going to give mass so it responds to gravity 
int mass = 1;

Vector3f fallInertia = new Vector3f(0,0,0); 
fallShape.calculateLocalInertia(mass,fallInertia); 

RigidBodyConstructionInfo fallRigidBodyCI = new RigidBodyConstructionInfo(mass,fallMotionState,fallShape,fallInertia); 
RigidBody fallRigidBody = new RigidBody(fallRigidBodyCI); 

//now we add it to our physics simulation 
dynamicsWorld.addRigidBody(fallRigidBody); 

for (int i=0 ; i<300 ; i++) { 
    dynamicsWorld.stepSimulation(1/60.f, 10); 

    Transform trans = new Transform();
    fallRigidBody.getMotionState().getWorldTransform(trans); 


    System.out.println("sphere height: " + trans.origin.y);
}

}

2
mikera On

Have you checked out the jMonkeyEngine demos and sample code?

Quite a few of these use jBullet as the physics engine, definitely worth playing with.

2
House On

Lets take a look at the example code from the tutorial you're working with. I've added comments in the code so you can better tell what's happening and how you should set up your code. It's important to note that the code below isn't actually going to show anything. It basically just creates a physics object, a ground and lets the object fall to the ground, outputting the height of the object as it steps through the simulation.

int main (void)
{
    //Set up all the required objects and controllers for simulating the physics
    //all this stuff would actually go into whatever initialize function you have
    btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

    btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

    dynamicsWorld->setGravity(btVector3(0,-10,0));

    //Create our physics objects, the planeShape is the ground
    btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

    //A sphere that will be dropping to the ground, 
    btCollisionShape* fallShape = new btSphereShape(1);

    //Create motion states for our objects
    //First the ground object. It will be in the XZ plane at -1 Y
    //note that we're not giving it any mass
    //zero mass in a physics simulation means it won't move when collided with
    //it also means that it won't respond to gravity
    btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
    btRigidBody::btRigidBodyConstructionInfo
                groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
    btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);

    //Add the ground to the simulation
    dynamicsWorld->addRigidBody(groundRigidBody);

    //now set up the motion state for our sphere, we'll put it at 50 Y
    btDefaultMotionState* fallMotionState =
                new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
    //This we're going to give mass so it responds to gravity
    btScalar mass = 1;
    btVector3 fallInertia(0,0,0);
    fallShape->calculateLocalInertia(mass,fallInertia);
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
    btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);

    //now we add it to our physics simulation
    dynamicsWorld->addRigidBody(fallRigidBody);


    //Here's where the magic happens. The physics simulation is stepped.
    //for each step, we're going to get the balls current position and write it out.
    //Everything inside this for loop would actually go into your *update* loop
    //your update loop would step the physics simulation
    //after stepping the simulation, you get the positions of your physics bodies
    //and make sure your object positions match those.

    for (int i=0 ; i<300 ; i++) {
            dynamicsWorld->stepSimulation(1/60.f,10);

            btTransform trans;
            fallRigidBody->getMotionState()->getWorldTransform(trans);

            //so you would take `trans` and use it to set the position of your cube
            //then your cube position would be updated to the same position as 
            //this physics object that's representing it.

            std::cout << "sphere height: " << trans.getOrigin().getY() << std::endl;
    }

    //everything else is clean up

    dynamicsWorld->removeRigidBody(fallRigidBody);
    delete fallRigidBody->getMotionState();
    delete fallRigidBody;

    dynamicsWorld->removeRigidBody(groundRigidBody);
    delete groundRigidBody->getMotionState();
    delete groundRigidBody;


    delete fallShape;

    delete groundShape;


    delete dynamicsWorld;
    delete solver;
    delete collisionConfiguration;
    delete dispatcher;
    delete broadphase;

    return 0;
}

Basically you want to recreate your game world inside the physics simulation. Then when you step your physics simulation, you update your game world with the new positions from the simulation. The physics simulation is telling you how to move your game objects so that it appears as if they're colliding with each other.

So for your setup, you would move the stuff in the for loop into your update loop. Then instead of writing the sphere position out to the console, you update your posX, posY, posZ with the position of the sphere. Now your cube is moving just the same as the sphere in the simulation!

So just a final push of the point. You're creating two worlds. The one where you're drawing detailed graphics and one where you have simple shapes representing the physical shapes of your detailed graphic objects. The physics world is simulating the interactions of all your objects, and the details graphic objects are just mirroring the positions of these simple physical shapes.

Hopefully that makes things clearer.