Advanced javascript in VRML
Introduction
This tutorial page assumes a good understanding of vrmlscript in particular directOutput and array access methods.
Dynamically adding objects to a world
This example uses a Script node to add an object to the world on loading.
#VRML V2.0 utf8
# When scene loads (initialize function) add the yellow sphere
# We store the new object in this Group node
DEF AddedObject Group {
children [
]
}
DEF Generate Script {
field SFNode addedObject USE AddedObject
field MFNode tempNode []
field SFString str ""
directOutput TRUE
url "javascript:
function initialize () {
// Create new object as a string
str+='Transform { ';
str+=' translation -2 0 0 ';
str+=' children [ ';
str+=' Shape { ';
str+=' appearance Appearance { ';
str+=' material DEF Yellow Material { ';
str+=' diffuseColor 1 1 0 ';
str+=' }';
str+=' }';
str+=' geometry Sphere { ';
str+=' radius 0.5 ';
str+=' }';
str+=' }';
str+=' ]';
str+='}';
// convert string to VRML and store in temporary
// node.
tempNode=Browser.createVrmlFromString(str);
// add the object to the scene
addedObject.addChildren=tempNode;
}
"
}
Dynamically adding objects and ROUTEs to a world
This example uses a Script node to add an object to the world and also add a ROUTE from an existing TimeSensor to the new geometry's transparency.
#VRML V2.0 utf8
# When the box is clicked on the 'Generate' Script
# creates a new yellow sphere which is linked to the existing 'Timer'
DEF Scene Group {
children [
DEF Sensor TouchSensor {}
Shape {
appearance Appearance {
material Material {
diffuseColor .1 .44 .22
shininess .1
specularColor .15 .15 .02
ambientIntensity 0
emissiveColor .04 .18 .09
}
}
geometry Box {
size 1 1 1
}
}
]
}
# existing TimeSensor we wish to utilize
# The new Object will have a ROUTE from this TimeSensor added
DEF Timer TimeSensor {
cycleInterval 1
startTime -1
loop TRUE
}
DEF AddedObject Group {
children [
]
}
DEF Generate Script {
eventIn SFTime touchTime
field SFNode addedObject USE AddedObject
field MFNode tempNode []
field SFString str ""
field SFNode timer USE Timer
directOutput TRUE
url "javascript:
function touchTime (val,ts) {
// Create new object as a string
str+='Transform { ';
str+=' translation -2 0 0 ';
str+=' children [ ';
str+=' Shape { ';
str+=' appearance Appearance { ';
str+=' material DEF Yellow Material { ';
str+=' diffuseColor 1 1 0 ';
str+=' }';
str+=' }';
str+=' geometry Sphere { ';
str+=' radius 0.5 ';
str+=' }';
str+=' }';
str+=' ]';
str+='}';
// convert string to VRML and store in temporary
// node.
tempNode=Browser.createVrmlFromString(str);
// add the object to the scene
addedObject.addChildren=tempNode;
// Now add the ROUTE from the Timer to the Yellow Material
// tempNode[0].children[0].appearance.material is the pointer to the
// yellow material's DEFed name
// that is 1st node, then 1st child of node, then appearance,
// then material
Browser.addRoute(timer, 'fraction_changed', tempNode[0].children[0].appearance.material, 'transparency');
}
"
}
# ROUTE touchTime to Script
ROUTE Sensor.touchTime TO Generate.touchTime
# ROUTE touchTime to TimeSensor
ROUTE Sensor.touchTime TO Timer.startTime
Examples
The 1st example in completed form Dynamically adding objects to a World
The 2nd example in completed form Dynamically adding objects and ROUTEs to a World
Notes
The usage of MFNode/SFNode in Browser.addRoute may appear odd but is actually necessary. Some worlds may already contain a DEFed node with the same name. Also it prevents problems which would occur with using just the DEFed names of nodes.
Usage of the print statement within the Script node is one way of figureing out the values for the tempNode values. For example print (tempNode[0].children[0]); would print Shape.
|