Collision detection problem

smallping
Posts: 11
Joined: Fri Oct 19, 2012 3:37 am

Collision detection problem

Post by smallping »

Hi, All, I have a problem about collision detection.

As shown in Figure 1, I want to simulate the motion of a probe tool (*.obj mesh object) through a torus hole (*.obj mesh object), it means that the probe tool can move back and forward and rotate around the hole. The torus object is fixed, and the probe tool is moving which is controlled by mouse or haptic device.
But now as shown in Figure 2, the probe tool can not be constrained by the torus hole, it is very easy to pop outside the torus object.

Here is my code.

Because the probe tool is moving, I use the btGImpactMeshShape, as following:
btRigidBody* BulletWrap::addMeshProbe(int numTriangles, int *indices, int numVertices, float *verts, btVector3 &position, btVector3 &inertia, btScalar mass, btScalar restitution, bool collision)
{
btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(numTriangles, indices,3*sizeof(int),numVertices, verts, 3*sizeof(float));

btGImpactMeshShape * trimesh = new btGImpactMeshShape(indexVertexArrays);
trimesh->setLocalScaling(btVector3(1.f,1.f,1.f));
trimesh->updateBound();
btCollisionShape *m_trimeshShape = trimesh;

btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_world->getDispatcher());
btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);

btTransform trans;
trans.setIdentity();
trans.setRotation(btQuaternion(btVector3(1,0.0,0.0),3.14/2));
trans.setOrigin( position );

inertia.setZero();
inertia[0] = 0.113870; inertia[1] = 0.210512; inertia[2] = 0.114837; inertia[3] = 0.0;
//m_trimeshShape->calculateLocalInertia( mass, inertia );

btDefaultMotionState* motionstate = new btDefaultMotionState( trans );
btRigidBody* body = new btRigidBody( mass, motionstate, m_trimeshShape, inertia );
//body->setRestitution( restitution );
body->setActivationState(ACTIVE_TAG);
body->setDamping(0.1,0.5);

m_world->addRigidBody( body );

if( collision )
m_collisionShapes.push_back(m_trimeshShape);

return body;
}

Because the torus object is static, firstly I tried btBvhTriangleMeshShape, as following, it is very easy to pop outside.
btRigidBody* BulletWrap::addTriangleMeshStatic( int numTriangles, int *indices, int numVertices, float *verts,btVector3 &position, bool useQuantizedBvhTree,btVector3 &inertia, btScalar mass, btScalar restitution, bool collision )
{
btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(numTriangles, indices, 3*sizeof(int), numVertices, verts, 3*sizeof(float));

btTransform trans;
trans.setIdentity();
trans.setRotation(btQuaternion(btVector3(1,0.0,0.0),g_dPI/2)); //X轴旋转90度
trans.setOrigin( position );

btCollisionShape* trimeshShape = new btBvhTriangleMeshShape(indexVertexArrays, useQuantizedBvhTree, true );
trimeshShape->calculateLocalInertia( mass, inertia ); //gives error

btDefaultMotionState* motionstate = new btDefaultMotionState( trans );

btRigidBody* body= new btRigidBody( mass, motionstate, trimeshShape, inertia );
//body->setRestitution( restitution );

m_triangleMeshBodies.push_back( body );
m_world->addRigidBody( body );

if( collision )
m_collisionShapes.push_back(trimeshShape);

return body;
}
Then I tried also btGImpactMeshShape, it is a little better, but also easy to pop outside.
btRigidBody* BulletWrap::addMeshTorus(int numTriangles, int *indices, int numVertices, float *verts, btVector3 &position, btVector3 &inertia, btScalar mass, btScalar restitution, bool collision)
{
btTriangleIndexVertexArray* indexVertexArrays = new btTriangleIndexVertexArray(numTriangles, indices,3*sizeof(int),numVertices, verts, 3*sizeof(float));

btGImpactMeshShape * trimesh = new btGImpactMeshShape(indexVertexArrays);
trimesh->setLocalScaling(btVector3(1.f,1.f,1.f));
trimesh->updateBound();
btCollisionShape *m_trimeshShape = trimesh;

btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_world->getDispatcher());
btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);

btTransform trans;
trans.setIdentity();
trans.setRotation(btQuaternion(btVector3(1,0.0,0.0),g_dPI/2)); //X轴旋转90度
trans.setOrigin( position );

inertia.setZero();
inertia[0] = 0.113870; inertia[1] = 0.210512; inertia[2] = 0.114837; inertia[3] = 0.0;
//m_trimeshShape->calculateLocalInertia( mass, inertia );

btDefaultMotionState* motionstate = new btDefaultMotionState( trans );

btRigidBody* body = new btRigidBody( mass, motionstate, m_trimeshShape, inertia );
//body->setRestitution( restitution );
body->setActivationState(ACTIVE_TAG);
body->setDamping(0.1,0.5);

m_world->addRigidBody( body );

if( collision )
m_collisionShapes.push_back(m_trimeshShape);

return body;
}

I also tried different time steps, such as stepPhysics(1/30.0), stepPhysics(1/60.0), stepPhysics(1/100.0), stepPhysics(1/300.0), the same problem exists.

Does somebody have any idea? I do not know why? The probe tool is very easy to pop outside the torus hole, cannot be constrained by the torus object.
You do not have the required permissions to view the files attached to this post.
Rikus
Posts: 4
Joined: Sat Sep 14, 2013 7:40 am

Re: Collision detection problem

Post by Rikus »

Did you tried increasing the solver iteration count?
more info: http://bulletphysics.org/mediawiki-1.5. ... SolverInfo

Beware, high values may hit your performance if you have many rigid bodies.
smallping
Posts: 11
Joined: Fri Oct 19, 2012 3:37 am

Re: Collision detection problem

Post by smallping »

Dear Rikus

Thanks very much for your reply. I tried, and it is the same problem, also my application is for medical knee surgery simulation, there are thousands of polygon meshes.

Does anyone has other idea? I do not know how to fix this? I think I use the wrong collision detection? or Bullet is not stable? or something else?
MaxDZ8
Posts: 149
Joined: Fri Jun 24, 2011 8:53 am

Re: Collision detection problem

Post by MaxDZ8 »

I'm not really sure you're doing your kinematics correctly because I don't remember what ACTIVE_TAG does... but if memory serves, it doesn't do what you want.
Try using setActivationState(DISABLE_DEACTIVATION) instead.

The problem arises from performance optimization. Bullet uses a "collision cache" internally and this cache is flushed only after a certain movement has been detected. Kinematics are considered pretty much like static objects internally so they stay there for quite a while. This causes them to accumulate a lot of distance before the old cache is flushed. I'm not sure how it is flushed to be honest, maybe it's also flushed periodically, I've never really checked.
But I'm sure I had a similar problem and I discovered my kinematics were incorrectly considered resting.
smallping
Posts: 11
Joined: Fri Oct 19, 2012 3:37 am

Re: Collision detection problem

Post by smallping »

Thanks for replying.
I tried using setActivationState(DISABLE_DEACTIVATION) instead, it is the same problem.

Actually I do not use any kinematics or constraints, I just load two mesh models(*.obj file), one model is static, and the other is moved by the haptic device or mouse.
I only use collision detection to constraint the probe model to move through and rotate inside the hole.
Because in bullet there is no any kinematic or constraint that can meet my requirement, like the hinge constraint, point constraint, they are different from my motion. My probe object can only move back and forward along the hole and also can rotate a small angle around the hole.

Does anybody has any idea? many thanks.
Rasoul
Posts: 8
Joined: Wed Sep 05, 2012 7:03 pm

Re: Collision detection problem

Post by Rasoul »

If you only need to detect the collision (and not a physics simulation on what happens when the probe hits the torus), then you don't need any Physics engine. All you need is a collision detection algorithm. I think you can use the PQP Library in your application. Here is the official website:

http://gamma.cs.unc.edu/SSV/
smallping
Posts: 11
Joined: Fri Oct 19, 2012 3:37 am

Re: Collision detection problem

Post by smallping »

Dear Rasoul

Thanks for your information.
We need physics simulation, and also force feedback.
Because we use haptic device, so not just for collision detection.

Best regards