6

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);
    }

}
  • Perhaps you can link to the demos you were looking at? – john_science Oct 17 '12 at 16:59
  • I was looking at the demos that are included with the library, I am sorry but they do not have them linked out. I would post the code but it is separated into multiple class files, and would be cumbersome to do on here. I have been looking through the bullet tutorials, but they really do not apply well to jBullet since the function names are different: http://bulletphysics.org/mediawiki-1.5.8/index.php/Hello_World –  Oct 18 '12 at 19:57
  • If you're talking about displaying the physics debug information on screen you'll need to implement your own `IDebugDraw` class. If you're talking about drawing objects that you want to be controlled by physics, you do that without the physics library being involved at all. jBullet should just be used for controlling the physics of your objects, i.e. moving them around and colliding with each other. Drawing your models or objects should be done by your own code. If you define what you're trying to do I'll provide an answer on how to do it. – House Oct 18 '12 at 22:54
  • I used the same Hello World tutorial when I implemented physics in my game. Converting the function names to the ones used in jBullet isn't too bad. Just draw objects like you normally would without physics, then use jBullet to add an invisible body to your object that represents its physical body. I started with a simple physics plane and cubes around my objects. Eventually extending jBullet to work with [my terrain](http://gamedev.stackexchange.com/questions/27405/). – House Oct 18 '12 at 23:38
  • Thanks Byte56, that makes sense. I guess I have not really seen anything that draws things the way I am, and then using jBullet to add the collision box to the cube. I added code of what my cube looks like, would I pretty much just use: CollisionShape groundShape = new StaticPlaneShape(myCube); ? –  Oct 19 '12 at 03:31
  • Is the converted code not working? How is it not working? Any errors being presented? It looks to be correct from what I can tell. – House Oct 19 '12 at 16:06

3 Answers3

4

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);
}

}

1

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.

mikera
  • 105,238
  • 25
  • 256
  • 415
  • I have looked at a few of the things with jMonkeyEngine, but its hard to figure out what really applies to me since I am using LWJGL to write my game. Really if I could see a basic example of someone using jBullet to add physics to a cube or ball, and then displaying that cube or ball I would be solid. My issue is when I have tried to write this myself nothing displays, so it would be helpful to see how someone else has done it. I guess I should write up some test code and post it so I can be told what I am doing wrong, I know that is what I should have done in the first place. –  Oct 18 '12 at 20:10
  • I really appreciate your input provided though, I am going to continue looking at JME stuff to see if I can figure out how they do it minus the JME specific stuff. –  Oct 18 '12 at 20:11
1

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.

House
  • 3,356
  • 2
  • 25
  • 29
  • That helped out a lot Byte56, I got the output now and I think I understand what you mean by creating two worlds. I was actually scared I was going to have to re-write a lot of code, but your explanation makes me think I will not have to which is awesome! Promise you will get first access to test my stuff as soon as I get the character creation part done. –  Oct 19 '12 at 06:04
  • the code is not erroring out, just not working as I expected when I moved it to my actual game. The test code works great though. –  Oct 21 '12 at 17:35