VRML Scripting

In order to determine what the result of an event should be, we need some kind of decision logic and state management. In VRML this is provided via a scripting mechanism.

The most widely supported VRML scripting languages are JavaScript and Java.

Scripts are expressed in Script nodes which received events from nodes, process them, and can send events to other nodes.

Scripts receive events in timestamp order and any events resulting from the execution of a script are given timestamps corresponding to the events that generated them (ie, conceptually a script takes no time to run).

JavaScript and Java scripts can define an initialise() method which is called before any events are generated (and can also be used to generate geometry, for example). it is also possible to define a shutdown() method which can be used for clean up operations (e.g. closing a network connection)

For example:

DEF MyNode Transform {}

DEF MyScript Script {
  eventIn  SFVec3f position
  eventOut SFVec3f newPosition
  url "javascript:
    function position(value, timestamp) {
       newPosition = value;
    }"
}

ROUTE MyScript.newPosition TO MyNode.set_translation

Note that the script is specified in a url field. JavaScript scripts (or Java scripts) can be placed in files referenced by the url instead, if that is more appropriate.

The script can access field and events in the Script node and in other nodes direcly if the Script nodes directOutput field is set to true. This is often more elegant than using ROUTEs to direct events from a script, but is not useful in all cases.

For example:

DEF MyNode Transform {}

Script {
  field SFNode theNode USE MyNode
  eventIn SFVec3f position
  directOutput TRUE
  url "javascript:
    function position(value, timestamp) {
       theNode.set_translation = value;
    }"
}

The Browser Script interface, e.g. JSAI (JavaScript Application Interface) provides a set of methods that can be used to get information from the browser. Methods available include getCurrentSpeed(), getWorldURL(), loadURL(), createVrmlFromString, ...

Example

Below is a slightly more interesting example than the small examples above. Here we have a sensor that toggles the material of a shape on and off using a Script to handle the logic. In this case we adjust the emissiveColor of the shape, as we would perhaps do for turning on and off a virtual lightbulb.

Bear in mind that a script node can have several eventIn and eventOut fields and that the function can be arbitrarily complex so this is a very powerful mechanism. While it is possible to do a great deal using JavaScript in this way, using Java offers many additional possibilities, such as accessing remote network services in a script.

#VRML V2.0 utf8
Group {
  children [
    NavigationInfo {
      type      "EXAMINE"
      headlight TRUE
    }
    DEF TheShape Shape {
      appearance Appearance {
        material DEF TheShapeMaterial Material {
          emissiveColor     .1 .1 .1
          diffuseColor .2 .2 .2
        }
      }
      geometry Sphere {
        radius 1
      }
    }
    DEF TheToggle TouchSensor {}

    DEF SwitchMaterial Script {

        eventIn  SFTime touched
        field    SFBool isOn FALSE
        field    SFColor glowing .8 .7 .5
        field    SFColor dull .1 .1 .1
        eventOut SFColor material
        url "javascript:
        function touched(value, timestamp) {
            if (isOn == false) {
                isOn = true;
                material = glowing;
            } else {
                isOn = false;
                material = dull;
            }
        }"

    }
  ]
}

ROUTE TheToggle.touchTime_changed TO SwitchMaterial.touched
ROUTE SwitchMaterial.material TO TheShapeMaterial.set_emissiveColor

View the example




Michael Louka, October 10, 2001