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);
}
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");
}
Any idea what is going on here?