BIFS Tutorial - Part II

Animation

We will now introduce animation to bring some life in the scene. BIFS offers two ways of animating a scene: using value interpolators and events generators as in VRML, or using live modifications by adding, removing or updating nodes in the tree through command or animation frames (encoded in a file, sent by a server).


Interpolator based animation:

In order to animate a value with an interpolator, we need 3 nodes: a target node to be animated (here we will use a Transform2D node), a node generating events (TimeSensor), an interpolator node (XXXXXInterpolator) and links between these three nodes (Route).


Transform2D Node:

The Transform2D node is the most commonly used transformation node in 2D scenes.Here is its syntax:

<Transform2D center="0 0" rotationAngle="0.0" scale="1 1" scaleOrientation="0.0" translation="0 0">

<children>... graphical primitives, other nodes ...</children>

</Transform2D>

These node is quite simple and powerfull. It applies an affine transformation to the visual nodes in sub-trees and nodes listed in the children field:

The transformations are applied in the following order: scaling, rotation and translation.

Let's use the previous rectangle example and transform it.

Transformation type

Example

A simple translation

rect4.xmt, rect4.bt, rect4.mp4

Rotation

rect5.xmt, rect5.bt, rect5.mp4

Scaling

rect6.xmt, rect6.bt, rect6.mp4

Combined transform to get a skewing effect

rect7.xmt, rect7.bt, rect7.mp4


Routes and Events :

Events and routes are the key elements when building interpolator-based animations. Events are usually generated (eventOut) by sensor nodes (click, drag, periodic events, ..) and shall be connected to event listener (eventIn) in order to modify the scene: this connection is called a Route. To fully understand these concepts, let's get back on the notion of field. In the nodes we have seen, we have found several types of fields (order, emissiveColor, translation, size ...) with different types (real, integers, boolean, ...). These types are called fieldType and define what type of numerical value the field is. A field also has a type for the kind of event it accepts or generates, called the eventType. A field can generate events (eventOut), accept event as an input ( eventin), do both ( exposedField) or none (field). Events are passed from emitters (eventOut or exposedField) to recievers (exposedField or eventIn) of a same value type. BIFS defines 22 fieldTypes :

field type

Semantics

SFBool

Boolean (TimeSensor.enabled, IndexedLineSet2D.colorPerVertex)

SFFloat

Real (LineProperties.lineWidth, Transform2D.rotationAngle)

SFTime

Double number for timing information only (TimeSensor.cycleInterval)

SFInt32

Signed integer (LineProperties.lineStyle)

SFString

Character string

SFVec3f

3D coordinate for points or vectors (real numbers)

SFVec2f

2D coordinate for points or vectors (real numbers)

SFColor

RGB values of a color. Each component is a real number in the interval [0, 1] (Material2D.emissiveColor)

SFRotation

Rotation givan by a 3D vector (rotation axis, as in SFVec3f) and a rotation angle in radians

SFImage

Pixel array, only used for small textures used by PixelTexture node

SFNode

Field is of type node and may accept a node as a value (IndexedFaceSet2D.color, Shape.material)

MFBool

SFBool Array

MFFloat

SFFloat Array

MFTime

SFTime Array

MFInt32

SFInt32 Array (IndexedFaceSet2D.colorIndex, OrderedGroup.order)

MFString

SFString Array

MFVec3f

SFVec3F Array

MFVec2f

SFVec2F Array (Coordinate2D.point)

MFColor

SFColor Array (Color.color)

MFRotation

SFRotation Array

MFImage

SFImage Array (never used by native nodes)

MFNode

SFNode Array (OrderedGroup.children, Transform2D.children)

In order to declare a route between 2 fields of 2 nodes, we need a way to identify these nodes so that the player understands how to dispatch (route) events. The mechanism used is the DEF/USE one, which allows to assign a usage name to a node (DEF) and reuse the node (USE) anywhere in the scene. The XMT syntax for the DEF mechanism is simple:

Examples :

<Transform2D scale="1 2" DEF="Y-Scaling">...</Transform2D>
<Shape DEF="ASquare">...</Shape>

<IndexedLineSet2D DEF="Line1" colorPerVertex="false">...</IndexedLineSet2D>

The XMT syntax for Route is:

<Route fromNode="Node1" fromField="field1" toNode="Node2" toField="field2"/>

In this syntax, 'Node1' is the same character string as the DEF one of the node owning the emitter field ('field1'), 'Node2' the same character string as the DEF one of the node owning the reciever field ('field2'). Names 'Node1' and 'Node2' are defined by the author, whereas names 'field1' et 'field2' are define by the node syntax (BIFS built-in nodes or prototypes).


The TimeSensor node:

The TimeSensor node is used to generate periodic time events. The period is given in seconds by the cycleInterval field. The startTime field specifies when the node shall start the event generation; it is expressed in seconds and relative to the scene simulation time. For now we will use it with its value to default (0), meaning it is active as soon as the scene is loaded. The stopTime field specifies when the node shall stop generating events; it is expressed in seconds and relative to the scene simulation time. We will use it with its value to default (-1), meaning the sensor is always active. The loop field indicates whether generation ends at the end of a cycle of cycleInterval seconds or not. The node can be disbaled (not sending events) by modifiying the enabled field.

The TimeSensor node generates 4 distinct events: cycleTime, isActive, fraction_changed and time. For interpolator-based animation, the most important event is the fraction_changed one. The fraction_changed field is an eventOut of type SFFloat; this real is in the interval [0, 1] and indicates the fraction of the current cycle since the start of the cycle. If the cycle starts at t and the current time is t+dt with a cycleInterval of T then fraction_changed is dt/T.

The XMT syntax is:

<TimeSensor cycleInterval="1"/>


Interpolators :

BIFS has many interpolator nodes for many field types: 3D coordinate (CoordinateInterpolator), 3D orientation (OrientationInterpolator), 3D normal (NormalInterpolator), 3D position (PositionInterpolator), 2D coordinate (CoordinateInterpolator2D), 2D position (PositionInterpolator2D), scalar (ScalarInterpolator)and color (ColorInterpolator). All interpolators have 4 common fields: 2 exposedfields called key (MFFloat type), and keyValue (type depending on the interpolator type), an eventIn called set_fraction (SFFloat type) and an eventOut called value_changed (type depending on the interpolator type). Interpolators used in 2D are as follows:

Interpolator Node

keyValue type

value_changed type

PositionInterpolator2D

MFVec2F

SFVec2F

CoordinateInterpolator2D

MFVec2f

MFVec2f

ScalarInterpolator

MFFloat

SFFloat

ColorInterpolator

MFColor

SFColor

Interpolators perform a piecewise-linear interpolation on the interval (-infinity, +infinity). The interpolation function is defined by the N values of the key field, called interpolation keys, and the N values of the keyValue field. Keys must be listed in increasing order but are not restricted to any interval. The interpolator uses the input fraction t recieved in set_fraction to evaluate the interpolation f(t) and give the result in the output value_changed field . If there are n keys (t0, t1, t2, ..., tn-1) in the key field, the interpolation is done on the intervals ]-infinity, t0[, [t0, t1[, [t1, t2[, ... , [tn-1, +infinity[. Let v0, .., vn-1 be the values of the keyValue field, then f(t) is:

f(t) = v0, if t <= t0,
f(t) = vn-1, if t >= tn-1,

f(t) = linear interpolation between (ti, vi) and (ti+1, vi+1) for ti<=t <= ti+1

2 following keys may be identical, hence allowing for discontinuities in f(t).

The XMT syntax is:

<PositionInterpolator2D key="0 1" keyValue="0 0 40 40"/>

This interpolator will output the event SFVec2f(30,30) in value_changed field if it gets the value 0.75 in its set_fraction field.


A complete animated scene:

Now that we have all elements to build a simple animation, let's make our rectangle move from position (0,0) to position (40,40) in 10 seconds : anim1.xmt, anim1.bt, anim1.mp4.

<OrderedGroup>
<children>
<Transform2D DEF="MoveRec">
<children><Shape><geometry><Rectangle size="50 40"/></geometry></Shape></children>
</Transform2D>
<TimeSensor DEF="Timer" cycleInterval="10"/>
<PositionInterpolator2D DEF="Interp" key="0 1" keyValue="0 0 40 40"/>
</children>
</OrderedGroup>
<Route fromNode="Timer" fromField="fraction_changed" toNode="Interp" toField="set_fraction"/>
<Route fromNode="Interp" fromField="value_changed" toNode="MoveRec" toField="translation"/>


BIFS-Update based animation:

One of the fundamentals of BIFS scenes is that the scene may be modified at will through commands. These commands are grouped in a timed entity called Access Unit in MPEG-4 Systems, which can be compared to a video frame.

A video is a sequence of images or frames where each frame is given a presentation time (the time at which the frame has to be displayed on the terminal). This indication is called the CompositionTimeStamp in MPEG-4 terminology. The sequence of timed video frames is called a video stream.

Similary, a BIFS scene is made of a sequence of BIFS-Commands access units (set of commands and presentation time), hence resulting in a BIFS stream. Playing a BIFS stream consists in applying modification described in the BIFS commands to the scene and displaying the result to the user. As in video, some BIFS commands may describe the entire scene (hence may be decoded without knowledge of previous BIFS commands) much like an I-frame in video coding, while others modify the existing scene much like a P-frame in video coding. In all cases the BIFS commands are called BIFS updates. There are two kinds of BIFS updates: the first one, called BIFS Command frames, consists in modifying node fields or adding or suppressing parts of the scene graph. The second type, called BIFS Animation frames, consists in modifying a pre-defined set of node fields with high compression techniques, and is designed for continuous animation. The BIFS animation frames can be re-written in BIFS command frames with higher bitrate, while the opposite is not true. This tutorial will not talk about BIFS animation frames.


Structure of an XMT document:

In order to add BIFS updates in an XMT document, we need to have a deeper look at the XMT structure of the vide.xmt document.

An XMT document begins with the XML XMT-A element. This element is made of the header element and the body element. We will come back on the header element later on. until now, the body element had the following syntax:

<body>
<Replace>
<Scene>
<OrderedGroup> The BIFS scene </OrderedGroup>
... eventually a list of ROUTEs ...
</Scene>
</Replace>
</body>

The body element indicates the begining of the BIFS stream. The CompositionTimeStamp for this element matches time T = 0. The Replace element indicates that the BIFS command used is a replacement command. Its sub-element Scene indicates that the whole scene (previously empty) is being replaced by the Scene element (eg, the top node and the list of Routes). This implicitly defines a BIFS stream with only one frame at time 0 containing one command.

Adding a frame to the BIFS stream in an XMT documant is done by appending the par element to the Replace sub-element of the body element:

<par begin="1.5"> .... </par>

The begin attribute indicates the presentation time of the frame in seconds. The content of the par element is a sequence of BIFS commands that will be applied in order to the scene at time begin.


BIFS Commands:

There are three types of BIFS commands: a replacement command (Replace), an insertion command (Insert) and a deletion command(Delete).


The Replace command:

As seen above, the Replace command can be used to replace the whole scene by a new one if its content is the Scene element. It can also be used to replace a defined node, a defined route or a field of a defined node.

Command Meaning

Syntax

Node replacement

<Replace atNode="Identifier">
... the new node to replace with ... </Replace>

Route replacement

<Replace atRoute="Identifier">
... the new route to replace with ...
</Replace>

Field replacement for any field types other than SFNode or MFNode

<Replace atNode="identifier" atField="Fieldname" value="NewValue"/>

Field replacement of field type SFNode

<Replace atNode="identifier" atField="FieldName">
... the new node to replace the field with...
</Replace>

Indexed replacement in a field of type MFNode

<Replace atNode="identifier" atField="FieldName" position="FIRST|END|n">
... remplacement node...
</Replace>

Indexed replacement in an MF field other than MFNode

<Replace atNode="identifier" atField="FieldName" position="FIRST|END|n"
value="NewValue"/>

Let's take our first example (rect.xmt) and replace after 2 seconds the rectangle by the rectangle used in our second example (rect2.xmt).

The resulting scene is : update1.xmt, update1.bt, update1.mp4.

NOTE : Although we have replaced a Shape node by a new one, the new Shape node doesn't have any identifier.


The Insert command:

The Insert command is used to ... insert a node, a route or an SF value at a given position in an MF field.

Command Meaning

Syntax

Node insertion at the first, n-th or last position in a field of type MFNode :

<Replace atNode="identifier" atField="Fieldname" position="FIRST|END|n">
... new node ...
</Replace>

Value insertion at the first, n-th or last position in an field MF other than MFNode :

<Replace atNode="identifier" atField="FieldName" position="FIRST|END|n" value="ValueToInsert"/>

Route insertion:

<Insert> ... route to insert ... </Insert>

Insert a Route and assign an identifier to this route :

<Insert atRoute="identifier"> ... route to insert ... </Insert>

Let's take the previous example (update1.xmt) and insert a circle (radius 10 pixels) centered at (20, 0) at time t=5 s. The resulting scene is : update2.xmt, update2.bt, update2.mp4 .


The Delete command:

The delete Delete is used to delete a node, a route or an SF value at a given position in an MF field.

Command Meaning

Syntax

Node deletion :

<Delete atNode="identifier" />

Deletion of an SF value at first, n-th or last position in an MF field :

<Delete atNode="identifier" atField="FieldName" position="FIRST|END|n"/>

Route deletion:

<Delete atRoute="Identifier" />

Let's take the previous example and delete the rectangle at time t = 7 s. The resulting scene is update3.xmt, update3.bt, update3.mp4.


Exercises:

Exercise 6 : Create a scene with a 50-pixel radius circle centered at (0,0), a rectangle (100x200 pixels), centered at (20,20) and a square (60x60 pixels) rotated 45° centered at (-20, 20).

Exercise 7 : take one of the examples and add identifiers to all nodes.

Exercise 8 :

1. Change the TimeSensor cycle duration and modify the interpolator keys to get a smoother and faster animation.
2. Animate the rotation of a rectangle around its center.
3. Animate the fill color of the rectangle.

Exercise 9 : Replace at time t=4s the line color of the rectangle (you will have to introduce identifiers).

Exercise 10 : Take the IndexedLineSet2D example and add points and colors at time t=3s.

Exercise 11 : Take the interpolator-based example and delete a route while animating. Note what's happening.


Conclusion

In this part we have seen how to transform graphical objects and animate the transformations through routes and interpolators, and through BIFS commands. With these simple tools and some practice and patience, you should be able to write a cartoon entirely in BIFS.


[ Home ] [ Very Simple Scenes ] [ Animation ] [ Including Media ]


Last Modified: 02/04/2005
Cyril Concolato & Jean Le Feuvre © 2002-2005