
   
   
                     THE VIRTUAL REALITY MODELING LANGUAGE
                                       
Version 1.0 Specification (Draft)

     Gavin Bell, Silicon Graphics, Inc.
     Anthony Parisi, Labyrinth Group
     Mark Pesce, Enterprise Integration Technologies, Inc.
     
   
   
   
     _________________________________________________________________
   
   
   
  ACKNOWLEDGEMENTS
  
     I want to thank three people who have been absolutely instrumental
     in the design process: Brian Behlendorf, whose drive (and disk
     space) made this process happen; and Tony Parisi and Gavin Bell, the
     final authors of this specification, who have put in a great deal of
     design work, ensuring that we have a satisfactory product. My hat
     goes off to all of them, and to all of you who have made this
     process a success.
     
   
   
   Mark Pesce
   
  TABLE OF CONTENTS
     * Introduction
       
          + VRML Mission Statement
          + History
          + Version 1.0 Requirements
   
       
     * Language Specification
       
          + Language Basics
          + Fields
          + Nodes
          + Instancing
          + Extensibility
          + An Example
   
       
     * Browser Considerations
       
          + File Extensions
          + MIME Types
            
   
   
   
     _________________________________________________________________
   
   
   
                                INTRODUCTION
                                       
   The Virtual Reality Modeling Language (VRML) is a language for
   describing multi-participant interactive simulations -- virtual worlds
   networked via the global Internet and hyperlinked with the World Wide
   Web. All aspects of virtual world display, interaction and
   internetworking can be specified using VRML. It is the intention of
   its designers that VRML become the standard language for interactive
   simulation within the World Wide Web.
   
   The first version of VRML allows for the creation of virtual worlds
   with limited interactive behavior. These worlds can contain objects
   which have hyperlinks to other worlds, HTML documents or other valid
   MIME types. When the user selects an object with a hyperlink, the
   appropriate MIME viewer is launched. When the user selects a link to a
   VRML document from within a correctly configured WWW browser, a VRML
   viewer is launched. Thus VRML viewers are the perfect companion
   applications to standard WWW browsers for navigating and visualizing
   the Web. Future versions of VRML will allow for richer behaviors,
   including animations, motion physics and real-time multi-user
   interaction.
   
   This document specifies the features and syntax of Version 1.0 of
   VRML.
   
VRML Mission Statement

   The history of the development of the Internet has had three distinct
   phases; first, the development of the TCP/IP infrastructure which
   allowed documents and data to be stored in a proximally independent
   way; that is, Internet provided a layer of abstraction between data
   sets and the hosts which manipulated them. While this abstraction was
   useful, it was also confusing; without any clear sense of "what went
   where", access to Internet was restricted to the class of sysops/net
   surfers who could maintain internal cognitive maps of the data space.
   
   Next, Tim Berners-Lee's work at CERN, where he developed the
   hypermedia system known as World Wide Web, added another layer of
   abstraction to the existing structure. This abstraction provided an
   "addressing" scheme, a unique identifier (the Universal Resource
   Locator), which could tell anyone "where to go and how to get there"
   for any piece of data within the Web. While useful, it lacked
   dimensionality; there's no there there within the web, and the only
   type of navigation permissible (other than surfing) is by direct
   reference. In other words, I can only tell you how to get to the VRML
   Forum home page by saying, "http://www.wired.com/", which is not
   human-centered data. In fact, I need to make an effort to remember it
   at all. So, while the World Wide Web provides a retreival mechanism to
   complement the existing storage mechanism, it leaves a lot to be
   desired, particularly for human beings.
   
   Finally, we move to "perceptualized" Internetworks, where the data has
   been sensualized, that is, rendered sensually. If something is
   represented sensually, it is possible to make sense of it. VRML is an
   attempt (how successful, only time and effort will tell) to place
   humans at the center of the Internet, ordering its universe to our
   whims. In order to do that, the most important single element is a
   standard that defines the particularities of perception. Virtual
   Reality Modeling Language is that standard, designed to be a universal
   description language for multi-participant simulations.
   
   These three phases, storage, retrieval, and perceptualization are
   analogous to the human process of consciousness, as expressed in terms
   of semantics and cognitive science. Events occur and are recorded
   (memory); inferences are drawn from memory (associations), and from
   sets of related events, maps of the universe are created (cognitive
   perception). What is important to remember is that the map is not the
   territory, and we should avoid becoming trapped in any single
   representation or world-view. Although we need to design to avoid
   disorientation, we should always push the envelope in the kinds of
   experience we can bring into manifestation!
   
   This document is the living proof of the success of a process that was
   committed to being open and flexible, responsive to the needs of a
   growing Web community. Rather than re-invent the wheel, we have
   adapted an existing specification (Open Inventor) as the basis from
   which our own work can grow, saving years of design work and perhaps
   many mistakes. Now our real work can begin; that of rendering our
   noospheric space.
   
History

   VRML was conceived in the spring of 1994 at the first annual World
   Wide Web Conference in Geneva, Switzerland. Tim Berners-Lee and Dave
   Raggett organized a Birds-of-a-Feather (BOF) session to discuss
   Virtual Reality interfaces to the World Wide Web. Several BOF
   attendees described projects already underway to build three
   dimensional graphical visualization tools which interoperate with the
   Web. Attendees agreed on the need for these tools to have a common
   language for specifying 3D scene description and WWW hyperlinks -- an
   analog of HTML for virtual reality. The term Virtual Reality Markup
   Language (VRML) was coined, and the group resolved to begin
   specification work after the conference. The word 'Markup' was later
   changed to 'Modeling' to reflect the graphical nature of VRML.
   
   Shortly after the Geneva BOF session, the www-vrml mailing list was
   created to discuss the development of a specification for the first
   version of VRML. The response to the list invitation was overwhelming:
   within a week, there were over a thousand members. After an initial
   settling-in period, list moderator Mark Pesce of Labyrinth Group
   announced his intention to have a draft version of the specification
   ready by the WWW Fall 1994 conference, a mere five months away. There
   was general agreement on the list that, while this schedule was
   aggressive, it was acheivable provided that the requirements for the
   first version were not too ambitious and that VRML could be adapted
   from an existing solution. The list quickly agreed upon a set of
   requirements for the first version, and began a search for
   technologies which could be adapted to fit the needs of VRML.
   
   The search for existing technologies turned up a several worthwhile
   candidates. After much deliberation the list came to a consensus: the
   Open Inventor ASCII File Format from Silicon Graphics, Inc. The
   Inventor File Format supports complete descriptions of 3D scenes with
   polygonally rendered objects, lighting, materials, ambient properties
   and realism effects. A subset of the Inventor File Format, with
   extensions to support networking, forms the basis of VRML. Gavin Bell
   of Silicon Graphics has adapted the Inventor File Format for VRML,
   with design input from the mailing list. SGI has publicly stated that
   the file format is available for use in the open market, and have
   contributed a file format parser into the public domain to bootstrap
   VRML viewer development.
   
Version 1.0 Requirements

   VRML 1.0 is designed to meet the following requirements:
   
     * Platform independence
     * Extensibility
     * Ability to work well over low-bandwidth connections
       
   
   
   As with HTML, the above are absolute requirements for a network
   language standard; they should need little explanation here.
   
   Early on the designers decided that VRML would not be an extension to
   HTML. HTML is designed for text, not graphics. Also, VRML requires
   even more finely tuned network optimizations than HTML; it is expected
   that a typical VRML scene will be composed of many more "inline"
   objects and served up by many more servers than a typical HTML
   document. Moreover, HTML is an accepted standard, with existing
   implementations that depend on it. To impede the HTML design process
   with VRML issues and straightjacket the VRML design process with HTML
   compatibility concerns would be to do both languages a disservice. As
   a network language, VRML will succeed or fail independent of HTML.
   
   It was also decided that, except for the hyperlinking feature, the
   first version of VRML would not support interactive behaviors. This
   was a practical decision intended to streamline design and
   implementation. Design of a language for describing interactive
   behaviors is a big job, especially when the language needs to express
   behaviors of objects communicating on a network. Such languages do
   exist; if we had chosen one of them, we would have risked getting into
   a "language war." People don't get exicited about the syntax of a
   language for describing polygonal objects; people get very excited
   about the syntax of real languages for writing programs. Religious
   wars can extend the design process by months or years. In addition,
   networked inter-object operation requires brokering services such as
   those provided by CORBA or OLE, services which don't exist yet within
   WWW; we would have had to invent them. Finally, by keeping behaviors
   out of Version 1, we have made it a much smaller task to implement a
   viewer. We acknowledge that support for arbitrary interactive
   behaviors is critical to the long-term success of VRML; they will be
   included in Version 2.
   
   
     _________________________________________________________________
   
   
   
                           LANGUAGE SPECIFICATION
                                       
Language Basics

   At the highest level of abstraction, VRML is just a way for objects to
   read and write themselves. Theoretically, the objects can contain
   anything -- 3D geometry, MIDI data, JPEG images, anything. VRML
   defines a set of objects useful for doing 3D graphics. These objects
   are called Nodes.
   
   Nodes are arranged in hierarchical structures called scene graphs.
   Scene graphs are more than just a collection of nodes; the scene graph
   defines an ordering for the nodes. The scene graph has a notion of
   state -- nodes earlier in the scene can affect nodes that appear
   later in the scene. For example, a Rotation or Material node will
   affect the nodes after it in the scene. A mechanism is defined to
   limit the effects of properties (Separator nodes), allowing parts of
   the scene graph to be functionally isolated from other parts.
   
   A node has the following characteristics:
   
     * What kind of object it is. A node might be a cube, a sphere, a
       texture map, a transformation, etc.
       
     * The parameters that distinguish this node from other nodes of the
       same type. For example, each Sphere node might have a different
       radius, and different texture maps nodes will certainly contain
       different images to use as the texture maps. These parameters are
       called Fields. A node can have 0 or more fields.
       
     * A name to identify this node. Being able to name nodes and refer
       to them elsewhere is very powerful; it allows a scene's author to
       give hints to applications using the scene about what is in the
       scene, and creates possibilities for very powerful scripting
       extensions. Nodes do not have to be named, but if they are named,
       they have only one name.
       
     * Child nodes. Object hierarchy is implemented by allowing nodes to
       contain other nodes. Parent nodes traverse their children in order
       during rendering. Nodes that may have children are referred to as
       group nodes. Group nodes can have zero or more children.
       
   
   
   The syntax chosen to represent these pieces of information is
   straightforward:
   

DEF objectname objecttype { fields  children }

   
   
   Only the object type and curly braces are required; nodes may or may
   not have a name, fields, and children.
   
   Node names must not begin with a digit, and must not contain spaces or
   control characters, single or double quote characters, backslashes,
   curly braces or the plus character.
   
   For example, this file contains a simple scene defining a view of a
   red cone and a blue sphere, lit by a directional light:
   

#VRML V1.0 ascii
Separator {
    DirectionalLight {
        direction 0 0 -1  # Light shining from viewer into scene
    }
    PerspectiveCamera {
        position    -8.6 2.1 5.6
        orientation -0.1352 -0.9831 -0.1233  1.1417
        focalDistance       10.84
    }
    Separator {   # The red sphere
        Material {
            diffuseColor 1 0 0   # Red
        }
        Translation { translation 3 0 1 }
        Sphere { radius 2.3 }
    }
    Separator {  # The blue cube
        Material {
            diffuseColor 0 0 1  # Blue
        }
        Transform {
            translation -2.4 .2 1
            rotation 0 1 1  .9
        }
        Cube {}
    }
}

   
   
  GENERAL SYNTAX
  
   For easy identification of VRML files, every VRML file must begin with
   the characters:
   

#VRML V1.0 ascii

   
   
   Any characters after these on the same line are ignored. The line is
   terminated by either the ASCII newline or carriage-return characters.
   
   The '#' character begins a comment; all characters until the next
   newline or carriage return are ignored. The only exception to this is
   within string fields, where the '#' character will be part of the
   string.
   
   Note: Comments and whitespace may not be preserved; in particular, a
   VRML document server may strip comments and extraneous whitespace from
   a VRML file before transmitting it. Info nodes should be used for
   persistent information like copyrights or author information.
   
   Blanks, tabs, newlines and carriage returns are whitespace characters
   wherever they appear outside of string fields. One or more whitespace
   characters separates the syntactical entities in VRML files, where
   necessary.
   
   After the required header, a VRML file contains exactly one VRML node.
   That node may of course be a group node, containing any number of
   other nodes.
   
Fields

   There are two general classes of fields; fields that contain a single
   value (where a value may be a single number, a vector, or even an
   image), and fields that contain multiple values. Single-valued fields
   all have names that begin with "SF", multiple-valued fields have names
   that begin with "MF". Each field type defines the format for the
   values it writes.
   
   Multiple-valued fields are written as a series of values separated by
   commas, all enclosed in square brackets. If the field has zero values
   then only the square brackets ("[]") are written. The last may
   optionally be followed by a comma. If the field has exactly one value,
   the brackets may be omitted and just the value written. For example,
   all of the following are valid for a multiple-valued field containing
   the single integer value 1:
   

1
[1,]
[ 1 ]

   
   
  SFBITMASK
  
   A single-value field that contains a mask of bit flags. Nodes that use
   this field class define mnemonic names for the bit flags. SoSFBitMasks
   are written to file as one or more mnemonic enumerated type names, in
   this format:
   

( flag1 | flag2 | ... )

   
   
   If only one flag is used in a mask, the parentheses are optional.
   These names differ among uses of this field in various node classes.
   
  SFBOOL
  
   A field containing a single boolean (true or false) value. SFBools may
   be written as 0 (representing FALSE), 1, TRUE, or FALSE.
   
  SFCOLOR
  
   A single-value field containing a color. SFColors are written to file
   as an RGB triple of floating point numbers in standard scientific
   notation, in the range 0.0 to 1.0.
   
  SFENUM
  
   A single-value field that contains an enumerated type value. Nodes
   that use this field class define mnemonic names for the values.
   SFEnums are written to file as a mnemonic enumerated type name. The
   name differs among uses of this field in various node classes.
   
  SFFLOAT
  
   A field that contains one single-precision floating point number.
   SFFloats are written to file in standard scientific notation.
   
  SFLONG
  
   A field containing a single long (32-bit) integer. SoSFLongs are
   written to file as an integer in decimal, hexadecimal (beginning with
   '0x') or octal (beginning with '0') format.
   
  SFMATRIX
  
   A field containing a transformation matrix. SFMatrices are written to
   file in row-major order as 16 floating point numbers separated by
   whitespace. For example, a matrix expressing a translation of 7 units
   along the X axis is written as:
   

1 0 0 0  0 1 0 0  0 0 1 0  7 0 0 1

   
   
  SFROTATION
  
   A field containing an arbitrary rotation. SFRotations are written to
   file as four floating point values separated by whitespace. The 4
   values represent an axis of rotation followed by the amount of
   right-handed rotation about that axis, in radians. For example, a 180
   degree rotation about the Y axis is:
   

0 1 0  3.14159265

   
   
  SFSTRING
  
   A field containing an ASCII string (sequence of characters). SFStrings
   are written to file as a sequence of ASCII characters in double quotes
   (optional if the string doesn't contain any whitespace). Any
   characters (including newlines) may appear within the quotes. To
   include a double quote character within the string, precede it with a
   backslash. For example:
   

Testing
"One, Two, Three"
"He said, \"Immel did it!\""

   
   
   are all valid strings.
   
  SFVEC2F
  
   Field containing a two-dimensional vector. SFVec2fs are written to
   file as a pair of floating point values separated by whitespace.
   
  SFVEC3F
  
   Field containing a three-dimensional vector. SFVec3fs are written to
   file as three floating point values separated by whitespace.
   
  MFCOLOR
  
   A multiple-value field that contains any number of RGB colors.
   MFColors are written to file as one or more RGB triples of floating
   point numbers in standard scientific notation. When more than one
   value is present, all of the values must be enclosed in square
   brackets and separated by commas. For example:
   

[ 1.0 0.0 0.0, 0 1 0, 0 0 1 ]

   
   
   represents the three colors red, green, and blue.
   
  MFLONG
  
   A multiple-value field that contains any number of long (32-bit)
   integers. MFLongs are written to file as one or more integer values,
   in decimal, hexadecimal or octal format. When more than one value is
   present, all the values are enclosed in square brackets and separated
   by commas; for example:
   

[ 17, -0xE20, -518820 ]

   
   
  MFVEC2F
  
   A multiple-value field that contains any number of two-dimensional
   vectors. MFVec2fs are written to file as one or more pairs of floating
   point values separated by whitespace. When more than one value is
   present, all of the values are enclosed in square brackets and
   separated by commas; for example:
   

[ 0 0, 1.2 3.4, 98.6 -4e1 ]

   
   
  MFVEC3F
  
   A multiple-value field that contains any number of three-dimensional
   vectors. MFVec3fs are written to file as one or more triples of
   floating point values separated by whitespace. When more than one
   value is present, all of the values are enclosed in square brackets
   and separated by commas; for example:
   

[ 0 0 0, 1.2 3.4 5.6, 98.6 -4e1 212 ]

   
   
Nodes

   VRML defines several different classes of nodes. Most of the nodes can
   be classified into one of three categories; shape, property or group.
   Shape nodes define the geometry in the scene. Conceptually, they are
   the only nodes that really draw anything. Property nodes affect the
   way shapes are drawn. And grouping nodes gather other nodes together,
   allowing collections of nodes to be treated as a single object.
   Grouping nodes can also control whether or not their children are
   drawn.
   
   Nodes may contain zero or more fields. Each node type defines the
   type, name, and default value for each of its fields. The default
   value for the field is used if a value for the field is not specified
   in the VRML file. The order in which the fields of a node are read is
   not important; for example, "Cube { width 2 height 4 depth 6 }" and
   "Cube { height 4 depth 6 width 2 }" are both valid.
   
  CONE
  
   This node represents a simple cone whose central axis is aligned with
   the y-axis. By default, the cone is centered at (0,0,0) and has a size
   of -1 to +1 in all three directions. The cone has a radius of 1 at the
   bottom and a height of 2, with its apex at 1. The cone has two parts:
   the sides and the bottom.
   
   The cone is transformed by the current cumulative transformation and
   is drawn with the current lighting model, drawing style, material, and
   geometric complexity.
   
   If the current material binding is PER_PART or PER_PART_INDEXED, the
   first current material is used for the sides of the cone, and the
   second is used for the bottom. Otherwise, the first material is used
   for the entire cone.
   
   When a texture is applied to a cone, it is applied differently to the
   sides and bottom. On the sides, the texture wraps counterclockwise
   (from above) starting at the back of the cone. The texture has a
   vertical seam at the back, intersecting the yz-plane. For the bottom,
   a circle is cut out of the texture square and applied to the cone's
   base circle. The texture appears right side up when the top of the
   cone is tilted away from the camera.
   

PARTS
     SIDES       The conical part
     BOTTOM      The bottom circular face
     ALL         All parts

FILE FORMAT/DEFAULTS
     Cone {
          parts         ALL     # SFBitMask
          bottomRadius  1       # SFFloat
          height        2       # SFFloat
     }

   
   
  COORDINATE3
  
   This node defines a set of 3D coordinates to be used by a subsequent
   IndexedFaceSet node. This node does not produce a visible result
   during rendering; it simply replaces the current coordinates in the
   rendering state for subsequent nodes to use.
   

FILE FORMAT/DEFAULTS
     Coordinate3 {
          point  0 0 0  # MFVec3f
     }

   
   
  CUBE
  
   This node represents a cuboid aligned with the coordinate axes. By
   default, the cube is centered at (0,0,0) and measures 2 units in each
   dimension, from -1 to +1. The cube is transformed by the current
   cumulative transformation and is drawn with the current lighting
   model, drawing style, material, and geometric complexity.
   
   If the current material binding is PER_PART, PER_PART_INDEXED,
   PER_FACE, or PER_FACE_INDEXED, materials will be bound to the faces of
   the cube in this order: front, back, left, right, top, and bottom.
   
   Textures are applied individually to each face of the cube; the entire
   texture goes on each face. On the front, back, right, and left sides
   of the cube, the texture is applied right side up. On the top, the
   texture appears right side up when the top of the cube is tilted
   toward the camera. On the bottom, the texture appears right side up
   when the top of the cube is tilted away from the camera.
   

FILE FORMAT/DEFAULTS
     Cube {
          width   2     # SFFloat
          height  2     # SFFloat
          depth   2     # SFFloat
     }

   
   
  CYLINDER
  
   This node represents a simple capped cylinder centered around the
   y-axis. By default, the cylinder is centered at (0,0,0) and has a
   default size of -1 to +1 in all three dimensions. You can use the
   radius and height fields to create a cylinder with a different size.
   
   The cylinder is transformed by the current cumulative transformation
   and is drawn with the current lighting model, drawing style, material,
   and geometric complexity.
   
   If the current material binding is PER_PART or PER_PART_INDEXED, the
   first current material is used for the sides of the cylinder, the
   second is used for the top, and the third is used for the bottom.
   Otherwise, the first material is used for the entire cylinder.
   
   When a texture is applied to a cylinder, it is applied differently to
   the sides, top, and bottom. On the sides, the texture wraps
   counterclockwise (from above) starting at the back of the cylinder.
   The texture has a vertical seam at the back, intersecting the
   yz-plane. For the top and bottom, a circle is cut out of the texture
   square and applied to the top or bottom circle. The top texture
   appears right side up when the top of the cylinder is tilted toward
   the camera, and the bottom texture appears right side up when the top
   of the cylinder is tilted away from the camera.
   

PARTS
     SIDES   The cylindrical part
     TOP     The top circular face
     BOTTOM  The bottom circular face
     ALL     All parts

FILE FORMAT/DEFAULTS
     Cylinder {
          parts   ALL   # SFBitMask
          radius  1     # SFFloat
          height  2     # SFFloat
     }

   
   
  DIRECTIONALLIGHT
  
   This node defines a directional light source that illuminates along
   rays parallel to a given 3-dimensional vector.
   
   A light node defines an illumination source that may affect subsequent
   shapes in the scene graph, depending on the current lighting style.
   Light sources are affected by the current transformation. A light node
   under a separator does not affect any objects outside that separator.
   

FILE FORMAT/DEFAULTS
     DirectionalLight {
          on         TRUE       # SFBool
          intensity  1          # SFFloat
          color      1 1 1      # SFColor
          direction  0 0 -1     # SFVec3f
     }

   
   
  GROUP
  
   This node defines the base class for all group nodes. Group is a node
   that contains an ordered list of child nodes. The ordering of the
   child nodes represents the traversal order for all operations (for
   example, rendering, picking, and so on). This node is simply a
   container for the child nodes and does not alter the traversal state
   in any way. During traversal, state accumulated for a child is passed
   on to each successive child and then to the parents of the group
   (Group does not push or pop traversal state as Separator does).
   

FILE FORMAT/DEFAULTS
     Group {
     }

   
   
  INDEXEDFACESET
  
   This node represents a 3D shape formed by constructing faces
   (polygons) from vertices located at the current coordinates.
   IndexedFaceSet uses the indices in the coordIndex field (from
   IndexedShape) to specify the polygonal faces. An index of -1 indicates
   that the current face has ended and the next one begins.
   
   The vertices of the faces are transformed by the current
   transformation matrix.
   
   Treatment of the current material and normal binding is as follows:
   The PER_PART and PER_FACE bindings specify a material or normal for
   each face. PER_VERTEX specifies a material or normal for each vertex.
   The corresponding _INDEXED bindings are the same, but use the
   materialIndex or normalIndex indices (see IndexedShape) The DEFAULT
   material binding is equal to OVERALL. The DEFAULT normal binding is
   equal to PER_VERTEX_INDEXED; if insufficient normals exist in the
   state, vertex normals will be generated automatically.
   
   Explicit texture coordinates (as defined by TextureCoordinate2) may be
   bound to vertices of an indexed shape consecutively (if the texture
   coordinate binding is PER_VERTEX) or by using the indices in the
   textureCoordIndex field (if the binding is PER_VERTEX_INDEXED). As
   with all vertex-based shapes, if there is a current texture but no
   texture coordinates are specified, a default texture coordinate
   mapping is calculated using the bounding box of the shape. The longest
   dimension of the bounding box defines the S coordinates, and the next
   longest defines the T coordinates. The value of the S coordinate
   ranges from 0 to 1, from one end of the bounding box to the other. The
   T coordinate ranges between 0 and the ratio of the second greatest
   dimension of the bounding box to the greatest dimension.
   
   Be sure that the indices contained in the coordIndex, materialIndex,
   normalIndex, and textureCoordIndex fields are valid with respect to
   the current state, or errors will occur.
   

FILE FORMAT/DEFAULTS
     IndexedFaceSet {
          coordIndex         0  # MFLong
          materialIndex      -1 # MFLong
          normalIndex        -1 # MFLong
          textureCoordIndex  -1 # MFLong
     }

   
   
  INDEXEDLINESET
  
   This node represents a 3D shape formed by constructing polylines from
   vertices located at the current coordinates. IndexedLineSet uses the
   indices in the coordIndex field (from IndexedShape) to specify the
   polylines. An index of -1 indicates that the current polyline has
   ended and the next one begins.
   
   The coordinates of the line set are transformed by the current
   cumulative transformation.
   
   Treatment of the current material and normal binding is as follows:
   The PER_PART binding specifies a material or normal for each segment
   of the line. The PER_FACE binding specifies a material or normal for
   each polyline. PER_VERTEX specifies a material or normal for each
   vertex. The corresponding _INDEXED bindings are the same, but use the
   materialIndex or normalIndex indices. The DEFAULT material binding is
   equal to OVERALL. The DEFAULT normal binding is equal to
   PER_VERTEX_INDEXED; if insufficient normals exist in the state, the
   lines will be drawn with lighting turned off. The same rules for
   texture coordinate generation as IndexedFaceSet are used.
   

FILE FORMAT/DEFAULTS
     IndexedLineSet {
          coordIndex         0  # MFLong
          materialIndex      -1 # MFLong
          normalIndex        -1 # MFLong
          textureCoordIndex  -1 # MFLong
     }

   
   
  INFO
  
   This class defines a information node in the scene graph. This node
   has no effect during traversal. It is used to store information in the
   scene graph, typically for application-specific purposes, copyright
   messages, or other strings.
   

     Info {
          string  ""    # SFString
     }

   
   
  LEVELOFDETAIL
  
   This group node is used to allow applications to switch between
   various representations of objects automatically. The children of this
   node typically represent the same object or objects at varying levels
   of detail, from highest detail to lowest. The size of the objects when
   projected into the viewport is used to determine which version to use
   (i.e., which child to traverse).
   
   The size is computed as the area of the screen rectangle enclosing the
   projection of the 3D bounding box that encloses all of the children.
   When rendering, this size is compared to the values in the screenArea
   field. If the size is greater than the first value, child 0 is
   traversed. If it is smaller than the first, but greater than the
   second, child 1 is traversed, and so on. If there are fewer children
   than are required by this rule, the last child is traversed. The
   screenArea field contains just 0 by default, so the first child is
   always traversed.
   

FILE FORMAT/DEFAULTS
     LevelOfDetail {
          screenArea  0 # MFFloat
     }

   
   
  MATERIAL
  
   This node defines the current surface material properties for all
   subsequent shapes. Material sets several components of the current
   material during traversal. Different shapes interpret materials with
   multiple values differently. To bind materials to shapes, use an
   MaterialBinding node.
   

FILE FORMAT/DEFAULTS
     Material {
          ambientColor   0.2 0.2 0.2    # MFColor
          diffuseColor   0.8 0.8 0.8    # MFColor
          specularColor  0 0 0          # MFColor
          emissiveColor  0 0 0          # MFColor
          shininess      0.2            # MFFloat
          transparency   0              # MFFloat
     }

  MATERIALBINDING
  
   This node specifies how the current materials are bound to shapes that
   follow in the scene graph. Each shape node may interpret bindings
   differently. The current material always has a base value, which is
   defined by the first value of all material fields. Since material
   fields may have multiple values, the binding determines how these
   values are distributed over a shape.
   
   The bindings for faces and vertices are meaningful only for shapes
   that are made from faces and vertices. Similarly, the indexed bindings
   are only used by the shapes that allow indexing.
   
   When multiple material values are bound, the values are cycled
   through, based on the period of the material component with the most
   values. For example, the following table shows the values used when
   cycling through (or indexing into) a material with 2 ambient colors, 3
   diffuse colors, and 1 of all other components in the current material.
   (The period of this material cycle is 3):
   

Material        Ambient color   Diffuse color   Other
 0                     0               0           0
 1                     1               1           0
 2                     1               2           0
 3 (same as 0)         0               0           0

   
   

BINDINGS
     DEFAULT            Use default binding
     OVERALL            Whole object has same material
     PER_PART           One material for each part of object
     PER_PART_INDEXED   One material for each part, indexed
     PER_FACE           One material for each face of object
     PER_FACE_INDEXED   One material for each face, indexed
     PER_VERTEX         One material for each vertex of object
     PER_VERTEX_INDEXED One material for each vertex, indexed

FILE FORMAT/DEFAULTS
     MaterialBinding {
          value  DEFAULT        # SFEnum
     }

   
   
  MATRIXTRANSFORM
  
   This node defines a geometric 3D transformation with a single
   SbMatrix. Note that some matrices (such as singular ones) may result
   in errors in bounding boxes, picking, and lighting.
   

FILE FORMAT/DEFAULTS
     MatrixTransform {
          matrix  1 0 0 0       # SFMatrix
                  0 1 0 0
                  0 0 1 0
                  0 0 0 1
     }

   
   
  NORMAL
  
   This node defines a set of 3D surface normal vectors to be used by
   vertex-based shape nodes that follow it in the scene graph. This node
   does not produce a visible result during rendering; it simply replaces
   the current normals in the rendering state for subsequent nodes to
   use. This node contains one multiple-valued field that contains the
   normal vectors.
   

FILE FORMAT/DEFAULTS
     Normal {
          vector  0 0 1 # MFVec3f
     }

   
   
  NORMALBINDING
  
   This node specifies how the current normals are bound to shapes that
   follow in the scene graph. Each shape node may interpret bindings
   differently.
   
   The bindings for faces and vertices are meaningful only for shapes
   that are made from faces and vertices. Similarly, the indexed bindings
   are only used by the shapes that allow indexing. For bindings that
   require multiple normals, be sure to have at least as many normals
   defined as are necessary; otherwise, errors will occur.
   

BINDINGS
     DEFAULT            Use default binding
     OVERALL            Whole object has same normal
     PER_PART           One normal for each part of object
     PER_PART_INDEXED   One normal for each part, indexed
     PER_FACE           One normal for each face of object
     PER_FACE_INDEXED   One normal for each face, indexed
     PER_VERTEX         One normal for each vertex of object
     PER_VERTEX_INDEXED One normal for each vertex, indexed

FILE FORMAT/DEFAULTS
     NormalBinding {
          value  DEFAULT        # SFEnum
     }

   
   
  ORTHOGRAPHICCAMERA
  
   An orthographic camera defines a parallel projection from a viewpoint.
   This camera does not diminish objects with distance, as an
   SoPerspectiveCamera does. The viewing volume for an orthographic
   camera is a rectangular parallelepiped (a box).
   
   By default, the camera is located at (0,0,1) and looks along the
   negative z-axis; the position and orientation fields can be used to
   change these values. The height field defines the total height of the
   viewing volume.
   
   Cameras are used to view a scene. When a camera is encountered during
   rendering, it sets the projection and viewing matrices and viewport
   appropriately; it does not draw geometry. Cameras should be placed
   before any shape nodes or light nodes in a scene graph; otherwise,
   those shapes or lights cannot be rendered properly. Cameras are
   affected by the current transformation, so you can position a camera
   by placing a transformation node before it in the scene graph . The
   default position and orientation of a camera is at (0,0,1) looking
   along the negative z-axis.
   

FILE FORMAT/DEFAULTS
     OrthographicCamera {
          position         0 0 1        # SFVec3f
          orientation      0 0 1  0     # SFRotation
          focalDistance    5            # SFFloat
          height           2            # SFFloat
     }

   
   
  PERSPECTIVECAMERA
  
   A perspective camera defines a perspective projection from a
   viewpoint. The viewing volume for a perspective camera is a truncated
   right pyramid.
   
   By default, the camera is located at (0,0,1) and looks along the
   negative z-axis; the position and orientation fields can be used to
   change these values. The heightAngle field defines the total vertical
   angle of the viewing volume.
   
   Cameras are used to view a scene. When a camera is encountered during
   rendering, it sets the projection and viewing matrices and viewport
   appropriately; it does not draw geometry. Cameras should be placed
   before any shape nodes or light nodes in a scene graph; otherwise,
   those shapes or lights cannot be rendered properly. Cameras are
   affected by the current transformation, so you can position a camera
   by placing a transformation node before it in the scene graph . The
   default position and orientation of a camera is at (0,0,1) looking
   along the negative z-axis.
   

FILE FORMAT/DEFAULTS
     PerspectiveCamera {
          position         0 0 1        # SFVec3f
          orientation      0 0 1  0     # SFRotation
          focalDistance    5            # SFFloat
          heightAngle      0.785398     # SFFloat
     }

   
   
  POINTLIGHT
  
   This node defines a point light source at a fixed 3D location. A point
   source illuminates equally in all directions; that is, it is omni-
   directional.
   
   A light node defines an illumination source that may affect subsequent
   shapes in the scene graph, depending on the current lighting style.
   Light sources are affected by the current transformation. A light node
   under a separator does not affect any objects outside that separator.
   

FILE FORMAT/DEFAULTS
     PointLight {
          on         TRUE       # SFBool
          intensity  1          # SFFloat
          color      1 1 1      # SFColor
          location   0 0 1      # SFVec3f
     }

   
   
  POINTSET
  
   This node represents a set of points located at the current
   coordinates. PointSet uses the current coordinates in order, starting
   at the index specified by the startIndex field. The number of points
   in the set is specified by the numPoints field. A value of -1 for this
   field indicates that all remaining values in the current coordinates
   are to be used as points.
   
   The coordinates of the point set are transformed by the current
   cumulative transformation. The points are drawn with the current light
   model and drawing style (drawing styles FILLED and LINES are treated
   as POINTS).
   
   Treatment of the current material and normal binding is as follows:
   PER_PART, PER_FACE, and PER_VERTEX bindings bind one material or
   normal to each point. The DEFAULT material binding is equal to
   OVERALL. The DEFAULT normal binding is equal to PER_VERTEX. The
   startIndex is also used for materials, normals, or texture coordinates
   when the binding indicates that they should be used per vertex.
   

FILE FORMAT/DEFAULTS
     PointSet {
          startIndex  0 # SFLong
          numPoints   -1        # SFLong
     }

   
   
  ROTATION
  
   This node defines a 3D rotation about an arbitrary axis through the
   origin. The rotation is accumulated into the current transformation,
   which is applied to subsequent shapes. The rotation field provides a
   variety of methods for specifying the rotation.
   

FILE FORMAT/DEFAULTS
     Rotation {
          rotation  0 0 1  0    # SFRotation
     }

  SCALE
  
   This node defines a 3D scaling about the origin. If the components of
   the scaling vector are not all the same, this produces a non-uniform
   scale.
   

FILE FORMAT/DEFAULTS
     Scale {
          scaleFactor  1 1 1    # SFVec3f
     }

  SEPARATOR
  
   This group node performs a push (save) of the traversal state before
   traversing its children and a pop (restore) after traversing them.
   This isolates the separator's children from the rest of the scene
   graph. A separator can include lights, cameras, coordinates, normals,
   bindings, and all other properties. Separators are relatively
   inexpensive, so they can be used freely within scenes.
   
   Separators can also perform culling during rendering and picking.
   Culling skips over traversal of the separator's children if they are
   not going to be rendered or picked, based on the comparison of the
   separator's bounding box with the current view volume. Culling is
   controlled by the renderCulling and pickCulling fields. These are also
   set to AUTO by default, allowing the implementation to decide whether
   or not to cull.
   

CULLING ENUMS
     ON    Always try to cull to the view volume
     OFF   Never try to cull to the view volume
     AUTO  Implementation-defined culling behavior

FILE FORMAT/DEFAULTS
     Separator {
          renderCulling       AUTO      # SFEnum
     }

   
   
  SHAPEHINTS
  
   The ShapeHints node indicates that IndexedFaceSets are solid, contain
   ordered vertices, or contain convex faces.
   
   These hints allow VRML implementations to optimize certain rendering
   features. Optimizations that may be performed include enabling
   back-face culling and disabling two-sided lighting. For example, if an
   object is solid and has ordered vertices, an implementation may turn
   on backface culling and turns off two-sided lighting. If the object is
   not solid but has ordered vertices, it may turn off backface culling
   and turns on two-sided lighting.
   
   The ShapeHints node also affects how default normals are generated.
   When an IndexedFaceSet has to generate default normals, it uses the
   creaseAngle field to determine which edges should be smooth- shaded
   and which ones should have a sharp crease. The crease angle is the
   angle between surface normals on adjacent polygons. For example, a
   crease angle of .5 radians (the default value) means that an edge
   between two adjacent polygonal faces will be smooth shaded if the
   normals to the two faces form an angle that is less than .5 radians
   (about 30 degrees). Otherwise, it will be faceted.
   

VERTEX ORDERING ENUMS
     UNKNOWN_ORDERING    Ordering of vertices is unknown
     CLOCKWISE           Face vertices are ordered clockwise
                          (from the outside)
     COUNTERCLOCKWISE    Face vertices are ordered counterclockwise
                          (from the outside)

SHAPE TYPE ENUMS
     UNKNOWN_SHAPE_TYPE  Nothing is known about the shape
     SOLID               The shape encloses a volume

FACE TYPE ENUMS
     UNKNOWN_FACE_TYPE   Nothing is known about faces
     CONVEX              All faces are convex

FILE FORMAT/DEFAULTS
     ShapeHints {
          vertexOrdering  UNKNOWN_ORDERING      # SFEnum
          shapeType       UNKNOWN_SHAPE_TYPE    # SFEnum
          faceType        CONVEX                # SFEnum
          creaseAngle     0.5                   # SFFloat
     }

   
   
  SPHERE
  
   This node represents a sphere. By default, the sphere is centered at
   the origin and has a radius of 1. The sphere is transformed by the
   current cumulative transformation and is drawn with the current
   lighting model, drawing style, material, and geometric complexity.
   
   A sphere does not have faces or parts. Therefore, the sphere ignores
   material and normal bindings, using the first material for the entire
   sphere and using its own normals. When a texture is applied to a
   sphere, the texture covers the entire surface, wrapping
   counterclockwise from the back of the sphere. The texture has a seam
   at the back on the yz-plane.
   

FILE FORMAT/DEFAULTS
     Sphere {
          radius  1     # SFFloat
     }

   
   
  SPOTLIGHT
  
   This node defines a spotlight style light source. A spotlight is
   placed at a fixed location in 3-space and illuminates in a cone along
   a particular direction. The intensity of the illumination drops off
   exponentially as a ray of light diverges from this direction toward
   the edges of the cone. The rate of drop-off and the angle of the cone
   are controlled by the dropOffRate and cutOffAngle fields.
   
   A light node defines an illumination source that may affect subsequent
   shapes in the scene graph, depending on the current lighting style.
   Light sources are affected by the current transformation. A light node
   under a separator does not affect any objects outside that separator.
   

FILE FORMAT/DEFAULTS
     SpotLight {
          on           TRUE     # SFBool
          intensity    1        # SFFloat
          color        1 1 1    # SFVec3f
          location     0 0 1    # SFVec3f
          direction    0 0 -1   # SFVec3f
          dropOffRate  0        # SFFloat
          cutOffAngle  0.785398 # SFFloat
     }

   
   
  SWITCH
  
   This group node usually traverses only one or none of its children. It
   implements an operation similar to the switch statement in C. One can
   use this node to switch on and off the effects of some properties or
   to switch between different properties.
   
   The whichChild field specifies the index of the child to traverse,
   where the first child has index 0.
   
   A value of -1 (the default) means do not traverse any children. A
   value of -3 traverses all children, making the switch behave exactly
   like a regular SoGroup.
   

FILE FORMAT/DEFAULTS
     Switch {
          whichChild  -1        # SFLong
     }

   
   
  TEXTURE2
  
   This property node defines a texture map and parameters for that map.
   This map is used to apply texture to subsequent shapes as they are
   rendered.
   
   The texture can be read from the file specified by the filename field.
   Once the texture has been read, the image field contains the texture
   data. However, this field is marked so the image is not written out
   when the texture node is written to a file. To turn off texturing, set
   the filename field to an empty string ("").
   
   Textures can also be specified in memory by setting the image field to
   contain the texture data. Doing so resets the filename to the empty
   string.
   

WRAP ENUM
     REPEAT  Repeats texture outside 0-1 texture coordinate range
     CLAMP   Clamps texture coordinates to lie within 0-1 range
     }

FILE FORMAT/DEFAULTS
     Texture2 {
          filename    ""        # SFString
          image       0 0 0     # SFImage
          wrapS       REPEAT    # SFEnum
          wrapT       REPEAT    # SFEnum
     }

   
   
  TEXTURE2TRANSFORM
  
   This node defines a 2D transformation applied to texture coordinates.
   This affects the way textures are applied to the surfaces of
   subsequent shapes. The transformation consists of (in order) a
   non-uniform scale about an arbitrary center point, a rotation about
   that same point, and a translation. (Note: while the transformations
   can be thought of as being applied in that order, the GL matrices are
   actually premultiplied in the opposite order. Therefore, the
   operations are listed in the reverse order throughout this reference
   page.) This allows a user to change the size and position of the
   textures on objects.
   

FILE FORMAT/DEFAULTS
     Texture2Transform {
          translation  0 0      # SFVec2f
          rotation     0        # SFFloat
          scaleFactor  1 1      # SFVec2f
          center       0 0      # SFVec2f
     }

   
   
  TEXTURECOORDINATE2
  
   This node defines a set of 2D coordinates to be used to map textures
   to subsequent vertex-based shapes (those derived from SoVertexShape).
   It replaces the current texture coordinates in the rendering state for
   the shapes to use.
   
   The current texture coordinate binding (see
   SoTextureCoordinateBinding) determines how texture coordinates are
   mapped to vertices of shapes. An alternative to using explicit texture
   coordinates is to generate them using a function; see
   SoTextureCoordinateFunction.
   
   Texture coordinates range from 0 to 1 across the texture. The
   horizontal coordinate, called S, is specified first, followed by the
   vertical coordinate, T.
   

FILE FORMAT/DEFAULTS
     TextureCoordinate2 {
          point  0 0    # MFVec2f
     }

   
   
  TRANSFORM
  
   This node defines a geometric 3D transformation consisting of (in
   order) a (possibly) non-uniform scale about an arbitrary point, a
   rotation about an arbitrary point and axis, and a translation.
   

FILE FORMAT/DEFAULTS
     Transform {
          translation       0 0 0       # SFVec3f
          rotation          0 0 1  0    # SFRotation
          scaleFactor       1 1 1       # SFVec3f
          scaleOrientation  0 0 1  0    # SFRotation
          center            0 0 0       # SFVec3f
     }

   
   
  TRANSFORMSEPARATOR
  
   This group node is similar to the SoSeparator node in that it saves
   state before traversing its children and restores it afterwards.
   However, it saves only the current transformation; all other state is
   left as is. This node can be useful for positioning a camera, since
   the transformations to the camera will not affect the rest of the
   scene, even through the camera will view the scene. Similarly, this
   node can be used to isolate transformations to light sources or other
   objects.
   

FILE FORMAT/DEFAULTS
     TransformSeparator {
     }

   
   
  TRANSLATION
  
   This node defines a translation by a 3D vector.
   

FILE FORMAT/DEFAULTS
     Translation {
          translation  0 0 0    # SFVec3f
     }

   
   
  WWWANCHOR
  
   The WWWAnchor node loads a new scene into a VRML browser when one of
   its children is chosen. Exactly how a user "chooses" a child of the
   WWWAnchor is up to the VRML browser; typically, clicking on one of its
   children with the mouse will result in the new scene replacing the
   current scene. A WWWAnchor with an empty ("") name does nothing when
   its children are chosen. The name is an arbitrary URL.
   
   The WWWAnchor's map field is an enumerated value that can be either
   NONE (the default) or POINT. If it is POINT then the object-space
   coordinates of the point on the object the user chose will be added to
   the URL in the name field, with the syntax "?x,y,z".
   

FILE FORMAT/DEFAULTS
     WWWAnchor {
          name ""       # SFString
          map NONE      # SFEnum
     }

   
   
  WWWINLINE
  
   The WWWInline node reads its children from anywhere in the World Wide
   Web. Exactly when its children are read is not defined; reading the
   children may be delayed until the WWWInline is actually displayed. A
   WWWInline with an empty name does nothing. The name is an arbitrary
   URL.
   
   If the WWWInline's bboxSize field specifies a non-empty bounding box
   (a bounding box is non-empty if at least one of its dimensions is
   greater than zero), then the WWWInline's bounding box is specified by
   its bboxSize and bboxCenter fields. This allows an implementation to
   view-volume cull or LevelOfDetail switch the WWWInline without reading
   its contents.
   

FILE FORMAT/DEFAULTS
     WWWInline {
          name ""               # SFString
          bboxSize 0 0 0        # SFVec3f
          bboxCenter 0 0 0      # SFVec3f
     }

   
   
Instancing

   A node may be the child of more than one group. This is called
   "instancing" (using the same instance of a node multiple times, called
   "aliasing" or "multiple references" by other systems), and is
   accomplished by using the "USE" keyword.
   
   The DEF keyword both defines a named node, and creates a single
   instance of it. The USE keyword indicates that the most recently
   defined instance should be used again. If several nodes were given the
   same name, then the last DEF encountered during parsing "wins".
   DEF/USE is limited to a single file; there is no mechanism for USE'ing
   nodes that are DEF'ed in other files.
   
   For example, rendering this scene will result in three spheres being
   drawn. Both of the spheres are named 'Joe'; the second (smaller)
   sphere is drawn twice:
   

Separator {
        DEF Joe Sphere { }
        Translation { translation 2 0 0 }
        DEF Joe Sphere { radius .2 }
        Translation { translation 2 0 0 }
        USE Joe
}

   
   
Extensibility

   Extensions to VRML are supported by supporting self-describing nodes.
   Nodes that are not part of standard VRML must write out a description
   of their fields first, so that all VRML implementations are able to
   parse and ignore the extensions.
   
   This description is written just after the opening curly-brace for the
   node, and consists of the keyword 'fields' followed by a list of the
   types and names of fields used by that node, all enclosed in square
   brackets and separated by commas. For example, if Cube was not a
   standard VRML node, it would be written like this:
   

Cube {
  fields [ SFFloat width, SFFloat height, SFFloat depth ]
  width 10 height 4 depth 3
}

   
   
   Specifying the fields for nodes that ARE part of standard VRML is not
   an error; VRML parsers must silently ignore the specification.
   
An Example

   This is a longer example of a VRML scene. It contains a simple model
   of a track-light consisting of primitive shapes, plus three walls
   (built out of polygons) and a reference to a shape defined elsewhere,
   both of which are illuminated by a spotlight. The shape acts as a
   hyperlink to some HTML text.
   

#VRML V1.0 ascii

Separator {
    Separator {       # Simple track-light geometry:
        Translation { translation 0 4 0 }
        Separator {
            Material { emissiveColor 0.1 0.3 0.3 }
            Cube {
                width   0.1
                height  0.1
                depth   4
            }
        }
        Rotation { rotation 0 1 0  1.57079 }
        Separator {
            Material { emissiveColor 0.3 0.1 0.3 }
            Cylinder {
                radius  0.1
                height  .2
            }
        }
        Rotation { rotation -1 0 0  1.57079 }
        Separator {
            Material { emissiveColor 0.3 0.3 0.1 }
            Rotation { rotation 1 0 0  1.57079 }
            Translation { translation 0 -.2 0 }
            Cone {
                height  .4
                bottomRadius .2
            }
            Translation { translation 0 .4 0 }
            Cylinder {
                radius  0.02
                height  .4
            }
        }
    }
    SpotLight {      # Light from above
        location 0 4 0
        direction 0 -1 0
        intensity       0.9
        cutOffAngle     0.7
    }
    Separator {      # Wall geometry; just three flat polygons
        Coordinate3 {
            point [
                   -2 0 -2, -2 0 2, 2 0 2, 2 0 -2,
                   -2 4 -2, -2 4 2, 2 4 2, 2 4 -2]
        }
        IndexedFaceSet {
            coordIndex [ 0, 1, 2, 3, -1,
                        0, 4, 5, 1, -1,
                        0, 3, 7, 4, -1
                        ]
        }
    }
    WWWAnchor {   # A hyperlinked cow:
        name "http://www.foo.edu/CowProject/AboutCows.html"

        Separator {
            Translation { translation 0 1 0 }
            WWWInline {   # Reference another object
                name "http://www.foo.edu/3DObjects/cow.wrl"
            }
        }
    }
}

   
   
   
     _________________________________________________________________
   
   
   
                           BROWSER CONSIDERATIONS
                                       
   This section describes the file naming and MIME conventions to be used
   in building VRML browsers and configuring WWW browsers to work with
   them.
   
File Extensions

   The file extension for VMRL files is .wrl (for world).
   
MIME

   The MIME type for VRML files is defined as follows:
   

world/vrml

   
   
   The MIME major type for 3D world descriptions is world. The MIME minor
   type for VRML documents is vrml. Other 3D world descriptions, such as
   oogl for The Geometry Center's Object-Oriented Geometry Language, or
   iv, for SGI's Open Inventor ASCII format, can be supported by using
   different MIME minor types.
   
   -- MDP - 2 November 1994

   =END=

   Press the ESC key to return to the main text.
   =============================================







