This document provides information about implementation notes for the Script node.
The Script Node implements VrmlScript and a JavaScript subset as defined in Annex C of the VRML97 specification and in Proposal for a VRML Script Node Authorin by Chris Marrin, Jim Kent (Originally from Cosmo site).
Supported Script node URL strings are strings that begin with the VrmlScript identifier tag "vrmlscript:" or strings that begin with the JavaScript identifier tag "javascript:". The later is treated internally as "vrmlscript:". Also script can reside in files with the extension .vs or .js.
If the "verbose VRML warnings" is switched on, there are diagnostic messages like duplicate defined script functions, use of unitialized variables in order to help debug script code.
The "object:" tag allows to embed native COM object, implementing the blaxxun VRML Script COM Interface. An Example is a availabe in the blaxxun Client SDK.
Java in the Script node is currently not supported.
Contact vrmlscript limitations compared to ECMA Script (ECMA)
Optimizing scripts
Scripts are interpreted, if a scripts runs often (e.g. a scripted complex animations in a PROTO instanced several times) Authors can speed up scripts by common programming techniques.
Subexpression elimination:
for (var i=0 ;i<children.length;i++) {
mycoord.pts[i]=Math.PI*10*i;
}
Optimized:
var len= children.length; // precompute & store to local value of children.length
var factor =Math.PI*10; // precompute factor
for (var i=0 ;i<len;i++) {
mycoord.pts[i]=factor*i;
}
In Contact each assigment mycoord.pts[i] will potentially trigger an event flow (Route update). Depending on the logic the following can be faster:
var len= children.length;
var factor =Math.PI*10;
var newPts = new MFVec3f();
newPts.length = len; // preallocate space in newPts
for (var i=0 ;i<len;i++) {
newPts[i]=factor*i;
}
mycoord.pts[i]=newPts; // only one update
Complex node field access can be speed up by saving a field object reference or using an additional SFNode variable.
myShape.appearance.material.diffuseColor.r = 1.0; myShape.appearance.material.diffuseColor.g = 1.0;
optimized:
var field = myShape.appearance.material.diffuseColor; field.r = 1.0; field.g = 1.0;
A script which does not receive events does not consume CPU time, this means using Sensors like ProximitySensor, VisibilitySensor complex computations can be enabled only if needed.
VRML Content using the features in this section will not be compatible with other VRML browser, if the script code does not contain fallback code for other browsers.
In the Script node interface exposedField is allowed.An exposedField behaves
as a field combined with an eventIn. This feature often can simplify PROTO authoring.
Example:
PROTO MyTransform [exposedField SFVec3f translation 1 2 3] { Transform { translation IS translation } Script { exposedField SFVec3f translation IS translation
url "javascript:
function translation(v) { print('Translation changed to '+v);
}" }
}Assignments to eventOut or assignment to node fields ("directOutput") will directly trigger any attached routes. eventOut's of the Script are not delayed triggered at the end of the Script execution as described in the VRML 97 spec.
vrmlscript Browser object extensions
additional member functions
float getCurrentTime() - gets the computer's current system time
float getTime() - gets the browser's current simulation time
float getWorldStartTime() - gets the time the world was loaded
void print(string); - print the string to the console. A typical use would be to debug scripts. Too many prints can slow down the performance due to the VRML Console update.
function x(value) { Browser.print(' value is '+value); }
In order to print timeStamps more easily, the following code fragment could
be used:
Browser.print('Time = '+ (timeStamp - Browser.getWorldStartTime()));
For compatibility with other VRML browsers, the built-in functions print(string); and trace(string); are supported.
createVrmlFromString - knows about PROTO definitions in the top-level VRML file. (non-standard !)
void setMyAvatar(node) - sets the avatar for third-person mode display
bool showMyAvatar(flag) - toggles third-person mode on/off
bool getThirdPersonView() -query if 3rd persion view mode is active
void setRenderMode(string) - changes rendering mode; supported values are Flat, Gouraud, Wireframe, Vertices. In addition, the OpenGL version supports Solid NonLighted BoundingBoxes.
void setNavigationMode(string) - changes navigation mode
string getNavigationMode() - gets the navigation mode (4.0)
void setCollisionDetection(flag) - changes collision detection mode
bool getCollisionDetection()
void setGravity(flag) - changes gravity, terrain following mode
bool getGravity()
void setHeadlight(flag) - changes headlight mode
bool getHeadLight() - returns current state of headlight
void setViewpointAnimation(flag) - If TRUE, viewpoint changes are animated;
if FALSE, viewpoint changes are immediate.
bool getViewpointAnimation() - returns current state of viewpoint animation
void setAvatarHeight(float value) - sets the avatar height, used for computing
distance of viewpoint to ground
void setCollisionDistance(float value) - changes the collision distance
float getCollisionDistance()
void setVisibilityLimit(float value) - changes visibility limit
float getVisibilityLimit()
void setWalkSpeed(float value) - changes walk speed
int getWindowSizeX() - returns the horizontal size in pixels of the rendering
window
int getWindowSizeY() - returns the vertical size in pixels of the rendering
window
float getWindowAspect() - get the aspect ratio (width/height) of the rendering
window, useful to adjust HUD display
float getAvatarHeight() - returns current avatar height navigation value
float getStepOverSize() - returns current avatar step over size navigation value
float getZNear() - return current actual znear clipping value
float getZFar() - return current actual zfar clipping value
Node computeRayHit (SFVec3f startPoint,SFVec3f endPoint, startingNode optional)
Computes an intersection of a ray with the scene graph. Result is null if no
intersection found or a PseudoNode RayHitInfo with the following information
stored:
PROTO RayHitInfo [
eventOut MFNode hitPath # the chain of grouping nodes, to the geometry node intersected eventOut SFVec3f hitNormal # normal at point of intersection eventOut SFVec3f hitPoint # point of intersection in global, world coordinates eventOut SFVec2f hitTexCoord # texture coordinate at point of intersection (without any texture matrix applied) eventOut SFMatrix hitMatrix # matrix transforming shape local coordinates to world coordinates eventOut SFVec3f hitNormalLocal eventOut SFVec3f hitPointLocal # intersection point in the shape's local coordinate system eventOut MFInt32 hitInfo # vertex index information ]
Example: rayhittest.wrl Navigate so that an object is in the center of the view and click the cylinder, information on hit will be displayed in the console.
Node mouseSelect (SFVec2f startPoint)
Computes an intersection of a ray throught the given 2D mouse position with the scene graph. Result is null if no intersection found or a RayHitInfo node.
Node computeCollision (SFNode sourceNode,VrmlMatrix sourceMatrix, SFNode targetScenegraph, VrmlMatrix targetMatrix)
Tests for collision between a geometry node the scene graph routed by target.
Result is null if no intersection found or a pseudo node CollisionInfo with
the following information stored:
PROTO CollisionInfo [
eventOut MFNode hitPath ## the chain of grouping nodes, to the geometry node source collided with eventOut SFMatrix hitMatrix ## matrix transforming the collided shape local coordinates to world coordinates eventOut MFInt32 hitInfo ## vertex/face index information ]
Example: collisiontest.wrl
Click the cylinder, information on collision will be displayed in the console.
Arguments 2 ..4 are optional, as matrix null value can be passed. Collision
is more performant if Matrices do no contain non uniform scale, or scale at
all. All Contact space subdivision techiques like Group's with bboxSize and
BspTree are fully exploited for speedupif used in the target scene graph.
setUnloadMode(int minNotActiveInlines, float percentageFactorToPurge)
Set strategy for purging inlines from memory:
if the number of inlines currently not rendered is greater minNotActiveInlines,
purge up to (number * percentage ) inlines from memory .
if percentage < 0 its an absolute number of inlines to purge
Example:
setUnloadMode(100,0.05)
if (more than 100 inlines are currently not rendered)
delete 5 % of the inlines not used for the longest time
setBspMode(order) - set bsp Traversal order
setBspLoadingMode( order) - set bsp inline Traversal order
TRAVERSE_NORMAL 0
TRAVERSE_BACK_TO_FRONT 1
TRAVERSE_FRONT_TO_BACK 2
int getCap(int what) - return browser capability information.
Example usage: adapt content to client platform, check if a certain feature like alpha blending is present.
Example: captest.wrl All available browser information is displayed in the console.
boolean isKeyPressed(int keyCode) - determines if the virtual key determined by keyCode (WIN32) is down
string getWorldBaseURL() - returns the base URL of the toplevel world
string getBaseURL() - get the base URL for the script node
Url's inside EXTERNPROTO instanced VRML Nodes are relative to the including VRML world. getBaseURL would return the baseUrl of the VRML file containing the Script node. This call can be used to resolve authoring problems, if URL references in the PROTO should be relative to the implementing PROTO.
loadURLrel(MFString url,MFString parameters) - same as loadURL - but URL is relative to getBaseURL()
setViewpointByValue(SFVec3f position,SFRotation orientation, int mode) - set current viewpoint position to position / orientation
Mode can be set to the following :
bit 0 1: animated transistion 0 : not animated
bit 1 1: set absolute viewpoint (unbind any bound viewpoint)
bit 2 1: values are a relative move distance (left/right, up/down, > in/out,
look left/right, look up/down, roll,)
bit 3 1: check for collision, 0 not
bit 4 1: check for ground, 0 not
This function can be used to program a custom navigation.
For navigation a new relative move distance can be computed from user input
an passed to the Browser as Browser.setViewpointByValue(distance,rotation,(4+8+16)
);
In relative move (bit 2, value = 4) the orientation axis is interpreted as 3 rotation angles about the relative x y z axes of the camera.
getViewpointByValue(SFVec3f position,SFRotation orientation, int mode) - get current viewpoint position
mode 0 : return data of local viewpoint
mode 1 : global viewpoint, value of local viewpoint transformed to global coordinates
if bound viepoints is inside a Transform
mode 2 : third person mode viewpoint
getViewpoinList(MFNode list) - store current set of scene (&Inline) viewpoints into list
void setSoundEnabled(flag) - if set to false lock the usage of the sound device
for this scene
flag getSoundEnabled() - returns current state of sound enabled state
String getInstallDirectory() - returns the string of the directory blaxxun CC3D resides
int prefetch(MFNode argument, boolean loadInlines=true, boolean loadTextures=true)
prefetch instructs the browser to load the Media resources listed in argument, optional parameter 2 and 3 are true by default. If the argument directly references ImageTexture MovieTexture Inline Script or AudioClip nodes the return value is the number of those nodes loaded.
Node getScript() - returns an SFNode referering the Script node of the script. Often script authors need to have a "this" reference in a Script. The common Method using an extra SFNode field in the Script field list is also possible but could result in Memory Leaks in Contact.
bool setOption(string option, string optionValue)
string getOption(string option)
The following options string are supported :
ISSE- Setting & querying Pentium III ISSE support :
print('ISSE = '+Browser.getOption('ISSE'));
Browser.setOption('ISSE','TRUE');
//Browser.setOption('ISSE','FALSE');
driver - returns the graphics card driver description
Overriding Nurbs Tessellation mode settings :
Browser.setOption('NurbsTesselationScale', '2.0');
Browser.setOption('NurbsTargetFps', '25');
Browser.setOption('NurbsTessellationMode', '0'); // 0 = static, 1=DYNAMIC, 2=
Frame Rate, 2= DYNAMIC & FRAME RATE
Option | Value | Explanation | Remarks and Contact version level |
antiAliasing | bool | set antiAliasing | set antiAliasing on or off, effects depends on driver and graphics card |
addAvatarTopLevel | bool | for 3rd person mode, add avatar to scene | Avatar is added by default as new toplevel node. if false the author can manually insert the avatar, by monitoring the Browser.boundAvatar field. (5.1) |
collisionDetection | bool | set collision detection | |
clear | bool | clear screen | if set to false the screen is not cleared and new frame data is drawn on top, this can give interesting effects for animations and music visualizations (5.1) |
dithering | bool | set dithering | |
exactCollision | bool | if false a simple ray based collission mechanism is used | |
fullScreen | bool | switch to fullscreen | |
fullSpeed | bool | use full system resources for rendering | |
gravity | bool | set gravity | |
ISSE | bool | Enable/Disable Intel Pentium III,IV specific ISSE code fragments | |
mipmap | bool | set texture mipmapping | |
lodScale | float >0 | float >0 | global scale factor for visibilityLimit, LOD (same as performance visibilty factor) |
lightScale | float >0 | lighting scale factor | global scale factor for light intensity |
NurbsTesselationScale | float | scale the tesselation of nurbs | Same values as in Rendering Options Dialog settings |
NurbsTargetFps | flaot | the wished target frame rate for dynmic tesselation control | |
NurbsTessellationMode | int | set NURBS tesselation mode |
Use to overrides the prefrences settings, Values 0 STATIC_TESSELATION, 1 DYNAMIC_TESSELATION, 2 FRAMERATE_TESSELATION 3 DYNAMIC_FRAMERATE_TESSELATION |
preload | preload as much resources the next frame |
Can be used to force loading of Textures in the next frame. (5.1) (see also PRELOAD parameter for Object Tag) |
|
relativeTime | bool | set relative time or VRML 97 time model | VRML absolute time values are seconds since 1970, relative time is relative to begin of scene. |
resetRelativeTime | relative time 0 set to now | ||
refreshTime | set url cache refreshtime to now | The internal refreshime for textures referenced is by default set to the last modified date of the refering VRML scene. setOption('refreshTime','') overwrites this date&time. New loading requests for Textures in the Scene will effectivley download them again. | |
smooth | bool | set texture filtering | |
soundQuality | float >0 | ||
soundDopplerFactor | float >0 | sets the Direct Sound doppler factor | |
soundRolloffFactor | float | sets the Direct Sound rolloff factor | |
soundVelocity | vx vy vz | sets the Direct Sound listeners velocity | |
soundVolume | not yet available | ||
soundPan | not yet available | ||
texturing | bool | set texturing | Texturing enable / disable |
tooltip | text | set current tooltip text | An empty string can be used to turn off tooltip (5.1) |
boolean addVrmlFromString(String vrmlSyntax [,Node groupNode]) # 5.1
creates VRML nodes by string, the result is add to the top-level scene , or if groupNode is given and not null to the group. Unlike createVrmlFromString addVrmlFromString can reference and update the top-level namescope. The namescope includes PROTO / EXTERNPROTO's and node by refernced by names.
boolean setCursor(String/ Number newCursor) # 5.1
Ssets current cursor.
boolean defineCursor(int cursorId,String localPathToCursorFile) # 5.1
Overrides built-in cursor shapes with WIN32 CUR Cursor files residing on the local file system.
SFVec3f screen2world(SFVec3f in)
SFVec3f world2screen(SFVec3f in)
SFVec3f cam2world(SFVec3f in)
SFVec3f world2cam(SFVec3f in)
Transform a coordinate to different coordinate spaces. screen : screen coordinate system, cam : camera coodinate system, world : world coordinate system
Browsers object properties
The Browser object itself is a VRML node with events and fields. By adding ROUTEs from vrmlscript or eventOut Observers from the EAI, these events can be observed.
Access from vrmlscript: Browser.xxxx
Access from EAI: Browser.getEventIn(xxx) Browser.getEventOut(xxx)
eventIn MFNode set_myAvatarNodes - set my avatar nodes (for createVrmlFromURL
callback)
eventIn SFString set_myAvatarURL - set my avatar URL
eventIn SFString set_myAvatarName - set my avatar nickname
eventIn SFBool set_showMyAvatar - toggle third-person mode
exposedField SFString myAvatarURL - current avatar URL
exposedField SFNode boundAvatar - the bound (displayed) avatar node (may contain
wrapper around myAvatar)
exposedField SFNode myAvatar - node currently used as myAvatar node
exposedField SFString myAvatarName - current avatar nickname
exposedField SFVec3f followDolly - x,y,z relative translation distance for third-person
viewing mode
exposedField SFVec3f followOrbit - x,y rotation value for third person viewing
mode
exposedField SFVec3f followPan - x,y pan rotation value for third person viewing
mode
# observable eventOuts
eventOut SFTime time_changed - the master clock, can be used for Java EAI to
driver frame based animations
eventOut SFVec3f viewpointPosition - global viewer postion
eventOut SFRotation viewpointOrientation- global viewer orientation
eventOut SFVec2f windowSize - rendering window width height
eventOut SFFloat windowAspect - aspect ratio of rendering window
exposedField MFNode viewpoints
exposedField SFNode boundViewpoint - the current bound viewpoint (top of stack)
exposedField MFNode boundViewpointStack - the other stacked viewpoints (if any)
exposedField SFNode boundNavigationInfo - the currently bound navigation info
exposedField MFNode boundNavigationInfoStack
exposedField SFNode boundFog - the currently bound fog
exposedField MFNode boundFogStack
exposedField SFNode boundBackground - the currently bound background node
exposedField MFNode boundBackgroundStack
exposedField SFString name - Browser name
exposedField SFString version - Browser version
exposedField SFString worldUrl - URL of the currently loaded world (set observer
to get a world changed notification)
exposedField MFNode overTouchSensors - list of TouchSensor's the mouse is over
exposedField MFNode activeVisibilitySensors - list of VisibilitySensors and
Occlusion nodes currently assumed to be visible
exposedField MFNode protoScenes - list of scenes with prototypes (loaded via
EXTERNPROTO URL ..) exposedField MFNode foreground - additonal set of nodes
rendered after scene
Extensions to field objects object
Methods
string getType() - get the type of the field as VRML fieldType name
string toString() - convert the field to its VRML string representation.
Extensions to vrmlscript SFNode object
Methods
String getType() - get the type of the node as VRML nodeType or prototype name
String getName() - get the node's DEF name if available. The node name is not avaible if the node is part of a PROTO and the node in this instance was copied.
Node copy() - creates a copy of the node (no deep copy on SFNode / MFNode fields)
FieldObject getEventIn(string eventInName) - get eventIn object of Node
boolean hasEventIn(string eventInName) - returns true if Node has an eventIn namved eventInName
FieldObject getEventOut(string eventOutName) - get eventOut object of Node
boolean hasEventOut(string eventOutName) - returns true if Node has an eventOut namved eventOutName
FieldObject getField(String fieldName) - get field object of Node, fieldName can be a field or exposedField
VrmlMatrix getMatrix() - get Matrix of Transform, MatrixTransform or last Matrix of HUD, Billboard
boolean setMatrix(vrmlMatrix) - set Matrix of Transform MatrixTransform nodes, false if matrix can not be set.
MFVec3f getBBox() - return the bounding box of the node, return value [0] returns the min position, value[1] the max position. The function is optimized if called for a Geometry node.
MFTime object
supports same members and methods as MFFloat object, but values are stored in double precicision.
Extensions to vrmlscript MFVec3f object
Methods:
setByVertexTransform(MFVec3f srcPoints, MFInt32 srcIndex,MFVec3f translation,MFRotation rotation,MFVec3f scale, MFRotation scaleOrientation,MFVec3f center)
This assignment function performs a series of transformations to coordinates in srcPoints and assigns the result to the MFVec3f object. The operation is comparable to a nested Transform scene graph used to animated a hierachrical model like an Avatar.
Up to the last 5 parameters can be omitted, in order to speed up the operation. if there a n group of vertices to transform, length of srcIndex must be n*3 and the length of each transformation data arraymust be at least n or 0. SrcIndex describes the transform hierachy and the range of coordinates affect by a transform.
Example:
{ 0 1 10 # stack level 0, transform 0, transform srcPoints[1..9]
1 10 12 # stack level 1, transform 1 combine with transform from stacklevel[ -1] (== transform 0), transform srcPoints[10..11]
}
The operation expressed in pseudo code:
VrmlMatrix matrixStack[];
var index;
for(index=0; index<srcIndex.length/3;index+=1) { // for all indices in groups by 3
var level=srcIndex[index*3]; // get the nesting level
var startIndex=srcIndex[index*3+1]; // start vertex index var endIndex=srcIndex[index*3+2]; // end vertex index
// compute transformation, right most arguments could be omitted for speed
matrixStack[level]=m.setTransform(translation[index], rotation[index],
scaleFactor[index],scaleOrientation[index], center[index]) ;
if (level!=0) matrixStack[level].MultiplyRight( matrixStack[level-1]); // combine with parent for(var i=startIndex;i<endIndex;i++) { // transform the Vec3f subset
this[i] = matrixStack[level] * srcPoints[i]; }
}
setByVertexTransformWeighted(MFVec3f srcPoints, MFInt32 srcIndex,MFInt32 coordIndex,MFFloat
weight,MFVec3f translation,MFRotation rotation,MFVec3f scale, MFRotation scaleOrientation,MFVec3f
center)
Introduced in Contact 5.1. This assignment function performs a series of transformations to coordinates in srcPoints and assigns the result to the object. The operation is comparable to a nested Transform scene graph used to animated a hierarchical model like an Avatar. Unlike setByVertexTransform one output point can be affected by several input points multiplied input matrices with a given weight.
The function can be used to implemented paletted matrix skinning or HANIM 1.2 seamless Avatar mesh animation.
Up to the last 5 parameters can be omitted, in order to speed up the operation. if there a n group of vertices to transform, length of srcIndex must be n*3 and the length of each transformation data arraymust be at least n or 0.
The operation expressed in pseudo code:
VrmlMatrix matrixStack[];
var index; if (this.length ==0) this.length =srcPoints.length; // set all points in this to 0 0 0 for(index=0; index<this.length;index+=1) this[i]=new SFVec3f(0,0,0);
for(index=0; index<srcIndex.length/3;index+=1) { // for all indices in groups by 3
var level=srcIndex[index*3]; // get the nesting level
var startIndex=srcIndex[index*3+1]; // start vertex index var endIndex=srcIndex[index*3+2]; // end vertex index
// compute transformation, right most arguments could be omitted for speed
matrixStack[level]=m.setTransform(translation[index], rotation[index],
scaleFactor[index],scaleOrientation[index], center[index]) ;
if (level!=0) matrixStack[level].MultiplyRight( matrixStack[level-1]); // combine with parent for(var i=startIndex;i<endIndex;i++) { // transform the Vec3f subset j=coordIndex[i];// lookup i,
this[j] += weight[i] * (matrixStack[level] * srcPoints[j]); }
}
MFVec3f getBBox() - return the bounding box of the arrar of Vec3f, return value [0] returns the min position, value[1] the max position.
Extensions to vrmlscript Math object
double atan2(double dy, double dx) - arc tangent -PI .. PI
double cosh(double x)
double sinh(double x)
double tanh(double x)
double randomGaussian() - gaussian random number -1 ..1
double noise(double x) - evaluates solid noise function on x
SFString object extensions
Methods:
int string.getCharCodeAt(index); returns the character code as integer at position i
string string.fromCharCode(int1, .... intn); constructs & returns a new string composed out the given sequence of character codes
SFImage object extensions
SFImage new SFImage(int width,int height, int componenents, MFFloat pixels) - construct SFImage using a float array of length widht*height*components. This function can be used to avoid the time consuming pixel packing in vrmlscript for dynamically computed SFImage objects.
MFNode object extensions
Methods:
boolean add(SFNode node) adds a single SFNode to the field.
boolean remove(SFNode node) removes a single SFNode to the field.
int find(SFNode node) returns the index of a node in field, -1 if not found.
Node findByName(String name) returns a the first node with a matching name, void if not found.
SFVec3f object extensions
Methods:
float noise() evals Perlin noise function
float turbulence(int numberOfOctiaves) evals Perlins Turbulence function