Пример 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 ответа

Решение

Пример кода для 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);
}

}

Давайте посмотрим на пример кода из учебника, с которым вы работаете. Я добавил комментарии в код, чтобы вы могли лучше узнать, что происходит и как вы должны настроить свой код. Важно отметить, что код ниже на самом деле ничего не показывает. По сути, он просто создает физический объект, землю и позволяет объекту упасть на землю, выводя высоту объекта, когда он проходит через симуляцию.

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 с положением сферы. Теперь ваш куб движется так же, как сфера в симуляции!

Так что просто последний толчок в точку. Вы создаете два мира. Та, где вы рисуете детальную графику, и та, где у вас есть простые фигуры, представляющие физические фигуры ваших детальных графических объектов. Мир физики моделирует взаимодействия всех ваших объектов, а детали графических объектов просто отражают положение этих простых физических форм.

Надеюсь, это проясняет ситуацию.

Вы проверили демоверсии jMonkeyEngine и пример кода?

Многие из них используют jBullet в качестве физического движка, с которым определенно стоит поиграть.

Другие вопросы по тегам