Using a Behavior Class : some issues

Programming Pitfalls

Where in the Scene Graph Should a Behavior Object Go?

or

Behavior Class Design Recommendations

Programming Pitfalls of Using Behavior Objects

In the three steps of the using a behavior class recipe, the two most likely programming mistakes are:

The intersection of the scheduling bounds of a behavior with the activation volume of a view determines whether or not Java 3D even considers the trigger stimulus for the behavior. Java 3D will not warn you of a missing scheduling bounds - the behavior will never be triggered.
Also, keep the scheduling bounds of each behavior object as small as possible for the best overall performance. As mentioned above, a behavior object that is not part of the scene graph will be considered garbage and eliminated on the next garbage collection cycle. This, too, will happen without error or warning.

Where in the Scene Graph Should a Behavior Object Go?

Behaviors can be placed anywhere in the scene graph. The issues in picking a scene graph location for a behavior object are 1) the effect on the scheduling bounds, and 2) code maintenance.
The bounds object referenced by a behavior object is subject to the local coordinate system of the behavior object's position in the scene graph. In the scene graph created in SimpleBehaviorApp, the SimpleBehavior object and the ColorCube are not subject to the same local coordinate system. In the example application this does not create a problem. The TransformGroup object of the example only rotates the ColorCube so that the scheduling bounds for the myRotationBehavior object always encloses the ColorCube object allowing interaction with the ColorCube when it is visible 2 .
However, if the TransformGroup object were used to translate the ColorCube object, it would be possible to move the ColorCube out of the view. Since the bounds object stays with the behavior object in this scene, the user would be able to continue to translate the object. As long as the activation volume of a view still intersects the scheduling bounds for the behavior, the behavior is still active. Being able to interact with a visual object that is not in the view is not bad (if that is what you want).
The problem lies in that if the view were to change such that the activation volume no longer intersects the scheduling bounds of the behavior, even to include the visual object, the behavior is inactive. So the visual object you want to interact with may be in your view but not active.
Most users will consider this a problem (even if it is intentional).

There two solutions to this problem. One is to change the scene graph to keep the scheduling bounds of the behavior with the visual object.
The alternativesolution uses a BoundingLeaf object for the scheduling bounds. Consult the Java 3D API Specification for information on the BoundingLeaf class.

Behavior Class Design Recommendations

The mechanics of writing a custom behavior are simple. However, you should be aware that a poorly written behavior can degrade rendering performance.

While there are other considerations in writing a behavior, two things to avoid are: memory burn and unnecessary trigger conditions.

'Memory burn' is the term for unnecessarily creating objects in Java. Excessive memory burn will cause garbage collections. Occasional pauses in rendering is typical of memory burn since during the garbage collection, the rendering will stop 45 . Behavior class methods are often responsible for creating memory burn problems. For example, in the last example, the processStimulus uses a 'new' in the invocation of wakeupOn (line 24). This causes a new object to be created each time the method is invoked. That object becomes garbage each time the behavior is triggered. Potential memory burn problems are normally easy to identify and avoid. Look for any use of 'new' in the code to find the source of memory burn problems. Whenever possible, replace the use of the new with code that reuses an object.

You will see it is possible to set a trigger condition that will wake a behavior every frame of the rendering. If there is nothing for the behavior to do, this is an unnecessary waste of processor power invoking the behavior's processStimulus method. Not to say that there isn't a good reason to trigger a behavior on every frame, just make sure you have the reason.