I started using Continuous Collision Detection on an iOS app, but I can't get it working properly.
In the game I'm developing, there are a lot of spheres, and I configure only the faster one with CCD. When this pass through other balls or through some walls, an error happens. While debugging the code I could catch a strange behavior with some information (linear velocity, velocityError, etc) with nan values. The btTransformUtil is the class where the calculations goes wrong.
I made a test, keeping only the fast ball and and a btRigidBody made up with a btConvexHullShape. The app doesn't crash anymore, but the ball keep passing through the wall when moving too fast.
I'm using a very tiny time step (0,0016). Actually that was my first attempt to solve this problem. In each graphics loop, I call stepSimulation several times. I'm slicing the deltaT in several 0.0016 steps;
The following are some interesting information about my world:
- Before activating ccd, I was using a very tiny time step enough to detect the collision even in the fastest velocity, but with no success;
- Sometimes the ball kick the wall and come back faster (sometimes much faster) than the collision velocity. All of the restitution coefficient are less than 1.0;
- I tried inverting the wall shape point orientation, but this didn't affect anything;
- In the actual device this problem happens less often than in the simulator. Simulator has a very low fps due to the lack of GPU for graphics (about 20fps in Simulator and 60fps in device)
That's my world creation code:
Code: Select all
//
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
// Set up the collision configuration and dispatcher
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
// The actual physics solver
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
// The world.
_world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
_world->setGravity(btVector3(0, 0, -kGravidade));
//Ccd
_world->getDispatchInfo().m_useContinuous=true;
//_world->getDispatchInfo().m_allowedCcdPenetration = 0.000001;
Code: Select all
btConvexHullShape *collisionShape = new btConvexHullShape();
collisionShape->addPoint(pt1);
collisionShape->addPoint(pt2);
collisionShape->addPoint(pt3);
collisionShape->addPoint(pt4);
collisionShape->addPoint(pt5);
collisionShape->addPoint(pt6);
collisionShape->setMargin(0);
// btTriangleMesh *mesh = new btTriangleMesh();
// mesh->addTriangle(pt1, pt2, pt3);
// mesh->addTriangle(pt2, pt3, pt4);
// mesh->addTriangle(pt3, pt4, pt5);
// mesh->addTriangle(pt4, pt5, pt6);
//
// I tried a triangle mesh as well
// btBvhTriangleMeshShape *collisionShape = new btBvhTriangleMeshShape(mesh, false);
btTransform transform;
transform.setIdentity();
btDefaultMotionState* motionState = new btDefaultMotionState(transform);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, motionState, collisionShape, btVector3(0,0,0));
btRigidBody *rigidBody = new btRigidBody(rigidBodyCI);
rigidBody->setFriction(kTabelaCoefFriccao);
rigidBody->setRestitution(kTabelaCoefRestituicao);
rigidBody->setWorldTransform(transform);
_world->addRigidBody(rigidBody);
Code: Select all
btCollisionShape *shape = [BolaDeJogo _sphereShape];
btVector3 inertia;
shape->calculateLocalInertia(kBolaMassa, inertia);
btMotionState *motionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,kBolaRaio)));
_corpoFisico = new btRigidBody(kBolaMassa, motionState, shape, inertia);
_corpoFisico->setFriction(kBolaCoefFriccao);
_corpoFisico->setDamping(kBolaDampingLinear, kBolaDampingAngular);
_corpoFisico->setRestitution(kBolaCoefRestituicao);
_corpoFisico->setLinearFactor(btVector3(1, 1, 0.01));
_corpoFisico->setActivationState(DISABLE_DEACTIVATION);
_corpoFisico->setCcdMotionThreshold(0.1 * kBolaRaio);
_corpoFisico->setCcdSweptSphereRadius(kBolaRaio);
Thank you,
Dilson