3. The basics of VRML

3.1 Defining names for nodes

As our example-files getting longer, we should recall the concept, that shapes are the building blocks of VRML worlds: if it is so, it will happen soon, that you will use the same building blocks many times in the same file(world). It would be silly to describe the same objects repeatedly in the same file: fortunately nodes can be named, and used repeatedly by referring to their names:

DEF MyShape Shape {

              . . .

          }

          . . .

          USE MyShape

          . . .

          USE MyShape

In the following example a sphere shape is definded - named "ball" - and reused twice in transform nodes: translated to left and right by 2 units from the "original".

Show the 3 balls
#VRML V2.0 utf8
#Naming and reusing objects

DEF ball Shape{
		appearance Appearance{
			material Material { }
				}
		geometry Sphere {
			radius  0.5  #radius in units  				}
			}
		}

    Transform {
      translation 2 0 0
      children   [ USE ball ]
    }

    Transform {
      translation -2 0 0
      children    [ USE ball ]
    }

3.2 Grouping objects

Besides naming shapes, you have the possibility to group them, thus creating more complex shapes - as you already did it with the "transform" node. VRML has several grouping nodes, including:


          Group       { . . . }

          Switch      { . . . }

          Transform   { . . . }

          Billboard   { . . . }

3.2.1 The group node

The Group node creates a basic group:

Group {

              children [ . . . ]

          }
Using the group node together with the DEF node, you can create more complex worlds, see the following simple example(grouping the previous 3 balls and recalling it in two other transform nodes):

Show the 3 groups
#VRML V2.0 utf8
#Naming and reusing groups and objects
DEF threeballs Group {
  children [
	DEF ball Shape{
			appearance Appearance{
				material Material { }
					}
			geometry Sphere {
				radius  0.5  #radius in units  				}
				}
			}

  	  Transform {
  	    translation 2 0 0
  	    children   [ USE ball ]
 	   }
  	  Transform {
 	     translation -2 0 0
  	    children    [ USE ball ]
  	  }
   ]
}

Transform {
	translation 0 2 0
  	   children   [ USE threeballs ]
 	   }

Transform {
	translation 0 -2 0
  	   children   [ USE threeballs ]
 	   }

3.2.2 The switch node

The Switch group node creates a switched group, from the childs only one is displayed at a time, selected by whichChoice.

Switch {
              whichChoice 0
              choice [ . . . ]
          }
Since the use of the switch node makes no sense without providing events to switch it, we will discuss it later.

3.2.3 The transformation node

In the previous chapter we discussed the global and local coordinate-system of VRML worlds: a transform node creates a coordinate system that is positioned rotated or scaled relative to a parent coordinate system. Shapes built in the new coordinate system(placed in the children-node) are positioned, rotated, and scaled along with it.

In the previous chapter we used the "translation" node to position the objects in the 3D space, but the "transform" node includes a rotation node to change the orientation, and a scale node to change the size of the new coordinate system (and it's childrens):


Transform {

              translation . . .

              rotation    . . .

              scale       . . .

              children  [ . . . ]

          }

We will not pay attention to some fields, for the complete description refer to the VRML/ISO Draft for International Standard (DIS) Node Reference.

In the following example we transform a cone in all possible ways: the "startingcone" is moved 1 unit in the negative Y direction(practically down) rotated by 180 degree around the Z axis, and scaled to the half size in X and Z directions:

Show the transform-example
#VRML V2.0 utf8
#the translation node

DEF startingcone Shape{
	appearance Appearance{
		material Material { }
			}

	geometry Cone{
		bottomRadius 1 #bottomradius in units
		height       1 #height in units
		side         TRUE #TRUE or FALSE determines the existence of the sides
		bottom       TRUE #TRUE or FALSE determines the existence of the bottom-cap
			}
	}

Transform {
translation 0.0 -1.0 0.0 #the translation in X Y Z directions
#		 X   Y   Z   Angle - the rotation around the X and/or Y and/or Z axes by Angle
rotation 	0.0 0.0 1.0  3.14 # the rotation around the Z axis by 180 degree
scale 	0.5 1.0 0.5 #scale factor in X Y Z dimensions
	children[ USE startingcone ]
}

In the following example you can examine the possibilities of nesting transform nodes into another one's children field. We use an inlined world(we will discuss inlining later) showing the coordinate-axes to illustrate the transformations and text objects. The first text "this is the global" is not in any transformation children node, so it is placed "in the center of the global universe", at X=0 Y=0 Z=0. (Note that we are using the simplest text objects without fontStyle; in this case text shapes are placed in the 3D world according to the first character's left-bottom corner, no matter how many lines are in the text-shape.)
The second text-shape "this is transformed 1" is in a transform-node: the text is translated to -4.0 in the X direction, 2.0 in the Y direction and 0.0 Z.
The third text shape "this is transformed 2(relative to transformed 1)" is a children of a Transform node, it is translated 6.0 units in the X, 2.0 units in Y, and 0.0 in the Z direction. But because of this Transform node ("transform 2", whoose children is this text) is itself a children of the previous transform ("transform 1"), its transformation is relative to it's parent ("transform 1"). The resulting translation is: -4.0+6.0=2.0 units in the X, 2.0+2.0=4.0 units in the Y, and 0.0+0.0=0.0 units in the Z direction.
This example well illustrates the hierarchical structure of VRML 2.0

Show the translation example
#VRML V2.0 utf8

Inline {
	url "coords.wrl"
	}

Shape {
    geometry Text {
        string [ "this is the global" ]
   			}
	}

Transform {
translation -4.0 2.0 0.0
		children[
				Shape {
				    geometry Text {
				        string [ "this is transformed 1" ]
	    						}
					}
	Transform {
	translation 6.0 2.0 0.0
			children[
					Shape {
				    		geometry Text {
				        		string [ "this is transformed 2",
									"(relative to transformed 1)" ]
	    						}
						}
		]
	}
  ]
}

The Transform nodes can contain any type of geometrical description in their children nodes: for example (as we already mentioned) viewpoints can be subject to transformations. In the following(recalling) example the default view("view all") is placed outside any transformations, and four "front" views are created for each primitives by placing the same viewpoint nodes in the different transform-children nodes:

Show the viewport translation example
#VRML V2.0 utf8
#the 4 primitive shapes

Viewpoint {
         position    0 0 10
         orientation 0 0 1 0
         description "view all"
     }

Transform {
translation -3.0 0.0 0.0 #the translation in X Y Z directions
	children[
Viewpoint {
         position    0 0 3
         orientation 0 0 1 0
         description "box"
     }
		Shape{
		appearance Appearance{
			material Material { }
				}
		geometry Box{
			####	X   Y   Z
			size 1.0 1.5 2.0 #the X,Y,Z dimensions of the box in units
				}
			}
		]
	}

Transform {
translation -1.0 0.0 0.0 #the translation in X Y Z directions
	children[
Viewpoint {
         position    0 0 3
         orientation 0 0 1 0
         description "cone"
     }
		Shape{
		appearance Appearance{
			material Material { }
				}
		geometry Cone{
			bottomRadius 1 #bottomradius in units
			height       1 #height in units
			side         TRUE #TRUE or FALSE determines the existence of the sides
			bottom       TRUE #TRUE or FALSE determines the existence of the bottom-cap
				}
			}
		]
	}

Transform {
translation 1.0 0.0 0.0 #the translation in X Y Z directions
	children[
Viewpoint {
        position    0 0 3
         orientation 0 0 1 0
         description "Cylinder"
     }
		Shape{
		appearance Appearance{
			material Material { }
				}
		geometry Cylinder {
			bottom  TRUE #TRUE or FALSE determines the existence of the bottom-cap
        		height 1.0 #height in units
        		radius 1.0 #radius in units
			side    TRUE #TRUE or FALSE determines the existence of the sides
			top     TRUE #TRUE or FALSE determines the existence of the top-cap    				}
				}
			}
		]
	}

Transform {
translation 3.0 0.0 0.0 #the translation in X Y Z directions
	children[
Viewpoint {
         position    0 0 3
         orientation 0 0 1 0
         description "Sphere"
     }
		Shape{
		appearance Appearance{
			material Material { }
				}
		geometry Sphere {
			radius  1  #radius in units  				}
			}
		]
	}

3.2.4 The billboard group

The Billboard group node creates a group with a special coordinate system, providing the possibility to turn it to face viewer(the Billboard node's local Z-axis turns to point at the viewer). The axisOfRotation axis defines a pole to rotate around similarly to a Transform node's rotation field, but without angle: the angle is auto computed to always face the children to the camera.

Billboard {

              axisOfRotation . . .

              children [ . . . ]

          }

In the following example two text-shapes are placed in two different billboard group: one is with the "axisOfRotation 0 1 0" trying to follow you around the Y axis, and another with the "axisOfRotation 1 0 0" trying to follow you around the X axis. The example contains the file illustrating the axes, and the six viewpoints by inlineing the "views.wrl" file. Examine the content using the viewpoints and by "flying" around the objects to see how the two "billboard-texts" are following your movements.

Show the billboards example
#VRML V2.0 utf8
#Example billboard groups

####the inlined file contains the coordinate-system and viewpoints
Inline {url "views.wrl" }
####this billboard 
Billboard {
axisOfRotation 0 1 0 #will turn around the Y axis
children [
		Shape{
		geometry Text{
			string [ "around Y" ]
				}
			}
		]
	}
  ]
}

Billboard {
axisOfRotation 1 0 0 #will turn around the X axis
children [	
	Transform {
	translation -4.0 0.0 0.0 #the translation in X Y Z directions
	children[
		Shape{
		geometry Text{
			string [ "around X" ]
				}
		]
	}
  ]
}

3.3 Inlining worlds

You already saw inline-nodes in the previous example although we used them to simplify the examples, it is obviously an important tool to build sophisticated worlds by combining files to build larger components. The Inline node creates a special group, its children are read from a VRML file selected by a URL.

Inline {

	url "coords.wrl"

}
See one of the first examples, showing a cylinder with the coordinate-system(note that inlined files are always loaded later to the browser):

Show the cylinder in coordinate-system
#VRML V2.0 utf8

Inline { url "coords.wrl" }

Shape {
    appearance Appearance {
        material Material { }
    }
    geometry Cylinder {
        height 2.0
        radius 1.5
    }
}

3.4 Adding anchors

Any shape or group of shapes can be an anchor. Selecting the anchor jumps to a new VRML world or Web-page: it works exactly the same way like the <a href="page.html"> syntax of HTML. The anchor node is a grouping node: selecting any of the child jumps to the new location specified in the "url" field. The content of the description field is displayed in the statusline of the browser (or in the world besides the objects: it can vary from browser to browser) when the user moves the mouse over the children shapes of the anchor node to give a hint on the linked location. The parameter field can be used to specify additional parameters to send in the http-request: for instance the target-frame to which the document shoud be loaded.

Anchor {

              url "otherworld.wrl"

              description "Click on me to jump to a new world"

		  parameter [ "target=name_of_frame" ]

              children [ . . . ]

          }

In the following example a simple box is the anchor to jump into one of the first example-worlds, which contains one cylinder:

Show the box with an anchor
#VRML V2.0 utf8

Anchor {
url "2trcyl1.wrl"
description "Click on me to jump to a new world"
children [ 
		Shape {
			geometry Box { }
		}
	]
}

Besides referring to other worlds, you can provide links to viewpoins contained in the same or in other VRML worlds. See the next example:

Show the linking to viewpoints example
#VRML V2.0 utf8

Viewpoint {
         position    0 0 15
         orientation 0 0 1 0
         description "front"
     }
Viewpoint {
         position    0 15 0
         orientation 1 0 0 -1.57
         description "top"
     }

Transform {
translation 0 -2 0
children [
	Shape {
		geometry Text {
			string "click on the cylinder to view it from the top"
			fontStyle FontStyle{ justify "MIDDLE"}
			}
		}
	]
}

Anchor {
url "#top"
description "Click on me to see the Cone from top"
children [
		Shape {
			appearance Appearance{
			material Material { }
				}
			geometry Cone { }
		}
	]
}