Deutsch

VRMLScript reference

 

 

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):

  • Scripts can be included in source form, inline rather than in a separate URL.
  • All VRML 2.0 data types are supported directly. Some, like the vector types have built in methods (such as cross product and normalize) to simplify working with them.
  • Receiving eventIns is handled with separate functions to ease development and to speed processing.
  • Sending eventOuts is done with simple assignment.
  • Scalar data (SFTime, SFInt32, SFFloat, SFBool) can be used directly in expressions. The JavaScript number object converts directly to any of the four scalar data types. For instance, you can add 3 seconds to an SFTime value with a = time + 3;
  • Constructors are available for most data types to ease creation and conversion of data.
  • A full set of JavaScript compatible math, date and string objects is available.
  • The full set of JavaScript string methods and properties are available. Scalar values automatically convert to strings when concatenated. This makes construction of URLs and VRML strings (for use in createVRMLFromString) easy.

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.

  • parseInt(s, [radix])
    • Converts the passed String, 's', to an integer valued number, using the optional passed numeric 'radix' as the base. If the radix is omitted base 10 is assumed. Numbers can be in decimal (123), hexadecimal (0x5C) or octal (0177) notation and may be preceeded by a minus sign ('-'). Conversion stops at the first unrecognized character. If the string begins with an unrecognized character, 0 is returned.
  • parseFloat(s)
    • Converts the passed String, 's', to a floating point valued number. Numbers can be in fixed (1.23) or exponential (12E3) notation and both the mantissa and exponent may be preceeded by a minus sign ('-'). Conversion stops at the first unrecognized character. If the string begins with an unrecognized character, 0 is returned.

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

  • String getName()
    • Get a string with the name of the VRML browser.
  • String getVersion()
    • Get a string containing the version of the VRML browser
  • SFFloat getCurrentSpeed()
    • Get the floating point current rate at which the user is traveling in the scene.
  • SFFloat getCurrentFrameRate()
    • Get the floating point current instantaneous frame rate of the scene rendering, in frames per second.
  • String getWorldURL()
    • Get a string containing the URL of the currently loaded world.
  • void replaceWorld(MFNode nodes)
    • Replace the current world with the passed list of nodes.
  • MFNode createVrmlFromString(String vrmlSyntax)
    • Parse the passed string into a VRML scene and return a the list of root nodes from the resulting scene.
  • void createVrmlFromURL(MFString url, Node node, String event)
    • Parse the passed URL into a VRML scene. When complete send the passed event to the passed node. The event is a string with the name of an MFNode eventIn in the passed node.
  • void addRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn)
    • Add a route from the passed eventOut to the passed eventIn.
  • void deleteRoute(SFNode fromNode, String fromEventOut, SFNode toNode, String toEventIn)
    • Remove the route between the passed eventOut and passed eventIn, if one exists.
  • void loadURL(MFString url, MFString parameter)
    • Load the passed URL, using the passed parameter string to possibly redirect it to another frame. If the destination is the frame containing the current scene, this method may never return.
  • void setDescription(String description)
    • Set the browser dependent description. This is the same function as that performed when the description field of the Anchor node is displayed.

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

  • E
    • Euler's constant, e, approximately 2.718
  • LN10
    • Natural logarithm of 10, approximately 2.302
  • LN2
    • Natural logarithm of 2, approximately 0.693
  • PI
    • Ratio of the circumference of a circle to its diameter, approximately 3.1415
  • SQRT1_2
    • square root of ½, approximately 0.707
  • SQRT2
    • square root of 2, approximately 1.414

Methods

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

  • abs(number)
    • Returns the absolute value of number
  • acos(number)
    • Returns the arc cosine (in radians) of number
  • asin(number)
    • Returns the arc sine (in radians) of number
  • atan(number)
    • Returns the arc tangent (in radians) of number
  • ceil(number)
    • Returns the least integer greater than or equal to number
  • cos(number)
    • Returns the cosine of number where number is expressed in radians
  • exp(number)
    • Returns e, to the power of number (i.e. enumber)
  • floor(number)
    • Returns the greatest integer less than or equal to its argument
  • log(number)
    • Returns the natural logarithm (base e) of number
  • max(number1, number2)
    • Returns the greater of number1 and number2
  • min(number1, number2)
    • Returns the lesser of number1 and number2
  • pow(base, exponent)
    • Returns base to the exponent power (i.e. base exponent)
  • random()
    • Returns a pseudo-random number between zero and one.
  • round(number)
    • Returns the value of number rounded to the nearest integer
  • sin(number)
    • Returns the sine of number where number is expressed in radians
  • sqrt(number)
    • Returns the square root of its argument
  • tan(number)
    • Returns the tangent of number, where number is expressed in radians

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)

  • sfColorObjectName = new SFColor(r, g, b)
    • r, g, and b are scalar values with the red, green, and blue values of the color

Properties

  • r
    • red component of the color
  • g
    • green component of the color
  • b
    • blue component of the color

Methods

None

5.5 SFImage Object

The SFImage object corresponds to a VRML 2.0 SFImage field.

Instance Creation Method(s)

  • sfImageObjectName = new SFImage(x, y, comp, array)
    • x is the x-dimension of the image. y is the y-dimension of the image. comp is the number of components of the image, 1 for greyscale, 2 for greyscale+alpha, 3 for rgb, 4 for rgb+alpha). All these values are scalar. Array is an MFInt32 field containing the x*y values for the pixels of the image. Format of each pixel is the same as the PixelTexture file format.

Properties

  • x
    • the x dimension of the image
  • y
    • the y dimension of the image
  • comp
    • the number of components of the image (1 for greyscale, 2 for greyscale+alpha, 3 for rgb, 4 for rgb+alpha)
  • array
    • the image data

Methods

None

5.6 SFNode Object

The SFNode object corresponds to a VRML 2.0 SFNode field.

Instance Creation Method(s)

  • sfNodeObjectName = new SFNode(vrmlstring)
    • vrmlstring is a ASCII string containing the definition of a VRML 2.0 node

Properties

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

Methods

  • None

5.7 SFRotation Object

The SFRotation object corresponds to a VRML 2.0 SFRotation field.

Instance Creation Method(s)

  • sfRotationObjectName = new SFRotation(x, y, z, angle)
    • x, y, and z are the axis of the rotation. angle is the angle of the rotation (in radians). All values are scalar.
  • sfRotationObjectName = new SFRotation(axis, angle)
    • axis is a SFVec3f object whose value is the axis of rotation. angle is the scalar angle of the rotation (in radians)
  • sfRotationObjectName = new SFRotation(fromVector, toVector)
    • fromVector and toVector are SFVec3f valued objects. These vectors are normalized and the rotation value that would rotate from the fromVector to the toVector is stored in the object.

Properties

  • x
    • Returns the first value of the axis vector
  • y
    • Returns the second value of the axis vector
  • z
    • Returns the third value of the axis vector
  • angle
    • a SFFloat corresponding to the angle of the rotation (in radians)

Methods

  • getAxis()
    • Returns the axis of rotation as an SFVec3f object.
  • inverse()
    • Returns a SFRotation object whose value is the inverse of this object's rotation
  • multiply(rotation)
    • Returns an SFRotation whose value is the object multiplied by the passed SFRotation.
  • multVec(vec)
    • Returns a SFVec3f whose value is the SFVec3f vec multiplied by the matrix corresponding to this object's rotation.
  • setAxis(vec)
    • Set the axis of rotation to the vector passed in vec.
  • slerp(destRotation, t)
    • Returns a SFRotation whose value is the spherical linear interpolation between this object's rotation and destRotation at value 0 <= t <= 1. For t = 0, the value is this object's rotation. For t = 1, the value is destRotation.

5.8 String Object

The String object corresponds to a VRML 2.0 SFString field.

Instance Creation Method(s)

  • stringObjectName = new String(number)
    • number is any scalar expression
  • stringObjectName = new String(string)
    • string is any UTF-8 string expression

Properties

  • length
    • An integer containing the number of characters in the string

Methods

  • charAt(index)
    • Returns a String containing the character of the string at position index in the string. index is an integer-valued expressio between 0 and length-1, where length is the number of characters in the string
  • indexOf(string, [fromIndex])
    • Returns the index of the first occurrence of string in the object, starting the search from fromIndex. fromIndex must be between 0 and length -1, where length is the number of characters in the string. If fromIndex is not specified, the search will start with character 0.
  • lastIndexOf(string, [fromIndex])
    • Returns the index of the first occurrence of string in the object, starting the search backwards from fromIndex. fromIndex must be between 0 and length -1, where length is the number of characters in the string. If fromIndex is not specified, the search will start with character length - 1.
  • substring(index1, index2)
    • Returns a String containing the desired substring. If index1 is less than index2, the substring returned starts with the character at index1 and ends with the character before index2. If index1 is greater than index2, the substring returned starts with the character at index2 and ends with the character before index1. If index1 equals index2, the empty string is returned. index1 and index2 are any integer-valued expressions where 0<=index1, index2<length, where length is the number of characters in the string
  • toLowerCase()
    • Returns a String with all alphabetic characters of the string converted to lower case.
  • toUpperCase()
    • Returns a String with all alphabetic characters of the string converted to upper case.

Special Operators

  • + (addition)
    • Creates a new string that represents the concatenation of two strings and/or scalar values

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)

  • sfVec2fObjectName = new SFVec2f(number1, number2)
    • where number1 and number2 are scalar expressions

Properties

  • x
    • Returns the first value of the vector
  • y
    • Returns the second value of the vector

Methods

  • add(vec)
    • Returns an SFVec2f whose value is the passed SFVec2f added, componentwise, to the object.
  • divide(number)
    • Returns an SFVec2f whose value is the object divided by the passed numeric value.
  • dot(vec)
    • Returns the dot product of this vector and SFVec2f vec
  • length()
    • Returns the geometric length of this vector
  • multiply(number)
    • Returns an SFVec2f whose value is the object multiplied by the passed numeric value.
  • negate()
    • Returns an SFVec2f whose value is the componentwise negation of the object.
  • normalize()
    • Returns an SFVec2f of object converted to unit length
  • subtract(vec)
    • Returns an SFVec2f whose value is the passed SFVec2f subtracted, componentwise, from the object.

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)

  • sfVec3fObjectName = new SFVec3f(number1, number2, number3)
    • where number1, number2, and number3 are scalar expressions

Properties

  • x
    • Returns the first value of the vector
  • y
    • Returns the second value of the vector
  • z
    • Returns the third value of the vector

Methods

  • add(vec)
    • Returns an SFVec3f whose value is the passed SFVec3f added, componentwise, to the object.
  • cross(vec)
    • Returns the cross product of the object and the passed SFVec3f.
  • divide(number)
    • Returns an SFVec3f whose value is the object divided by the passed numeric value.
  • dot(vec)
    • Returns the dot product of this vector and SFVec3f vec
  • length()
    • Returns the geometric length of this vector
  • multiply(number)
    • Returns an SFVec3f whose value is the object multiplied by the passed numeric value.
  • negate()
    • Returns an SFVec3f whose value is the componentwise negation of the object.
  • normalize()
    • Returns an SFVec3f of object converted to unit length
  • subtract(vec)
    • Returns an SFVec3f whose value is the passed SFVec3f subtracted, componentwise, from the object.

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)

  • mfColorObjectName = new MFColor([SFColor, SFColor, ...])
    • The creation method can be passed 0 or more SFColor-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfFloatObjectName = new MFFloat([number, number...])
    • The creation method can be passed 0 or more numeric-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfInt32ObjectName = new MFInt32([number, number, ...])
    • The creation method can be passed 0 or more integer-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfNodeObjectName = new MFNode([SFNode, SFNode, ...])
    • The creation method can be passed 0 or more SFNode-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfRotationObjectName = new MFRotation([SFRotation, SFRotation, ...])
    • The creation method can be passed 0 or more SFRotation-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfStringObjectName = new MFString[string, string, ...])
    • The creation method can be passed 0 or more string-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfVec2fObjectName = new MFVec2f([SFVec2f, SFVec2f, ...])
    • The creation method can be passed 0 or more SFVec2f-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • mfVec3fObjectName = new MFVec3f([SFVec3f, SFVec3f, ...])
    • The creation method can be passed 0 or more SFVec3f-valued expressions to initialize the elements of the array.

Properties

  • length
    • An integer containing the number of elements in the array. Assigning an integer to length changes the number of elements in the array.

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)

  • vrmlMatrixObjectName = new VrmlMatrix(f11, f12, f13, f14, f21, f22, f23, f24, f31, f32, f33, f34, f41, f42, f43, f44)
    • A new matrix initialized with the values in f11 through f44 is created and returned.
  • vrmlMatrixObjectName = new VrmlMatrix()
    • A new matrix initialized with the identity matrix is created and returned.

Properties

  • None

Methods

  • setTransform(translation, rotation, scaleFactor, scaleOrientation, center)
    • Sets the VrmlMatrix to the passed values. translation is an SFVec3f object, rotation is a SFRotation object, scaleFactor is a SFVec3f object, scaleOrientation is a SFRotation object and center is a SFVec3f object. Any of the rightmost parameters can be omitted. In other words, the method can take from 0 to 5 parameters. For example, you can specify 0 parameters (resulting in a identity matrix), 1 parameter (a translation), 2 parameters (a translation and a rotation), 3 parameters (a translation, rotation and a scaleFactor), etc. Any unspecified parameter is set to its default as specified in the Transform node section of the VRML 2.0 specification.
  • getTransform(translation, rotation, scaleFactor)
    • Decomposes the VrmlMatrix and returns the components in the passed translation, rotation, and scaleFactor objects. The types of the parameters are the same as in setTransform. Any projection or shear information in the matrix is ignored.
  • inverse()
    • Returns a VrmlMatrix whose value is the inverse of this object.
  • transpose()
    • Returns a VrmlMatrix whose value is the transpose of this object.
  • multLeft()
    • Returns a VrmlMatrix whose value is the object multiplied by the passed matrix on the left.
  • multRight(matrix)
    • Returns a VrmlMatrix whose value is the object multiplied by the passed matrix on the right.
  • multVecMatrix(vec)
    • Returns a SFVec3f whose value is the object multiplied by the passed row vector.
  • multMatrixVec(vec)
    • Returns a SFVec3f whose value is the object multiplied by the passed column vector.

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:

  • you must credit Silicon Graphics for the code
  • you cannot sell the source
  • if you redistribute this package, you must do so intact, including the readme.txt file
  • you may not use the code for purposes other than implementing a VRMLScript compiler and interpreter.

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.