Shpere accelerating on non-tilting surface (VIDEO)

apanloco
Posts: 7
Joined: Wed Dec 29, 2010 12:08 am

Shpere accelerating on non-tilting surface (VIDEO)

Post by apanloco »

I am developing a simple game with Bullet (2.77) and Ogre3D, and have stumbled upon a problem. Sometimes when a ball (btSphereShape) is dropped on a table (btBvhTriangleMeshShape, converted with BtOgre) it starts accelerating even though it landed on a non-tilting surface.

I have uploaded a video on youtube to demonstrate the problem:

http://www.youtube.com/watch?v=RJISa__WanY

In the video you should note that,
- I drop an apparently troubled ball that starts accelerating. It doesn't only accelerate in one direction, it accelerates forwards in any direction.
- I drop two other balls, that both come to a rest.
- I hide and show 3D/Physics during the movie, so you maybe can spot an error.

APPENDIX

Here is some extra commented code in case it helps anyone.

I add a ball with the following code (physics code second half):

Code: Select all

bool Ball::create(int n, Ogre::SceneManager *sceneManager, Ogre::Vector3 position, Ogre::Vector3 initialVelocity) {
  _position = position;
  _sceneManager = sceneManager;

  std::string name = "Ball" + boost::lexical_cast<std::string>(n);
  _entity = sceneManager->createEntity(name, "ball.mesh");

  _entity->setMaterialName("Ball");

  _node = sceneManager->getRootSceneNode()->createChildSceneNode();
  _node->attachObject(_entity);
  _node->scale(
      Settings::getInstance().getFloat("ball_scale_x") * Settings::getInstance().getFloat("world_scale"),
      Settings::getInstance().getFloat("ball_scale_y") * Settings::getInstance().getFloat("world_scale"),
      Settings::getInstance().getFloat("ball_scale_z") * Settings::getInstance().getFloat("world_scale"));

  _node->setPosition(position);

  Ogre::Real radius = entity->getBoundingRadius();
  _shape = new btSphereShape(radius);

  MotionState *state = new MotionState(_node);

  btScalar mass = Settings::getInstance().getFloat("ball_mass"); // 1
  btVector3 inertia;
  _shape->calculateLocalInertia(mass, inertia);

  _body = new btRigidBody(mass, state, _shape, inertia);
  _body->setRestitution(Settings::getInstance().getFloat("ball_restitution")); // 0.9
  _body->setFriction(Settings::getInstance().getFloat("ball_friction")); // 0.5
  _body->setDamping(
      Settings::getInstance().getFloat("ball_lin_damping"), // 0.1
      Settings::getInstance().getFloat("ball_ang_damping")); // 0.5
  Physics::getInstance().getWorld()->addRigidBody(_body, Physics::getBallCollisionGroup(), Physics::getBallCollidesWith());

  _created = true;

  return true;
}
I add the table with the following code (physics code second half):

Code: Select all

bool Table::create(Ogre::SceneManager *sceneManager, Ogre::Vector3 position) {
  _position = position;
  _sceneManager = sceneManager;

  _entity = sceneManager->createEntity("Table", "table.mesh");
  _node = sceneManager->getRootSceneNode()->createChildSceneNode();
  _node->scale(
      Settings::getInstance().getFloat("table_scale_x") * Settings::getInstance().getFloat("world_scale"),
      Settings::getInstance().getFloat("table_scale_y") * Settings::getInstance().getFloat("world_scale"),
      Settings::getInstance().getFloat("table_scale_z") * Settings::getInstance().getFloat("world_scale"));
  _node->setPosition(_position);
  _node->attachObject(_entity);

  BtOgre::StaticMeshToShapeConverter converter(entity);
  _shape = converter.createTrimesh();

  _body = new btRigidBody(0, new btDefaultMotionState(btTransform(btQuaternion(
      0, 0, 0, 1), btVector3(0, 0, 0))), _shape, btVector3(0, 0, 0));

  _body->setRestitution(Settings::getInstance().getFloat("table_restitution")); // 0.7
  _body->setFriction(Settings::getInstance().getFloat("table_friction")); // 0.3
  _body->setDamping(
      Settings::getInstance().getFloat("table_lin_damping"), // 0.1
      Settings::getInstance().getFloat("table_ang_damping")); // 0.5

  Physics::getInstance().getWorld()->addRigidBody(_body, Physics::getTableCollisionGroup(), Physics::getTableCollidesWith());

  _created = true;

  return true;
}

I step simulation with following code:

Code: Select all

  const Ogre::Real elapsedTime = evt.timeSinceLastFrame;
  int maxSubSteps = 100;
  const Ogre::Real fixedTimestep = 1. / 240.;

  if (fixedTimestep * maxSubSteps < elapsedTime) {
    LOG("WARNING: Simulation lagging begind");
  }

  if (!_keyboard->isKeyDown(OIS::KC_F2)) {
    Physics::getInstance().getWorld()->stepSimulation(elapsedTime, maxSubSteps, fixedTimestep);
    if (_keyboard->isKeyDown(OIS::KC_F3)) {
      CProfileManager::dumpAll();
    }
  }
And the physics is initiated with the following code:

Code: Select all

void Physics::initialize(PhysicsTickCallback *callback) {
  _callback = callback;
  _broadphase = new btAxisSweep3(btVector3(-METERS(10), -METERS(10), -METERS(10)), btVector3(METERS(10), METERS(10), METERS(10)));
  _collisionConfig = new btDefaultCollisionConfiguration();
  _dispatcher = new btCollisionDispatcher(_collisionConfig);
  _solver = new btSequentialImpulseConstraintSolver();

  _world = new btDiscreteDynamicsWorld(_dispatcher, _broadphase, _solver, _collisionConfig);
  btVector3 gravity(0, 0, Settings::getInstance().getFloat("gravity") * Settings::getInstance().getFloat("world_scale"));
  _world->setGravity(gravity);
  _world->setInternalTickCallback(globalTickCallback, static_cast<void *>(this));
}
Again, thanks.

BR, apanloco
apanloco
Posts: 7
Joined: Wed Dec 29, 2010 12:08 am

Re: Shpere accelerating on non-tilting surface (VIDEO)

Post by apanloco »

Ok, so the problem seems to be with the btBvhTriangleMeshShape. I tested by replacing only the floor with either a btStaticPlaneShape or a btBox2dShape hovering just above the table and I couldn't reproduce the problem.

EDIT: It seems (I could still be wrong) that what triggers this is the boundaries between the triangles. In other words when the ball lands on, or passes, between two triangles, it gets a force that it doesn't loose. I have logged and tripple checked all vertices from blender to whats passed to BvhTriangleMeshShape and they are identical, and perfectly flat (z = 0).

Still, any hints on how a btBvhTriangleMeshShape that _looks_ good with DebugDrawer could behave like this is highly appreciated.

BR, apanloco
vostorus
Posts: 1
Joined: Wed Aug 19, 2009 2:14 pm

Re: Shpere accelerating on non-tilting surface (VIDEO)

Post by vostorus »

Others have had issues of jitter and such with contacts on internal edges of a concave mesh. It doesn't sound like the exact same problem you are running into, but similar, so it's probably worth a look.

Refer to http://code.google.com/p/bullet/issues/detail?id=27 to follow the discussion/solution to that issue. Basic idea is that in 2.76, btInternalEdgeUtility was added that has a collection of functions that can be used to help alleviate the jittering issue with internal edge contacts.
apanloco
Posts: 7
Joined: Wed Dec 29, 2010 12:08 am

Re: Shpere accelerating on non-tilting surface (VIDEO)

Post by apanloco »

Thank you!

Indeed it sounds like the same problem, but unfortunately the provided solution (triangleInfoMap + btAdjustInternalEdgeContacts) didn't help at all.

I will avoid using triangle meshes and simply (or rather, tediously) use simple shapes instead. They work very well.

BR, apanloco