Collision Detection Only
Posted: Tue Oct 25, 2016 2:17 pm
I'm trying to use bullet to perform collision detection only on an existing application but bullet seems to detect collisions when there shouldn't be any. I am trying to find out what I am doing incorrectly.
My application creates collision shapes and objects for the characters involved: a main object, which the application itself moves (ie no bullet dynamics) and a bunch of static objects.
If a collision between the main object and another object is detected then the main object is returned to its last position before colliding.
The main object rotates on the spot and when doing so I expect no collision to be detected because it is round, but collisions are being detected even just when the shape tries to turn a few degrees after being returned to a previous collision-free position.
I also implemented a debug drawer and I can see that the main object and the static object would not collide if it rotated on the spot. The attached screenshot below shows the main object stuck next to two rectangular objects:
This is how I implemented the aplication
1. Created the world:
btDefaultCollisionConfiguration* m_collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btBroadphaseInterface* m_broadphase = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver* m_solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
2. Created the main object:
// mainshape contains an array of vertices in local coordinates
btConvexHullShape* col = new btConvexHullShape();
for (Vector vertex : mainShape->GetVertices())
{
col->addPoint(btVector3(vertex.x(), vertex.y(), 0));
col->addPoint(btVector3(vertex.x(), vertex.y(), height));
}
btCollisionObject* m_mainCollisionObject->setCollisionShape(col);
m_dynamicsWorld->getCollisionWorld()->addCollisionObject(m_mainCollisionObject);
3. Created the static objects:
const int32_t numberOfObjects = objects->GetNumObjects();
for (int32_t i=0; i < numberOfObjects; i++)
{
AbstractObject* object = objects->GetObject(i);
btCollisionShape* col = object->CollisionShape();
btCollisionObject* obj = new btCollisionObject();
obj->setCollisionShape(col);
const Vector& pos = object->GetPosition();
const Angle& angle = object->GetRotation();
float degrees = angle.Degrees();
obj->setWorldTransform(btTransform(btQuaternion(0, 0, degrees), btVector3(pos.x(), pos.y(), object->GetDimensions().z()/2.0f)));
m_dynamicsWorld->getCollisionWorld()->addCollisionObject(obj);
}
4. Every time the program calculates a new position for the main object is calls the following method to detect collisions. If a collision
is detected the main object is repositioned back to the last non-colliding position:
Position Apply(const Positon& pos)
{
m_mainCollisionObject->setWorldTransform(btTransform(btQuaternion(0, 0, pos.Degrees()), btVector3(pos.x, pos.y, pos,z));
int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
for (int i=0; i < numManifolds; i++)
{
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
if ((obA != m_mainCollisionObject) && (obB != m_mainCollisionObject))
{
continue;
}
for (int p=0; p < contactManifold->getNumContacts(); p++)
{
const btManifoldPoint& pt = contactManifold->getContactPoint(p);
if (pt.getDistance() < 0.f)
{
m_collided = true;
break;
}
}
if (m_collided)
{
break;
}
if (! m_collided)
{
m_oldPos = pos;
return pos;
}
// Main object collided so reposition to last non-collided position
m_mainCollisionObject->setWorldTransform(btTransform(btQuaternion(0, 0, m_oldPos.Degrees()), btVector3(m_oldPos.x, m_oldPos.y, m_oldPos,z));
return m_oldPos;
}
}
A trace of the main object colliding, being returned to its previous position, turning on the spot and colliding :
2317 new: { x=0.0291771, y=2.37609, z=0, theta=14.3193(100.435)} col: 1
2318 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 1
2319 new: { x=0.0291771, y=2.37609, z=0, theta=14.3193(100.435)} col: 1
2320 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 1
2321 new: { x=0.0291771, y=2.37609, z=0, theta=14.388(104.374)} col: 0
2322 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 0
2323 new: { x=0.0291771, y=2.37609, z=0, theta=14.4792(109.595)} col: 1 <- here the main object turned on the spot but collided
Thank you
My application creates collision shapes and objects for the characters involved: a main object, which the application itself moves (ie no bullet dynamics) and a bunch of static objects.
If a collision between the main object and another object is detected then the main object is returned to its last position before colliding.
The main object rotates on the spot and when doing so I expect no collision to be detected because it is round, but collisions are being detected even just when the shape tries to turn a few degrees after being returned to a previous collision-free position.
I also implemented a debug drawer and I can see that the main object and the static object would not collide if it rotated on the spot. The attached screenshot below shows the main object stuck next to two rectangular objects:
This is how I implemented the aplication
1. Created the world:
btDefaultCollisionConfiguration* m_collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
btBroadphaseInterface* m_broadphase = new btDbvtBroadphase();
btSequentialImpulseConstraintSolver* m_solver = new btSequentialImpulseConstraintSolver;
btDiscreteDynamicsWorld* m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
2. Created the main object:
// mainshape contains an array of vertices in local coordinates
btConvexHullShape* col = new btConvexHullShape();
for (Vector vertex : mainShape->GetVertices())
{
col->addPoint(btVector3(vertex.x(), vertex.y(), 0));
col->addPoint(btVector3(vertex.x(), vertex.y(), height));
}
btCollisionObject* m_mainCollisionObject->setCollisionShape(col);
m_dynamicsWorld->getCollisionWorld()->addCollisionObject(m_mainCollisionObject);
3. Created the static objects:
const int32_t numberOfObjects = objects->GetNumObjects();
for (int32_t i=0; i < numberOfObjects; i++)
{
AbstractObject* object = objects->GetObject(i);
btCollisionShape* col = object->CollisionShape();
btCollisionObject* obj = new btCollisionObject();
obj->setCollisionShape(col);
const Vector& pos = object->GetPosition();
const Angle& angle = object->GetRotation();
float degrees = angle.Degrees();
obj->setWorldTransform(btTransform(btQuaternion(0, 0, degrees), btVector3(pos.x(), pos.y(), object->GetDimensions().z()/2.0f)));
m_dynamicsWorld->getCollisionWorld()->addCollisionObject(obj);
}
4. Every time the program calculates a new position for the main object is calls the following method to detect collisions. If a collision
is detected the main object is repositioned back to the last non-colliding position:
Position Apply(const Positon& pos)
{
m_mainCollisionObject->setWorldTransform(btTransform(btQuaternion(0, 0, pos.Degrees()), btVector3(pos.x, pos.y, pos,z));
int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
for (int i=0; i < numManifolds; i++)
{
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
if ((obA != m_mainCollisionObject) && (obB != m_mainCollisionObject))
{
continue;
}
for (int p=0; p < contactManifold->getNumContacts(); p++)
{
const btManifoldPoint& pt = contactManifold->getContactPoint(p);
if (pt.getDistance() < 0.f)
{
m_collided = true;
break;
}
}
if (m_collided)
{
break;
}
if (! m_collided)
{
m_oldPos = pos;
return pos;
}
// Main object collided so reposition to last non-collided position
m_mainCollisionObject->setWorldTransform(btTransform(btQuaternion(0, 0, m_oldPos.Degrees()), btVector3(m_oldPos.x, m_oldPos.y, m_oldPos,z));
return m_oldPos;
}
}
A trace of the main object colliding, being returned to its previous position, turning on the spot and colliding :
2317 new: { x=0.0291771, y=2.37609, z=0, theta=14.3193(100.435)} col: 1
2318 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 1
2319 new: { x=0.0291771, y=2.37609, z=0, theta=14.3193(100.435)} col: 1
2320 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 1
2321 new: { x=0.0291771, y=2.37609, z=0, theta=14.388(104.374)} col: 0
2322 old: { x=0.0291771, y=2.37609, z=0, theta=14.2969(99.1535)} col: 0
2323 new: { x=0.0291771, y=2.37609, z=0, theta=14.4792(109.595)} col: 1 <- here the main object turned on the spot but collided
Thank you