6

我正在尝试学习如何在我正在处理的项目中使用 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);
    }

}
4

3 回答 3

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

}

于 2012-10-21T17:36:07.800 回答
1

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

其中不少使用 jBullet 作为物理引擎,绝对值得一玩。

于 2012-10-17T05:39:29.950 回答
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到更新循环中。然后,您无需将球体位置写入控制台,而是使用球体的位置更新posX, posY, posZ。现在,您的立方体正在像模拟中的球体一样移动!

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

希望这能让事情更清楚。

于 2012-10-19T04:59:30.883 回答