Problems with Ray casting

I was trying with the ray casting stuff in Panda3d. So I went on defining a bullet world by,

world = BulletWorld()
world.setGravity(Vec3(0, 0, -9.81))

then I defined a ground plane with the following lines of codes,

shape = BulletPlaneShape(Vec3(0, 0, 1), 1)
node = BulletRigidBodyNode('Ground')
node.addShape(shape)
np = render.attachNewNode(node)
np.setPos(0, 0, -2)
world.attachRigidBody(node)

and placed couple of simple boxes at the origin,

model = loader.loadModel("boxes.dae", noCache=True)
model.setPos(-0.5, -0.5, -0.5)
model.setHpr(0, 90, 0)
model.flattenLight()

shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5))
node = BulletRigidBodyNode('Box')
node.setMass(1.0)
node.addShape(shape)
np = render.attachNewNode(node)
np.setPos(0, 0, 0)
world.attachRigidBody(node)
model.copyTo(np)

After this, I defined a ray with

RayOrigin = Point3(0.4, -10, 0.2)
RayEnd = Point3(0.4, 10, 0.2)

and rendered a line segment to check if the ray casting is indeed working or not, with

segs = LineSegs('lines')
segs.setColor(1, 1, 1, 1)
segs.moveTo(RayOrigin)
segs.drawTo(RayEnd)
segsnode = segs.create()
render.attachNewNode(segsnode)

Finally I called the rayTestClosest() function to check if the ray is in collision with the boxes, with

result = world.rayTestClosest(RayOrigin,RayEnd)
print(result.hasHit())
print(result.getHitPos())

To my surprise, the rayTestClosest is returing True even if the ray is not intersecting the boxes. Here is a screenshot of that

What am I missing here?
Thanks in advance.

Ok, it may be that rayTestClosest() only checks intersections between a ray and an object’s bounding volume. That seems a purely geometric approach. Is there any image space based methods for checking ray object intersections in either Bulletphysics or in Panda3D? One which involves sequential culling of front and back side of an object and checks for depth or stencil buffer etc.?

Thanks in adavnce.

I doubt that “rayTestClosest” is only checking bounding-boxes–I’ve used it, I believe, and haven’t noticed the sorts of problems that I’d expect if that were the case.

As to your problem, hmm… Could it be that you’re calling “rayTestClosest” before the box has had a chance to fall?

As originally defined, the box is at position (0, 0, 0), and has half-extents (0.5, 0.5, 0.5), meaning that it runs from -0.5 to 0.5 on each axis. The ray has an x-coordinate of 0.4, which likes within those extents, a z-position of 0.2, likewise, and runs along the y-axis from -10 to 10, which should pass through the box’s y-range. Thus, before the box has fallen, it should indeed intersect the ray-cast.

Thanks. I checked the thing what you said. So, what I did is that I modified the code a bit so that whenever I click a left mouse button, a ray casting event happens. If the rays intersection result return Ture, then I render the ray in blue color. I make sure that once the box settles to the floor, I then click for the ray casting. So here is the first result


So here I select BulletBoxShape(Vec3(0.5,0.5,0.5)). With that collision box primitives extents I could see the above result.
Next I change the box shape extents to (Vec3(1.0,1.0,1.0)) with the below result

Clearly I can see that only where the ray is intersecting with the bounding volume, it returns True. I also tried with non convex shapes and with arbitrary box extents such as below
Seems like the ray intersection only happening between the ray and the collision shape primitives.
I am sure, I am missing a key thing here. What is that?

It doesn’t look to me like it’s colliding with the bounding-box, but with the collider.

Note that the visual model that you have attached–that vehicle, or the set of bricks–is unrelated to this; it’s just something that’s shown, and takes no part in collisions.

All that’s relevant is the green box–the collision object, if I’m not much mistaken–and the red box–the collision-object’s bounding-box, I imagine. And it looks to me likely enough that those rays of yours are colliding with the green box.

I believe that we can test this, however: instead of a box-shape, use something else–let’s say a BulletSphereShape. Presuming that such a shape also has a box-shaped set of bounds, we can then re-run your test, shifting the rays up a bit to fall in the top-half of the sphere–this so that the sphere presents a target-area that doesn’t take up the full extent of the bounding-box. If I’m correct, then your rays should only hit the sphere, and not the bounding-box.

Thanks for your answer. I must admit that I did not convey the problem properly. Actually, I was looking to retrieve the points on the rendered objects which are in collision with the ray. So if I use a box type collision shape primitive, the rays will only check if those are in collision with the primitive or not, and hence I will get a over conservative estimate. You are correct, the actual object does not take a part in the ray collision checking process.
I think I should look for something like image space based method, as I mentioned earlier.

Ah, I see. Yeah, in that case I see a few options:

  • Approximate your models with multiple primitives
  • Create custom collision-geometry for your models
  • Use an image-based technique, as you suggested
    • Perhaps render your objects with an id-colour per object, and then examine the colour under the cursor.
    • If you have just a single ray per frame, and the ray comes from the camera, then you could perhaps render a single pixel: the one that corresponds with the ray.
  • Use Panda’s collision system and ray-cast against visible geometry
    • Note, however, that this is rather inefficient–visible geometry is not ideal for collision-detection, I believe! Approach this option with caution.