1998 Winter Quarter

Project 2 Help Session

This document should give you a basic introduction to VRML so that you can get started on project 2, Articulate. There is a lot of information on the web about VRML. One of my favorite resources is sgvenus.cern.ch/vrmltut/, which should have info on just about anything you might want to do for this project. To go into even more depth vrml.sgi.com/developer is the place to go. These links and more are on the project handout. Finally, there should also be a few useful books on VRML available in the lab.

Introduction

The basic elements of VRML files are nodes. Every type of node has a set of fields associated with it. Each field is assigned a value of a specific type. The types include scalers, vectors, colors, rotations, and other nodes. Some fields can also be assigned a list of values (all of the same type). Notice that nodes can be placed in the fields of other nodes, this is how hierarchies are constructed.

There is one other important concept in VRML, that of events. Information is sent back and forth between nodes via events. The section on ROUTEing Events covers the basics of events and their use.

Syntax

The basic syntax is quite simple. Fields are set by listing each field name and its value and enclosing the whole thing in braces after the node name. Lists are enclosed in brackets. A comment begins with the pound sign (#) and goes to the end of a line. This is nearly all the punctuation you will ever use.

Types of Nodes

Creating Shapes

Actually creating objects involves using the Shape node. The Shape node has two fields: geometry and appearance. There are a variety of different geometry nodes, but the basic four are Box, Sphere, Cylinder, and Cone.

The default scaling of these objects is roughly 2 units on a side. So, for example, the cylinder will default to a radius of 1 and a height of 2. Objects can be scaled either by using the Transform node or by setting the appropriate fields in the geometry node.

For the sake of standardization you should consider the unit of distance to be meters, and choose sizes appropriately. This is a common standard and is designed to reduce the need for special scaling when combining VRML models together.

Example

To create a cone of height 3.0 and radius 1.0 (at the base) centered at the origin you would type
```Shape {
geometry Cone {
height 3.0
}
}
```

The Appearance Field

The color of the cone created in the previous section probably defaulted to white, to change the color you must set the Shape's appearance field. In the appearance field, strangely enough, you put the Appearance node. The Appearance node has three fields, the most important being the material field which takes a Material node. The other two fields are for texture maps, which you may want to use for bells and whistles.

The Material node has a number of fields, all of which you should become intimately familiar with in the next project, Trace. For now you can get by using just the diffuseColor field. Colors are specified as floating point RGB triples.

Example

To make a Shape purple, you would set its appearance field to
```Appearance {
material Material {
diffuseColor 0.3 0 0.4
}
}
```

Transform and Other Grouping Nodes

The structure of a VRML model is build from the grouping nodes: Group, Transform, Collision, etc. All of these nodes have a field called children. The value of the children field can be a node or list of nodes.

The Transform node is by far the most important of the grouping nodes. It has a number of additional fields such as scale, rotation, and translation. These transformations act on all of the children of the Transform node.

• The translation field takes a vector along which to translate.
• The rotation field takes a vector defining the rotation axis followed by the rotation angle in RADIANS.
• The scale field takes a vector defining the scaling along each axis. The elements of the scaling vector should all be positive; VRML viewers probably won't do something sensible, like reflection, when the scaling is negative.

The three basic transformations of scale, rotation, and translation are always done in that order. The order in which you list the fields does not change this. If you want a different order you can either nest Transform nodes or make use the two additional fields center and scaleOrientation. The center field defines the center of the scaling and rotation. The scaleOrientation is a rotation done on the axes before the object is scaled.

Example

To draw a thin cone pointing down enter,
```Transform {
translate  0.0 2.0 0.0         # happens third
scale      0.5 2.0 0.5         # happens first
rotate     0   0   1   3.141   # happens second
children [
Shape {
geometry Cone {}
}
]
}
```

Naming Nodes and Sending Signals

This section discusses a few special types of nodes as well as two constructs that are neither nodes nor fields. This material will be most important when you begin to animate your model.

DEF

The DEF keyword is used to DEFine a label for a particular node. You may want to do this for two reasons.
1. It allows you to reUSE that node again somewhere else in the model using the USE keyword.
2. Once a node has been defined you can send signals to it using ROUTE as discussed in the next section.

There is another way of reusing code called a PROTO, check a reference for the details of how to define and use a PROTO. In some ways this may be more familiar to you than DEF because it bares a strong resemblance to function definitions in other programming languages. Be aware, though, that you will be using your VRML model again in project 4 and PROTOs are currently not supported in that software.

Example

We will replicate our cone and point the cones in four different directions.
```DEF a_cone Transform {
scale 0.5 2.0 0.5
translation 0.0 2.0 0.0
children Shape {
geometry Cone {}
}
}
Transform {
rotation 0 0 1 1.5707
children USE a_cone
}
Transform {
rotation 0 0 1 3.1415
children USE a_cone
}
Transform {
rotation 0 0 1 -1.5707
children USE a_cone
}
```

ROUTEing Events

Once you understand how to build a static model the next big step is understanding events. A node will output an event for any number of reasons: the user clicks on a part of your VRML model, an object runs into another object, a unit of time passes, etc. To find out about all the possible events that can be sent and received and how these events can be used, check a good VRML reference.

Sensors are the most common source of events, and the TimeSensor is probably the most important of the sensors. When a TimeSensor is started it ticks off the time by sending off events. It has a startTime and stopTime as well as a cycleInterval and true or false field called loop. One of the events that it sends is the fraction_changed event, which has values from 0.0 to 1.0 depending on what part of the cycle it is in.

To make use of this fraction_changed event you will probably need an interpolator node. The PositionInterpolator for example will translate these fractions into 3D vectors which may be used to relocate objects in the scene. You can think of the PositionInterpolator's role as defining a parameterization of a path in 3D by the interval from 0 to 1. Other interpolators parameterize scalers, colors, or rotations.

An interpolator has key and keyValue fields. The key field is a list of increasing numbers in the range from 0 to 1, typically beginning with 0 and ending with 1. The keyValue field lists what output value is associated with each key. When the interpolator gets a fraction not specified in its key list it will linearly interpolate between the nearest specified points. The event input for an interpolator is set_fraction and the event output is value_changed.

Finally, we come to ROUTE. ROUTE is used to wire all of these events up. ROUTE is used this way

```ROUTE name.event_out TO name.event_in
```
In the above, `name` refers to the identifier the node was given using DEF. Even if you are not going to reuse a node you need to give it a name with DEF so that it can send or receive events.

Example

Here we will make a ball "bounce" up and down. The output of the PositionInterpolator is ROUTEd to a Transform where it alters the translation of the ball. In general, a field can be changed by sending an event to set_fieldname as I do here with set_translation.
```DEF ball_ts TimeSensor {
cycleInterval 2
loop TRUE
}
DEF ball_pi PositionInterpolator {
key [0 0.5 1]
keyValue [0 0 0   0 3.0 0   0 0 0]
}
DEF ball_t Transform {
translation 0 0 0
children Shape {
geometry Sphere {}
}
}
ROUTE ball_ts.fraction_changed TO ball_pi.set_fraction
ROUTE ball_pi.value_changed    TO ball_t.set_translation
```

Miscellaneous Notes

This is a short list of extraneous things to remember or take note of.
• Comments begin with # and go until the end of the line
• Everything is case sensitive (I think.)
• Suppress your urge to use commas when typing vectors
• For serious C programmers: there are no semicolons in VRML.
• Special commands such as DEF, ROUTE, and PROTO are in all capitals. Node names are capitalized, and field names begin with a lowercase letter.
• The standard is to have 1 unit = 1 meter, follow this when making your character for this assignment.
• Remember to express angles in RADIANS
• From the default viewpoint the x-axis goes to the right, the y-axis goes up and and the z-axis points toward you.
• When using an interpolator make sure the number of elements in the key and keyValue lists are the same.
• Unfortunately there is no way to change one part of a field independently. So, for example, you cannot us a ScalarInterpolator to change just the x value of a Transform's translation field. In this case use a PositionInterpolator when the y and z values in the keyValue list are all the same.
• DEFs must come before the corresponding USEs

Putting It All Together

This is some of the details of getting your first VRML model up and running.

Edit a text file, your file should have the standard suffix .wrl so that it will be recognized as VRML by your web browser. On the first line you need to add the magic incantation

```#VRML V2.0 utf8
```
This specifies the VRML version and character encoding of the file.

Next type in your code. It might be easiest to start off by using one of the small examples above. Once the .wrl file is saved you can open it up in Netscape. There is no need to put the file on a web server, just open it up locally. Cosmoplayer will take a little while to load, if all goes well your 3D world should appear, if not you will get an error window. There are a number of ways to move through the world, try right clicking in the Cosmoplayer window to bring up a menu with viewing options.

Send questions or comments to Alan Wilson (alan@cs.washington.edu)