@Agent
Hello,
The math to find the height isn't too hard. What I'll explain and the terms I'll use you probably already know most of it. The concept is this:
The distance to a plane can be found by using the dot product. The bumps and slopes of a terrain are all planes facing different directions. To determine which direction a plane is facing, or rather, the tilt of the plane, you need the face normal of that plane.
The normal is a vector that points perpendicular to the plane. We will call the plane a face from now on - meaning a face is one of the triangles that makes up your terrain. The face has 3 vertices. If we know the value of one of these vertices, and we know the face normal, we have enough to know where the face is in 3d space. If we have some other point in 3d space, we can find the distance between this point and the face. This distance can be our terrain height for that face.
Assuming that the terrain is X wide and Z long with height Y, we assume our height check point is from some X,Z position where Y=0. So basically, we are saying that a height of 0 is the lowest point and the distance from (X,0,Z) up to a face on the terrain is the height on the terrain at that point. Using the dot product, we can find this distance.
The first thing is to find out which face your X,Z position is under or over. You can do that by knowing the dimensions of your terrain and it's position relative to the lower left corner of the terrain being at (0,Y,0). Let's say your terrain is 10x10 cells, and it is 1000 units in both the x and z directions. Cell 0 is in the lower left corner and cell 99 is in the upper right corner.
If your object's X,Z position on the terrain is 78,34 , which cell is it in?
xcells=10
zcells=10
cellsizex=1000/xcells
cellsizez=1000/zcells
cell = (78/cellsizex)+((34/cellsizez)*xcells)
You'd have to add bounds checking to make sure you are within the terrain.
Anyway, we know in this scenario the cell at position X,Z=78,34 is cell 0. We will assume 2 faces per cell. We will also assume that the vertices for each cell/face have been previously stored or are accessible. To find which face (triangle) in the cell we are under or over, we want the slope between the lower left X,Z vert of the cell and our X,Z point. For Cell 0, the lower left X and Z is 0,0.
slope = (Z-lowerZ)/(X-lowerX)
If this slope is greater than (cellsizez/cellsizex), then we are under triangle 1 in the current cell. If the slope is less than or equal, we are under triangle 2 of the current cell. In our case, our slope is less so we are in triangle 2. This assumes the rotation order of the vertices is the same as for a DB matrix. The cells look like this
*------*
| /|
| 1 / |
| / |
| / |
| / 2 |
|/ |
*------*
Once you know the triangle, assuming you have also stored the face normal for each triangle (face), you can use the dot product and all of the information we have gathered to determine the height at any given X,Z position.
height = dot_product(X-trianglecornerx,0-trianglecornery,Z-trianglecornerz,normalx,normaly,normalz)
end
function dot_product(ax#,ay#,az#,bx#,by#,bz#)
result#=(ax# * bx#) + (ay# * by#) + (az# * bz#)
endfunction result#
It's pretty fast, especially if you have your normal and points stored ahead of time for look up. If you don't have the face normal, you can calculate those using the cross product and any two edges of the face. Just make sure your vectors (edges) are going the correct direction or your normal will be in the opposite direction.
This dot product method only checks the cell you are over so it doesn't have to query the entire mesh.
Enjoy your day.