0

弾丸物理学を OpenGL ゲームに実装する際に問題が発生しました。問題は、translatef 値を継続的に更新するのではなく、最後にのみ更新することです。bullet のコードは次のようになります。

void CGL::initPhysics( void ) {
broadphase = new btDbvtBroadphase();
collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration);
solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

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


ballShape = new btSphereShape(1);
pinShape = new btCylinderShape(btVector3(1,1,1));
pinShape->setMargin(0.04);

fallMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,10,0)));
btScalar mass = 1;
btVector3 fallInertia(0,0,0);
ballShape->calculateLocalInertia(mass,fallInertia);

btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

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);
dynamicsWorld->addRigidBody(groundRigidBody);

btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,ballShape,fallInertia);
btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
dynamicsWorld->addRigidBody(fallRigidBody);

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

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

    fallY = trans.getOrigin().getY();
}
state_list.remove( STATE_FALL_BALL );
printf("stoped\n");

}

そして、最初に呼び出される描画関数は次のようになります。

void CGL::fallingBall( void ) {
glPushMatrix();

float colBall2[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
glMaterialfv( GL_FRONT, GL_AMBIENT, colBall2);

glTranslatef(0.0f,fallY,0.0f);

printf("fallY: %f\n",fallY);

glutSolidSphere(1.0f,20,20);

glPopMatrix();

}

問題は、この関数の printf で正しい値が表示されることですが、変換は最初にのみ呼び出されます。つまり、最後の状態しか表示されないということです。

編集

これは関数とループを変更したものです。すべての情報を収集すると、機能するはずですが、機能しません。何も描きません。

initPhysics(){
    for (int i=0 ; i<500 ; i++) 
    {
        draw();

    }
    state_list.remove( STATE_FALL_BALL );
    printf("stoped\n");
}

void CGL::draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            current_time = getTime();
            since_update = current_time - last_update;
            printf("time: %f\n",since_update);
            if(since_update>timestep)
            {
                dynamicsWorld->stepSimulation(timestep,10);
                last_update = current_time;
            }
            btTransform trans;
            fallRigidBody->getMotionState()->getWorldTransform(trans);

            fallY = trans.getOrigin().getY();
            fallingBall();
            printf("fallY: %f\n",fallY);
glFlush();
    }

そして、最初の変数宣言は次のようになります。

last_update = 0;
timestep = 100;
current_time = 0;
since_update = 0;
4

1 に答える 1

1

それは少し混乱しているように見えます。マルチスレッドを掘り下げずに差し迫った問題を解決する基本的な間違いは、次のようなことだと思います。

//pseudo-code to get the idea
void draw(){
    // clear Buffers and setup matricies
    ....
    //calculate the time that has pased since the last time that the physics have been calculated
    time_t current_time = getCurrentTime();
    time_t since_update = current_time - last_update;

    //if enough time has passed since the last redraw calculate physics
    if(since_update>timestep)
    {
        dynamicsWorld->stepSimulation(timestep,10);
        last_update = current_time;
    }
    btTransform trans;
    fallRigidBody->getMotionState()->getWorldTransform(trans);

    fallY = trans.getOrigin().getY();

    //draw various object
    ....
    fallingBall();
    //swap buffers or flush()
    glSwapBuffers();
}

OpenGL を直接使用する明確な理由がない限り、より高いレベルのツールキットを使用することをお勧めします。また、現在古いバージョンの OpenGL を使用しているという通常の免責事項。

于 2012-01-06T12:25:12.443 に答える