trying to get ray casting working for picking objects

Heiko
Posts: 5
Joined: Wed Feb 02, 2011 2:51 pm

trying to get ray casting working for picking objects

Post by Heiko »

Hello! I'm new to bullet and I'm trying to get ray casting working for picking objects. For now I'm using simple test shapes but I get unexpected results. Each object I'm trying to pick is created like this:

Code: Select all

// create a boxShape with size 2, 2, 2
btCollisionShape *shape = new btBoxShape(btVector3(1, 1, 1));
btCollisionObject *body = new btCollisionObject();
body->setCollisionShape(shape);
body->setUserPointer(this);
	
// world is a btDynamicsWorld *
world->addCollisionObject(body);
The position of this object is updated as follows:

Code: Select all

btTransform pos;
pos.setIdentity();

// mat is a btScalar * containing an OpenGL type matrix
pos.setFromOpenGLMatrix(mat);

// apply the transform to the object
body->setWorldTransform(pos);
And the ray cast is performed like this:

Code: Select all

btCollisionWorld::ClosestRayResultCallback resultCallback(from, to);
world->rayTest(from, to, resultCallback);

if (resultCallback.hasHit())
{
  // some object was hit
}
For debugging purposes I request all collision objects from the world (with getCollisionObjectArray();), print their origins, the from and to vectors and the calculated world xy coordinate at the z coordinate of the origin of the object. Actual output is shown below:

Code: Select all

// a hit was expected given this ray, the objects origin and the size of the object
from: [-0.155175, -0.020690, 27.001001]
to:   [-776.752686, -103.567055, -4972.657227]
obj[0], origin: [-4.000000, 0.000000, 0.000000] // according to world->getCollisionObjectArray().at(0).getWorldTransform().getOrigin();
obj[0], calculated ray xy coordinate @z==0.000000: [-4.349244, -0.579899] // debug, calculated myself using from/to/origin.z
resultCallback.hasHit(): false

// again, I would have expected a hit
from: [-0.143106, 0.000000, 27.001001]
to:   [-716.338684, 0.000000, -4972.657227]
obj[0], origin: [-4.000000, 0.000000, 0.000000] // according to world->getCollisionObjectArray().at(0)..getWorldTransform().getOrigin();
obj[0], calculated ray xy coordinate @z==0.000000: [-4.010970, 0.000000] // debug, calculated myself using from/to/origin.z
resultCallback.hasHit(): false
I was able to get some hits in case the object was very close to the center of the screen. But also in this case the hit area was generally smaller than the size of the object I was trying to hit. Anything obvious I'm doing wrong here? Are there any important steps in setting up the btDynamicsWorld which I could be missing?

Any help would be greatly appreciated!

one more thing: the objects are static (they don't move, the camera doesn't move either but that doesn't really matter I guess; only for the result of my unproject code).
lulzfish
Posts: 43
Joined: Mon Jan 03, 2011 4:26 pm

Re: trying to get ray casting working for picking objects

Post by lulzfish »

I see you are setting the transform from an OpenGL matrix. Is it possible that this matrix scales your graphics objects? I'm not sure how Bullet supports scaling as I have never tried to scale something, and my unscaled objects seem to pick fine using the same approach you use here.
Heiko
Posts: 5
Joined: Wed Feb 02, 2011 2:51 pm

Re: trying to get ray casting working for picking objects

Post by Heiko »

Thank you for your reply. I've been thinking about that myself. The matrix _should_ not scale the object. But I'll have a good look at the matrices I'm feeding the btCollisionObjects.

update: the matrices seem fine: the matrix I store in the btTransform of the btCollisionObject is the same as the one I get back when requesting the matrix from the object. The matrix does not contain any rotation or scaling. It just contains a translation.
Heiko
Posts: 5
Joined: Wed Feb 02, 2011 2:51 pm

Re: trying to get ray casting working for picking objects

Post by Heiko »

From what I can tell the following is happening:

Ray testing works if the ray passes through the origin of the world or passes the origin close enough. For example: if I place the camera on [-28, -14, 5] and I place the target object on [28, 14, -5] a hit is detected. The edge of the object is also properly detected if the ray to the edge is close enough to the origin of the world.

However, if the ray does not get in proximity of the origin of the world, a hit is not detected. For example: if I place the camera on [28, 0, 0] and I place the target object on [-28, 2, 0] a hit is only detected properly in the lower part of the object. Shooting a ray from [27.002, 0.038, 0] to [-471.649, 18.708, 0] does not result in a hit while this ray clearly goes through the object (z must be 0, and on x == -28 y ~= 2: the center of the object).

When I increase the size of the btBoxShape the maximum distance between the ray and the origin of the world in which a hit can be detected gets larger. For example: if I increase the btBoxShape size from 1,1,1 to 2,2,2 the ray from the example above does result in a hit.

I'm puzzled: the from and to vectors in the examples above are precisely those which I'm feeding to the btCollisionWorld::rayTest function (and the resultCallback object). The origins of the objects are requested from the btCollisionWorld and therefore can't be wrong either.

Requesting the matrices for the btCollisionObjects results in proper matrices which are exactly equal to the matrices I'm feeding the objects. No rotations or scaling is applied. I've tried creating both a btDiscreteDynamics world and a btCollisionWorld; there was no difference in behaviour. I've also tried using a btSphereShape instead of a box: no difference either. I tried using different types of result callback objects (closest, all): no difference.

Could it be I encountered a bug in the rayTest functionality? For the record: I'm using bullet 2.77 on ios 4.2 simulator.

update: I tried bullet 2.75 and bullet 2.76 as well. These versions have the same behavior. Probably I'm doing something wrong.
Heiko
Posts: 5
Joined: Wed Feb 02, 2011 2:51 pm

Re: trying to get ray casting working for picking objects

Post by Heiko »

I have solved the problem. All I needed to do was a `updateAabbs' on the world after something changed.
lulzfish
Posts: 43
Joined: Mon Jan 03, 2011 4:26 pm

Re: trying to get ray casting working for picking objects

Post by lulzfish »

Heiko wrote:I have solved the problem. All I needed to do was a `updateAabbs' on the world after something changed.
Huh, I might have had that problem earlier and not noticed. Are you supposed to call that after you move an object manually?
Heiko
Posts: 5
Joined: Wed Feb 02, 2011 2:51 pm

Re: trying to get ray casting working for picking objects

Post by Heiko »

The step function now seems to handle this properly as well. After some changes were made to that part of the code, the explicit updateAabbs call wasn't necessary anymore.
iain.price2
Posts: 2
Joined: Mon Jul 16, 2012 10:14 pm

Re: trying to get ray casting working for picking objects

Post by iain.price2 »

Is there a tutorial for picking? I am using xcode and bullet physics on the cube/balls/both demo and am trying to make it so you can select a shape to destroy it. Finding it a bit tricky. Any help? tutoirals? examples?

Thanks