The Java 3D API Specification Contents Previous Next Index


C H A P T E R10

Behaviors and Interpolators




BEHAVIOR nodes provide the means for animating objects, processing keyboard and mouse inputs, reacting to movement, and enabling and processing pick events. Behavior nodes contain Java code and state variables. A Behavior node's Java code can interact with Java objects, change node values within a Java 3D scene graph, change the behavior's internal state-in general, perform any computation it wishes.

Simple behaviors can add surprisingly interesting effects to a scene graph. For example, one can animate a rigid object by using a Behavior node to repetitively modify the TransformGroup node that points to the object one wishes to animate. Alternatively, a Behavior node can track the current position of a mouse and modify portions of the scene graph in response.

10.1 Behavior Object

A Behavior leaf node object contains a scheduling region and two methods: an initialize method called once when the behavior becomes "live" and a processStimulus method called whenever appropriate by the Java 3D behavior scheduler. The Behavior object also contains the state information needed by its initialize and processStimulus methods.

The scheduling region defines a spatial volume that serves to enable the scheduling of Behavior nodes. A Behavior node is active (can receive stimuli) whenever a ViewPlatform's activation volume intersects a Behavior object's scheduling region. Only active behaviors can receive stimuli.

The initialize method allows a Behavior object to initialize its internal state and specify its initial wakeup condition(s). Java 3D invokes a behavior's initialize code when the behavior's containing BranchGroup node is added to the virtual universe. Java 3D does not invoke the initialize method in a new thread. Thus, for Java 3D to regain control, the initialize method must not execute an infinite loop: It must return. Furthermore, a wakeup condition must be set or else the behavior's processStimulus method is never executed.

The processStimulus method receives and processes a behavior's ongoing messages. The Java 3D behavior scheduler invokes a Behavior node's processStimulus method when a ViewPlatform's activation volume intersects a Behavior object's scheduling region and all of that behavior's wakeup criteria are satisfied. The processStimulus method performs its computations and actions (possibly including the registration of state change information that could cause Java 3D to wake other Behavior objects), establishes its next wakeup condition, and finally exits.

10.1.1 Code Structure

When the Java 3D behavior scheduler invokes a Behavior object's processStimulus method, that method may perform any computation it wishes. Usually, it will change its internal state and specify its new wakeup conditions. Most probably, it will manipulate scene graph elements. However, the behavior code can change only those aspects of a scene graph element permitted by the capabilities associated with that scene graph element. A scene graph's capabilities restrict behavioral manipulation to those manipulations explicitly allowed.

The application must provide the Behavior object with references to those scene graph elements that the Behavior object will manipulate. The application provides those references as arguments to the behavior's constructor when it creates the Behavior object. Alternatively, the Behavior object itself can obtain access to the relevant scene graph elements either when Java 3D invokes its initialize method or each time Java 3D invokes its processStimulus method.

Behavior methods have a very rigid structure. Java 3D assumes that they always run to completion (if needed, they can spawn threads). Each method's basic structure consists of the following:

10.1.2 WakeupCondition Object

A WakeupCondition object is an abstract class specialized to fourteen different WakeupCriterion objects and to four combining objects containing multiple WakeupCriterion objects.

A Behavior node provides the Java 3D behavior scheduler with a WakeupCondition object. When that object's WakeupCondition has been satisfied, the behavior scheduler hands that same WakeupCondition back to the Behavior via an enumeration.

10.1.3 WakeupCriterion Object

Java 3D provides a rich set of wakeup criteria that Behavior objects can use in specifying a complex WakeupCondition. These wakeup criteria can cause Java 3D's behavior scheduler to invoke a behavior's processStimulus method whenever

A Behavior object constructs a WakeupCriterion by constructing the appropriate criterion object. The Behavior object must provide the appropriate arguments (usually a reference to some scene graph object and possibly a region of interest). Thus, to specify a WakeupOnViewPlatformEntry, a behavior would specify the region that will cause the behavior to execute if a ViewPlatform enters it.

10.1.4 Composing WakeupCriterion Objects

A Behavior object can combine multiple WakeupCriterion objects into a more powerful, composite WakeupCondition. Java 3D behaviors construct a composite WakeupCondition in one of the following ways:

            WakeupCriterion && WakeupCriterion && ...
            WakeupCriterion || WakeupCriterion || ...
            WakeupOr && WakeupOr && ...
            WakeupAnd || WakeupAnd || ...

10.2 Composing Behaviors

Behavior objects can condition themselves to awaken only when signaled by another Behavior node. The WakeupOnBehaviorPost WakeupCriterion takes as arguments a reference to a Behavior node and an integer. These two arguments allow a behavior to limit its wakeup criterion to a specific post by a specific behavior.

The WakeupOnBehaviorPost WakeupCriterion permits behaviors to chain their computations, allowing parenthetical computations-one behavior opens a door and the second closes the same door, or one behavior highlights an object and the second unhighlights the same object.

10.3 Scheduling

As a virtual universe grows large, Java 3D must carefully husband its resources to ensure adequate performance. In a 10,000-object virtual universe with 400 or so Behavior nodes, a naive implementation of Java 3D could easily end up consuming the majority of its compute cycles in executing the behaviors associated with the 400 Behavior objects before it draws a frame. In such a situation, the frame rate could easily drop to unacceptable levels.

Behavior objects are usually associated with geometric objects in the virtual universe. In our example of 400 Behavior objects scattered throughout a 10,000-object virtual universe, only a few of these associated geometric objects would be visible at a given time. A sizable fraction of the Behavior nodes-those associated with nonvisible objects-need not be executed. Only those relatively few Behavior objects that are associated with visible objects must be executed.

Java 3D mitigates the problem of a large number of Behavior nodes in a high-population virtual universe through execution culling-choosing to invoke only those behaviors that have high relevance.

Java 3D requires each behavior to have a scheduling region and to post a wakeup condition. Together a behavior's scheduling region and wakeup condition provide Java 3D's behavior scheduler with sufficient domain knowledge to selectively prune behavior invocations and invoke only those behaviors that absolutely need to be executed.

10.4 How Java 3D Performs Execution Culling

Java 3D finds all scheduling regions associated with Behavior nodes and constructs a scheduling/volume tree. It also creates an AND/OR tree containing all the Behavior node wakeup criteria. These two data structures provide the domain knowledge Java 3D needs to prune unneeded behavior execution (to perform "execution triage").

Java 3D must track a behavior's wakeup conditions only if a ViewPlatform object's activation volume intersects with that Behavior object's scheduling region. If the ViewPlatform object's activation volume does not intersect with a behavior's scheduling region, Java 3D can safely ignore that behavior's wakeup criteria.

In essence, the Java 3D scheduler performs the following checks:

Java 3D's behavior scheduler executes those Behavior objects that have been scheduled by calling the behavior's processStimulus method.

10.5 The Behavior API

The Java 3D behavior API spreads its functionality across three objects: the Behavior leaf node, the WakeupCondition object and its subclasses, and the WakeupCriterion objects.

10.5.1 The Behavior Node

The Behavior object is an abstract class that contains the framework for all behavioral components in Java 3D.

Constructor
The Behavior leaf node class defines the following constructor:

public Behavior()
Constructs a Behavior node with default parameters:

Parameter Default Value
enable flag true
schedulingBounds null
schedulingBoundingLeaf null

Methods
The Behavior leaf node class defines the following methods:

public abstract void initialize()
This method, invoked by Java 3D's behavior scheduler, is used to initialize the behavior's state variables and to establish its WakeupConditions. Classes that extend Behavior must provide their own initialize method. Applications should not call this method.

public abstract void processStimulus(Enumeration criteria)
This method processes stimuli destined for this behavior. The behavior scheduler invokes this method if its WakeupCondition is satisfied. Classes that extend Behavior must provide their own processStimulus method. Applications should not call this method.

public void setSchedulingBounds(Bounds region)
public Bounds getSchedulingBounds()
These two methods access or modify the Behavior node's scheduling bounds. This bounds is used as the scheduling region when the scheduling bounding leaf is set to null. A behavior is scheduled for activation when its scheduling region intersects the ViewPlatform's activation volume (if its wakeup criteria have been satisfied). The getSchedulingBounds method returns a copy of the associated bounds.

public void setSchedulingBoundingLeaf(BoundingLeaf region)
public BoundingLeaf getSchedulingBoundingLeaf()
These two methods access or modify the Behavior node's scheduling bounding leaf. When set to a value other than null, this bounding leaf overrides the scheduling bounds object and is used as the scheduling region.

protected void wakeupOn(WakeupCondition criteria)
This method defines this behavior's wakeup criteria. This method may be called only from a Behavior object's initialize or processStimulus methods to (re)arm the next wakeup. It should be the last thing done by those methods.

public void postId(int postId)
This method, when invoked by a behavior, informs the Java 3D scheduler of the identified event. The scheduler will schedule other Behavior objects that have registered interest in this posting.

protected View getView()
This method returns the primary view associated with this behavior. This method is useful with certain types of behaviors, such as Billboard and LOD, that rely on per-View information and with behaviors in general in regards to scheduling (the distance from the view platform determines the active behaviors). The "primary" view is defined to be the first View attached to a live ViewPlatform, if there is more than one active View. So, for instance, Billboard behaviors would be oriented toward this primary view, in the case of multiple active views into the same scene graph.

10.5.2 WakeupCondition Object

WakeupCondition is an abstract class that is extended by the WakeupCriterion, WakeupOr, WakeupAnd, WakeupOrOfAnds, and WakeupAndOfOr classes. A Behavior node hands a WakeupCondition object to the behavior scheduler, and the behavior scheduler hands back an enumeration of that WakeupCondition.

Methods
The Java 3D API provides two methods for constructing WakeupCondition enumerations:

public Enumeration allElements()
public Enumeration triggeredElements()
These two methods create enumerators that sequentially access this WakeupCondition's wakeup criteria. The first method creates an enumerator that sequentially presents all wakeup criteria that were used to construct this WakeupCondition. The second method creates an enumerator that sequentially presents only those wakeup criteria that have been satisfied.

10.5.3 The WakeupCriterion Objects

WakeupCriterion is an abstract class that consists of several subclasses. Each subclass specifies one particular wakeup criterion, that criterion's associated arguments (if any), and either a flag that indicates whether this criterion caused a Behavior object to awaken or a return field containing the information that caused the Behavior object to awaken.

Methods
public boolean hasTriggered()
This predicate method returns true if this WakeupCriterion contributed to waking a Behavior object.

10.5.3.1 WakeupOnAWTEvent

This WakeupCriterion object specifies that Java 3D should awaken a behavior when the specified AWT event occurs.

Constructors
public WakeupOnAWTEvent(int AWTId)
public WakeupOnAWTEvent(long eventMask)
The first constructor creates a WakeupOnAWTEvent object that informs the Java 3D scheduler to wake up the specified Behavior object whenever the AWT event specified by AWTId occurs. The second constructor creates a WakeupOnAWTEvent object that informs the Java 3D scheduler to wake up the specified Behavior object whenever any of the specified AWT EVENT_MASK events occur. The eventMask consists of an ORed collection of EVENT_MASK values.

Methods
public AWTEvent[] getAWTEvent()
This method returns the array of consecutive AWT events that triggered this WakeupCriterion to awaken the Behavior object. The Behavior object can retrieve the AWTEvent array and process it in any way it wishes.

10.5.3.2 WakeupOnActivation

The WakeupOnActivation object specifies a wakeup the first time the ViewPlatform's activation region intersects with this object's scheduling region. This gives the behavior an explicit means of executing code when it is activated.

Constructors
public WakeupOnActivation()
This constructor creates a WakeupOnActivation criterion.

10.5.3.3 WakeupOnBehaviorPost

This WakeupCriterion object specifies that Java 3D should awaken this behavior when the specified behavior posts the specified ID.

Constructors
public WakeupOnBehaviorPost(Behavior behavior, int postId)
This constructor creates a WakeupOnBehaviorPost object that informs the Java 3D scheduler to wake up this Behavior object whenever the specified behavior posts the specified postId. A postId of 0 specifies that this behavior should awaken on any post from the specified behavior. Specifying a null behavior implies that this behavior should awaken whenever any behavior posts the specified postId.

Methods
public int getPostId()
This method returns the postId used in creating this WakeupCriterion.

public Behavior getBehavior()
This method returns the behavior specified in this object's constructor.

public int getTriggeringPostId()
This method returns the postid that caused the behavior to wake up. If the postid used to construct this wakeup criterion was not zero, the triggering postid will always be equal to the postid used in the constructor.

public Behavior getTriggeringBehavior()
This method returns the behavior that triggered this wakeup. If the arming behavior used to construct this object was not null, the triggering behavior will be the same as the arming behavior.

10.5.3.4 WakeupOnDeactivation

The WakeupOnDeactivation object specifies a wakeup on the first detection of a ViewPlatform's activation region no longer intersecting with this object's scheduling region. This gives the behavior an explicit means of executing code when it is deactivated.

Constructors
public WakeupOnDeactivation()
This constructor creates a new WakeupOnDeactivation criterion.

10.5.3.5 WakeupOnElapsedFrames

This WakeupCriterion object specifies that Java 3D should awaken this behavior after it has rendered the specified number of frames. A value of 0 implies that Java 3D will awaken this behavior at the next frame. The wakeup criterion can be either passive or nonpassive. If a behavior uses a nonpassive WakeupOn-ElapsedFrames, the rendering system will run continuously.

Constructors
public WakeupOnElapsedFrames(int frameCount)
This constructor creates a nonpassive WakeupOnElapsedFrames object that informs the Java 3D scheduler to wake up the specified Behavior object after it has drawn frameCount frames. A frameCount value of N means wake up at the end of frame N, where the current frame is 0. A frameCount value of 0 means wake up at the end of the current frame.

public WakeupOnElapsedFrames(int frameCount, boolean passive)
This constructor creates a WakeupOnElapsedFrames criterion. The passive flag indicates whether this behavior is passive. A nonpassive behavior will cause the rendering system to run continuously. A passive behavior will run only when some other event causes a frame to be run.

Methods
public int getElapsedFrameCount()
This method returns the frame count that was specified when constructing this object.

public boolean isPassive()
This method retrieves the state of the passive flag that was used when constructing this object.

10.5.3.6 WakeupOnElapsedTime

This WakeupCriterion object specifies that Java 3D should awaken this behavior after an elapsed number of milliseconds.

Constructors
public WakeupOnElapsedTime(long milliseconds)
This constructor creates a WakeupOnElapsedTime object that informs the Java 3D scheduler to wake up the specified Behavior object after the specified number of milliseconds.


Note: The Java 3D scheduler will schedule the object after the specified number of milliseconds have elapsed, not before. However, the elapsed time may actually be slightly greater than the time specified.
Methods
public long getElapsedFrameTime()
This method returns the WakeupCriterion's elapsed time value in milliseconds.

10.5.3.7 WakeupOnSensorEntry

This WakeupCriterion object specifies that Java 3D should awaken this behavior when any sensor enters the specified region.


Note: There can be situations in which a sensor may enter and then exit an armed region so rapidly that neither the Entry nor Exit condition is engaged.
Constructors
public WakeupOnSensorEntry(Bounds region)
This constructor creates a WakeupOnSensorEntry object that informs the Java 3D scheduler to wake up the specified Behavior object whenever it detects a sensor within the specified region for the first time.

Methods
public Bounds getBounds()
This method returns the Bounds object used in creating this WakeupCriterion.

public Sensor getTriggeringSensor()
This method retrieves he Sensor object that caused the wakeup.

10.5.3.8 WakeupOnSensorExit

This WakeupCriterion object specifies that Java 3D should awaken this behavior when any sensor, already marked as within the region, is no longer in that region.


Note: This semantic guarantees that an Exit condition is engaged if its corresponding Entry condition was engaged.
Constructors
public WakeupOnSensorExit(Bounds region)
This constructor creates a WakeupOnSensorExit object that informs the Java 3D scheduler to wake up the specified Behavior object the first time it detects that a sensor has left the specified region.

Methods
public Bounds getBounds()
This method returns the Bounds object used in creating this WakeupCriterion.

public Sensor getTriggeringSensor()
This method retrieves the Sensor object that caused the wakeup.

10.5.3.9 WakeupOnCollisionEntry

This WakeupCriterion object specifies that Java 3D should awaken the WakeupOnCollisionEntry behavior when the specified object collides with any other object in the scene graph.

Constants
public static final int USE_GEOMETRY
public static final int USE_BOUNDS
These constants specify whether collision against a Group, Shape, or Morph node is done using the actual geometry or whether the geometric bounds are used as an approximation.

Constructors
public WakeupOnCollisionEntry(SceneGraphPath armingPath)
public WakeupOnCollisionEntry(SceneGraphPath armingPath,
       int  speedHint)
public WakeupOnCollisionEntry(Node armingNode)
public WakeupOnCollisionEntry(Node armingNode, int speedHint)
public WakeupOnCollisionEntry(Bounds armingBounds)
These constructors create a WakeupOnCollisionEntry object that informs the Java 3D scheduler to wake up the specified Behavior object if the specified "armed" node's geometry or the specified "armed" bounds collides with any other object in the scene graph. The speedHint flag is either USE_GEOMETRY or USE_BOUNDS.

Methods
public SceneGraphPath getArmingPath()
public Bounds getArmingBounds()
These methods return the "collidable" path or bounds object used in specifying the collision detection.

public SceneGraphPath getTriggeringPath()
public Bounds getTriggeringBounds()
These methods return the path or bounds object that caused the collision.

10.5.3.10 WakeupOnCollisionExit

This WakeupCriterion object specifies that Java 3D should awaken the WakeupOnCollisionExit behavior when the specified object no longer collides with any other object in the scene graph.

Constants
public static final int USE_GEOMETRY
public static final int USE_BOUNDS
These constants specify whether collision against a Group, Shape, or Morph node is done using the actual geometry or whether the geometric bounds are used as an approximation.

Constructors
public WakeupOnCollisionExit(SceneGraphPath armingPath)
public WakeupOnCollisionExit(SceneGraphPath armingPath,
       int  speedHint)
public WakeupOnCollisionExit(Node armingNode)
public WakeupOnCollisionExit(Node armingNode, int speedHint)
public WakeupOnCollisionExit(Bounds armingBounds)
These constructors create a WakeupOnCollisionExit object that informs the Java 3D scheduler to wake up the specified Behavior object if the specified "armed" node's geometry or the specified "armed" bounds no longer collides with any other object in the scene graph. The speedHint flag is either USE_GEOMETRY or USE_BOUNDS.

Methods
public SceneGraphPath getArmingPath()
public Bounds getArmingBounds()
These methods return the "collidable" path or bounds object used in specifying the collision detection.

public SceneGraphPath getTriggeringPath()
public Bounds getTriggeringBounds()
These methods return the path or bounds object that caused the collision.

10.5.3.11 WakeupOnCollisionMovement

This WakeupCriterion object specifies that Java 3D should awaken the WakeupOnCollisionMovement behavior when the specified object moves while in a state of collision with any other object in the scene graph.

Constants
public static final int USE_GEOMETRY
public static final int USE_BOUNDS
These constants specify whether collision against a Group, Shape, or Morph node is done using the actual geometry or whether the geometric bounds are used as an approximation.

Constructors
public WakeupOnCollisionMovement(SceneGraphPath armingPath)
public WakeupOnCollisionMovement(SceneGraphPath armingPath,
       int  speedHint)
public WakeupOnCollisionMovement(Node armingNode)
public WakeupOnCollisionMovement(Node armingNode, int speedHint)
public WakeupOnCollisionMovement(Bounds armingBounds)
These constructors create a WakeupOnCollisionMovement object that informs the Java 3D scheduler to wake up the specified Behavior object if the specified node's geometry or the specified bounds collides with any other object in the scene graph. The speedHint flag is either USE_GEOMETRY or USE_BOUNDS.

Methods
public SceneGraphPath getArmingPath()
public Bounds getArmingBounds()
These methods return the "collidable" path or bounds object used in specifying the collision detection.

public SceneGraphPath getTriggeringPath()
public Bounds getTriggeringBounds()
These methods return the path or bounds object that caused the collision.

10.5.3.12 WakeupOnViewPlatformEntry

This WakeupCriterion object specifies that Java 3D should awaken the WakeupOnViewPlatformEntry behavior when any ViewPlatform enters the specified region.


Note: There can be situations in which a ViewPlatform may enter and then exit an armed region so rapidly that neither the Entry nor Exit condition is engaged.
Constructors
public WakeupOnViewPlatformEntry(Bounds region)
This constructor creates a WakeupOnViewPlatformEntry object that informs the Java 3D scheduler to wake up the specified Behavior object whenever it detects a ViewPlatform center within the specified region for the first time.

Methods
public Bounds getBounds()
This method returns the Bounds object used in creating this WakeupCriterion.

10.5.3.13 WakeupOnViewPlatformExit

This WakeupCriterion object specifies that Java 3D should awaken the WakeupOnViewPlatformExit behavior when any ViewPlatform, already marked as within the region, is no longer in that region.


Note: This semantic guarantees that an Exit condition gets engaged if its corresponding Entry condition was engaged.
Constructors
public WakeupOnViewPlatformExit(Bounds region)
This constructor creates a WakeupOnViewPlatformExit object that informs the Java 3D scheduler to wake up the specified Behavior object the first time it detects that a ViewPlatform has left the specified region.

Methods
public Bounds getBounds()
This method returns the Bounds object used in creating this WakeupCriterion.

10.5.3.14 WakeupOnTransformChange

The WakeupOnTransformChange object specifies a wakeup when the transform within a specified TransformGroup changes.

Constructors
public WakeupOnTransformChange(TransformGroup node)
This constructor creates a new WakeupOnTransformChange criterion.

Methods
public TransformGroup getTransformGroup()
This method returns the TransformGroup node used in creating this WakeupCriterion.

10.5.3.15 WakeupAnd

The WakeupAnd class specifies any number of wakeup conditions ANDed together. This WakeupCondition object specifies that Java 3D should awaken this Behavior when all of the WakeupCondition's constituent wakeup criteria become valid.

Constructors
public WakeupAnd(WakeupCriterion conditions[])
This constructor creates a WakeupAnd object that informs the Java 3D scheduler to wake up this Behavior object when all the conditions specified in the array of WakeupCriterion objects have become valid.

10.5.3.16 WakeupOr

The WakeupOr class specifies any number of wakeup conditions ORed together. This WakeupCondition object specifies that Java 3D should awaken this Behavior when any of the WakeupCondition's constituent wakeup criteria becomes valid.

Constructors
public WakeupOr(WakeupCriterion conditions[])
This constructor creates a WakeupOr object that informs the Java 3D scheduler to wake up this Behavior object when any condition specified in the array of WakeupCriterion objects becomes valid.

10.5.3.17 WakeupAndOfOrs

The WakeupAndOfOrs class specifies any number of OR wakeup conditions ANDed together. This WakeupCondition object specifies that Java 3D should awaken this Behavior when all of the WakeupCondition's constituent WakeupOr conditions become valid.

Constructors
public WakeupAndOfOrs(WakeupOr conditions[])
This constructor creates a WakeupAndOfOrs object that informs the Java 3D scheduler to wake up this Behavior object when all of the WakeupOr conditions specified in the array of WakeupOr objects become valid.

10.5.3.18 WakeupOrOfAnds

The WakeupOrOfAnds class specifies any number of AND wakeup conditions ORed together. This WakeupCondition object specifies that Java 3D should awaken this Behavior when any of the WakeupCondition's constituent Wakeup-And conditions becomes valid.

Constructors
public WakeupOrOfAnds(WakeupAnd conditions[])
This constructor creates a WakeupOrOfAnds object that informs the Java 3D scheduler to wake up this Behavior object when any of the WakeupAnd conditions specified in the array of WakeupAnd objects becomes valid.

10.6 Interpolator Behaviors

This section describes Java 3D's predefined Interpolator behaviors. They are called interpolators because they smoothly interpolate between the two extreme values that an interpolator can produce. Interpolators perform simple behavioral acts, yet they provide broad functionality.

The Java 3D API provides interpolators for a number of functions: manipulating transforms within a TransformGroup, modifying the values of a Switch node, and modifying Material attributes such as color and transparency.

These predefined Interpolator behaviors share the same mechanism for specifying and later for converting a temporal value into an alpha value. Interpolators consist of two portions: a generic portion that all interpolators share and a domain-specific portion.

The generic portion maps time in milliseconds onto a value in the range [0.0, 1.0] inclusive. The domain-specific portion maps an alpha value in the range [0.0, 1.0] onto a value appropriate to the predefined behavior's range of outputs. An alpha value of 0.0 generates an interpolator's minimum value, an alpha value of 1.0 generates an interpolator's maximum value, and an alpha value somewhere in between generates a value proportionally in between the minimum and maximum values.

10.6.1 Mapping Time to Alpha

Several parameters control the mapping of time onto an alpha value. That mapping is deterministic as long as its parameters do not change. Thus, two different interpolators with the same parameters will generate the same alpha value given the same time value. This means that two interpolators that do not communicate can still precisely coordinate their activities, even if they reside in different threads or even different processors-as long as those processors have consistent clocks.

Figure 10-1 shows the components of an interpolator's time-to-alpha mapping. Time is represented on the horizontal axis. Alpha is represented on the vertical axis. As we move from left to right, we see the alpha value start at 0.0, rise to 1.0, and then decline back to 0.0 on the right-hand side.

On the left-hand side, the trigger time defines when this interpolator's waveform begins in milliseconds. The region directly to the right of the trigger time, labeled Phase Delay, defines a time period where the waveform does not change. During phase delays alpha is either 0 or 1, depending on which region it precedes.

Phase delays provide an important means for offsetting multiple interpolators from one another, especially where the interpolators have all the same parameters. The next four regions, labeled increasing, at 1, decreasing, and at 0, all specify durations for the corresponding values of alpha.

Interpolators have a loop count that determines how many times to repeat the sequence of alpha increasing, alpha at 1, alpha decreasing, and alpha at 0; they also have associated mode flags that enable either the increasing or decreasing portions, or both, of the waveform.

Developers can use the loop count in conjunction with the mode flags to generate various kinds of actions. Specifying a loop count of 1 and enabling the mode flag for only the alpha-increasing and alpha-at-1 portion of the waveform, we would get the waveform shown in Figure 10-2.

In Figure 10-2, the alpha value is 0 before the combination of trigger time plus the phase delay duration. The alpha value changes from 0 to 1 over a specified interval of time, and thereafter the alpha value remains 1 (subject to the reprogramming of the interpolator's parameters). A possible use of a single alpha-increasing value might be to combine it with a rotation interpolator to program a door opening.

Similarly, by specifying a loop count of 1 and a mode flag that enables only the alpha-decreasing and alpha-at-0 portion of the waveform, we would get the waveform shown in Figure 10-3.

In Figure 10-3, the alpha value is 1 before the combination of trigger time plus the phase delay duration. The alpha value changes from 1 to 0 over a specified interval; thereafter the alpha value remains 0 (subject to the reprogramming of the interpolator's parameters). A possible use of a single -decreasing value might be to combine it with a rotation interpolator to program a door closing.

We can combine both of the above waveforms by specifying a loop count of 1 and setting the mode flag to enable both the alpha-increasing and alpha-at-1 portion of the waveform as well as the alpha-decreasing and alpha-at-0 portion of the waveform. This combination would result in the waveform shown in Figure 10-4.

In Figure 10-4, the alpha value is 0 before the combination of trigger time plus the phase delay duration. The alpha value changes from 0 to 1 over a specified period of time, remains at 1 for another specified period of time, then changes from 1 to 0 over a third specified period of time; thereafter the alpha value remains 0 (subject to the reprogramming of the interpolator's parameters). A possible use of an alpha-increasing value followed by an alpha-decreasing value might be to combine it with a rotation interpolator to program a door swinging open and then closing.

By increasing the loop count, we can get repetitive behavior, such as a door swinging open and closed some number of times. At the extreme, we can specify a loop count of -1 (representing infinity).

We can construct looped versions of the waveforms shown in Figure 10-2, Figure 10-3, and Figure 10-4. Figure 10-5 shows a looping interpolator with mode flags set to enable only the alpha-increasing and alpha-at-1 portion of the waveform.

In Figure 10-5, alpha goes from 0 to 1 over a fixed duration of time, stays at 1 for another fixed duration of time, and then repeats.

Similarly, Figure 10-6 shows a looping interpolator with mode flags set to enable only the alpha-decreasing and alpha-at-0 portion of the waveform.

Finally, Figure 10-7 shows a looping interpolator with both the increasing and decreasing portions of the waveform enabled.

In all three cases shown by Figure 10-5, Figure 10-6, and Figure 10-7, we can compute the exact value of alpha at any point in time.

Java 3D's preprogrammed behaviors permit other behaviors to change their parameters. When such a change occurs, the alpha value changes to match the state of the newly parameterized interpolator.

10.6.2 Acceleration of Alpha

Commonly, developers want alpha to change slowly at first and then to speed up until the change in alpha reaches some appropriate rate. This is analogous to accelerating your car up to the speed limit-it does not start off immediately at the speed limit. Developers specify this "ease-in, ease-out" behavior through two additional parameters, the increasingAlphaRampDuration and the decreasing-AlphaRampDuration.

Each of these parameters specifies a period within the increasing or decreasing alpha duration region during which the "change in alpha" is accelerated (until it reaches its maximum per-unit-of-time step size) and then symmetrically decelerated. Figure 10-8 shows three general examples of how the increasingAlphaRampDuration method can be used to modify the alpha waveform. A value of 0 for the increasing ramp duration implies that is not accelerated; it changes at a constant rate. A value of 0.5 or greater (clamped to 0.5) for this increasing ramp duration implies that the change in is accelerated during the first half of the period and then decelerated during the second half of the period. For a value of n that is less than 0.5, alpha is accelerated for duration n, held constant for duration (1.0 - 2n), then decelerated for duration n of the period.

10.6.3 The Alpha Class

The Alpha node component object provides common methods for converting a time value into an alpha value (a value in the range 0.0 to 1.0). The Alpha object is effectively a function of time that generates alpha values in the range [0,1] when sampled: ft = [0,1]. The function ft and the characteristics of the Alpha object are determined by the following user-definable parameters:

The increasing Alpha parameters are

The decreasing Alpha parameters are

Constants
public static final int INCREASING_ENABLE
public static final int DECREASING_ENABLE
These flags specify that this alpha's mode is to use the increasing or decreasing component of the alpha, respectively.

Constructors
public Alpha()
Constructs an Alpha object with the following default parameters:

Parameter Default Value
loopCount -1
mode INCREASING_ENABLE
triggerTime 0
phaseDelayDuration 0
increasingAlphaDuration 1000
increasingAlphaRampDuration 0
alphaAtOneDuration 0
decreasingAlphaDuration 0
decreasingAlphaRampDuration 0
alphaAtZeroDuration 0

public Alpha(int loopCount, long increasingAlphaDuration)
       public Alpha(int loopCount, long triggerTime,
       long  phaseDelayDuration, long increasingAlphaDuration,
       long  increasingAlphaRampDuration, long  alphaAtOneDuration)
public Alpha(int loopCount, int mode, long triggerTime,
       long  phaseDelayDuration, long increasingAlphaDuration,
       long  increasingAlphaRampDuration, long  alphaAtOneDuration,
       long  decreasingAlphaDuration,
       long  decreasingAlphaRampDuration, long  alphaAtZeroDuration)
Constructs a new Alpha object using the specified parameters to define the alpha phases for the object.

Methods
public float value()
public float value(long atTime)
These methods return the alpha value (between 0.0 and 1.0 inclusive) based on the time-to-alpha parameters established for this interpolator. The first method returns the alpha for the current time. The second method returns the alpha for an arbitrary given time. If the alpha mapping has not started, the starting alpha value is returned. If the alpha mapping has completed, the ending alpha value is returned.

public void setStartTime(long startTime)
public long getStartTime()
These methods set and retrieve this alpha's start time, the base for all relative time specifications. The default value of startTime is the system start time, defined to be a global time base representing the start of Java 3D execution.

public void setLoopCount(int loopCount)
public int getLoopCount()
These methods set and retrieve this alpha's loop count.

public void setMode(int mode)
public int getMode()
These methods set and retrieve this alpha's mode, which defines which of the alpha regions are active. The mode is one of the following values: INCREASING_ENABLE, DECREASING_ENABLE, or both (when both of these modes are ORed together).

If the mode is INCREASING_ENABLE, the increasingAlphaDuration, increasingAlphaRampDuration, and alphaAtOneDuration are active. If the mode is DECREASING_ENABLE, the decreasingAlphaDuration, decreasingAlphaRampDuration, and alphaAtZeroDuration are active. If the mode is both constants ORed, all regions are active. Active regions are all preceded by the phase delay region.

public void setTriggerTime(long triggerTime)
public long getTriggerTime()
These methods set and retrieve this alpha's trigger time.

public void setPhaseDelayDuration(long phaseDelayDuration)
public long getPhaseDelayDuration()
These methods set and retrieve this alpha's phase delay duration.

public void setIncreasingAlphaDuration(long
       increasingAlphaDuration)
public long getIncreasingAlphaDuration()
These methods set and retrieve this alpha's increasingAlphaDuration.

public void setIncreasingAlphaRampDuration(long
       increasingAlphaRampDuration)
public long getIncreasingAlphaRampDuration()
These methods set and retrieve this alpha's increasingAlphaRampDuration.

public long getAlphaAtOneDuration()
This method sets and retrieves this alpha's alphaAtOneDuration.

public void setDecreasingAlphaDuration(long
       decreasingAlphaDuration)
public long getDecreasingAlphaDuration()
These methods set and retrieve this alpha's decreasingAlphaDuration.

public void setDecreasingAlphaRampDuration(long
       decreasingAlphaRampDuration)
public long getDecreasingAlphaRampDuration()
These methods set and retrieve this alpha's decreasingAlphaRampDuration.

public long getAlphaAtZeroDuration()
This method sets and retrieves this alpha's alphaAtZeroDuration.

public boolean finished()
This method returns true if this Alpha object is past its activity window-that is, if it has finished all its looping activity. This method returns false if this Alpha object is still active.

10.6.4 The Interpolator Base Class

Interpolator is an abstract behavior class from which several subclasses are derived. The base Interpolator class contains an Alpha object that provides the means for converting a time value (in milliseconds) into an alpha value in the range [0.0, 1.0] inclusive. Its subclasses map this alpha value into domain-specific values in their range.

Constants
protected WakeupCriterion defaultWakeupCriterion
This is the default WakeupCondition for all interpolators. The wakeupOn method of Behavior, which takes a WakeupCondition as the method parameter, will need to be called at the end of the processStimulus method of any class that subclasses Interpolator. This is done with the following method call:

wakeupOn(defaultWakeupCriterion);
Constructors
The Interpolator behavior class has the following constructors:

public Interpolator()
Constructs and initializes a new Interpolator with a null alpha value.

public Interpolator(Alpha alpha)
Constructs and initializes a new Interpolator with the specified alpha value. This constructor provides the common initialization code for all specializations of Interpolator.

Methods
public void setAlpha(Alpha alpha)
public Alpha getAlpha()
These methods set and retrieve this interpolator's Alpha object. Setting it to null causes the Interpolator to stop running.

public void setEnable(boolean state)
public boolean getEnable()
These methods set and retrieve this Interpolator's enabled state-the default is enabled.

public void initialize()
This is the generic predefined interpolator initialize method. It schedules the behavior to awaken at the next frame.

10.6.5 PositionInterpolator Object

The PositionInterpolator class extends Interpolator. It modifies the translational component of its target TransformGroup by linearly interpolating between a pair of specified positions (using the value generated by the specified Alpha object). The interpolated position is used to generate a translation transform along the local X-axis of this interpolator.

Constructors
The PositionInterpolator object specifies the following constructors:

public PositionInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial position interpolator with a specified target, an axisOf-Translation set to the identity transformation, a startPosition of 0.0, and an endPosition of 1.0 along the X-axis.

public PositionInterpolator(Alpha alpha, TransformGroup target,
       Transform3D axisOfTranslation, float startPosition,
       float  endPosition)
Constructs and initializes a new PositionInterpolator that varies the target TransformGroup node's translational component (startPosition and endPosition). The axisOfTranslation parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The translation is done along the X-axis of this local coordinate system.

Methods
The PositionInterpolator object specifies the following methods:

public void setStartPosition(float position)
public float getStartPosition()
These two methods set and get the Interpolator's start position.

public void setEndPosition(float position)
public float getEndPosition()
These two methods set and get the Interpolator's end position.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the Interpolator's target TransformGroup node.

public void setAxisOfTranslation(Transform3D axis)
public Transform3D getAxisOfTranslation()
These two methods set and get the Interpolator's axis of translation.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a translation value, computes a transform based on this value, and updates the specified TransformGroup node with this new transform.

10.6.6 RotationInterpolator Object

The RotationInterpolator class extends Interpolator. It modifies the rotational component of its target TransformGroup by linearly interpolating between a pair of specified angles (using the value generated by the specified Alpha object). The interpolated angle is used to generate a rotation transform about the local Y-axis of this interpolator.

Constructors
public RotationInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial rotation interpolator with a specified target, an axisOf-Rotation set to identity, a minimum angle of 0 radians, and a maximum angle of 2 radians.

public RotationInterpolator(Alpha alpha, TransformGroup target,
       Transform3D axisOfRotation, float minimumAngle,
       float  maximumAngle)
Constructs a new rotation interpolator that varies the target TransformGroup node's rotational component. The minimumAngle parameter is the starting angle, in radians; maximumAngle is the ending angle, in radians. The axisOfRotation parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The rotation is done about the Y-axis of this local coordinate system.

Methods
public void setMinimumAngle(float angle)
public float getMinimumAngle()
These two methods set and get the interpolator's minimum rotation angle, in radians.

public void setMaximumAngle(float angle)
public float getMaximumAngle()
These two methods set and get the interpolator's maximum rotation angle, in radians.

public void setAxisOfRotation(Transform3D axis)
public Transform3D getAxisOfRotation()
These two methods set and get the interpolator's axis of rotation.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup node.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a rotation angle, computes a transform based on this angle, and updates the specified TransformGroup node with this new transform.

10.6.7 ColorInterpolator Object

The ColorInterpolator class extends Interpolator. It modifies the diffuse color of its target material object by linearly interpolating between a pair of specified colors (using the value generated by the specified Alpha object).

Constructors
public ColorInterpolator(Alpha alpha, Material target)
Constructs a trivial color interpolator with a specified target, a start color of black, and an end color of white.

public ColorInterpolator(Alpha alpha, Material target,
       Color3f  startColor, color3f endColor)
Constructs a new ColorInterpolator object that varies the diffuse color of the target material between two color values (startColor and endColor).

Methods
public void setStartColor(Color3f color)
public void getStartColor(Color3f color)
These two methods set and get the interpolator's start color.

public void setEndColor(Color3f color)
public void getEndColor(Color3f color)
These two methods set and get the interpolator's end color.

public void setTarget(Material target)
public Material getTarget()
These two methods set and get the interpolator's target Material component object.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a color value and updates the diffuse color of the target Material object with this new color value.

10.6.8 ScaleInterpolator Object

The ScaleInterpolator class extends Interpolator. It modifies the uniform scale component of its target TransformGroup by linearly interpolating between a pair of specified scale values (using the value generated by the specified Alpha object). The interpolated scale value is used to generate a scale transform in the local coordinate system of this interpolator.

Constructors
public ScaleInterpolator(Alpha alpha, TransformGroup target)
Constructs a trivial scale interpolator that varies its target TransformGroup node between the two scale values, using the specified alpha, an identity matrix, a minimum scale of 0.1, and a maximum scale of 1.0.

public ScaleInterpolator(Alpha alpha, TransformGroup target,
       Transform3D axisOfScale, float minimumScale,
       float  maximumScale)
Constructs a new ScaleInterpolator object that varies the target TransformGroup node's scale component between two scale values (minimumScale and maximumScale). The axisOfScale parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The scale is done about the origin of this local coordinate system.

Methods
public void setMinimumScale(float scale)
public float getMinimumScale()
These two methods set and get the interpolator's minimum scale.

public void setMaximumScale(float scale)
public float getMaximumScale()
These two methods set and get the interpolator's maximum scale.

public void setAxisOfScale(Transform3D axis)
public Transform3D getAxisOfScale()
These two methods set and get the interpolator's axis of scale.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup node.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a scale value, computes a transform based on this value, and updates the specified TransformGroup node with this new transform.

10.6.9 SwitchValueInterpolator Object

The SwitchValueInterpolator class extends Interpolator. It modifies the selected child of the target Switch node by linearly interpolating between a pair of specified child index values (using the value generated by the specified Alpha object).

Constructors
public SwitchValueInterpolator(Alpha alpha, Switch target)
public SwitchValueInterpolator(Alpha alpha, Switch target,
       int  firstChildIndex, int lastChildIndex)
Constructs a new SwitchValueInterpolator object that varies the target Switch node's child index between the two values provided (firstChildIndex, the index of the first children in the Switch node to select; and lastChildIndex, the index of the last children in the Switch node to select).

Methods
public void setFirstChildIndex(int firstIndex)
public int getFirstChildIndex()
These two methods set and get the interpolator's first child index.

public void setLastChildIndex(int lastIndex)
public int getLastChildIndex()
These two methods set and get the interpolator's last child index.

public void setTarget(Switch target)
public Switch getTarget()
These two methods set and get the interpolator's target Switch node.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a child index value and updates the specified Switch node with this new child index value.

10.6.10 TransparencyInterpolator Object

The TransparencyInterpolator class extends Interpolator. It modifies the transparency of its target TransparencyAttributes object by linearly interpolating between a pair of specified transparency values (using the value generated by the specified Alpha object).

Constructors
public TransparencyInterpolator(Alpha alpha,
       TransparencyAttributes target)
Constructs a trivial transparency interpolator with a specified target, a minimum transparency of 0.0 and a maximum transparency of 1.0.

public TransparencyInterpolator(Alpha alpha,
       TransparencyAttributes target, float  minimumTransparency,
       float maximumTransparency)
Constructs a new TransparencyInterpolator object that varies the target material's transparency between the two transparency values (minimumTransparency, the starting transparency; and maximumTransparency, the ending transparency).

Methods
public void setMinimumTransparency(float transparency)
public float getMinimumTransparency()
These two methods set and get the interpolator's minimum transparency.

public void setMaximumTransparency(float transparency)
public float getMaximumTransparency()
These two methods set and get the interpolator's maximum transparency.

public void setTarget(TransparencyAttributes target)
public TransparencyAttributes getTarget()
These two methods set and get the interpolator's target TransparencyAttributes component object.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a transparency value and updates the specified TransparencyAttributes object with this new transparency value.

10.6.11 PathInterpolator Object

The PathInterpolator class extends Interpolator. This class defines the base class for all path interpolators. Subclasses have access to the computePathInterpolation method, which computes the currentInterpolationValue given the current time and alpha. The method also computes the currentKnotIndex, which is based on the currentInterpolationValue.

The currentInterpolationValue is calculated by linearly interpolating among a series of predefined knot and orientation, pairs (using the value generated by the specified Alpha object). The last knot must have a value of 1.0; an intermediate knot with index k must have a value strictly greater than any knot with index less than k.

Constants
protected float currentInterpolationValue
This value is the ratio between knot values indicated by the currentKnotIndex variable. So if a subclass wanted to interpolate between knot values, it would use the currentKnotIndex to get the bounding knots for the "real" value and then use the currentInterpolationValue to interpolate between the knots. To calculate this variable, a subclass needs to call the computePathInterpolation method from the subclass's processStimulus method. Then this variable will hold a valid value that can be used in further calculations by the subclass.

protected int currentKnotIndex
This value is the index of the current base knot value, as determined by the alpha function. A subclass wishing to interpolate between bounding knots would use this index and the one following it and would use the currentInterpolationValue variable as the ratio between these indices. To calculate this variable, a subclass needs to call the computePathInterpolation method from the subclass's processStimulus method. Then this variable will hold a valid value that can be used in further calculations by the subclass.

Constructors
public PathInterpolator(Alpha alpha, float knots[])
Constructs a new PathInterpolator object that varies the target TransformGroup node's transform.

Methods
public int getArrayLengths()
This method retrieves the length of the knot and position arrays (which are the same length).

public void setKnot(int index, float knot)
public float getKnot(int index)
These methods set and retrieve the knot at the specified index for this interpolator.

protected void setKnots(float[] knots)
public void getKnots(float[] knots)
These methods set and retrieve an array of knot values. The set method replaces the existing array with the specified array. The get method copies the array of knots from this interpolator into the specified array. The array must be large enough to hold all of the knots.

protected void computePathInterpolation()
This method computes the base knot index and interpolation value, given the current value of alpha and the knots[] array. If the index is 0 and there should be no interpolation, both the index variable and the interpolation variable are set to 0. Otherwise, currentKnotIndex is set to the lower index of the two bounding knot points, and the currentInterpolationValue variable is set to the ratio of the alpha value between these two bounding knot points.

10.6.12 PositionPathInterpolator Object

The PositionPathInterpolator class extends PathInterpolator. It modifies the translational component of its target TransformGroup by linearly interpolating among a series of predefined knot/position pairs (using the value generated by the specified Alpha object). The interpolated position is used to generate a translation transform in the local coordinate system of this interpolator.

The first knot must have a value of 0.0. The last knot must have a value of 1.0. An intermediate knot with index k must have a value strictly greater than any knot with index less than k.

Constructors
public PositionPathInterpolator(Alpha alpha,
       TransformGroup  target, Transform3D axisOfTranslation,
       float knots[], Point3f positions[])
Constructs a new PositionPathInterpolator that varies the translation of the target TransformGroup's transform. The axisOfTranslation parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The knots parameter specifies an array of knot values that specifies a spline. The positions parameter specifies an array of position values at the knots.

Methods
public void setPosition(int index, Point3f position)
public void getPosition(int index, Point3f position)
These two methods set and get the interpolator's indexed position.

public void getPositions(Point3f[] positions)
This method copies the array of position values from this interpolator into the specified array. The array must be large enough to hold all of the positions. The individual array elements must be allocated by the caller.

public void setAxisOfTranslation(Transform3D axis)
public Transform3D getAxisOfTranslation()
These two methods set and get the interpolator's axis of translation.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup object.

public void setPathArrays(float[] knots, Point3f[] positions)
This method replaces the existing arrays of knot values and position values with the specified arrays. The arrays of knots and positions are copied into this interpolator object.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a translation value, computes a transform based on this value, and updates the specified TransformGroup node with this new transform.

10.6.13 RotPosPathInterpolator Object

The RotPosPathInterpolator class extends PathInterpolator. It modifies the rotational and translational components of its target TransformGroup by linearly interpolating among a series of predefined knot/position and knot/orientation pairs (using the value generated by the specified Alpha object). The interpolated position and orientation are used to generate a transform in the local coordinate system of this interpolator.

The first knot must have a value of 0.0. The last knot must have a value of 1.0. An intermediate knot with index k must have a value strictly greater than any knot with index less than k.

Constructors
public RotPosPathInterpolator(Alpha alpha, TransformGroup target,
       Transform3D  axisOfRotPos, float knots[], Quat4f  quats[],
       Point3f  positions[])
This constructor constructs a new RotPosPathInterpolator that varies the rotation and translation of the target TransformGroup's transform. The axisOfRotPos parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The knots parameter specifies an array of knot values that specifies a spline. The quats parameter specifies an array of quaternion values at the knots. The positions parameter specifies an array of position values at the knots.

Methods
public void setQuat(int index, Quat4f quat)
public void getQuat(int index, Quat4f quat)
These two methods set and get the interpolator's indexed quaternion value.

public void getQuats(Quat4f[] quats)
This method copies the array of quaternion values from this interpolator into the specified array. The array must be large enough to hold all of the quats. The individual array elements must be allocated by the caller.

public void setPosition(int index, Point3f position)
public void getPosition(int index, Point3f position)
These two methods set and get the interpolator's indexed position.

public void getPositions(Point3f[] positions)
This method copies the array of position values from this interpolator into the specified array. The array must be large enough to hold all of the positions. The individual array elements must be allocated by the caller.

public void setAxisOfRotPos(Transform3D axisOfRotPos)
public Transform3D getAxisOfRotPos()
These two methods set and get the interpolator's axis of rotation and translation.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup object.

public void setPathArrays(float[] knots, Quat4f[] quats,
       Point3f[]  positions)
This method replaces the existing arrays of knot values, quaternion values, and position values with the specified arrays. The arrays of knots, quats, and positions are copied into this interpolator object.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into translation and rotation values, computes a transform based on these values, and updates the specified TransformGroup node with this new transform.

10.6.14 RotPosScalePathInterpolator Object

The RotPosScalePathInterpolator class extends PathInterpolator. It varies the rotational, translational, and scale components of its target TransformGroup by linearly interpolating among a series of predefined knot/position, knot/orientation, and knot/scale pairs (using the value generated by the specified Alpha object). The interpolated position, orientation, and scale are used to generate a transform in the local coordinate system of this interpolator.

The first knot must have a value of 0.0. The last knot must have a value of 1.0. An intermediate knot with index k must have a value strictly greater than any knot with index less than k.

Constructors
public RotPosScalePathInterpolator(Alpha alpha,
       TransformGroup  target, Transform3D  axisOfRotPosScale,
       float knots[], Quat4f  quats[], Point3f  positions[],
       float  scales[])
This constructor constructs a new RotPosScalePathInterpolator that varies the rotation, translation, and scale of the target TransformGroup's transform. The axisOfRotPosScale parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The knots parameter specifies an array of knot values that specifies a spline. The quats parameter specifies an array of quaternion values at the knots. The positions parameter specifies an array of position values at the knots. The scale parameter specifies the scale component value.

Methods
public void setScale(int index, float scale)
public float getScale(int index)
These two methods set and get the interpolator's indexed scale value.

public void getScales(float[] scales)
This method copies the array of scale values from this interpolator into the specified array. The array must be large enough to hold all of the scales.

public void setQuat(int index, Quat4f quat)
public void getQuat(int index, Quat4f quat)
These two methods set and get the interpolator's indexed quaternion value.

public void getQuats(Quat4f[] quats)
This method copies the array of quaternion values from this interpolator into the specified array. The array must be large enough to hold all of the quats. The individual array elements must be allocated by the caller.

public void setPosition(int index, Point3f position)
public void getPosition(int index, Point3f position)
These two methods set and get the interpolator's indexed position.

public void getPositions(Point3f[] positions)
This method copies the array of position values from this interpolator into the specified array. The array must be large enough to hold all of the positions. The individual array elements must be allocated by the caller.

public void setAxisOfRotPosScale(Transform3D axisOfRotPosScale)
public Transform3D getAxisOfRotPosScale()
These two methods set and get the interpolator's axis of rotation, translation, and scale.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup object.

public void setPathArrays(float[] knots, Quat4f[] quats,
       Point3f[]  positions, float[] scales)
This method replaces the existing arrays of knot values, quaternion values, position values, and scale values with the specified arrays. The arrays of knots, quats, positions, and scales are copied into this interpolator object.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into translation, rotation, and scale values; computes a transform based on these values; and updates the specified TransformGroup node with this new transform.

10.6.15 RotationPathInterpolator Object

The RotationPathInterpolator class extends the PathInterpolator class. It varies the rotational component of its target TransformGroup by linearly interpolating among a series of predefined knot/orientation pairs (using the value generated by the specified Alpha object). The interpolated orientation is used to generate a rotation transform in the local coordinate system of this interpolator.

The first knot must have a value of 0.0. The last knot must have a value of 1.0. An intermediate knot with index k must have a value strictly greater than any knot with index less than k.

Constructors
public RotationPathInterpolator(Alpha alpha,
       TransformGroup  target, Transform3D  axisOfRotation,
       float  knots[], Quat4f quats[])
This constructor constructs a new RotationPathInterpolator object that varies the target TransformGroup node's transform. The axisOfRotation parameter specifies the transform that defines the local coordinate system in which this interpolator operates. The knots parameter specifies an array of knot values that specifies a spline. The quats parameter specifies an array of quaternion values at the knots.

Methods
public void setQuat(int index, Quat4f quat)
public void getQuat(int index, Quat4f quat)
These two methods set and get the interpolator's indexed quaternion value.

public void setAxisOfRotation(Transform3D axisOfRotation)
public Transform3D getAxisOfRotation()
These two methods set and get the interpolator's axis of rotation.

public void setTarget(TransformGroup target)
public TransformGroup getTarget()
These two methods set and get the interpolator's target TransformGroup object.

public void setPathArrays(float[] knots, Quat4f[] quats)
This method replaces the existing arrays of knot values and quaternion values with the specified arrays. The arrays of knots and quats are copied into this interpolator object.

public void getQuats(Quat4f[] quats)
This method copies the array of quaternion values from this interpolator into the specified array. The array must be large enough to hold all of the quats. The individual array elements must be allocated by the caller.

public void processStimulus(Enumeration criteria)
This method is invoked by the behavior scheduler every frame. It maps the alpha value that corresponds to the current time into a rotation angle, computes a transform based on this angle, and updates the specified TransformGroup node with this new transform.

10.7 Level-of-Detail Behaviors

The LOD (Level of Detail) leaf node is an abstract behavior class that operates on a list of Switch group nodes to select one of the children of the Switch nodes. Specializations of the LOD abstract behavior node implement various level-of-detail policies.

10.7.1 LOD Object

The LOD behavior node is an abstract class that is subclassed to implement selection among two or more levels of detail using an LOD selection criteria defined by the subclass.

Constructors
public LOD()
Constructs and initializes a new LOD node.

Methods
The LOD node class defines the following methods:

public void addSwitch(Switch switchNode)
public void setSwitch(Switch switchNode, int index)
public void insertSwitch(Switch switchNode, int index)
public void removeSwitch(int index)
public Switch getSwitch(int index)
public int numSwitches()
The addSwitch method appends the specified Switch node to this LOD's list of switches. The setSwitch method replaces the specified Switch node with the Switch node provided. The insertSwitch method inserts the specified Switch node at the specified index. The removeSwitch method removes the Switch node at the specified index. The getSwitch method returns the Switch node specified by the index. The numSwitches method returns a count of this LOD's switches.

public Enumeration getAllSwitches()
This method returns the Enumeration object of all switches.

10.7.2 DistanceLOD Object

The DistanceLOD behavior node implements a distance-based LOD policy. It operates on a Switch group node to select one of the children of that Switch node based on the distance of this LOD node from the viewer. An array of n monotonically increasing distance values is specified, such that distances[0] is associated with the highest level of detail, and distances[n-1] is associated with the lowest level of detail. Based on the actual distance from the viewer to this DistanceLOD node, these n distance values [0, n-1] select from among n+1 levels of detail [0, n]. If d is the distance from the viewer to the LOD node, then the equation for determining which level of detail (child of the Switch node) is selected is

0, if d distances[0]

i, if distances[i-1] < d distances[i]

n, if d > distances[n-1]

Both the position of this node and the array of LOD distances are defined in the local coordinate system of this node.

Constructors
public DistanceLOD()
This constructor creates a DistanceLOD object with a single distance value set to 0.0 and is, therefore, not very useful.

public DistanceLOD(float distances[])
public DistanceLOD(float distances[], Point3f position)
Construct and initialize a new DistanceLOD node. The distances parameter specifies a vector of doubles representing LOD cutoff distances. The position parameter specifies the position of this node in local coordinates. The default position is (0,0,0).

Methods
public void setPosition(Point3f position)
public void getPosition(Point3f position)
These methods set and retrieve the position parameter for this DistanceLOD node. This position is specified in the local coordinates of this node, and is the position from which the distance to the viewer is computed.

public int numDistances()
public double getDistance(int whichDistance)
public void setDistance(int whichDistance, double distance)
The numDistances method returns a count of the number of LOD distance cutoff parameters. The getDistance method returns a particular LOD cutoff distance. The setDistance method sets a particular LOD cutoff distance.

public void initialize()
This method sets up the initial wakeup criteria.

public void processStimulus(Enumeration criteria)
This method computes the appropriate level of detail.

10.8 Billboard Behavior

The Billboard behavior node operates on the TransformGroup node to cause the local +z axis of the TransformGroup to point at the viewer's eye position. This is done regardless of the transforms above the specified TransformGroup node in the scene graph.

Billboard nodes provide the most benefit for complex, roughly symmetric objects. A typical use might consist of a quadrilateral that contains a texture map of a tree.

The Billboard node is similar in functionality to the OrientedShape3D node. See also Section 6.2.1, "OrientedShape3D Node."

Constants
The Billboard class adds the following new constants:

public static final int ROTATE_ABOUT_AXIS
Specifies that rotation should be about the specified axis.

public static final int ROTATE_ABOUT_POINT
Specifies that rotation should be about the specified point and that the children's y-axis should match the ViewPlatform's Y-axis.

Constructors
The Billboard class specifies the following constructors:

public Billboard()
Constructs a Billboard node with the following default parameters:

Parameter Default Value
alignmentMode ROTATE_ABOUT_AXIS
alignmentAxis y-axis (0,1,0)
rotationPoint (0,0,1)
target transform group null

public Billboard(TransformGroup tg)
Constructs a Billboard node with default parameters that operates on the specified TransformGroup node. The default alignment mode is ROTATE_ABOUT_AXIS rotation with the axis pointing along the y-axis.

public Billboard(TransformGroup tg, int mode, Vector3f axis)
public Billboard(TransformGroup tg, int mode, Point3f point)
The first constructor constructs a Billboard behavior node with default parameters that operates on the specified target TransformGroup node. The default alignment mode is ROTATE_ABOUT_AXIS, with the axis along the Y-axis. The next two constructors construct a Billboard behavior node with the specified axis and mode that operate on the specified TransformGroup node. The axis parameter specifies the ray about which the billboard rotates. The point parameter specifies the position about which the billboard rotates. The mode parameter is the alignment mode and is either ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT.

Methods
The Billboard class defines the following methods:

public void setAlignmentMode(int mode)
public int getAlignmentMode()
These methods, if enabled by the appropriate flag, permit an application to either retrieve or set the Billboard node's alignment mode, one of ROTATE_ABOUT_AXIS or ROTATE_ABOUT_POINT.

public void setAlignmentAxis(Vector3f axis)
public void setAlignmentAxis(float x, float y, float z)
public void getAlignmentAxis(Vector3f axis)
These methods, if enabled by the appropriate flag, permit an application to set or retrieve the Billboard node's alignment axis.

public void setTarget(TransformGroup tg)
public TransformGroup getTarget()
These methods set or retrieve the target TransformGroup node for this Billboard object.

public void setRotationPoint(float x, float y, float z)
public void setRotationPoint(Point3f point)
public void getRotationPoint(Point3f point)
The first two methods set the rotation point. The third method gets the rotation point and sets the parameter to this value.

public void initialize()
This method sets up the initial wakeup criteria.

public void processStimulus(Enumeration criteria)
This method computes the appropriate transform.



   The Java 3D API Specification Contents Previous Next Index


Copyright © 2000, Sun Microsystems, Inc. All rights reserved.