Need help (newbie level) for collisions with a ray and my custom terrain geometry

I apologize in advance for asking dumb questions that have probably already been addressed, but I’ve been googling the docs and searching the forum and I haven’t been able to connect all the dots. Maybe someone here can help point me in the right direction?

I have a simple demo I’ve been building that assembles a world out of tiles using the slippy tile (OSM) level of detail scheme. This scheme basically subdivides the world up into quad trees. For terrain I’ve been using SRTM data. I’ve been doing this at flight-sim world scales … so maybe 50 mile visibility range.

What I would like to do is figure out code that will intersect any arbitrary ray with my quad-tree terrain mesh. (So I am not going to be using collision solids … I need the exact point of collision) Even though the world is divided up logically into quad trees, I’m attaching individual tiles to “render” so it’s a flat list of tiles that are visible. Initially I’ll probably just point a ray straight down to see if I can get height above ground, but eventually I want to try shooting rays in arbitrary directions. What I hope to get back is the X, Y, Z of the intersection point(s) of an arbitrary ray.

Is there a code example floating around that could help me understand what parts of the collision detection system I need to focus on to make something like this work?

As a fall back I could just query the raw SRTM mesh directly, but I was hoping to avoid that because it seems less general purpose and I really would like to figure out and experiment with the collision functions in panda3d.

Thanks in advance!


I uploaded my code on monday, so I’m not sure how much help it will be. But here goes:

Basically what you want is a ray object, and then octree collections of cubes or squares. The mapping should be obvious and then call for each level of detail:

Add your ray to the collection you want to check
cTrav.traverse() on the collection of the appropriate detail level

Then go smaller or you’re done.

I haven’t got much feedback on my code yet, so especially if it’s not clear to you which parts do what, ask away and I can improve my code and help you.

It’s sort of kind of like the mouse ray I’m setting up in my code, except the point of origin is different. I too want to interaction with the terrain, so I’m creating the collision objects from polygon shapes with “create_complex”

1 Like

Hi Max12345, thanks for the reply and the sample code. As I read through, it sounds like I can’t just do collisions against arbitrary polygons in panda3d, I would need to create a parallel tree of collision solid primatives that approximate my actual geometry and then the collision ray is intersected with this collection of collision solids. Am I understanding that correctly? What I was hoping for would be to just build up my polygon mesh and compute intersections against the polygons themselves, but maybe that isn’t supported in panda3d?



It works like this, and it has nothing to do with panda.

Panda does not limit you, but in fact you will have to repeat the functionality of the panda collision system, if you do this on python, then this will have consequences for performance.

You can play around with the example, but you will need a depth buffer render and, accordingly, a camera in the location with the beam.

1 Like

Oh, interesting to grab the intersection point out of the depth buffer, that is a cool idea … especially for mouse clicks.

However I may need to do intersections with terrain below me that isn’t current in the view frustum.

And sure, I can puzzle through doing the intersection work with the raw faces myself the hard way … and that’s ok if that’s the answer … but I was just hoping panda3d would have functionality to do this without all the headache. But no worries.

It sounds like one way or another, the best option is to maintain my own parallel geometry and do the intersection math myself.

Appreciate the feedback, that lets me know what direction I need to push.

Yes, you will need to duplicate the camera to render the buffer if you want to test the additional ray.

Yes, you will need to duplicate the camera to render the buffer if you want to test the additional ray.

Oh, but that would be another rendering pass, right?

Yes, this is not a problem, the problem is copying this texture into RAM. This is not a very fast operation…

1 Like

This is all good to know and good thoughts and ideas. I know like 5% (optimistically) :slight_smile: and there is so much more to panda3d and 3d graphics in general. I have SRTM tiles cached so I can interpolate my elevation for any lat/lon from that … but due to LOD the ‘true’ elevation might vary slightly from the rendered elevation but probably will be close enough.

I would like to add that if you don’t need arbitrary clicking on the surface, you can theoretically create a buffer of 1 by 1 pixel or so. Since the vector is static, it makes no sense to display the entire view from the camera completely, it is enough that lies in the direction of the camera vector. This will reduce the size of the texture being copied to RAM, which will be faster.

1 Like

Oh, it seems Epihaius is already using this trick.

This is perhaps an aside, but the above is not entire correct, I believe.

Specifically, Panda does allow collisions against visible geometry, if I’m not much mistaken–but it’s not recommended. In short, visible geometry isn’t optimised for collision-detection, and thus may be slower to collide with than dedicated collision-geometry.

However, I imagine that the approach offered by Epihaius is likely better in your scenario anyway!

However, this is also incorrect, because a copy of the data is created under the hood for collision during program execution.

In other words, you get the same collision polygon, but without your participation. And you also need to use ray to calculate the point.

1 Like