Page 1 of 1
					
				Updating btCollisionObject position (collision detection only)
				Posted: Wed May 15, 2019 9:29 am
				by bi1cimer
				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
			 
			
					
				Re: Updating btCollisionObject position (collision detection only)
				Posted: Wed May 15, 2019 9:52 am
				by bi1cimer
				Oh, and it might be better with some code : 
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;
Creating the world 
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);
Adding objects 
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);
Updating the world
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);
}
Computing collisions
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;
            }
}
 
			
					
				Re: Updating btCollisionObject position (collision detection only)
				Posted: Wed May 15, 2019 3:47 pm
				by drleviathan
				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.
			 
			
					
				Re: Updating btCollisionObject position (collision detection only)
				Posted: Wed May 15, 2019 4:29 pm
				by bi1cimer
				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