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:
// 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->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.
// Creating the transforms for sweeping the sphere. (Converting between Eigen and btVector3)
rayFromTrans.setOrigin(btVector3(sphereOrigin(0), sphereOrigin(1), sphereOrigin(2)));
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.
The code to call the function is as follows:
btCollisionWorld::ClosestConvexResultCallback result(btVector3(sphereOrigin(0), sphereOrigin(1), sphereOrigin(2)), btVector3(sphereEnd(0), sphereEnd(1), sphereEnd(2)));
rayEnvironment->sphereCast(sphereOrigin, sphereEnd, sphere.GetRadius(), result);
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?