jBullet的例子

时间:2012-10-17 05:28:01

标签: java physics game-engine collision jbullet

我正在尝试学习如何在我正在处理的项目中使用jBullet,并且我已经查看了源代码提供的演示,但我无法弄清楚这些演示如何显示对象。有没有人有一个很好的资源,他们可以指出我或提供一个基本的例子,在屏幕上显示一个或两个对象?

提前谢谢你,我很抱歉我没有任何代码可以显示我可以快速写一些,如果需要但只是真正寻找方向去。

谢谢,

我正在使用的多维数据集的代码,所以我试图添加碰撞,但我不确定如何使用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();
}

以下是来自hello world测试代码的转换代码,这对每个人来说都是正确的吗? :

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 个答案:

答案 0 :(得分:4)

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 :(得分:1)

您是否查看了jMonkeyEngine演示和示例代码?

其中相当一部分使用jBullet作为物理引擎,绝对值得玩。

答案 2 :(得分:1)

让我们看一下您正在使用的教程中的示例代码。我在代码中添加了注释,以便您可以更好地了解正在发生的事情以及如何设置代码。重要的是要注意下面的代码实际上并没有显示任何内容。它基本上只是创建一个物理对象,一个地面,让对象掉到地上,在逐步模拟时输出对象的高度。

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

基本上你想在物理模拟中重建你的游戏世界。然后当您进行物理模拟时,您将使用模拟中的新位置更新游戏世界。物理模拟告诉你如何移动你的游戏对象,使它看起来好像是相互碰撞。

因此,对于您的设置,您可以将for循环中的内容移动到更新循环中。然后,不是将球体位置写入控制台,而是使用球体的位置更新posXposYposZ。现在你的立方体移动与模拟中的球体一样!

所以只是最后一点。你正在创造两个世界。用于绘制详细图形的图形和用于表示详细图形对象的物理形状的简单形状的图形。物理世界正在模拟所有物体的相互作用,而细节图形物体只是反映了这些简单物理形状的位置。

希望这会让事情更加清晰。