Proposal for a VRML Script Node Authoring Interface

VRMLScript Reference

Chris Marrin, Jim Kent

Silicon Graphics, Inc.

October 6, 1996

This is a proposal for VRMLScript, a scripting language for VRML 2.0 Script nodes. VRMLScript grew out of the need for a lightweight script language in VRML. It is a subset of the JavaScript language, with VRML data types supported as JavaScript built-in objects. Because of this it has many advantages over other script languages (such as Java):

Please see the examples section to find out about the freely available source reference implementation of VRMLScript.

1 Language

1.1 BNF Grammar

1.2 Objects and Variables

1.2.1 Values, Names and Literals
1.2.2 Objects and Fields
1.2.3 Object Construction
1.2.4 Data Conversion
1.2.5 MF Objects

1.3 Statements

1.3.1 Conditional Statements
1.3.2 Looping Statements
1.3.3 Expression Statements
1.3.4 Return Statement
1.3.5 Break Statement
1.3.6 Continue Statement

1.4 Expressions

1.4.1 Assignment Operators
1.4.2 Arithmetic Operators
1.4.3 Bitwise Operators
1.4.4 Logical and Comparison Operators
1.4.5 String Operators
1.4.6 Operator Precedence

2 Supported Protocol in the Script node's url field

2.1 File Extension

2.2 MIME Type

3 EventIn Handling

3.1 Parameter passing and the EventIn Function

3.2 eventsProcessed() Method

3.3 initialize() Method

3.3 shutdown() Method

4 Accessing Fields and Events

4.1 Accessing Fields and EventOuts of the Script

4.2 Accessing Fields and EventOuts of Other Nodes

4.3 Sending EventOuts

5 Object and Function Definitions

5.1 parseInt and parseFloat Functions

5.2 Browser Object

5.3 Math Object

5.4 SFColor Object

5.5 SFImage Object

5.6 SFNode Object

5.7 SFRotation Object

5.8 String Object

5.9 SFVec2f Object

5.10 SFVec3f Object

5.11 MFColor Object

5.12 MFFloat Object

5.13 MFInt32 Object

5.14 MFNode Object

5.15 MFRotation Object

5.16 MFString Object

5.17 MFVec2f Object

5.18 MFVec3f Object

5.19 VrmlMatrix Object

6 Examples

1 Language

The script syntax has similarities to JavaScript as well as several other scripting languages. VRMLScript was designed to be parsed by YACC and is therefore an LALR(1) grammar.

1.1 BNF of script syntax

script :
functions
NULL

functions:
functions function
function

function:
function beginFunction ( args ) statementBlock

beginFunction:
identifier

args:
args , identifier
identifier
NULL

stmntblk:
{ statements }
{ }
statement

statements :
statements statement
statement

statement :
ifStatement
forStatement
whileStatement
returnStatement ;
breakStatement ;
continueStatement ;
compoundExpression ;

ifStatement :
if ( compoundExpression ) statementBlock
if ( compoundExpression ) statementBlock else statementBlock

forStatement :
for ( optionalExpression ; optionalExpression ; optionalExpression ) statementBlock

whileStatement :
while ( compoundExpression ) statementBlock

returnStatement :
return compoundExpression
return

breakStatement :
break

continueStatement :
continue

compoundExpression :
expression , compoundExpression
expression

optionalExpression:
compoundExpression
NULL

expression : ( compoundExpression )
- expression
! expression
~ expression
leftVariable = expression
leftVariable += expression
leftVariable -= expression
leftVariable *= expression
leftVariable /= expression
leftVariable %= expression
leftVariable &= expression
leftVariable |= expression
leftVariable ^= expression
leftVariable <<= expression
leftVariable >>= expression
leftVariable >>>= expression
++ expression
-- expression
expression ++
expression --
expression ? expression : expression
expression == expression
expression != expression
expression < expression
expression <= expression
expression >= expression
expression > expression
expression + expression
expression - expression
expression * expression
expression / expression
expression % expression
expression && expression
expression || expression
expression & expression
expression | expression
expression ^ expression
expression << expression
expression >> expression
expression >>> expression
string
number
objectMethodCall
objectMemberAccess
functionCall
new constructor
arrayDereference
variable

functionCall :
identifier ( params )

constructor :
identifier ( params )

objectMethodCall :
expression . identifier ( params )

objectMethodAccess :
expression . identifier

params :
params , expression
expression
NULL

arrayDereference :
expression [ compoundExpression ]

leftVariable :
objectMethodAccess
arrayDereference
variable

variable :
identifier

string:
' utf8 '

number:
0{0-7}+
... ANSI C floating point number ...
0X{ 0-9 }+
0x{ 0-9 }+
TRUE
true
FALSE
false

identifier:
utf8Character { utf8 }*

utf8Character:
... any legal UTF8 character except 0-9 ...

utf8:
utf8Character
0-9

1.2 Objects and Variables

Data in VRMLScript is represented as objects. The object types correspond to the VRML field types. A variable contains an instance of an object, and can be predefined (appearing in the Script node) or defined locally.

1.2.1 Values, Names and Literals

A VRMLScript variable holds an instance of an object. If a name is defined as a field or eventOut of the Script node containing the script then there is a variable with that same name available globally to the script. The type of this variable is always the type of the field or eventOut. Assignment to this variable converts the expression to its type or generates a run-time error if a conversion is not possible (see Data Conversion).

The names specified in the declaration of a function (the data value and the timestamp) are local to the function in which they are declared. It is a run-time error to assign to these variables.

Local variables can be created simply by assigning to a name that does not yet exist. Assigning to such a variable causes it take the type of the expression, so these local variables always have the type of the last assignment. Local variables are scoped by the block in which they were first introduced. Once that block is exited, the variable ceases to exist. Variables corresponding to eventOuts or fields of the Script node are global in scope.

Variable names must start with the a lowercase character ('a' through 'z'), an uppercase character ('A' through 'Z'), or an underscore ('_'). Subsequent characters can be any of these or a digit ('0' through '9'). Variable names are case sensitive.

Numeric, boolean, and string literals are allowed. Numeric literals can be integers in decimal (417), hex (0x5C), or octal (0177) notation. They can also be floating point numbers in fixed (1.76) or exponential (2.7e-12) notation. All numeric literals are of the number type. Boolean literals can be 'true' or 'false' and have the boolean type. String literals can be any sequence of UTF8 characters enclosed in single quotes ('), and have the type String. Special (non-printable) characters can be included in a string using the following escape sequences:

Sequence Meaning
\b backspace
\f form feed
\n new line
\r carriage return
\t tab
\' single quote (apostrophe)
\" double quote
\\ backslash

Here are some examples:

Script {
    field    SFFloat aField  0
    field    SFVec3f aVector 0 0 0
    eventOut SFInt32 anEventOut
    eventIn  SFBool  event

    url "vrmlscript:
        function event(value, timestamp) {
            if (aField == 1.5) {
                a = true;      // 'a' contains a boolean
            }

            if (a) {             // this is NOT the same 'a' as above!
                value = 5;       // ERROR,
                                 //   can't assign to function parameter!
            }

            aField = anEventOut; // SFInt32 converted to SFFloat
            b = aField;          // 'b' contains a number
            b = anEventOut;      // 'b' now contains a different number
            aField = aVector;    // ERROR,
                                 //   can't assign SFVec3f to SFFloat!
            s = 'Two\nLines';    // 's' contains a String
     
    }"
}

1.2.2 Objects and Fields

For each field and eventOut in the Script node containing the script there is a corresponding global variable with the same name. Field variables are persistant; they keep their last stored value across function calls. Local variables, on the other hand, are destroyed on exit from the block in which they were defined. Local variables defined in the outermost block of a function are destroyed when the function exits so they do not persist across function calls.

EventOut variables are very similar to field variables in that their values persist across function calls. But when an assignment is made to an eventOut variable an event is generated.

Every object has a set of properties and methods (see Object and Function Definitions). Properties are names on the object that can be selected (using the '.' operator) then used in an expression or as the target of an expression. Methods are names on the object that can be called (using the function call operator) to perform some operation on the object. For example:

function someFunction() {
    a = new SFColor(0.5, 0.5, 0.5);
    b = a.r;                      // 'b' contains 0.5
    a.setHSV(0.1, 0.1, 0.1);      // 'a' now contains new properties
}

The value a.r selects the property which corresponds to the red component of the color. The value a.setHSV() selects the method which sets the color in HSV space.

1.2.3 Object Construction

For each object type there is a corresponding constructor (see Object and Function Definitions). Constructors typically take a flexible set of parameters to allow construction of objects with any initial value. MF objects are essentially arrays so they always take 0 or more parameters of the corresponding SF object type. A value of a given data type is created using the new keyword with the data type name. For instance:

a = new SFVec3f(0, 1, 0);   // 'a' has a SFVec3f containing 0, 1, 0
b = new MFFloat(1, 2, 3, 4) // 'b' has a MFFloat containing 4 floats

1.2.4 Data Conversion

Combining objects of different types in a single expression or assignment statement will often perform implicit type conversion. Rules for this conversion are described in the following table:

Type

Rules

String
  • Combining a String with any number or boolean type produces a String
  • Use parseInt() or parseFloat to convert a String to a number
Number and boolean types
  • Assigning a number or boolean expression to a fixed variable (field or eventOut) of scalar type (SFBool, SFInt32, SFFloat, SFTime) converts to the type of the fixed variable
Vector types
SFVec2f
SFVec3f
SFRotation
SFColor
  • Only combine with like types
  • Dereference (foo[1]) produces a value of number type
SFImage
  • Assignment ('=') and selection ('.') are the only allowed operations
  • Can only assign SFImage type
SFNode
  • Assignment ('=') and selection ('.') are the only allowed operations
  • Can only assign SFNode type
MF types
MFString
MFInt32
MFFloat
MFVec2f
MFVec3f
MFRotation
MFColor
MFNode
  • Only combine with like types
  • Dereference (myArray[3]) produces the corresponding SF type.
  • Dereferenced SF types follow same rules as normal SF types.

1.2.5 MF Objects

Most SF objects in VRMLScript have a corresponding MF object. An MFObject is essentially an array of objects, with each element of the array having the type of the corresponding SF object. All MF objects have a length property which returns or sets the number of elements in the MF object. Array indexes start at 0. If vecArray is an MFVec3f object then vecArray[0] is the first SFVec3f object in the array.

Dereferencing an MF object creates a new object of the corresponding SF object type with the contents of the dereferenced element. Assigning an SF object to a dereferenced MF object (which must be of the corresponding type) copies the contents of the SF object into the dereferenced element.

1.3 Statements

VRMLScript statements are block scoped the same as other C-like languages. A statement can appear alone in the body of an if or for statement. A body with multiple simple statements, or compound statement, must be placed between '{' and '}' characters. This constitutes a new block and all variables defined in this block go out of scope at the end of the block. All simple statements must end with the ';' character.

Example:

if (a < b)
    c = d;      // simple statement, c is local to the if statement

else {          // compound statement, c is no longer defined here
    e = f;      // e is local to the else block
    c = h + 1;
}               // e is no longer defined here

1.3.1 Conditional Statements

The if statement evaluates an expression, and selects one of two statements for execution. A simple if statement executes the statement following the condition if the result of the expression evaluation is not 0. The if...else statement additionally executes the statement following the else clause if the result of the expression evaluation is 0. For nested if...else statements, the else clause matches the nearest if statement. Braces can be used to override this.

Example

if (a < 0)  // simple if statement
    <statement>

if (a == 0)
    if (b > 5)  // if...else statement
        <statement>
    else        // this else clause matches the 'if (b > 5)' statement
        <statement>

if (a == 0) {
    if (b > 5)
        <statement>
}
else            // this else clause matches the 'if (a == 0)' statement
    <statement>

1.3.2 Looping Statements

The for statement contains 3 expressions which control the looping behavior, followed by a statement to which the loop is applied. It executes its first expression once before loop execution. It then evaluates its second expression before each loop and, if the expression evaluates to 0, exits the loop. It then executes the statement, followed by evaluation of the third expression. The loop then repeats, until looping is terminated, either by the second expression evaluating to 0 or until a break statement is encountered. In typical use, the first expression initializes a loop counter, the second evaluates it, and the third increments it.

Example:

for (i = 0; i < 10; ++i)
    <statement>

The while statement contains a single expression which controls the looping behavior, followed by a statement to which the loop is applied. Before each loop it evaluates the expression and, if the expression evaluates to 0, exits the loop. Otherwise it executes the statement and tests the expression again. The loop continues until terminated by the expression evaluating to 0 or until a break statement is encountered.

Example:

while (i < 10)
    <statement>

1.3.3 Expression Statements

Any valid expression in VRMLScript can be a statement. The 2 most common expressions are the function call and the assignment expression (see below).

1.3.4 Return Statement

The return statement does an immediate return from the function regardless of its nesting level in the block structure. If specified, its expression is evaluated and the result is returned to the calling function.

Example:

if (a == 0) {
    d = 1;
    return 5 + d;
}

1.3.5 Break Statement

The break statement exits the deepest enclosing looping statement. Execution continues at the statement following the looping statement.

Example:

while (i < 0) {
    if (q == 5) 
        break;
    <other statements>
}

// execution commences here upon break.

1.3.6 Continue Statement

The continue statement jumps to the end of the deepest enclosing looping statement. Execution continues at the end of the loop. In the case of the for statement, the third expression is evaluated and then the second expression is tested to see if the loop should be continued. In the case of the for...in statement the next element is assigned to the variable and the loop is continued. In the case of the while statement the expression is tested to see if the loop should be continued.

Example:

for a in colorArray {
    if (a[0] > 0.5)
        continue;
    <other statements>

    // loop commences here upon continue.
}

1.4 Expressions

Expressions combine variables, objects, constants and the results of other expressions with operators. The result of an expression evaluation is always another expression. In this way compound expressions can be built out of simpler ones. Operators combine one (unary), two (binary) or three (tertiary) values. Unary operators are placed before (prefix) or after (postfix) the value to be opertated on. Binary operators are placed between the values to be operated on. Tertiary operators always consist of 2 symbols, with one symbol place between each pair of values to be operated on.

Example:

a = -b;          // unary prefix operator
a = b++;         // unary postfix operator
a = b + c;       // binary operator
a = b ? c : d;   // tertiary operator
a = b * c + d;   // compound expression
                 // the product of b * c produces a value which
                 // is added to d

1.4.1 Assignment Operators

An expression of the form expression = expression assigns the result of the right-hand expression to the expression on the left-hand side. The left-hand expression must result in a variable into which a value may be stored. This includes simple identifiers, subscripting operators, members of objects, and the return value of a function call.

Examples:

a = 5;          // simple assignment
a[3] = 4;       // subscripted assignment
foo()[2] = 3;   // function returning an MFField

In addition, a set of shorthand operators exist for doing an binary operation using the left-hand expression and the right-hand expression, then assigning the result to the left-hand expression. These operators are plus-equal ('+='), minus-equal ('-='), times-equal ('*=') divide-equal ('/='), mod-equal ('%='), and-equal ('&='), or-equal ('|='), xor-equal ('^='), shift-left-equal ('<<='), shift-right-equal ('>>='), shift-right-fill-zero-equal ('>>>=').

Examples:

a += 5;              // adds 5 to the value of a and assigns it to a
a[3] &= 0x0000FFFF;  // performs bitwise-and of a[3] and 0x0000FFFF
                     // assigning result to a[3]

1.4.2 Arithmetic Operators

Arithmetic operators include negation ('-'), ones-complement ('~'), increment ('++'), decrement ('--') and the operators ('+', '-', '*', '/', '%'). Negation and ones-complement are prefix unary. Increment and decrement are prefix or postfix unary. The rest are binary.

Examples:

5 + b
(c + 5) * 7
(-b / 4) % 6
(c & 0xFF) | 256

The increment an decrement operators behave differently depending on whether they are used as prefix or postfix operators. In either case, if the expression to which the operator is applied is a variable, the value of that variable is incremented or decremented. A value is also returned from the expression. When used as a prefix operator the value returned is that of the expression after the increment or decrement. When used as a postfix operator the value returned is that of the expression before the increment or decrement.

Examples

a = 5;         // Value of 'a' is 5
b = a++;       // Value of 'b' is 5, value of 'a' is 6
c = ++b;       // Value of 'c' is 6, value of 'b' is 6

1.4.3 Bitwise Operators

Bitwise operators include and ('&'), or ('|'), exclusive or ('^'), left shift ('<<'), right shift ('>>'), and right shift, zero fill ('>>>'). These are all binary operators and are valid on any scalar type. When they are applied the scalar value is converted to an SFInt32 before the operation, and back to the original expression type after. Therefore roundoff error can occur when applying them to SFFloat or SFTime values. The shift operators shift the operand on the left side the number of bits specified by the operator on the right side. The difference between right shift and right shift, zero fill is that the former preserves the sign of the left operator and the latter always puts a zero in the most significant bits.

Examples:

a & 0x0FF       // clears upper 24 bits of 'a'
a >> 5          // shift 'a' 5 bits to the right, sign extend

1.4.4 Logical and Comparison Operators

Logical expressions include logical and ('&&'), logical or ('||'), logical not ('!'), and the comparison operators ('<', '<=', '==', '!=', '>=', '>'). Logical not is prefix unary, the rest are binary. Each evaluates to either 0 (false) or 1 (true). The constants true, false, TRUE, and FALSE can also be used.

Examples:

a < 5
b > 0 && c > 1
!((a > 4) || (b < 6))

1.4.5 String Operators

All the comparison operators can be used to compare Strings for lexicographic order. Additionally the operators '+' and '+=' can be used to concatenate 2 strings. Any expression involving a String and any scalar type will first convert the scalar to a string and then perform the concatentation. Conversion of a String to a scalar type can be done with the functions parseInt() and parseFloat().

Examples:

'A one and ' + 'a two'         // result is "A one and a two"
'The magic number is ' + 7     // result is 'The magic number is 7'
a = 5;                         // 'a' contains an SFTime
a += 'is correct';             // 'a' is now the String '5 is correct'

1.4.6 Operator Precedence

Precedence rules are used to order evaluation. In the above compound expression example multiplication ('*') is evaluated before addition ('+'). For operations of equal precedence evaluation order is shown in the table below. The default rules can be overridden with the use of the '(' and ')' characters to bracket operations to be performed first.

Example:

a = b + c * d;    // c * d is evaluated first
a = (b + c) * d;  // b + c is evaluated first
a = b * c / d;    // b * c is evaluated first 
                  // ('*' and '/' have equal precedence, evaluation
                  // order is left-to-right)

Order of precedence is (unless otherwise stated evaluation order is left-to-right):

Operator Type Operator Comments
comma ,
assignment = += -= *= /= %=
<<= >>= >>>= &= ^= |=
right-to-left
conditional ?: tertiary operator
logical-or ||
logical-and &&
bitwise-or |
bitwise-xor ^
bitwise-and &
equality == !=
relational < <= > >=
bitwise shift << >> >>>
add/subtract + -
multiply/divide * / %
negate/increment ! ~ - ++ -- unary operators
call, member () [] .

2 Supported Protocol in the Script Node's url Field

The url field of the Script node may contain a URL that references VRMLScript code:

 Script {  url "http://foo.com/myScript.vs"  }

The vrmlscript: protocol allows the script to be placed inline as follows:

    Script {  url "vrmlscript: function foo() { ... }"   }

The url field may contain multiple URLs and thus reference a remote file or in-line code:

    Script { 
        url [ "http://foo.com/myScript.vs",
              "vrmlscript: function foo() { ... }" ]
    }

2.1 File Extension

The file extension for VRMLScript source code is .vs.

2.2 MIME Type

The MIME type for VRMLScript source code is defined as follows:

        application/x-vrmlscript

3 EventIn Handling

Events sent to the Script node are passed to the corresponding VRMLScript function in the script. It is necessary to specify the script in the url field of the Script node. The function's name is the same as the eventIn and is passed two arguments, the event value and its timestamp (See "Parameter passing and the EventIn function"). If there isn't a corresponding VRMLScript function in the script, the browser's behavior is undefined.

For example, the following Script node has one eventIn field whose name is start:

    Script { 
        eventIn SFBool start
        url "vrmlscript: function start(value, timestamp) { ... }"
    }

In the above example, when the start eventIn is sent the start() function is executed.

3.1 Parameter Passing and the EventIn Function

When a Script node receives an eventIn, a corresponding method in the file specified in the url field of the Script node is called, which has two arguments. The value of the eventIn is passed as the first argument and timestamp of the eventIn is passed as the second argument. The type of the value is the same as the type of the EventIn and the type of the timestamp is SFTime.

3.2 eventsProcessed() Method

Authors may define a function named eventsProcessed which will be called after some set of events has been received. Some implementations will call this function after the return from each EventIn function, while others will call it only after processing a number of EventIn functions. In the latter case an author can improve performance by placing lengthy processing algorithms which do not need to be executed for every event received into the eventsProcessed function.

Example:
The author needs to compute a complex inverse kinematics operation at each time step of an animation sequence. The sequence is single-stepped using a TouchSensor and button geometry. Normally the author would have an EventIn function execute whenever the button is pressed. This function would increment the time step then run the inverse kinematics algorithm. But this would execute the complex algorithm at every button press and the user could easily get ahead of the algorithm by clicking on the button rapidly. To solve this the EventIn function can be changed to simply increment the time step and the IK algorithm can be moved to an eventsProcessed function. In an efficient implementation the clicks would be queued. When the user clicks quickly the time step would be incremented once for each button click but the complex algorithm will be executed only once. This way the animation sequence will keep up with the user.

The eventsProcessed function takes no parameters. Events generated from it are given the timestamp of the last event processed.

3.3 initialize() Method

Authors may define a function named initialize which is called when the corresponding Script node has been loaded and before any events are processed. This can be used to prepare for processing before events are received, such as constructing geometry or initializing external mechanisms.

The initialize function takes no parameters. Events generated from it are given the timestamp of when the Script node was loaded.

3.3 shutdown() Method

Authors may define a function named shutdown which is called when the corresponding Script node is deleted or the world containing the Script node is unloaded or replaced by another world. This can be used to send events informing external mechanisms that the Script node is being deleted so they can clean up files, etc.

The shutdown function takes no parameters. Events generated from it are given the timestamp of when the Script node was deleted.

4 Accessing Fields

The fields, eventIns and eventOuts of a Script node are accessible from its VRMLScript functions. As in all other nodes the fields are accessible only within the Script. The Script's eventIns can be routed to and its eventOuts can be routed from. Another Script node with a pointer to this node can access its eventIns and eventOuts just like any other node.

4.1 Accessing Fields and EventOuts of the Script

Fields defined in the Script node are available to the script by using its name. It's value can be read or written. This value is persistent across function calls. EventOuts defined in the script node can also be read. The value is the last value sent.

4.2 Accessing Fields and EventOuts of Other Nodes

The script can access any exposedField, eventIn or eventOut of any node to which it has a pointer:

    DEF SomeNode Transform { }
    Script {
        field SFNode node USE SomeNode
        eventIn SFVec3f pos
        directOutput TRUE
        url "... 
            function pos(value) { 
                node.set_translation = value; 
            }"
    }

This sends a set_translation eventIn to the Transform node. An eventIn on a passed node can appear only on the left side of the assignment. An eventOut in the passed node can appear only on the right side, which reads the last value sent out. Fields in the passed node cannot be accessed, but exposedFields can either send an event to the "set_..." eventIn, or read the current value of the "..._changed" eventOut. This follows the routing model of the rest of VRML.

4.3 Sending EventOuts

Assigning to an eventOut sends that event at the completion of the currently executing function. This implies that assigning to the eventOut multiple times during one execution of the function still only sends one event and that event is the last value assigned.

5 Object and Function Definitions

There are a fixed set of objects in VRMLScript, each of which have a fixed set of properties (i.e. values) and methods (i.e. functions). For all object types except Math, there are functions to create an instance of the object. The supported set of objects are:

5.1 parseInt and parseFloat Functions

These 2 functions are provided to convert a String value to an SFInt32 or SFFloat value.

5.2 Browser Object

This section lists the methods available in the browser object, which allows scripts to get and set browser information. For descriptions of the methods, see the Browser Interface topic of the Scripting section of the VRML 2.0 spec.

Instance Creation Method(s)

None. One global instance of the object is available. The name of the instance is Browser.

Properties

None

Methods

5.3 Math Object

The Math object is unique in VRMLScript in that there is exactly one globally available instance of the object, named Math. Properties can be accessed using the syntax Math.<property-name>. Methods can be invoked using the syntax Math.<function-name> ( <argument-list> ).

Instance Creation Method(s)

None. One global instance of the object is available. The name of the instance is Math.

Properties

Methods

Note number, number1, number2, base, and exponent indicate any expression with a scalar value.

5.4 SFColor Object

The SFColor object corresponds to a VRML 2.0 SFColor field. All properties are accessed using the syntax sfColorObjectName.<property>, where sfColorObjectName is an instance of a SFColor object. All methods are invoked using the syntax sfColorObjectName.method(<argument-list>), where sfColorObjectName is an instance of a SFColor object.

Instance Creation Method(s)

Properties

Methods

None

5.5 SFImage Object

The SFImage object corresponds to a VRML 2.0 SFImage field.

Instance Creation Method(s)

Properties

Methods

None

5.6 SFNode Object

The SFNode object corresponds to a VRML 2.0 SFNode field.

Instance Creation Method(s)

Properties

Each node may assign values to its eventIns and obtain the last output values of its eventOuts using the sfNodeObjectName.eventName syntax.

Methods

5.7 SFRotation Object

The SFRotation object corresponds to a VRML 2.0 SFRotation field.

Instance Creation Method(s)

Properties

Methods

5.8 String Object

The String object corresponds to a VRML 2.0 SFString field.

Instance Creation Method(s)

Properties

Methods

Special Operators

5.9 SFVec2f Object

The SFVec2f object corresponds to a VRML 2.0 SFVec2f field. Each component of the vector can be accessed using the x and y properties or using C-style array dereferencing (i.e. sfVec2fObjectName[0] or sfVec2fObjectName[1]).

Instance Creation Method(s)

Properties

Methods

5.10 SFVec3f Object

The SFVec3f object corresponds to a VRML 2.0 SFVec3f field. Each component of the vector can be accessed using the x, y, and z properties or using C-style array dereferencing (i.e. sfVec3fObjectName[0], sfVec3fObjectName[1] or sfVec3fObjectName[2]).

Instance Creation Method(s)

Properties

Methods

5.11 MFColor Object

The MFColor object corresponds to a VRML 2.0 MFColor field. It is used to store a one-dimensional array of SFColor objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfColorObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to SFColor(0, 0, 0).

Instance Creation Method(s)

Properties

Methods

None

5.12 MFFloat Object

The MFFloat object corresponds to a VRML 2.0 MFFloat field. It is used to store a one-dimensional array of SFFloat objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfFloatObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to 0.0.

Instance Creation Method(s)

Properties

Methods

None

5.13 MFInt32 Object

The MFInt32 object corresponds to a VRML 2.0 MFInt32 field. It is used to store a one-dimensional array of SFInt32 objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfInt32ObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to 0.

Instance Creation Method(s)

Properties

Methods

None

5.14 MFNode Object

The MFNode object corresponds to a VRML 2.0 MFNode field. It is used to store a one-dimensional array of SFNode objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfNodeObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to NULL.

Instance Creation Method(s)

Properties

Methods

None

5.15 MFRotation Object

The MFRotation object corresponds to a VRML 2.0 MFRotation field. It is used to store a one-dimensional array of SFRotation objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfRotationObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to SFRotation(0, 0, 1, 0).

Instance Creation Method(s)

Properties

Methods

None

5.16 MFString Object

The MFString object corresponds to a VRML 2.0 MFString field. It is used to store a one-dimensional array of String objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfStringObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to the empty string.

Instance Creation Method(s)

Properties

Methods

None

5.17 MFVec2f Object

The MFVec2f object corresponds to a VRML 2.0 MFVec2f field. It is used to store a one-dimensional array of SFVec2f objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfVec2fObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to SFVec2f(0, 0).

Instance Creation Method(s)

Properties

Methods

None

5.18 MFVec3f Object

The MFVec3f object corresponds to a VRML 2.0 MFVec3f field. It is used to store a one-dimensional array of SFVec3f objects. Individual elements of the array can be referenced using the standard C-style dereferencing operator (e.g. mfVec3fObjectName[index], where index is an integer-valued expression with 0<=index<length and length is the number of elements in the array). Assigning to an element with index > length results in the array being dynamically expanded to contain length elements. All elements not explicitly initialized are set to SFVec3f(0, 0, 0).

Instance Creation Method(s)

Properties

Methods

None

5.19 VrmlMatrix Object

The VrmlMatrix object provides many useful methods for performing manipulations on 4x4 matrices. Each of element of the matrix can be accessed using C-style array dereferencing (i.e., vrmlMatrixObjectName[0][1] is the element in row 0, column 1). The results of dereferencing a VrmlMatrix object using a single index (i.e. vrmlMatrixObjectName[0]) are undefined.

Instance Creation Method(s)

Properties

Methods

6 Examples

Source code for a reference implementation of VRMLScript is available in the archive vrmlscript.zip. This source is freely available for use in adding VRMLScript to your browser. Please read the readme.txt file contained in that package. It lists the restrictions for use, which are:

The package contains everything you need to parse and interpret VRMLScript. Also included are classes to implement the data types, including vector and quaternion math, a general MF array class, string functions and time functions. Currently it is packaged for use on a PC with Windows 95 and Microsoft Developer Studio. If you port the code to other environments, please let us know and we will add links to your site.

 Contact cmarrin@sgi.com, ormailto:jkent@sgi.com with questions or comments.