ConvexSweepTest Keeps Failing

Post Reply
mklingen
Posts: 5
Joined: Wed Jul 25, 2012 8:13 pm

ConvexSweepTest Keeps Failing

Post by mklingen »

I am trying to use btCollisionWorld::convexSweepTest to find out where along a line of motion a sphere intersects a mesh, in Bullet 2.76.

There are three objects in my world: a mesh object, a box object, and a sphere object. The sphere object is created during my function to check for the convexSweepTest, added to the broadphase, and then deleted when the test has ended. The sphere object's collision shape is passed in to convexSweepTest as the first argument. The collision flags and masks are set up to work properly for the sphere, the callback, and the objects in the environment.

We have our own custom needsbroadphase function, which, in this case, seems to correctly return "true" when testing between the sphere and the mesh and box, but the broadphase collision detector we are using is btDbvtBroadphase.

Unfortunately, convexSweepTest seems to fail to detect a hit every time :( While our discrete collision check seems to work correctly.


Here specifically is the function we use to perform the test:

Code: Select all

// Casts a sphere from the start position to the end position, and if there is a hit, stores it in the ConvexResultCallback.
void Environment::sphereCast(Eigen::Vector3d sphereOrigin, Eigen::Vector3d sphereEnd, double sphereRadius, btCollisionWorld::ConvexResultCallback& result)
{
    // Creates a custom object for our environment. SphereObject extents btCollisionObject
    arms::SphereObject* sphereObject = new arms::SphereObject();

    // Setting up properties for the custom object.
    sphereObject->setRadius(sphereRadius);
    sphereObject->name = "cast_sphere";

    // Here, ROBOT = 1 and INANIMATE = 2. 
    sphereObject->collisionGroup = arms::Object::ROBOT;
    sphereObject->collisionMask = arms::Object::INANIMATE | arms::Object::ROBOT;
    sphereObject->pose.translation() = sphereOrigin;

    // Custom function that adds the object to the broadphase collision pairs.
    addObject(*sphereObject, true, true);

    // Custom function that sets the transforms of objects to their correct positions in Bullet.
    syncBullet();

    // Creating the transforms for sweeping the sphere. (Converting between Eigen and btVector3)
    btTransform rayFromTrans;
    rayFromTrans.setIdentity();
    rayFromTrans.setOrigin(btVector3(sphereOrigin(0), sphereOrigin(1), sphereOrigin(2)));

    btTransform rayToTrans;
    rayToTrans.setIdentity();
    rayToTrans.setOrigin(btVector3(sphereEnd(0), sphereEnd(1), sphereEnd(2)));

    // Make sure the result callback has the correct collision flags. The objects we will be casting against
    // have collisionGroup = INANIMATE and collisionFilter = ROBOT.
    result.m_collisionFilterGroup = arms::Object::ROBOT;
    result.m_collisionFilterMask = arms::Object::INANIMATE | arms::Object::ROBOT;

   // Perform the sweep test.
    collisionWorld->convexSweepTest((btSphereShape*)sphereObject->getCollisionShape(), rayFromTrans, rayToTrans, result);

    // Get rid of the temporary object we created to do the sphere cast.
    removeObject(sphereObject->uid);
}
The code to call the function is as follows:

Code: Select all

        

btCollisionWorld::ClosestConvexResultCallback result(btVector3(sphereOrigin(0), sphereOrigin(1), sphereOrigin(2)), btVector3(sphereEnd(0), sphereEnd(1), sphereEnd(2)));

rayEnvironment->sphereCast(sphereOrigin, sphereEnd, sphere.GetRadius(), result);

if(result.hasHit())
{
    printf("Has hit!\n");
}
else
{
   printf("Didn't hit!\n");
}
And, after this function is called, "hasHit()" is always "false." I have attached a screenshot of the ray successfully going through the object as displayed in our environment -- yet the sweep test still fails. Again, our "needsbroadphase" function seems to be correctly returning "true" for both the mesh object and the box object with respect to the cast sphere.

Any idea what is going on here?
Attachments
spherecast.png
spherecast.png (9.66 KiB) Viewed 6571 times
mklingen
Posts: 5
Joined: Wed Jul 25, 2012 8:13 pm

Re: ConvexSweepTest Keeps Failing

Post by mklingen »

Okay, I solved the issue. Turns out this is a fundamental issue with our implementation of a kinematic bullet environment:

updateAABBs needs to be called when anything moves in the world. Normally, this is taken care of inside tick(), but since we are using bullet merely for kinematic collision checking, this is never called. After putting "updateAABBs" after "syncBullet", ray casts and sphere casts now work!
monkeyman
Posts: 22
Joined: Sat Nov 26, 2011 5:41 pm

Re: ConvexSweepTest Keeps Failing

Post by monkeyman »

mklingen wrote:Okay, I solved the issue. Turns out this is a fundamental issue with our implementation of a kinematic bullet environment:

updateAABBs needs to be called when anything moves in the world. Normally, this is taken care of inside tick(), but since we are using bullet merely for kinematic collision checking, this is never called. After putting "updateAABBs" after "syncBullet", ray casts and sphere casts now work!
As a side-note, the btKinematicCharacterController has the same bug, it updates positions of the character without recalculating the AABBs and hence will miss interpenetrations..

Was recently struck with something similar :)
bcsanches
Posts: 10
Joined: Mon Feb 02, 2009 2:15 pm

Re: ConvexSweepTest Keeps Failing

Post by bcsanches »

As a side-note, the btKinematicCharacterController has the same bug, it updates positions of the character without recalculating the AABBs and hence will miss interpenetrations..
Hello,

how you update the ghost object AABBs for the btKinematicCharacterController?

Thank you
Bruno
monkeyman
Posts: 22
Joined: Sat Nov 26, 2011 5:41 pm

Re: ConvexSweepTest Keeps Failing

Post by monkeyman »

bcsanches wrote:
As a side-note, the btKinematicCharacterController has the same bug, it updates positions of the character without recalculating the AABBs and hence will miss interpenetrations..
Hello,

how you update the ghost object AABBs for the btKinematicCharacterController?

Thank you
Bruno
You need to put something like this in the beginning of recoverFromPenetration, so it updates the AABBs in the beginning of each iteration:

Code: Select all

	btVector3 minAabb, maxAabb;
	myghostshape->getAabb(myghostobject->getWorldTransform(), minAabb,maxAabb);
	collisionWorld->getBroadphase()->setAabb(myghostobject->getBroadphaseHandle(), 
						 minAabb, 
						 maxAabb, 
						 collisionWorld->getDispatcher());
Causes really subtle bugs otherwise..
amrishkum
Posts: 17
Joined: Wed May 23, 2012 7:08 pm

Re: ConvexSweepTest Keeps Failing

Post by amrishkum »

Hi

As I was looking at your post, I need similar kind of help. I am trying to detect collision between a primitive shape object (like sphere, cone, cylinder, etc) with triangular mesh object with the help of Concave Convex routine. I want to transform primitive object as well as triangular mesh (which I can do by using quaternions) so what is the correct way of detecting collision . I have attached a sample code.

Can anyone please guide me through this?

Regards
Amrish Kumar
Attachments
CollisionInterface.cpp
(6.67 KiB) Downloaded 374 times
Post Reply