Java3D Specific Hints

12. Combine behaviours and schedule them for consistent performance

The Java3D documentation tells you to set tight bounding volumes on behaviours so that they only run when they're absolutely required

tip #4 that it is better to have a constant frame-rate than a highly variable one.

The solution is to concentrate all your code into a small number of intelligent Behaviour nodes with large (or infinite) scheduling bounds.

Behaviour nodes are the smarts in you application. The interesting bits. By using Java3Ds interpolators and other behaviours in novel ways you can wire some clever logic into your scene without having to write a single line of code. The Java3D documentation tends to encourage this, and it also tells you to set tight bounding volumes on behaviours so that they only run when they're absolutely required (see tip #10). Wiring logic directly into a scene seems like a pretty cool idea at first and many new Java3D programmers take this approach to heart. Having tight scheduling bounds also seems like a cool optimisation by only running those behaviours that are actually visible.

So the temptation is to try to build everything out of the existing behaviours, and write very simple little behaviours to plug any gaps. It seems like a win-win situation. The Java3D scheduler has plenty of flexibility in running the minimum number of behaviours based on the visible area of the scene. You win too because by keeping your behaviours simple you get plenty of opportunity to reuse them in other applications. But not everthing that seems like a good idea actually turns out to be so. Fortran seemed like a good idea at the time. So did the Leyland P.76.

What have I got against behaviours? Essentially it comes back to the point in tip #4 that it is better to have a constant frame-rate than a highly variable one. Turning behaviours on and off all the time is a great way to guarantee inconsistent frame-rate. Sure it improves things for one or two individual frames, but the overall effect is more fluctuation in performance. This is a bad thing. It is also inefficient to use the Java3D behaviour scheduler to arrange what bits of your code should run when. To decide if a behaviour should run, Java3D has to check the bounding volume of the behaviour against the visible volumes of the scene. This means mapping the behaviour volume into world space (remember those long transform chains in tip #11) and then intersecting it with the view volume. Every behaviour, every frame.

The solution is to concentrate all your code into a small number of intelligent Behaviour nodes with large (or infinite) scheduling bounds. That way you get more consistent frame rates, and when it comes to turning on and off certain pieces of code you are almost always in a better position to make that decision than the Java3D scheduler (usually without having to map all sorts of complex volumes through a chain of coordinate transformations).

Good behaviour is rewarded with good performance.