The Annotated VRML 97 Reference

1 Intro     Concepts     3 Nodes     4 Fields/Events    Conformance
A Grammar     B Java     C JavaScript     D Examples     E Related Info    References
Quick Java         Quick JavaScript         Quick Nodes   
 

  About the Book
  
Help
  Copyright © 1997-99
  Purchase the book from Amazon.com


Chapter 2
Key Concepts

2.1 Intro

2.1.1 Overview
2.1.2 TOC
2.1.3 Conventions

2.2 Overview
2.2.1 File Structure
2.2.2 Header
2.2.3 Scene graph
2.2.4 Prototypes
2.2.5 Routing
2.2.6 Generating files
2.2.7 Presentation
     Interaction
2.2.8 Profiles

2.3 UTF-8 syntax
2.3.1 Clear text
2.3.2 Statements
2.3.3 Node
2.3.4 Field
2.3.5 PROTO
2.3.6 IS
2.3.7 EXTERNPROTO
2.3.8 USE
2.3.9 ROUTE

2.4 Scene graph
2.4.1 Root nodes
2.4.2 Hierarchy
2.4.3 Descendants
       & ancestors
2.4.4 Hierarchy
2.4.5 Units coord sys

2.5 VRML & WWW
2.5.1 MIME type
2.5.2 URLs
2.5.3 Relative URLs
2.5.4 data:
2.5.5 Scripting protocols
2.5.6 URNs

2.6 Nodes
2.6.1 Intro
2.6.2 DEF/USE
2.6.3 Geometry
2.6.4 Bboxes
2.6.5 Grouping & children
2.6.6 Lights
2.6.7 Sensors
2.6.8 Interpolators
2.6.9 Time nodes
2.6.10 Bindable children
2.6.11 Textures

2.7 Field, eventIn,
     eventOut

2.8 PROTO
2.8.1 Declaration
2.8.2 Definition
2.8.3 Scoping

2.9 EXTERNPROTO
2.9.1  Interface
2.9.2  URL
2.9.3 Extensions

2.10 Events
2.10.1 Intro
2.10.2 Routes
2.10.3 Execution
2.10.4 Loops
2.10.5 Fan-in & fan-out

2.11 Time
2.11.1 Intro
2.11.2 Origin
2.11.3 Discrete/cont

2.12 Scripting
2.12.1 Intro
2.12.2 Execution
2.12.3 Initialize/shutdown
2.12.4 eventsProcessed
2.12.5 Direct outputs
2.12.6 Asynchronous
2.12.7 Languages
2.12.8 EventIns
2.12.9 fields events
2.12.10 Browser interface

2.13 Navigation
2.13.1 Intro
2.13.2 Navigation
2.13.3 Viewing
2.13.4 Collisions

2.14 Lighting
2.14.1 Intro
2.14.2 'off'
2.14.3 'on'
2.14.4 Equations
2.14.5 References

+ 2.8 Prototype semantics

The PROTO statement defines a new node type in terms of already defined (built-in or prototyped) node types. Once defined, prototyped node types may be instantiated in the scene graph exactly like the built-in node types.

Node type names must be unique in each VRML file. Defining a prototype with the same name as a previously defined prototype or a built-in node type is an error.

TECHNICAL NOTE: Prototypes have many possible uses and can be thought of as:
  • An extensibility mechanism that allows a new node type to be defined in terms of other, predefined nodes. Prototypes replace the VRML 1.0 extension features (isA and fields[]) with a single, more general mechanism.
  • A protection mechanism that allows an author to limit what can be done to an object. The only way to violate the interface defined by a prototype is to make a copy of its implementation and modify the copy.
  • A method of defining a library of reusable objects
  • An object-definition mechanism that allows someone to impose application--specific policies on top of the general VRML scene structure
  • A convenience mechanism that allows geometry and/or behavior to be packaged in an easy-to-use way
  • An optimization mechanism that allows browsers to reason about which objects can and cannot be changed
  • A bandwidth-saving mechanism that allows the definition of a world structure to be defined once and reused multiple times, and allows the creation of abbreviations for commonly used nodes
  • An alternative to DEF/USE instancing

Prototypes give VRML 2.0 much of its flexibility. Many arguments about the details of the VRML design were ended by pointing out that the feature in question can be implemented using the prototyping mechanism and the built-in nodes.

The prototype interface defines the fields, eventIns, and eventOuts for the new node type. The interface declaration includes the types and names for the eventIns and eventOuts of the prototype, as well as the types, names, and default values for the prototype's fields.

The interface declaration may contain exposedField declarations, which are a convenient way of defining an eventIn, field, and eventOut at the same time. If an exposedField named zzz is declared, it is equivalent to declaring a field named zzz, an eventIn named set_zzz, and an eventOut named zzz_changed.

Each prototype instance can be considered to be a complete copy of the prototype, with its own fields, events, and copy of the prototype definition. A prototyped node type is instantiated using standard node syntax. For example, the following prototype (which has an empty interface declaration):

    PROTO Cube [ ] { Box { } }

may be instantiated as follows:

    Shape { geometry Cube { } }

It is recommended that user-defined field or event names defined in PROTO interface declarations statements follow the naming conventions described in "2.7 Fields, eventIns, and eventOuts semantics."

TECHNICAL NOTE: The prototype declaration defines its interface--how the prototype communicates with the rest of the scene and what parameters may be set for each instance of the prototype.

TECHNICAL NOTE: VRML's prototyping mechanism is not equivalent to the object-oriented notion of inheritance. Object-oriented notions such as superclass and subclass are consciously kept out of the VRML specification, although many of the node classes are designed to make an object-oriented implementation straightforward. For example, the Transform node can be implemented as a subclass of the Group node, and all of the interpolator nodes can share much of their code in a common base class. Anticipating implementation needs but not requiring any particular implementation was another of the many design constraints on VRML. Because the second and subsequent root nodes in a PROTO definition are not part of the scene's transformation hierarchy, only the following node types should be used there: Script, TimeSensor, and interpolators. Using any of the other node types as the second or subsequent root of a PROTO is never useful, but is not prohibited because there were no compelling reasons to do so.

2.8.2 PROTO definition semantics

A prototype definition consists of one or more root nodes, nested PROTO statements, and ROUTE statements. The first node found in the prototype definition is used to define the node type of this prototype. This first node type determines how instantiations of the prototype can be used in a VRML file. An instantiation is created by filling in the parameters of the prototype declaration and inserting copies of the first node (and its scene graph) wherever the prototype instantiation occurs. For example, if the first node in the prototype definition is a Material node, instantiations of the prototype can be used wherever a Material can be used. Any other nodes and accompanying scene graphs are not part of the transformation hierarchy, but may be referenced by ROUTE statements or Script nodes in the prototype definition.

TECHNICAL NOTE: The prototype definition is the implementation of the prototype, defining exactly what the prototype does in terms of other prototypes and built-in node

Nodes in the prototype definition may have their fields, eventIns, or eventOuts associated with the fields, eventIns, and eventOuts of the prototype interface declaration. This is accomplished using IS statements in the body of the node. When prototype instances are read from a VRML file, field values for the fields of the prototype interface may be given. If given, the field values are used for all nodes in the prototype definition that have IS statements for those fields. Similarly, when a prototype instance is sent an event, the event is delivered to all nodes that have IS statements for that event. When a node in a prototype instance generates an event that has an IS statement, the event is sent to any eventIns connected (via ROUTE) to the prototype instance's eventOut.

IS statements may appear inside the prototype definition wherever fields may appear. IS statements shall refer to fields or events defined in the prototype declaration. It is an error for an IS statement to refer to a non-existent declaration. It is an error if the type of the field or event being associated does not match the type declared in the prototype's interface declaration. For example, it is illegal to associate an SFColor with an SFVec3f. It is also illegal to associate an SFColor with an MFColor or vice versa.

It is illegal for an eventIn to be associated with a field or an eventOut, an eventOut to be associated with a field or eventIn, or a field to be associated with an eventIn or eventOut. An exposedField in the prototype interface may be associated only with an exposedField in the prototype definition, but an exposedField in the prototype definition may be associated with either a field, eventIn, eventOut or exposedField in the prototype interface. When associating an exposedField in a prototype definition with an eventIn or eventOut in the prototype declaration, it is valid to use either the shorthand exposedField name (e.g., translation) or the explicit event name (e.g., set_translation or translation_changed). Table 2-4 defines the rules for mapping between the prototype declarations and the primary scene graph's nodes (yes denotes a legal mapping, no denotes an error).

Table 2-4: Rules for mapping PROTOTYPE declarations to node instances

                  Prototype declaration

Prototype

scene

graph
exposedField field eventIn eventOut
exposedField yes yes yes yes
field no yes no no
eventIn no no yes no
eventOut no no no yes

Results are undefined if a field, eventIn, or eventOut of a node in the prototype definition is associated with more than one field, eventIn, or eventOut in the prototype's interface (i.e., multiple IS statements for a field/eventIn/eventOut in a node in the prototype definition), but multiple IS statements for the fields/eventIns/eventOuts in the prototype interface declaration is valid. Results are undefined if a field of a node in a prototype definition is both defined with initial values (i.e., field statement) and associated by an IS statement with a field in the prototype's interface. If a prototype instance has an eventOut E associated with multiple eventOuts in the prototype definition ED i , the value of E is the value of the eventOut that generated the event with the greatest timestamp. If two or more of the eventOuts generated events with identical timestamps, results are undefined.

TECHNICAL NOTE: ExposedFields are really just a shorthand notation for the combination of an eventIn, an eventOut, and a field, along with the semantics that eventOuts are generated whenever eventIns are received. Allowing the eventIn portion of an exposedField to be referred to without its set_ prefix and the eventOut portion without its _changed suffix makes it easier to create VRML files in a text editor, but makes both the specification and implementations a little more complicated.

TECHNICAL NOTE: Allowing multiple eventIns to be mapped to the same prototype parameter is a convenient way to do ROUTE fan-out transparently. For example, you might want a prototype that starts several TimeSensors when it receives a set_startTime eventIn:
        PROTO Animations [ eventIn SFTime set_startTime ] { 
          DEF ANIM1 TimeSensor { 
            set_startTime IS set_startTime 
            cycleInterval 4.5 
          } 
          DEF ANIM2 TimeSensor { 
            set_startTime IS set_startTime 
            cycleInterval 11.3 
          } 
        } 

Instantiating and ROUTE-ing to an Animations object, like this:

        DEF ANIMS Animations { } 
        DEF SENSOR TouchSensor { } 
        ROUTE SENSOR.touchTime TO ANIMS.set_startTime 

is equivalent to doing this:

        DEF ANIM1 TimeSensor { cycleInterval 4.5 } 
        DEF ANIM2 TimeSensor { cycleInterval 11.3} 
        DEF SENSOR TouchSensor { } 
        ROUTE SENSOR.touchTime TO ANIM1.set_startTime 
        ROUTE SENSOR.touchTime TO ANIM2.set_startTime 

Similarly, allowing multiple eventOuts to be mapped to the same prototype parameter allows implicit fan-in and, like regular ROUTE fan-in, care must be taken to ensure that indeterministic situations are not created. For example, events from this PROTO's out eventOut are undefined:

        PROTO BAD [ 
          eventIn SFTime set_startTime 
          eventOut SFFloat out ] 
        { 
          DEF ANIM1 TimeSensor { 
            set_startTime IS set_startTime 
            cycleInterval 4.5 
            fraction_changed IS out 
          } 
          DEF ANIM2 TimeSensor { 
            set_startTime IS set_startTime 
            cycleInterval 11.3 
            fraction_changed IS out 
          } 
        } 

Although legal syntactically, such a construction makes no sense semantically. In general, it is best to avoid associating multiple eventOuts with a single prototype parameter.


2.8.3 Prototype scoping rules

Prototype definitions appearing inside a prototype definition (i.e., nested) are local to the enclosing prototype. IS statements inside a nested prototype's implementation may refer to the prototype declarations of the innermost prototype.

A PROTO statement establishes a DEF/USE name scope separate from the rest of the scene and separate from any nested PROTO statements. Nodes given a name by a DEF construct inside the prototype may not be referenced in a USE construct outside of the prototype's scope. Nodes given a name by a DEF construct outside the prototype scope may not be referenced in a USE construct inside the prototype scope.

A prototype may be instantiated in a file anywhere after the completion of the prototype definition. A prototype may not be instantiated inside its own implementation (i.e., recursive prototypes are illegal).

TECHNICAL NOTE: A PROTO definition is almost like a completely separate VRML file inside the VRML file. The only communication between the main file and the nodes in the PROTO definition must occur through the parameters defined in the prototype declaration, which is why it is not possible to DEF a node in the main file and USE it inside the prototype's definition or vice versa. However, prototypes can be defined in terms of other prototypes. PROTOs defined before the PROTO definition may be used inside the PROTO's definition, although the converse is not true (PROTOs defined inside a prototype definition are not available outside of that definition).

TECHNICAL NOTE: Like ROUTE statements, the position of a PROTO definition in a file is irrelevant; the only constraint is that the PROTO appear in the file before any instance of the prototype. Tools that read and write VRML files will typically put all PROTO definitions at the top of the file.

TECHNICAL NOTE: Each prototype instance is, conceptually, a completely new copy of the prototype's definition inserted into the scene. Each instance of a prototype must act independently of any other instance. The USE keyword, on the other hand, inserts the same object into the scene again. If it weren't for this key difference, PROTO could replace the USE statement. The following DEF/USE statements:

        DEF Something Transform { ... } 
        USE Something 

are almost equivalent to the following:

        PROTO Something [ ] { Transform { ... } } 
        Something { } 
        Something { } 

The first two statements define and create a Something node, very much like the previous DEF statement. And, instantiating another Something node is very much like the USE statement. The key difference is that in the first example there is only one Transform node, while in the second example there are two different nodes.

Smart implementations can determine which parts of a prototype instance can't possibly change and can automatically share those parts of the prototype definition between instances. For example, the Transform node of the Something prototype can never change because none of its eventIns are exposed in the prototype's interface, and Transform is not given a name so there cannot be any ROUTE statements inside the prototype that refer to it. If none of Transform's children can change either, then implementations can create just one Transform node to save memory. In VRML, there is no way to tell the difference between two copies of a node if the copies are identical and cannot change, which allows implementations to optimize and create just one copy.