An Introduction to VRML

Mr. Lukka takes a look at VRML basics including scripting, animation and applications.
Animation and Interaction

Of course, creating static scenes is not such a big deal. The truly interesting part of VRML is its ability to interact with the user. Suppose you want to demonstrate the concept of a cross product of two vectors to a friend. You can draw all sorts of 2-D diagrams, but what would be a better description than a 3-D graph in which your friend could adjust two vectors and see the cross product change in real time (especially since you can embed it into a web page using the HTML embed tag)? One of the FreeWRL demos (Figure 4) does exactly this, plus the vector sum and difference.

Figure 4

In the previous section, you saw how the Nodes describe the scene to be rendered. What I didn't mention is that nodes can send events to each other along specified routes. The event routes are independent of the scene hierarchy.

Routes are specified by ROUTE statements. For example, Listing 4 creates a white box (Figure 5), which cycles smoothly through red and blue when clicked, returning to white 2.5 seconds after the click. What happens when you click on the box? First, the BUTTON node senses it (most sensors in VRML sense events from their siblings, in this case the Shape node defining the box) and sends a touchTime event. The ROUTE statement causes that event to be routed into the startTime of the TimeSensor TS, which causes it to start generating time events for one cycle (the length of the cycle is 2.5 seconds). At each clock tick, the TimeSensor sends an event called fraction_changed with an SFFloat value between 0 and 1 (giving the fraction of the time in the cycle that has gone by). This event is then routed to CI which is a ColorInterpolator, i.e., it does piecewise linear interpolations of color values. CI then sends a value_changed event that MAT receives as diffuseColor, then the color of the box changes. For example, if CI receives a set_fraction event with the value 0.3, it checks its key field and notices that 0.3 is between the first and second value. It is six tenths of the way to the second value; therefore, the output is the color (0.6 0.6 0.6).

Having events go through an interpolator to reach their destination is a fairly common idiom in VRML, as this allows you to specify arbitrary mappings relatively easily and cheaply. Several different kinds of interpolators are in the VRML97 specification, for different data types.


However, interpolators will take you only so far: for one thing, they can't toggle on a light at a particular point in the sequence. It would have been easy for the VRML97 specification authors to add a node type to accomplish this, but they chose not to. Instead, they chose to create a very general interface to external scripting languages, Java and JavaScript. You can define arbitrary behaviours for your world using these programming languages.

If we want to have the Box in the previous example disappear and be replaced by a small blue sphere for the first 1.5 seconds of each cycle, we need to use a Script node. This particular example is shown in Listing 5. The TS and CI nodes and the routes between them and MAT are the same as in the previous example.

As is obvious from the example, the syntax of specifying fields inside the Script node is similar to the PROTO interface section: instead of just saying fieldName value we are saying kind Type fieldName followed by value for fields. This is because the specification defines only three fields for the Script node: url, directOutput and mustEvaluate and leaves it up to the programmer to define the eventIns, fields and eventOuts of his script.

The actual script inside the Script node is specified in the url field. In this case, it is written in JavaScript and is embedded into the URL. It would also have been possible to write the script into a file (with the .js suffix) and to refer to that file in the URL. Alternatively, the script could have been written in another scripting language (e.g., Java or Perl).


So far, we've discussed how to write VRML. However, the most interesting results come from creating VRML automatically. Static worlds that are programmed once are interesting mostly for games, art or advertisements. Great possibilities remain to be exploited in the interface between the rest of the information world and the 3-D browser.

Figure 5

Also, we can use the API provided by the browser to create an application that uses VRML to provide a part of the GUI. A fairly simple interface can be written as a Perl program that uses the FreeWRL browser and GTK together to provide a user interface, which would be difficult to do in VRML or GTK alone. The main window consists of an entry into which you can enter a function you want the program to plot, a button to plot it, and three labels showing the X,Y coordinates and the function value at the point where your mouse last touched the function surface. The program also places a blue box at this point in the 3-D window. It would be trivial to add code to take 2-D or 3-D snapshots of this scene, as either the usual image files (GIF/JPEG) or VRML, once you have the scene displayed in the browser.

Basically, in addition to creating the GTK GUI, the code simply creates a browser window, loads a VRML world from a string and then calls a browser method to obtain a reference to an ElevationGrid node in the scene. It then sends events to this ElevationGrid to set the shape of the surface via the height field. The program also registers a listener for a TouchSensor node in the scene, so it is able to obtain the mouse position on the surface. The really interesting thing is that all the code for this application is under 200 lines with comments. (The application is included in the FreeWRL distribution, so I will not include the full source code here.)

It is also possible to access the VRML browser through a Java API called EAI (external authoring interface). This enables one to write web applets that access a VRML scene. At the time of this writing, FreeWRL partially implements the Java EAI API but isn't yet able to provide this API while running inside Netscape. By the time you read this article, this situation may have changed.