Rigid body with child sensors

Post Reply
justjayel
Posts: 9
Joined: Sat Aug 28, 2021 4:08 pm

Rigid body with child sensors

Post by justjayel »

Hiya

I am curious what is the best way to create a rigid body linked with a sensor object such as a ghost object? I want the sensor object to move with the parent rigid body and detect collisions.

I don't think btCompoubdShape is correct since I believe that only affects the shape of the rigid body. Also I have read constraints aren't absolute since the constraint slowly deteriorates.

Thanks.
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Rigid body with child sensors

Post by drleviathan »

To make a ghost object that follows a body I use an action. I derive GhostFollowsBody from the pure virtual base class btActionInterface and implement its updateAction() method like so:

Code: Select all

class GhostFollowsBody : public btActionInterface {
    btRigidBody* m_body;
    btGhostObject* m_ghost;
    
public:
    void GhostFollowsBody(btRigidBody* body, btGhostObject* ghost) : m_body(body), m_ghost(ghost) {} 
    
    void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) override {
        if (m_body->isActive()) {
            btTransform t;
            t.setIdentity();
            t.setOrigin(m_body->getWorldTransform().getOrigin());
            m_ghost->setWorldTransform(t);
        }
    }    
};
When you add a ghostFollowsBody instance to the World Bullet will call its updateAction() method every substep.

I believe the order of operations inside the substep where the actions are updated is closer to the end, after collisions have been computed and final velocities known, but before recomputing object activations. So if you ever teleport the body to an arbitrary location you should probably manually call ghostFollowsBody->updateAction(world, 0.0f) if body is active, else update the ghost through more explicit manual logic. Otherwise you may get all of the way through the important parts of the next substep before the ghost is moved to where the body is.
justjayel
Posts: 9
Joined: Sat Aug 28, 2021 4:08 pm

Re: Rigid body with child sensors

Post by justjayel »

Thanks for the reply.

I have been looking at creating a btGhostObject or btPairCachingGhostObject, but other rigid bodies seem to collide with them unless I set the below; is that correct?

Code: Select all

dynamicWorld->addCollisionObject(groundSensor, btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::StaticFilter);
I found the above code from: viewtopic.php?t=10855
But majority of my code is based on this (just setup, no motorPreTickCallback or manifold checks): viewtopic.php?t=7468
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Rigid body with child sensors

Post by drleviathan »

Those collision filter groups are there for your convenience; they are completely optional. If you examine the Bullet source code you'll find they are declared in a header but never actually used anywhere except in an example.

To get what you want I think you need to something like this before you add ghost to the world:

Code: Select all

ghost->setCollisionFlags(ghost->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
justjayel
Posts: 9
Joined: Sat Aug 28, 2021 4:08 pm

Re: Rigid body with child sensors

Post by justjayel »

This is what I got but the rigid body is moving up when it starts off at the same position as the ghost object.

Code: Select all

dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
dynamicsWorld ->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());

btCollisionShape* sensorShape = new btSphereShape(2);
btTransform sensorTf(btQuaternion(0, 0, 0, 1), btVector3(0, 2, 0));

btGhostObject* groundSensor = new btPairCachingGhostObject();
groundSensor->setCollisionShape(sensorShape);
groundSensor->setWorldTransform(sensorTf);
groundSensor->setCollisionFlags(groundSensor->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
dynamicsWorld->addCollisionObject(groundSensor);
justjayel
Posts: 9
Joined: Sat Aug 28, 2021 4:08 pm

Re: Rigid body with child sensors

Post by justjayel »

Fixed the broken ghost object; my issue was due to:

Code: Select all

this->dynamicsWorld->getSimulationIslandManager()->setSplitIslands(false);
Post Reply