2
\$\begingroup\$

So I've got Bullet 3D controlling the motion of objects rendered with DirectX. In the clipping below I've got 2 identical rectangles & 5 balls. The lowest rectangle has a mass of 0 and doesn't move (as expected). All other objects have a mass of 1 and fall as expected.

There are two issues that I'm seeing: 1. When the balls land on an angled surface (not shown) they don't rotate, but they do move 'down hill'. 2. Pictured below you see that the top rectangle is perched on the bottom rectangle when it should've rotated a bit and kept falling.

What do I need to do in Bullet to enable object rotations? I'm not a physicist so I suspect my google-fu is lacking, also the Bullet docs are painfully inadequate.

Screen Clipping

This code here is how I initialize my rigid bodies:

RESULT_CODE ubAddRigidBody(HANDLE collisionShape, float mass, ubVector3 position, ubVector4 orientation, HANDLE* rigidBodyHandle)
{
if (rigidBodyHandle == nullptr)
{
    return INVALID_PARAM;
}

if (_world->isValidCollisionShapeHandle(collisionShape) != SUCCESS)
{
    return INVALID_HANDLE;
}

auto transform = btTransform(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w), btVector3(position.x, position.y, position.z));
auto collisionShapeObject = _world->m_collisionShapes[collisionShape].get();

auto motionStateObject = new btDefaultMotionState();
motionStateObject->setWorldTransform(transform);

auto rigidBodyInfo = btRigidBody::btRigidBodyConstructionInfo(btScalar(mass), motionStateObject, collisionShapeObject);

// Enable rotations for the object

collisionShapeObject->calculateLocalInertia(mass, rigidBodyInfo.m_localInertia);
rigidBodyInfo.m_linearDamping = .2f;
rigidBodyInfo.m_angularDamping = .2f;

auto rigidBody = new btRigidBody(rigidBodyInfo);
auto uniqueHandle = _world->getUniqueHandle();

rigidBody->setFriction(.5f);
rigidBody->setRollingFriction(.5f);

_world->m_world->addRigidBody(rigidBody);
_world->m_rigidBodies[uniqueHandle] = unique_ptr<ubRigidBody>(new ubRigidBody(rigidBody, collisionShapeObject, motionStateObject));

*rigidBodyHandle = uniqueHandle;

return SUCCESS;
}
\$\endgroup\$
  • 2
    \$\begingroup\$ There is nothing in Bullet Physics to enable rotations when getting started. They should work out of the box unless they are somehow disabled. I suggest going through the bundled demos and comparing them to your code until you find the problem. \$\endgroup\$ – msell Jun 24 '14 at 4:31
  • 1
    \$\begingroup\$ Maybe you don't update your rotations of your renderable objects? \$\endgroup\$ – János Turánszki Jun 24 '14 at 9:52
  • \$\begingroup\$ That's what I thought too, but if I was simply failing to update the orientation of my rendered objects the box wouldn't be sitting where it is. Instead it would 'fall through' the other box. \$\endgroup\$ – mamidon Jun 24 '14 at 18:30
  • \$\begingroup\$ OK this is just a hunch, but maybe your angular damping is too high. Also the friction may to to low. Imagine a ultra low friction ball with little mass, that may actually slide off a surface than roll of it. \$\endgroup\$ – rioki Nov 27 '14 at 8:59
  • \$\begingroup\$ This code looks fine so perhaps there's a bug in rotation reading code and it simply isn't drawn correctly? Have you tried creating bodies with different initial rotation? Have you tried printing the rotation values instead of using them in rendering? What about using the btIDebugDraw class to draw Bullet Physics object data? \$\endgroup\$ – snake5 Sep 24 '15 at 10:04
2
\$\begingroup\$

Your problem is that you're not supplying an inertia vector in the btRigidBodyConstructionInfo constructor. Your rigid body dynamic spheres end up with a default inertia of (0,0,0). This prevents angular motion, but not linear, so your objects slide but don't rotate. Look at some of the Bullet demo code and you'll see examples of the inertia being calculated for specific collision shapes, there are helper methods in the collision object or shape class.

\$\endgroup\$
0
\$\begingroup\$

you probably didn't calculateLocalInertia()

If I comment out that line here, the objects don't rotate:

btVector3 myStartingInertia(0, 0, 0);
instanceData[thisLocation].myDefaultMotionState = new 
btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), 
btVector3(spawnLocation.x, spawnLocation.y, spawnLocation.z)));
myCollisionShape->calculateLocalInertia(myMass, myStartingInertia);
btRigidBody::btRigidBodyConstructionInfo myRigidBodyConstructionInfo(myMass, 
instanceData[thisLocation].myDefaultMotionState, myCollisionShape, 
myStartingInertia);
myRigidBodyConstructionInfo.m_restitution = 0.35;
myRigidBodyConstructionInfo.m_friction = 0.0;
\$\endgroup\$
-1
\$\begingroup\$

I don't know about C++ clearly but when I use it in java the bullet library there is method called setToRotation you can check that

\$\endgroup\$

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.