1
\$\begingroup\$

I just started using bullet and I'm having an issue where once my rigid body is at reset at the floor it won't move when I apply a force to it.

I have created a small demo to show this using the hello world example provided here.

for(int i = 0; i<30000; i++) // Give it a lot of time to hit the ground
{
    dynamicsWorld->stepSimulation(1 / 60.f, 10);
}

btVector3 froce(0.0, 2000.0, 0.0); 
fallRigidBody->applyCentralForce(froce);// Apply a force on the Y axis 

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

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

    std::cout << "Frame # : " << i
        << "\t: X: " << trans.getOrigin().getX()
        << "\t, Y: " << trans.getOrigin().getY()
        << "\t, Z: " << trans.getOrigin().getZ()
        << "\n";
}

The result I get out of this is:

Frame # : 0     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 1     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 2     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 3     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 4     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 5     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 6     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 7     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 8     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 9     : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 10    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 11    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 12    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 13    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 14    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 15    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 16    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 17    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 18    : X: 0.00       , Y: 1.00       , Z: 0.00
Frame # : 19    : X: 0.00       , Y: 1.00       , Z: 0.00

As you can see, the object never moved.

Now if I lower the first loop from 30000 to 300 then it will move just as I expect

What am I doing wrong?

Here is the full code if anyone wants to test it out

#include <iostream>
#include <iomanip>
#include <btBulletDynamicsCommon.h>

int main(void)
{

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


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

    btCollisionShape* fallShape = new btSphereShape(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);


    btDefaultMotionState* fallMotionState =
        new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));
    btScalar mass = 1;
    btVector3 fallInertia(0, 0, 0);
    fallShape->calculateLocalInertia(mass, fallInertia);
    btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
    btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
    dynamicsWorld->addRigidBody(fallRigidBody);

    std::cout << std::fixed << std::setprecision(2);

    for(int i = 0; i<300; i++) // Give it a lot of time to follow to the ground
    {
        dynamicsWorld->stepSimulation(1 / 60.f, 10);
    }

    btVector3 froce(0.0, 2000.0, 0.0); 
    fallRigidBody->applyCentralForce(froce);// Apply a force on the Y axis 

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

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

        std::cout << "Frame # : " << i
            << "\t: X: " << trans.getOrigin().getX()
            << "\t, Y: " << trans.getOrigin().getY()
            << "\t, Z: " << trans.getOrigin().getZ()
            << "\n";
    }

    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;
}
\$\endgroup\$
3
\$\begingroup\$

I looked in this issue, and it seems that you have to call the activate function on the rigidbody after applying the force. This article does say that you generally do not have to but it seems that you must do it manually once it is has gone to sleep.

\$\endgroup\$
  • \$\begingroup\$ This looks about right. Usually with sleeping you need to set an awake flag for the simulation to include a sleeping body back into the island simulating. \$\endgroup\$ – RandyGaul Feb 18 '14 at 16:40
  • \$\begingroup\$ @RandyGaul You would think that internally, when you add a force then the flag should be set automatically with it. I can't imagine a reason why you wouldn't want the library to do that. \$\endgroup\$ – Caesar Feb 19 '14 at 1:54
  • \$\begingroup\$ Yeah you'd think so. My own implementation does this, and I thing Box2D does too. Usually it won't even matter in terms of cache hits as the memory for applying a force is next to the bitmask for the sleeping flag... \$\endgroup\$ – RandyGaul Feb 19 '14 at 6:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.