Moving over the Surface
The KeyBehavior class is similar to the one in FractalLand3D in that it permits the user to move over the surface of the terrain and to float above it. However, there's one small change and one large one. The small change is the addition of the w key, which prints the user's current location on the landscape to System.out.
The major change is that a move doesn't immediately affect the user's vertical position on the terrain. The height calculation is delegated to a HeightFinder object, which may take one or two seconds to obtain the result through picking. In the meantime, KeyBehavior continues to use the old value. As a consequence, the user can move inside mountains, but the vertical position will be corrected. The reason for the slow picking is the large terrain size (e.g., over 66,000 vertices in test2.obj, specifying 131,000 faces), all packaged inside a single GeometryArray.
This approach has the advantage that key processing is decoupled from the height calculation. This means that the KeyBehavior object doesn't have to wait those few seconds after each move-related key press, which would quickly drive the user to distraction. At the end of the chapter, I discuss various alternatives to this coding technique.
Where Am I?
When the user presses the w key, printLandLocation() is called:
private void printLandLocation()
{ targetTG.getTransform(t3d);
t3d.get(trans);
trans.y -= MOVE_STEP*zOffset; // ignore user floating
Vector3d whereVec = land.worldToLand