Find first point of collision from quad into mesh

This is giving me far more trouble then warranted…

Basically I’m trying to find a way when a quad (literally a square in my case) will first collide into the (heightmap-based) terrain as it pitches down along one side.

Put plainly: Imagine holding up a square piece of plywood vertically so that one edge is on the ground. You now let go of plywood and it falls down. At what point (or even just, at which angle) does the board make contact with a piece of ground?

Colliding a poly-quad into a another poly mesh is, as far as I can tell, unsupported. Do I have to break out the Bullet colliders? I’ve played around with them, and a) aligning their nodes with regular panda nodes is kind of a pain (the debug view just can’t handle heightmap colliders - too much info i guess) and b) I really really don’t need a full physics sim - just this one collision test.

It feels like I’m missing something here - like this should be totally doable with just the built-in colliders. However, so far the only thing that comes to mind is a segment test that basically sweeps the area I’m interested in left to right, then down, line by line (like a CRT linescan but erm… wedge shaped). Since precision isn’t very important here, this might actually work OK, just doing an 8x8 scan (for a total of 64 line collision scans) might not be so bad. That’s some hacky problem solving though :confused:

I’m very open to ideas.

why not have one tiny ball on each vertex of the quad, and test collision on the balls?

That would be no better then checking segment collisions around the edges (worse actually). The will just poke through the middle. I suppose since I know the ground isn’t too “spiky” for my quad this might make an OK estimate though…

It’s an idea failing other approaches.

In general, collision detection against terrain is much easier and faster if you have a height map that describes your terrain. If you have a height map, you can simply find the pixel that corresponds to the X, Y position of the vertices of your square, and match the value of that pixel against the Z value of that vertex.

(You will need to test a line of pixels between the two points if you want to handle the case where the square bumps into a peak.)

Oooo that’s brilliant actually. And very easy.

So I take it I just load up the image and just look at the offsets of the same ratio of the image as the offsets on the terrain bounds… and pure white would correspond to the Sz of the generated mesh? Or is there some specific function built into GeoMipTerrain (possibly involving rendering a it’s own height map as a texture maybe?)

If your terrain is not changing, you can probably use a plugin for your modelling tool to generate a height map from your terrain mesh, or make a Panda scripts that renders your terrain using a simple shader that writes the z value into the output colour of a texture.
Or, you may decide to make your terrain in a heightfield-based terrain editor such as L3DT in the first place.

If you’re using a terrain mesh, you will need some way of converting a pixel position on your height map to an X, Y position in 3D space. This is easiest if you alter your terrain mesh such that it starts at 0, 0, 0 and ends at (x_size - 1, y_size - 1, max_height), where (x_size, y_size) is the size in pixels of your terrain mesh and max_z is the highest point on your terrain. Then, you can simply map x to x and y to y, and you have a single value by which to scale the Z position, which is max_z.
If you don’t want to reposition and rescale your terrain mesh, you can also create a node that represents the coordinate space of your height map with the appropriate translation, rotation and scale set on it, and then you can use Panda’s constructs to get your coordinates in that coordinate space.

If you’re using GeoMipTerrain to generate the terrain from the heightmap, then you can use get_elevation(x, y) to get the elevation at a specific point. It does bilinear interpolation between pixels for you.

I am using GeoMipTerrain, so it sounds like this is all I need. Well, this makes everything fantastically easier.

Thank you so much :slight_smile: