Collision Shape Offset / Drift in time

Post Reply
oberluz
Posts: 8
Joined: Tue Oct 25, 2016 2:12 pm

Collision Shape Offset / Drift in time

Post by oberluz »

Hi,

I'm using bullet 2.85 to detect collisions in an existing simulator, ie I don't step the discrete dynamic world at all, instead I set the center of mass transform for the moving object.

Collision detection works fine - but the collision shape of the moving object drifts about the shape of the rigid body. This is illustrated in the following video (top orthogonal view in 2D), the round moving collision shape is a btConvexHullShape (drawn in white). The blue circles are my own debug draws of the rigid body of the moving shape. The red circle is the debug draw of the location the object should be occupying.

https://streamable.com/dk5lh

The rigid body seems to be always correctly positioned, but the collision shape seems to move about and I can't figure out why.

I've tried setting the world transform in the moving object motion state rather than setting the center of mass transform to see if it made any difference, without success.

Can anyone point out why this is happening?

Thank you,
Paul
oberluz
Posts: 8
Joined: Tue Oct 25, 2016 2:12 pm

Re: Collision Shape Offset / Drift in time

Post by oberluz »

UPDATE:

I suspected maybe using a btConvexHullShape, which was made up of 60 vertexes for the top and 60 for the bottom may have been the issue so I replaced it with a btCylinderShapeZ instead but I still see exactly the same issue.

I've also tried different scalings for the world, none of them made a difference.

I also, I re-wrote the code to not use the btDiscreteDynamicsWorld but instead use a btCollisionWorld (ie no rigid bodies), but it still shows the collision shape drift about.

Is it normal for the collision shape to shift about like that?
Last edited by oberluz on Fri Aug 11, 2017 1:13 pm, edited 2 times in total.
oberluz
Posts: 8
Joined: Tue Oct 25, 2016 2:12 pm

Re: Collision Shape Offset / Drift in time

Post by oberluz »

UPDATE:

It seems the collision shape is moved when I make the call to performDiscreteCollisiondetection(). If I don't call this method the rigid object moves (blue circles in the video) but the collision shape stays put.

Maybe I need to do something before calling performDiscreteCollisiondetection?

in the following snippet m_objectRigidBody is a unique_ptr to the rigid body that was constructed with the m_objectMotionState in its btRigidBody::btRigidBodyConstructionInfo

This is how I constructed the world:

Code: Select all

    m_collisionConfiguration = misc::make_unique<btDefaultCollisionConfiguration>();
    m_dispatcher = misc::make_unique<btCollisionDispatcher>(m_collisionConfiguration.get());
    m_broadphase = misc::make_unique<btDbvtBroadphase>();
    m_solver = misc::make_unique<btSequentialImpulseConstraintSolver>();
    m_dynamicsWorld = misc::make_unique<btDiscreteDynamicsWorld>(m_dispatcher.get(), m_broadphase.get(), m_solver.get(), m_collisionConfiguration.get());
    m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
This is how I constructed the rigid object and added the collision shape it it:

Code: Select all


    btVector3 objectCollisionShapeHalfExtents(115 * SCALE_WORLD_FACTOR, height * SCALE_WORLD_FACTOR, 0);
    m_objectCollisionShape = misc::make_unique<btCylinderShapeZ>(objectCollisionShapeHalfExtents);

    btVector3 objectInertia(0, 0, 0);
    m_objectCollisionShape->calculateLocalInertia(mass, objectInertia);
    const SimPose pose = (SimPose) pos;
    Angle angle = pose.angle;
    float radians = angle.Radians(Angle::BEST_SCALE_FOR_RADIANS)/ float(Angle::BEST_SCALE_FOR_RADIANS);
    m_objectMotionState = misc::make_unique<btDefaultMotionState>((btTransform(btQuaternion(0, 0, radians), btVector3(pose.pos.x(), pose.pos.y(), height/2))));
    btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, m_objectMotionState.get(), m_objectCollisionShape.get(), objectInertia);
    m_objectRigidBody = misc::make_unique<btRigidBody>(rigidBodyCI);
    m_dynamicsWorld->addRigidBody(m_objectRigidBody.get(), COL_OBJECT, COL_WALLS);

Code: Select all


    m_objectMotionState->setWorldTransform(btTransform(btQuaternion(0, 0, pos.Radians()),  btVector3(pos.fX, pos.fY, pos.fZ );
    Vector collisionLocation;
    m_collided = CollisionDetection(collisionLocation);


bool Physics::CollisionDetection(Vector& collisionLocation)
{
    bool collided = false;
    btCollisionWorld* collisionWorld = m_dynamicsWorld->getCollisionWorld();
    collisionWorld->performDiscreteCollisionDetection();
    int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
    for (int i=0; ((!collided) && (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_objectRigidBody.get()) && (obB != m_objectRigidBody.get()))
        {
            continue;
        }

        for (int p=0; p < contactManifold->getNumContacts(); p++)
        {
            const btManifoldPoint& pt = contactManifold->getContactPoint(p);
            const btVector3& localPoint = (obA == m_objectRigidBody.get()) ? pt.m_localPointA : pt.m_localPointB;
            collisionLocation = Vector(localPoint.x()/SCALE_WORLD_FACTOR, localPoint.y()/SCALE_WORLD_FACTOR, localPoint.z()/SCALE_WORLD_FACTOR);
            collided = true;
            break;
        }
    }

    return collided;
}
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Collision Shape Offset / Drift in time

Post by drleviathan »

Bullet has some penetration resolution code that tries to extract the penetrating objects from each other. This is independent of the dynamics in that it tends to just shift the position of objects rather than add velocity which would tend to pump energy into the simulation and would make things explode apart. I wonder if that logic is kicking in for your simulation. Dunno how to disable it or where it lives but maybe you can find it.
oberluz
Posts: 8
Joined: Tue Oct 25, 2016 2:12 pm

Re: Collision Shape Offset / Drift in time

Post by oberluz »

Hi drleviathan,

I tried finding that code without success. In any case why would the penetration code to play a role here as the object is nowhere near other objects. Also the collision margin should be symmetrical about the object, but in my case the bounding box and collision shape move relative to the object.

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

Re: Collision Shape Offset / Drift in time

Post by drleviathan »

Oops, sorry I don't think I fully understood your problem. Now that I read things more carefully I still don't understand. I thought you had a RigidBody and another CollisionObject but I see you have a btRigidBody and... a btCollisionShape? I don't see the code for the second thing. In any case, talking about the position of a "collision shape" in the world frame does not make any sense. I'm confused.

For example, you could create a single btSphereShape with some radius R. And then you could create 100 RigidBody's that all use the single btSphereShape instance as their shape. Where is the shape in the world? Nowhere, it exists as a description of how each RigidBody collides in its local frame. Meanwhile each RigidBody has a world transform.

So you're drawing the RigidBody according to its transform, and you're drawing... "something else" according to... what? What is the second thing and how to you obtain its transform?
Post Reply