Need help with picking!

I’m trying to do picking for the first time. And somehow I’ve bungled it, so that it seems a matter of considerable randomness whether a mouseclick will find any object in its path or not. Would someone be willing to take a look at my code, and see what I’ve skipped? This bug-demonstrator program is adapted from the Minecraft example here, considerably reduced. But I’m trying to pick blocks as complex objects, not just elementary cubes as that example does.

Fundamentally: a click on the main block (the one floating above the terrain) should begin rotating the main block; a click anywhere else should begin rotating the world.

Issues:

  1. It seems a matter of considerable randomness whether the code ever reaches line 62 when I click on the main block. In particular, an initial click on that block before I have done any rotating of the world, NEVER hits anything, although it often does after I have messed around a little.

  2. I am quite perplexed as to whether lines 59 and 60 (currently commented out) should even be there. The minecraft tutorial example as given (code here), contains NO call to cTrav.traverse or anything of the sort. And yet it works. But this document suggests that that call should be there.

Minimouse.zip (11.6 KB)

Without looking at the code, I can at least give some answer to issue (2), I believe:

In short, it’s required that one call “traverse” on one’s collision-traversers–unless they’re assigned to the “cTrav” variable of ShowBase. Any traverser assigned to that variable is automatically updated behind the scenes.

Hence, I daresay, the Minecraft tutorial (which I gather uses “cTrav”) not calling “traverse”, but the manual-page (which, note, _doesn’t+ use “cTrav”) calling it.

Okay, let me come at this question from another angle, perhaps this is my issue: the documentation tells me that you can go at it two ways. You can pick using the geometry itself, which is less efficient, or you can pick using CollisionNodes. Given that my geometry consists entirely of cube primitives, seems like picking directly from the geometry should not be too much of a performance issue. But where do I go to flip the switch? Where do I go to tell it that picking should find regular geometry not just CollisionNode type objects?

The problem is that within the framework of the concept of ordinary geometry, an automatically created collision polygon is understood. Thus, when using the geometry of the cube, 12 created triangles will be checked, which is theoretically slower than using a box shape.

However, it is also worth considering that the polygon is divided into two types, these are either two triangles or one quadrilateral. Accordingly, the four-square will be twice as fast, since in the case of a cube, the check will occur 6 times with each side of the cube. Which is six times more than with the box shape.

When you use geometry, usually in the case of a cube it will be 12 separate triangles or six rectangles, depending on how you generated the collision polygon. When using the setCollideMask function, triangles are generated automatically.

As serega says, even if your visible geometry is composed of cubes, unless you’re doing something unusual those are not likely to be actual cube primitives, but rather collections of polygons composing cubes.

On the other hand, the collision system can make use of actual cube-primitives for picking.

Still, it might be worth trying collision against visible geometry and determining whether or not it’s too slow for your specific case.

So:

This is described in the following manual page, in the first paragraph, I believe: There it shows the NodePath for the picking-ray being given GeomNode’s “default collide mask”–and since your visible geometry will tend to be composed of GeomNodes, that gives it the collide-mask for visible geometry.
https://docs.panda3d.org/1.10/python/programming/collision-detection/clicking-on-3d-objects

Thanks. It wasn’t clear to me exactly what that default collide mask was doing. Thanks for clarifying.

1 Like