I'm relatively new to bullet (I've been using it in my current project for the past few months), I've managed to solve most of my issues so far excluding this one issue I've been having with the btDynamicsWorld.rayTest on an "AllHitsRayResultCallback". I've set up a full 3D world and am casting a ray from the position of the camera to world objects to determine when I can pick up an object, which is fine the majority of the time, excluding when I am standing on a standard btBoxShape rigidbody and casting over the corner of the box to an object below it when they ray will -Occasionally- hit the object correctly, but slight differences in camera position and orientation will cause the ray to hit the object that the player is standing on even though it should be missing.
Here are some screenshots of my issue:


The lines drawn in the images are from the camera position (the ray origin), to the hit point of the ray result, and from the ray hit point to the ray hit point plus the normal of the collision. (to make the hit point slightly more obvious for testing). They seem to be hitting the plane of the box that the player is above (or beside as it works when looking up and over the box), without taking into account if this is off the box or not.
These hits are returned inconsistently and slightly rotating the camera or moving it can cause it to swap between hitting it and not hitting it (as stated above), this is additionally confusing as all other physics objects in the world (such as the other blocks shown in the image), collide exactly as expected with the ground boxes.
I've spent a fair amount of time attempting to debug this issue, and I have found that the ray is simply returning the ground box that I am standing on as the nearest collision, when it should not be one of the collisions in the result at all (through checking user pointer information).
This is the code I am using to generate the physics boxes is as follow:
Code: Select all
objects[i]->boxShape = new btBoxShape(btVector3(tempScale.x/2, tempScale.y/2, tempScale.z/2));
objects[i]->boxShape->setLocalScaling(btVector3(1,1,1));
objects[i]->body = new btRigidBody(0, 0, objects[i]->boxShape);
objects[i]->body->getWorldTransform().setOrigin(GetbtVect(tempPos));
objects[i]->body->getWorldTransform().setRotation(btQuaternion(tempRotation.x,tempRotation.y,tempRotation.z,tempRotation.w));
objects[i]->body->setUserPointer(objects[i]);
objects[i]->body->setRestitution(0.2);
objects[i]->body->setCollisionFlags(objects[i]->body->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
//objects[i]->boxShape->setMargin(0.0f);
int tempInt = COL_REG;
PhysicsMgr::Get().GetWorld().addRigidBody(objects[i]->body, COL_REG, tempInt);
Code: Select all
btVector3 tempStart = GetbtVect(mRenderer->GetCamera()->getDerivedPosition());
btVector3 tempEnd = GetbtVect(mRenderer->GetCamera()->getDerivedPosition() + (mRenderer->GetCamera()->getDerivedDirection() * mPickUpDistance));
btCollisionWorld::AllHitsRayResultCallback result(tempStart, tempEnd);
PhysicsMgr::Get().GetWorld().rayTest(tempStart, tempEnd, result);
Code: Select all
for (int i = 0; i < result.m_collisionObjects.size(); ++i)
{
// Run through the collision objects to find the closest
float tempDist = (result.m_hitPointWorld[i] - tempStart).length2();
if (tempDist < nearest && tempDist > currentDistance)
{
// The object is closer than the one stored so far and further away than the previous one
nearest = tempDist;
nearestObj = i;
}
}
My last resort is to perform my own ray test against a box that I create separate from the bullet box with my own ray testing code and seeing if that hits to then exclude the result from further checks, but if it's avoidable I would prefer to not.
Thanks for your help,
Humungo