Since three.js objects do not have hard surfaces, you will need to create your own. You can use these surfaces to create runways, landable carrier decks, and deadly mountains.
ACflyt uses the following variables to represent the aircraft map position: MPosXV (east/west), MPosYV (altitude), MPosZV (north/south). The variable GrdZed represents the ground elevation. The variable for the ground elevation is GrdZed. The Aircraft Data File contains MinAlt, the variable for the minimum height of the aircraft axis. This height is different for each aircraft. ACflyt does not allow the aircraft axis to drop below GrdZed plus MinAlt. The Demo Program starts with the aircraft at map position 0,0 which means that MPosXV = 0 and MPosZV = 0.
The Demo Program uses a default GrdZed of sea level (0). The value of MinAlt in the Aircraft Data File assumes that the aircraft will land right-side-up with landing gear fully extended. The Demo Program does not "punish" the user for crashing through GrdZed plus MinAlt since that would be a waste of time. But odd things may happen if you do so.
The simplest surface is a single rectangle which is aligned either north/south (z) or east/west (x). In this case, you merely need to specify the xz outline of the runway (west, east, north and south) and the elevation of the runway. With each repetition, the program will check to see if your aircraft xz map location is within the bounds of this rectangle, i.e. if the aircraft x location is greater than W and less than E and if the aircraft z location is greater than S and less than N. If so, then the ground elevation is changed to the airport elevation. If the aircraft minimum altitude (including landing gear) is less than the ground elevation, you have either crashed or landed.
In the Demo Program, the aircraft starts out on a runway located on an island. the runway boundaries are defined as offsets of the island xz map location. Since this island is the first in a series of objects, the variables for the island xz map location are ObjMPX[1] and ObjMPZ[1]. The variables for the runway offsets are BasXlf (west), BasXrt (east), BasZfr (north) and BasZbk (south). The program computes the map values for the runway parameters by adding ObjMPX[1] to BasXlf and BasXrt and ObjMPZ[1] to BasZfr and BasZbk. The variables for the resulting xz map values of the runway are XL (west), XR (east), ZF (north) and ZB (south). Since the island is not moving, you only need to compute these values once. The variable for the airport altitude is BasAlt.
To determine whether the aircraft is over the runway, the program uses the following comparison:
if (XL < MPosXV && XR > MPosXV && ZF > MPosZV && ZB < MPosZV)
If all of these things are true then the aircraft is over the runway and GrdZed = BasAlt.
ACflyt will not allow the aircraft to drop below this altitude.
If your simulation has variable terrain, you will want to make sure that the aircraft does not crash through the terrain. If the terrain is flat enough to land on, you might want to classify the terrain to determine is a landing would be successful. The Demo Program does not harden or classify the terrain, but this is easily done. To harden the terrain, you need an array of altitude values which corresponds with your terrain. Since you will generally not be landing or taxiing on the terrain, the altitude values do not have to be extremely precise. Nor do you have to go to a lot of work to create this array. If, as is common, you use a grayscale elevation map to create your terrain, you can use the values in that map.
If you create your terrain using discrete Blender objects, you would use the grayscale elevation map that you used to create each object. You would determine the xz map position of each grid as an offset of the object center. You would then determine if you are over the object. If so, then you would determine which grid you are over and load the elevation for that grid. Alternatively, if you create your terrain using an elevation map that covers an entire area, you merely need to use the elevation data from that map.
In addition to elevation information, you might want to use other information about the terrain in your simulation. For example, if the terrain is flat enough, you might allow the plane to land on the terrain. In that case, you could store information about the nature of the terrain, such as whether the terrain is water, paved, hard, soft or covered with trees. As with elevation, this information can be stored in a bmp file (grayscale or color)
You can allow the program to determine whether the terrain is flat enough to land on by having the program compute the gradient of the terrain. This would involve comparing the altitude of the current terrain with the altitude of adjacent grids. If the change in elevation is too great, the terrain is not landable (even in a helicopter).