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;
}
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;
}
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();
}
}
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));
}
BR, apanloco