Basic Principles of Three-Dimensional Graphics (Introduction to Computer Graphics Using Java 2D and 3D) Part 3

Animation and Moving Objects

So far, only static three-dimensional scenes were considered. For dynamic scenes, similar techniques as described in Sect. 2.9 for the two-dimensional case are applied. Movements can be implemented as piecewise interpolations or convex combinations between positions or states. The same applies to other transitions, for instance a slow change from one colour to another or the transition from bright light to the dark. In the two-dimensional case, complex or combined movements, as for instance in the example of the moving clock with rotating hand, were modelled by explicit compositions of single transformations. A scenegraph also simplifies modelling and handling complex or combined movements. Each transformation group can have its own movement which is then applied to all objects that are located below the corresponding transformation group in the hierarchy of the scenegraph. For the example of the moving clock, the hand would be assigned to a transformation group with a rotation and this transformation group could be a child of another transformation group with the frame of the clock and the movement of the whole clock. In this way, the rotation and the linear movement of the clock would be applied automatically to the hand. The principle is the same as for static transformations to position objects. The transformations in a transformation group in the upper part of the scenegraph are applied to all nodes below the corresponding transformation group.


To illustrate the principle of modelling animations, the helicopter scene in Fig. 5.3 on page 107 is considered again. The helicopter is supposed to start the rotor blade and should then take off from the platform in a slightly tilted upwards direction. This means that the rotor blade itself will carry out a helix-like movement, composed of the rotation of the blade and the linear movement of the helicopter. Based on a suitable scenegraph, the complex movement can be described and handled in a very simple manner. The rotor blade is generated in the origin of the coordinate system and a rotation around the y-axis is assigned to the transformation group of the rotor blade. Then the whole transformation group of the rotor blade including its rotation is assigned to another transformation group that positions the rotor blade on top of the cockpit. This will have the effect that the blade no longer rotates in the origin of the coordinate system but on top of the cockpit. When the whole helicopter is positioned on the platform and also when the platform together with the helicopter is positioned somewhere in the scene, the blade including its rotation will be transformed in the correct way. A linear movement for the take-off of the helicopter from the platform will be assigned to the transformation group of the helicopter. Again, this movement will also be applied to the blade including the rotation.

For dynamic scenes, it is not only possible to assign objects, other transformation groups and transformations for positioning objects to a transformation group. Interpolators for the description of the dynamic changes can also be assigned to transformation groups. Figure 5.6 shows an excerpt of the extended scenegraph for the helicopter in which the rotation of the rotor blade and the take-off of the helicopter can be described. The names of those transformation groups that contain dynamic movements, i.e., interpolators, start with the letters tgm for Transformation Group with Movement.

The transformation group tgmRotor contains the rotor blade constructed as a box centred in the origin of the coordinate system and two dynamic rotations br and brStart around the y-axis. These two movements are carried out one after the other. The first one starts the rotor blade slowly and then the second one takes over to model the accelerated rotation of the blade. Only after the accelerated rotation has started, the helicopter should take off. The linear movement of the helicopter for the take-off is implemented in the transformation group tgmHeli-copter.

It is important to separate positioning from dynamic movements within the transformation groups. It should be avoided to have static and dynamic transformations in the same transformation group. In this case, it is not clear whether the static or the dynamic transformations should be carried out first.

Excerpt of the scenegraph with dynamic transformations

Fig. 5.6 Excerpt of the scenegraph with dynamic transformations

Therefore, such a transformation group should be split into two transformation groups, one for the static and one for the dynamic part. One of the transformation groups should be the child of the other one. Which one should be the parent and which one the child depends on how the movement is intended. In the example of the helicopter, the rotor blade is first rotated in the origin of the coordinate system. This happens in the transformation group tgmRotor. Then this transformation group becomes a child of the transformation group tgRotor which positions the rotor together with its rotation on top of the cockpit.

The same applies to the linear movement of the helicopter. The take-off of the helicopter is described in the transformation group tgmHelicopter relative to the origin of the coordinate system. Afterwards, the helicopter together with its movement is positioned on the platform in the parent transformation group tgHelicopter so that the take-off takes place from the top of the platform. It would also be possible to exchange the order of these two transformation groups in the scenegraph. The way the movement was modelled here, corresponds to the following principle. The helicopter should take off from the platform and ascend for h units, measured from the platform. The height of the platform itself is of no importance for the ascend. The helicopter will fly exactly h units. However, if the helicopter should ascent from the platform until it has reached a fixed height, measured from the ground, the duration of the flight depends on the height of the platform. In this case, it might make sense to exchange the two transformation groups for the movement and the positioning of the helicopter. Nevertheless, the movement of the helicopter in the transformation group tgmHelicopter would have to be defined in a different way, since it starts from another point.

Animation in Java 3D

For animated scenes Java 3D provides the abstract class Interpolator with a number of subclasses. There, Java 3D extends the basic principle which was introduced in Sect. 2.11. For modelling a continuous change within an animation, an initial and a final state are needed. For example, the animation could be a linear movement of an object between two points along a line in the form of a translation or a circular movement along an orbit in the form of a rotation. It could also be the transition from one colour to another one. The initial state is associated with the value zero, the final state with one. Intermediate states correspond to values between zero and one. The interpretation of the initial and the final state and the computation of intermediate states depends on the type of interpolation, whether a linear movement between two positions, a circular orbit or the change between two colours is desired. There are certain basic parameters that are required for an interpolator, independent of the precise interpretation of the states. For example, the following specifications are always needed for an interpolator.

•    When should the interpolation start?

•    Should the interpolation only go from state zero to state one or should it also be reversed?

•    How long should the transition from state zero to state one take?

•    Should the transition between the two states zero and one be carried out with constant speed or should it accelerate slowly in the beginning at state zero until a maximum speed is reached and then slow down again to have a smooth stop in state one?

•    Should the interpolation be carried out just once or should it be repeated?

In Java 3D, these properties are specified within the class Alpha. An Alpha object must be associated with every interpolator. To generate an instance of the class Alpha, the following constructor can be used:

Alpha a = new Alpha(lc,id,tt,pdd,iad,iard,aa1d,dad, dard,aa0d);

Figure 5.7 illustrates the meaning of the main parameters of Alpha, which will be explained in the following in detail. For a better understanding of the single parameters, the example of the helicopter is used again. The corresponding Alpha object shall be used to describe the timing of the linear movement of the helicopter. The state zero corresponds to the initial position of the helicopter at the ground. In state one the helicopter is at its highest point.

The integer value lc specifies the attribute loopCount which determines how often the interpolator should be repeated. For instance, the helicopter could ascent and descend three times. In this case, one would choose lc=3. Setting lc=-1 implies that the interpolator is repeated without end. This means that the helicopter would never stop the alternating scheme of ascending and descending. The second parameter id for the attribute mode defines in which direction the interpolator should be carried out. There are three possibilities.

Progression of the Alpha-values

Fig. 5.7 Progression of the Alpha-values

•    id=Alpha.INCREASING_ENABLE: Only the interpolation from state zero to state one is carried out. If lc > 1 is chosen, it will be carried out more than once. In this case, the helicopter would only ascend and jump back to its initial position instead of flying back after the ascend is finished.

•    id=Alpha.DECREASING_ENABLE: Only the interpolation from state one to state zero is carried out so that the helicopter could only descend for landing. Instead of a slow take-off it would jump to the highest position.

•    id=Alpha.INCREASING_ENABLE+Alpha.DECREASING_ENABLE: Here, the interpolator alternates between the transition from state zero to state one and the reverse transition. This is the correct solution for the helicopter. The helicopter could alternate between ascending and descending. However, for modelling the movement of the rotor blade, one would only define id=Alpha.INCREASING_ENABLE, since the blade should rotate only in one direction and not backwards as well.

All other parameters in the above-mentioned constructor for Alpha are of the type long. They are integer values specifying times or time intervals in milliseconds.

The attribute triggerTime of Alpha is given by the value tt. tt determines after how many milliseconds after the start of the program Alpha should deliver the first values. pdd determines the value of the attribute phaseDelayDuration. Alpha remains in the state zero for phaseDelayDuration milliseconds after the triggerTime has passed. In all programs presented here, it is sufficient to use only one of the two values triggerTime or phaseDelayDuration. The example programs will always assume phaseDelayDuration=0 and the start of the animation will be controlled by triggerTime alone. In the example of the helicopter, triggerTime should be chosen in such a way that the take-off of the helicopter starts after the slow blade rotation is finished and the fast blade rotation has begun.

The parameter iad defines how long the transition time increasingAlphaDuration from the state zero to the state one should take. For the helicopter, this is the time it should take from take-off to reach the highest point. The next parameter iard determines the value of the attribute increasing Alpha Ramp Duration. In the case of the helicopter and in many other applications, it is not realistic that the object remains in the initial position until the triggerTime has passed and then suddenly moves without continuous acceleration from state zero to state one. iard specifies the duration of the linear acceleration phase until the constant maximum speed is reached. The value iard is also used for slowing down the movement, before state one is reached, so that the object comes to a smooth and not a sudden stop. The speed is decreased linearly. The appropriate continuous accelerations and the appropriate constant maximum speed are calculated by Java 3D automatically.

After the transition from state zero to state one is completed, aa1d determines the value alphaAtOneDuration, i.e., how long state one should be kept. For the helicopter, this would correspond to the time it would spend hovering in the air at its top position.

The values dad and dard are used for the attributes decreasingAlphaDuration and decreasingAlphaRampDuration, respectively. Theyhavethe same meaning as increasingAlphaDuration and increasingAlphaRampDuration, respectively. However, they do not refer to the transition from state zero to state one but to the reverse transition from state one to state zero. Therefore, in the helicopter example, dad determines how long the descending flight of the helicopter should take. Accordingly, dard specifies how long the phase of acceleration and slowing down should be.

Finally, aa0d is for the attribute alphaAtZeroDuration, i.e., how long to stay in the state zero after a cycle from state zero to state one and back has been completed. This value is only of importance when the movement or transition should be repeated, i.e., when the parameter lc for loopCount was either greater than 1 or — 1. If a repetition is desired, the sequence consisting of

•    increasingAlphaDuration,

•    alphaAtOneDuration,

•    decreasingAlphaDuration and

•    alphaAtZeroDuration

is iterated, taking into account the values for increasingAlphaRampDuration and decreasingAlphaRampDuration for the acceleration and braking time.

The specified durations increasingAlphaDuration and increasingAlphaRampDuration are only relevant when Alpha.INCREASING_ENABLE was set within the parameters    id.

Analogously, the    durations    decreasing Alpha Duration and decreasing Alpha Ramp Duration are only taken into account when Alpha.DECREASING_ENABLE was set.

The class Alpha serves as a description of the timing of a movement or, more generally, of an interpolator. The interpolator itself to which the Alpha object is associated determines what the state changes look like. The Alpha object calculates the appropriate value between zero and one for the state at any time. Java 3D provides a number of standard interpolators. Some selected interpolators will be explained here in more detail.

The PositionInterpolator is responsible for movements between two points along a straight line.

tmpc009-245_thumb[2][2]

The first argument of this constructor is an instance of the class Alpha to describe the timing of the movement along the straight line. The second argument specifies the transformation group in which the interpolator should be applied. The instance axis of the class Transform3D determines the axis or the line along which the movement should take place. This axis should be created before the constructor of the interpolator is called.

Transform3D axis = new Transform3D();

In this way, the identical transformation is generated. If this transformation is used directly in the constructor of the interpolator, then the axis for the movement will be the x-axis. If a movement along another axis should take place, the transformation axis must be defined in such a way that it maps the x-axis onto the desired axis. For instance, a movement along the y-axis is achieved by a rotation around the z-axis by 90° since this transformation maps the x-axis to the y-axis. In this case, one would add the line axis.rotZ(Math.PI/2); before calling the constructor for the PositionInterpolator.

The values startingPoint and endPoint determine the states zero and one, i.e., the starting and the endpoint of the linear movement along the specified axis. The starting point should be located at the same position as the object or transformation group to which the position interpolator is applied. For instance, if one generated an object centred in the origin of the coordinate system to be moved along the x-axis, the choice of startingPoint=1 would lead to a sudden jump of the object to the starting point (1,0,0) when the movement is initiated. Vice versa, if the object has been shifted to some other point than the origin of the coordinate system and a position interpolator along the x-axis with startingPoint=0 is defined for the corresponding transformation group, then the object would jump back to the origin of the coordinate system at the start of the movement.

For the definition of an interpolator further specifications are needed. A bounding region must be assigned to interpolators and a number of other concepts in Java 3D. This bounding region determines whether the corresponding concept should be taken into account for rendering or not, depending on the viewer’s position. When the bounding region does not contain the viewer or a part of the clipping region, the corresponding concept is not applied. For instance, in an office building with a large number of rooms, each room might have a clock hanging on the wall. If the viewer is inside one of the offices, it is not necessary to compute the movement of the hands of the clocks in the other rooms since the viewer will not be able to see them, as long as he stays in his office. Therefore, the movement of the clock hands would be restricted to the bounding region coinciding with the office in which the clock is located. The avoidance of calculating unnoticed changes and movement can save a significant amount of computation time for larger virtual worlds. The interpolator is reactivated, once the viewer enters its bounding region again. The interpolator is not started at the same point where it was frozen when the viewer had left the room. Based on the Alpha object associated with the interpolator and the current time, the actual state of the interpolator can be computed exactly, even though the intermediate states have not been calculated while the viewer was outside the bounding region. In the example of the office building with the clocks, the clock would stop its movement, once the viewer has left the room. But when the viewer enters the room again, the clock will simply jump to the current time and continue its movement so that the viewer will not notice that intermediate states were not calculated.

tmpc009-246_thumb[2][2]

can be used to define a bounding region. In this way, a spherical bounding region with radius r and centre point (x,y,z) is specified. For an unlimited bounding region, one can choose r=Double.MAX_VALUE. The class BoundingBox allows the definition of bounding regions in the form of a box.

After the definition of a suitable bounding region bs, this bounding region has to be assigned to the interpolator pi by pi.setSchedulingBounds(bs);

For static objects which will not be changed or moved in a scene, certain rendering properties can be calculated in advance for efficiency reasons in Java 3D. Therefore, it is necessary to state explicitly by

tmpc009-247_thumb[2][2]

that the corresponding transformation group transformationgroup can be changed by transformations during the animation. Finally, the interpolator pi has to be assigned to its transformation group by

tmpc009-248_thumb[2][2]

The class RotationInterpolator can be used to model rotations in the same way as position interpolators are used for linear movements. In the constructor

tmpc009-249_thumb[2][2]

the parameters alpha and transformgroup have the same meaning as in the case of position interpolators. The rotation axis is specified by the instance axis of the class Transform3D. If axis is the identity, i.e., it was created by the default constructor of Transform3D without further modifications, then the y-axis will become the rotation axis. For another rotation axis, the transformation axis must be defined in such a way that the y-axis is mapped onto the desired rotation axis. For instance,

tmpc009-250_thumb[2][2]

defines a rotation around the z-axis. Theparameters startAngle and endAngle specify the starting and the final angle of the rotation in radians. It should be noted that negative angles and angles larger than 2π are mapped to the interval [0, 2π]. For instance, choosing π as the starting and 4π as the final angle, will only lead to a rotation starting at π and ending at 2π, but not to 1.5 full rotations.

For rotation interpolators the same lines of code concerning the bounding region and the associated transformation group are required as in the case of position interpolators.

In the same way, scalings can be defined based on the class ScaleInterpolator with the constructor

tmpc009-251_thumb[2][2]

If the scaling should not be carried out with respect to the origin of the coordinate system, the Transform3D axis should be defined in such a way that it maps the origin to the desired fixed point of the scaling. The parameters startScale and endScale determine the scaling factors for the states zero and one, respectively. Usually, startScale=1 will be chosen. Otherwise, the object will first be scaled to the value of startScale in a sudden jump, before the continuous scaling of the interpolator is started, unless the object has been scaled before. For instance, to let an object grow to double its size, one would define startScale=1 and endScale=2.

Examples for the use of position and rotation interpolators can be found in the example programs SimpleAnimation3d.java of the helicopter, where a position interpolator models the flight and rotation interpolators are responsible for rotations of the rotor blade. A scaling interpolator can be found in the example program InteractionExample.java, which will be described in Chap. 9.

Next post:

Previous post: