While the topic can be quite bi,g I will summarize the process in 3 steps. I will try to be concise:
Identify the set triangle(s) that your character is likely be standing on (Broad phase)
This is a classic problem in collision detection, which is identifying the possible collisions (also called broad phase) in your world instead of checking for each pairs (the character and every triangle in your case).
The problem lays in the usually huge number of possible collisions, for example if your terrain consists of 1 million triangles, then here is one million checks just to know which triangle the character is standing on.
The good news is, such cases are typically solved by exploiting the spatial coherency of the world, closer object are more likely to hit each other than farther away objects. A classic implementation of such an idea is typically some kind of spatial data structures like uniform grids, kd-trees, and octrees. These will potentially narrow down the number of collision tests from O(n^2) to O(n), which (loosely speeking) most likely be "few number" of intersection tests.
I want to add, that in case your terrain triangles count or number of objects are small it's ok to use brute force which will take O(n^2), since it's "fine" for small sets.
Check ray intersection with the potential triangles
Once you identified the potential triangles, you need to perform intersection test, from a ray that is dropped down from your character with the potential set of triangles, and calculate the intersection point.
Calculate character standing height
Once you calculate the intersection point, you can do one of two things, depending on the situation:
- Directly use the "Y" of the calculated intersection point to adjust the standing point of your character.
- Use bi-linear interpolation, in case your character is still in the same cell, and is intersecting with the same set of triangles, to calculate the height and adjust the character's position.