Physic Bullet - Any 'Ghost' Body?

Viewed 685

I'm using bullet to manage any of my physics problems.

Now I'm trying to do something like a 'sensor', the goal is easy, other bodies are doing their collisions and movements together and I want to be able to send a signal when a body reach a specific area.

The problem is to create this area and add it into the world

I only found documentation about RigidBody and SoftBody, and I need something like a "GhostBody" that other object can cross it without be affected by the collision but the collisions have to be detected.

Do anyone have any idea to do it ?

I tried to use the method addCollisionObject(ghostObject), but any body colliding with the ghostObject is affected by the collision.

Adding btBroadphaseProxy::SensorTrigger don't change the effect or just ignore the collision

For info i found this link : https://pybullet.org/Bullet/phpBB3/viewtopic.php?t=7468 collisions are detected but still affect the movment of the RigidBody

Thank you a lot !

EDIT

For now i have this code :

    /*Rigid Body ---------------- */
    shape = new btBoxShape(btVector3(0.5f, 0.75f, 0.5f));
    btTransform transform ;
    transform.setIdentity();
    transform.setOrigin( btVector3(0.0f, 0.95f, 0.0f) );

    btVector3 localInertia(0.0f, 0.0f, 0.0f);
    btScalar mass = 0.5f ;
    if(mass)
    {
        shape->calculateLocalInertia(mass, localInertia);
    }
    motionState = new btDefaultMotionState(transform);

    btRigidBody::btRigidBodyConstructionInfo boxRigidBodyConstructionInfo(mass, motionState, shape, localInertia);

    
    body = new btRigidBody(boxRigidBodyConstructionInfo);

    body->setActivationState(DISABLE_DEACTIVATION);

    world->addRigidBody(body, btBroadphaseProxy::KinematicFilter, btBroadphaseProxy::AllFilter & ~btBroadphaseProxy::SensorTrigger);

    /*GhostObject ---------------- */
    transform.setIdentity();
    transform.setOrigin( btVector3(0.0f, 0.1f, 0.0f) );
    level_sensor = new btGhostObject();
    level_sensor->setCollisionShape(new btBoxShape(btVector3(0.5f, 0.1f, 0.5f)));
    level_sensor->setWorldTransform(transform);
    world->addCollisionObject(level_sensor,btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::KinematicFilter);
    world->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback()); 
    world->setInternalTickCallback(motorPreTickCallback);

Here is the callback motorPreTickCallback :

void motorPreTickCallback (btDynamicsWorld *world, btScalar timeStep)
{
    for(int i = 0; i < level_sensor->getNumOverlappingObjects(); i++)
    {
        btRigidBody *pRigidBody = dynamic_cast<btRigidBody *>(level_sensor->getOverlappingObject(i));
        std::cout << "Collision !!!!" << std::endl;
    }
}

By using those masks in the methods addRigidBody and addCollisionObject :

-> - it is not doing any iteration in the loop. ( i don't want )

-> + the collision has no effect on the rigidBody ( i do want )

By NOT using any mask :

-> + it is doing iteration on collisions ( i do want )

-> - the collision affect the rigidBody ( i don't want )

It look like the mask logic for collision affect A & B or i'm not iterating like I want.

By using this method :

world->getBroadphase()->getOverlappingPairCache()->setOverlapFilterCallback(filterCallback);

instead of :

world->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());

I can do something like this in the callback :

// return true when pairs need collision
    virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
    {
        bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
        collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
        
        //add some additional logic here that modified 'collides'

        //if(proxy0->m_clientObject is type of sensor )
        //  Cast then sensor.method(proxy1->m_clientObject)

        //if(proxy0->m_clientObject is type of sensor )
        //  Cast then sensor.method(proxy1->m_clientObject)

        return collides;
    }

But it's really hugly ...

1 Answers

Already answered here : Ghost objects - bulletphysics The line :

level_sensor->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);

was missing

Related