Welcome
About VRML
VRML Worlds
Mars Craters
Mars Valleys
Mars Mountains
Moon Topography
Internet Links
VRML Tutorial
E Cubed
Site Map
e-mail me

Sponsored Links
 

Create VRML file

A VRML world is a simple text (*.txt) document consisting of various nodes which create a VRML (*.wrl) world when viewed by an Internet browser equipped with a VRML plug-in. There are 54 nodes a designer can use to create a VRML world but not all of them have to be used for a particular world. The designer first needs to imagine what the world will look like, then break the world down into simple objects. Next, the designer creates the various objects by placing nodes in a document, each node configured to represent exactly what the designer had in mind. Finally, the designer places more nodes in the document to manipulate the object nodes, the viewer's position, and the world's background properties. When viewed, the document is read from the top down, so the first nodes encountered will be rendered first and so on. Because of this, if a node that manipulates another node precedes that node, an error is generated since the manipulated node hasn't been created yet.

Let's start with a new document in a text editor. The editor should save the document without any markups or formatting; Wordpad or Notepad will do nicely. The first line in every VRML document must be:

# VRML V2.0 utf8

This is the header line: the # is used for comments - everything on the line after it is ignored by the browser. We're working with VRML version 2, sometimes referred to as VRML 97. Save the file. The editor will save it as a .txt document, so put quotes around the title with a .wrl extension. Example: "MyWorld.wrl".

This is the first step in creating a VRML world - Open a new text document, type the header line and save the file as a .wrl file. When you save the file again, you don't have to put quotes around the title, just click Save.

Create Objects

You can design just about any type of object in VRML - if you have the patience and the talent. Fortunately, there are 4 predefined shape nodes ( Box, Cone, Cylinder and Sphere) so you can combine these to make a more complex shape. There are a few other nodes that allow you to build your own shapes (Extrusion, Elevation Grid, IndexedFaceSet, IndexedLineSet and PointSet). You use the Shape node to create any of these shapes. The Shape node has two fields which are both filled with nodes themselves. The geometry field is where you place the node for your specific shape - 1 node per Shape node. So each object will consist of at least a Shape node with a geometric object in the geometry field. The browser will place this object at point 0 0 0 - the center of the world. If you create another object, it too will be placed at point 0 0 0. Objects don't have any collision detection between themselves. Here's a simple box object:

Shape { geometry Box {size 4 2 5 } }

The browser will show a box with the X length of 4 meters, the Y height of 2 meters, and the Z depth of 5 meters. VRML uses a grid system with the positive Z axis pointing towards you. The positive X axis is to your right and the positive Y axis is above the horizon. The default color is white. You define the color of the object with the appearance field in the Shape node. The Appearance node goes in the appearance field and it has 3 fields (material, texture, and textureTransform) that require nodes themselves. The material field is the main one; the other two are for more sophisticated effects. The Material node goes in the material field and it's field diffuseColor is the one that defines the color of the object. Color is defined in RGB (Red, Green, Blue) values ranging from 0 to 1 each.

Red = 1 0 0; Green = 0 1 0; Blue = 0 0 1; Black = 0 0 0; White = 1 1 1

Various combinations create various colors. Here's a blue box object:

Shape 
{ appearance Appearance
             { material Material {diffuseColor 0 0 1}}
  geometry Box {size 4 2 5}
} # end of Shape node

You've probably noticed the curly brackets }. These encase the fields of the various nodes. You have to ensure that they match - for every one facing right, there must be one facing left. This is the source of many errors. Also, the identical names for nodes and fields can cause confusion. The nodes are capitalized and are followed by a curly bracket. Some people place a node's fields on separate lines to facilitate reading the code. Many put comments in the code to remind them of what is going on in the nodes.

This is all it takes to make a simple object in a VRML file: write a Shape node, use the appearance field to define the color and use the geometry field to define the specific shape. Remember to save the file before trying to view it in your browser.

Move objects

The object must first exist before it can be moved. Once it is defined, it must be placed inside a Transform node. The Transform node is a grouping node which means it can contain many nodes. This allows the VRML designer to move several objects at once. The Transform node can also contain other Transform nodes that already move an object. So if a designer wanted to create a human form, an arm object would be placed inside one Transform node, the other arm would be inside another Transform node and the whole body would be placed under a single third Transform node. Each arm could swing at different time rates and in different directions - the Transform node containing the arm would be manipulated. To move the whole body, manipulate the third Transform node; as the body moves forward, the arms would swing at their assigned rates, yet they would also move with the body.

The Transform node can also rotate objects, so the previous human object can sway while it moves forward. VRML uses the right-hand rule in determing rotation angles. The field type SFRotation ( 0 1 0 0 ) describes the angle the object will face. The first three numbers correspond to the three axis in the coordinate grid ( X Y Z 0 ). The fourth number is the angle in radians.

Degrees to Radians: 0 = 0; 45 = .78; 90 = 1.57; 135 = 2.35; 180 = 3.14; 225 = 3.92; 270 = 4.71; 315 = 5.48; 360 = 6.28.

Defining this field can get complicated. It is best to keep the values either zero or one; one refers to the axis of rotation, zero means ignore that axis. So a field definition of 0 1 0 .78 means rotate about the Y axis .78 radians. Using the right hand rule, wrap your right hand around the axis of rotation with your thumb pointing in the positive direction and rotate in the direction of your fingers. This example rotates a box 45 degrees:

Transform
{ rotation 0 1 0 .78
  children Shape
           { appearance Appearance
                       { material Material
                                 { diffuseColor 0 0 1 }
                       } # end Appearance node
             geometry Box {size 4 2 5 }
           } # end of Shape node
} # end Transform node 

To move the box, define the translation field of the transform node. This will center the box around the point defined in the translation field. This won't cause the box to move while it's being viewed - it will be in the new position when the scene is rendered. To animate the box, the TimeSensor node is required. This node acts like a separate clock and can be used to start or stop a movement, either a translation or a rotation or both.

Interpolator nodes compute the values between a starting and ending value. The designer sets the main values so the interpolators do most of the work. There are 6 interpolator nodes; ColorInterpolator, CoordinateInterpolator, NormalInterpolator, OrientationInterpolator, PositionInterpolator, ScalarInterpolator. The PositionInterpolator is for movement while the OrientationInterpolator is for rotations. All interpolators have a key field, which ranges from 0 to 1. The designer can define intervals between these values to vary the amount of manipulation over time. All interpolators have a keyValue field which defines the value the object changes to.The interpolator computes the logical values between each keyValue value and each userdefined value must match up with a user defined Key value; there should be the same number of items in each field.

To complete the puzzle, these nodes need to be connected. Routes are used to essentially plug one field in a node to a field in another node. The only stipulation is that both fields must be the same type. So you route the TimeSensor fraction_changed node to the interpolator's set_fraction field. That's an eventOut field to an eventIn field. You can't route eventIns to eventIn or eventOuts to eventOuts. ( exposedFields have both eventIn and eventOut capabilities )

Next you route the interpolator's value_changed field to the Transform node's translation or rotation field. You don't have to worry about the Shape node itself, the Transform node controls the movement. To establish a route, the node has to be named. The DEF and USE features define a node and refer to a previously defined node. Put the userdefined name after the DEF or USE keyword and then continue on with the node definition. Once everything is all wired together, the object will perform the movement when the browser loads the scene - maybe.

The TimeSensor node determines when the manipulation will begin. As long as the stopTime value is less than the startTime value, the manipulation will occur. The cycleInterval field sets the time the manipulation will occur ( in seconds), the loop field determines if the manipulation will repeat itself, and the enabled field determines if the node will work at all ( TRUE means it will work ). This example will move the box from left to right:

DEF BlueBox Transform 
{ rotation 0 1 0 .78
  children Shape
           { appearance Appearance
                       { material Material
                                 { diffuseColor 0 0 1 }
                       } # end Appearance node 
             geometry Box {size 2 3 5} 
           } # end of Shape node
} # end Transform BlueBox
DEF BoxTime TimeSensor
{ cycleInterval 4
  loop TRUE
  stopTime -1
} # end TimeSensor BoxTime
      DEF BoxMovement PositionInterpolator 
      { key [ 0, .5, .6, 1]
        keyValue [0 0 0, 10 0 0, 10 0 0, 0 0 0]
      } # end PositionInterpolator BoxMovement
      ROUTE BoxTime.fraction TO BoxMovement.fraction
      ROUTE BoxMovement.value TO BlueBox.translation

Notice that the two middle values in the key field of the PositionInterpolator node are close to each other in value. This causes the box to pause at the far right. Notice that there are 4 items in both the key and the keyValue fields - there must be a 1:1 correlation between the two fields. Notice that ROUTE and TO are capitalized - this is mandatory. Notice that there are no 'set' or 'changed' attachments to the route 'fraction' or 'value' tags: the browser knows what to do. Finally, notice that the box is still angled 45 degrees. This would change if the OrientationInterpolator was used and routed to the rotation field.

DEF BoxRotate OrientationInterpolator 
{ key [ 0, .5, .9, 1]
  keyValue [0 1 0 0, 0 1 0 3.13, 0 1 0 6, 0 1 0 6.28]
} # end PositionInterpolator BoxMovement
ROUTE BoxTime.fraction TO BoxRotate.fraction
ROUTE BoxRotate.value TO BlueBox.rotation

When rotating, VRML rotates to the desired angle via the shortest route. So if you were at .78 radians (45 degrees) and wanted to go to -.78 radians (315 degrees or -45 degrees), if you set the start value at .78 and the end value at -.78, the OrientationInterpolator would compute a path which would resemble a pendulum swinging back and forth. But if you wanted the object to rotate from .78 around to the -.78 angle, then you need to insert a middle value, like 3.14, midway between the two values.

DEF BoxRotate OrientationInterpolator 
{ # rotates all the way around
  key [ 0, .5, 1]
  keyValue [0 1 0 .78, 0 1 0 3.14, 0 1 0 -.78]
} # end PositionInterpolator BoxMovement
DEF BoxRotate OrientationInterpolator 
{ # swings back
  key [ 0, 1]
  keyValue [0 1 0 .78, 0 1 0 -.78]
} # end PositionInterpolator BoxMovement
DEF BoxRotate OrientationInterpolator 
{ # swings back and forth
  key [ 0, .2, .25, .6, .65, 1]
  keyValue [ 0 1 0 0, 0 1 0 .78, 0 1 0 .78, 0 1 0 -.78,
             0 1 0 -.78, 0 1 0 0 ]
} # end PositionInterpolator BoxMovement

Movement seems complicated but if you keep it simple, it is a straightforward exercise. Remember, once the movement starts, the object will take on the values of the keyValue field in the interpolator. So if it's original location is 0 0 0 and the starting value of the keyValue field is 0 2 0, the object will jump to the starting value once the TimeSensor node begins the manipulation. A VRML designer can move an object all over the world, stop it, start it again, and/or spin it around; whatever one can imagine!

Inlines & Prototypes

Search
 
Google


 


|Welcome| |About VRML| |VRML Worlds| |Mars Craters| |Mars Valleys| |Mars Mountains| |Moon Topography| |Internet Links| |VRML Tutorial| |E Cubed| |Site Map|


Copyright 2005 Ernest E. Rose III