Hi everyone,
I use Bullet Physics only for collision detection. My goal is to detect collision in a Mass-Spring system.
So, I have a btCollisionWorld in which i add some btCollisionObject, with a btCollisionShape corresponding to a btCompoundShape. Those btCompoundShape have btTriangleShapes as children. To update my btCollisionWorld, i created a unordered_map which associate a ptr btVector3 of each btTriangleSHapes to a ptr of a particle from the MSS, so i can update the child shape btVector3s positions depending on the particle it is associated to.
The problem is the following : after manually updating the btVector3s, i need to recreate the btCollisionObjects, readd them to the world, and delete the old ones so the collisions are detected. If i just update the btVector3 position, the collision are not detected (even if the collision shape is moving in the debugger).
Do you have any idea why this happens ?
Thanks
Updating btCollisionObject position (collision detection only)
-
- Posts: 3
- Joined: Tue May 14, 2019 11:01 pm
-
- Posts: 3
- Joined: Tue May 14, 2019 11:01 pm
Re: Updating btCollisionObject position (collision detection only)
Oh, and it might be better with some code :
My members
Creating the world
Adding objects
Updating the world
Computing collisions
My members
Code: Select all
btCollisionConfiguration* m_collision_configuration;
btCollisionDispatcher* m_dispatcher;
btBroadphaseInterface* m_broadphase;
btCollisionWorld* m_collision_world;
std::map<btVector3*, vec3*> map_btVector3_Vector;
Code: Select all
double scene_size = 500;
unsigned int max_objects = 16000;
m_collision_configuration = new btDefaultCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collision_configuration);
btScalar sscene_size = (btScalar) scene_size;
btVector3 worldAabbMin(-sscene_size, -sscene_size, -sscene_size);
btVector3 worldAabbMax(sscene_size, sscene_size, sscene_size);
m_broadphase = new bt32BitAxisSweep3(worldAabbMin, worldAabbMax, max_objects, 0, true); // true for disabling raycast accelerator
m_collision_world = new btCollisionWorld(m_dispatcher, m_broadphase, m_collision_configuration);
m_collision_world->setForceUpdateAllAabbs(true);
Code: Select all
auto compoundShape = new btCompoundShape();
btTransform transform;
transform.setIdentity();
transform.setOrigin(btVector3(0,0,0));
int a, b, c;
for(unsigned int i=0; i< mesh.triangle_count(); ++i)
{
a= mesh.indices()[i*3];
b= mesh.indices()[i*3 +1];
c= mesh.indices()[i*3 +2];
btVector3 v1(mesh.positions()[a].x, mesh.positions()[a].y, mesh.positions()[a].z);
btVector3 v2(mesh.positions()[b].x, mesh.positions()[b].y, mesh.positions()[b].z);
btVector3 v3(mesh.positions()[c].x, mesh.positions()[c].y, mesh.positions()[c].z);
auto triangle = new btTriangleShape(v1, v2, v3);
triangle->setMargin(0);
compoundShape->addChildShape(transform, triangle);
map_btVector3_Vector.insert(std::pair<btVector3*, vec3*>(&triangle->getVertexPtr(0), &mesh.positions()[a]));
map_btVector3_Vector.insert(std::pair<btVector3*, vec3*>(&triangle->getVertexPtr(1), &mesh.positions()[b]));
map_btVector3_Vector.insert(std::pair<btVector3*, vec3*>(&triangle->getVertexPtr(2), &mesh.positions()[c]));
}
auto* object = new btCollisionObject();
object->setCollisionShape(compoundShape);
object->setActivationState(1);
m_collision_world->addCollisionObject(object);
Code: Select all
for (auto& element : map_btVector3_Vector)
{
btVector3* btVector = element.first;
vec3* vector = element.second;
btVector->m_floats[0] = vector->x;
btVector->m_floats[1] = vector->y;
btVector->m_floats[2] = vector->z;
}
int nb_objects = m_collision_world->getCollisionObjectArray().size();
std::vector<btCollisionObject*> objects;
for (int k = 0; k < nb_objects; k++)
{
auto* object = m_collision_world->getCollisionObjectArray()[k];
objects.emplace_back(object);
auto compoundShape = dynamic_cast<btCompoundShape*> (object->getCollisionShape());
auto newCompoundShape = new btCompoundShape();
//std::cout << "NB CHILDREN" << compoundShape->getNumChildShapes() << std::endl;
for (int nb_children = 0; nb_children < compoundShape->getNumChildShapes(); nb_children++)
{
btTransform newChildTransform = compoundShape->getChildTransform(nb_children);
newCompoundShape->addChildShape(newChildTransform,compoundShape->getChildShape(nb_children));
}
auto newObject = new btCollisionObject();
newObject->setCollisionShape(newCompoundShape);
m_collision_world->addCollisionObject(newObject);
}
for (btCollisionObject* object : objects)
{
m_collision_world->removeCollisionObject(object);
}
Code: Select all
m_collision_world->performDiscreteCollisionDetection();
bool one_collision = false;
int numContacts = 0;
int numManifolds = m_collision_world->getDispatcher()->getNumManifolds();
//For each contact manifold
for (int i = 0; i < numManifolds; i++)
{
btPersistentManifold* contactManifold = m_collision_world->getDispatcher()->getManifoldByIndexInternal(i);
const btCollisionObject* ob0 = contactManifold->getBody0();
const btCollisionObject* ob1 = contactManifold->getBody1();
contactManifold->refreshContactPoints(ob0->getWorldTransform(), ob1->getWorldTransform());
numContacts = contactManifold->getNumContacts();
for (int j = 0; j < numContacts; j++)
{
one_collision = true;
std::cout << "----------------- contact number : " << j <<std::endl;
}
}
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Updating btCollisionObject position (collision detection only)
The btCompoundShape has an internal AabbTree which is supposed to be automatically updated by default whenever you add/remove/transform one of the children. This AabbTree is used to optimize narrow-phase collision detection.
If you weren't already: you should be using using btCompoundShape::updateChildTransform() to communicate the new local-frame transform of each child, not by poking the child shape directly.
If you were already using that then... I dunno. Show us the old not-working code rather than the new semi-working-but-not-ideal code.
If you weren't already: you should be using using btCompoundShape::updateChildTransform() to communicate the new local-frame transform of each child, not by poking the child shape directly.
If you were already using that then... I dunno. Show us the old not-working code rather than the new semi-working-but-not-ideal code.
-
- Posts: 3
- Joined: Tue May 14, 2019 11:01 pm
Re: Updating btCollisionObject position (collision detection only)
Thanks for the reply and for the hint !
I thought earlier about btCompoundShape::updateChildTransform(), but seeing that it needed a btTransform, i told myself that I couldn't compute the new transform of the triangle
But creating a btTransform with origin btVector3(0,0,0) and updating all child shapes with it made it work. Hope it's a not too bad method
Thanks
I thought earlier about btCompoundShape::updateChildTransform(), but seeing that it needed a btTransform, i told myself that I couldn't compute the new transform of the triangle
But creating a btTransform with origin btVector3(0,0,0) and updating all child shapes with it made it work. Hope it's a not too bad method
Thanks