Navigation Utilities Implementation

The navigation utilities code come from a wide range of capabilities. The main area of interest from an implementation perspective is how we move the viewpoint in response to commands from the mouse and keyboard.

Navigation provides a number of different modes. Within each mode you can have the ability to do terrain following and/or collision avoidance. For collision avoidance and terrain following, we will refer you to the tutorial on the main site as the process is described there. The one footnote to add is that we use the geometry intersection tools from this library.

The terrain following is based on a generalised collision detection system. As we have to build a completely generalised system we cannot use more specialised code. In fact, we recommend that if you can build a specialised scenegraph for your application that it will be more efficient than this code.


Code Outline

Class Structure

Freeform Navigation

Viewpoint Management

Determining Frame Delay Amounts

This section is provided by Lazlo about how he came up with the numbers in the code for calculating the frame delays for movement.

The goal is to increase frame-rate as much as possible on a Canvas3D. The main question is when should I ask a Canvas3D to render a new frame?

  • If too early it just can not do the job, because it has not finished the previous one yet.
  • If I ask it too late, then I loose important milliseconds and it just sits around lazy.
The perfect synchronization is when a Canvas3D has just finished drawing and gets the next job immediately.

First guess would be:

long approximateTimeForNextFrameDuration= view.getLastFrameDuration();
I wrote a small test program to find the maximum possible frame-rate for a scene with a few iterations. It measured the elapsed time in the rendering loop, then set a timer which triggered the Canvas3D rendering. When it found the optimal value it printed it. After examining the resulting values compared with the view.getLastFrameDuration() I knew that there is a BIG FISH hanging on the rope. The values were about the half of it!!! That night it was hard to get some sleep.

My first navigation module worked with this iterating algorithm. Then I got tired of it and decided to find the function that is the most closest to the iterating algorithm's result, so I might even gain more performance with not doing the iteration, but loose some timing accuracy.

Just think of it! If you turn around in a scene and in a corner of the room there is a messy heavy object, but the other end is empty (You should see my flat!), then the iterating algorithm really has a job to do and some frames will not be shot with the best possible timing until the algorithm settles.

The function that fitted the best was this:

timerDelay = 10 + (int)view.getLastFrameDuration() / 2;

WHY /2.0 ???
WHY +10 ???

I do not understand this function, but it gave me the best results ever.

Then I tested it with different video cards and platforms and operating systems. They all gave the same results. Actually the value 10 could be smaller for faster PCs, but 10 worked for all and 10ms is not much.


Other References