Event Routing Some VRML nodes generate events in response to environmental changes or user
interaction. Event routing gives authors a mechanism, separate from the scene graph hierarchy, through which these events can be propagated to effect changes in other nodes.
Once generated, events are sent to their routed destinations in time order and processed by the receiving node. This processing can change the state of the node, generate additional events, or change the structure of the scene graph.
Script nodes allow arbitrary, author-defined event processing. An event received by a Script node causes the execution of a script function which has the ability to send events through the normal event-routing mechanism.
The ideal event model processes all events instantaneously in the order that they are generated.
A timestamp, the time at which an event is delivered to a node, serves two purposes. First, it is a conceptual device used to describe the chronological flow of the event mechanism. It ensures that deterministic results can be achieved by real-world implementations which must address processing delays and asynchronous interaction with external devices. Second, timestamps are also made available to Script nodes to allow events to be processed based on the order of user actions or the elapsed time between events.
Events & Routes (Interacting with the Scene)
A class of nodes, called sensors reacts to user events in some prescribed ways.
TouchSensor, ProximitySensor
a sensor is wired to a Script node that runs a program
TouchSensor
Node
Sound
NodeeventOut
eventIn
Rout
#VRML V2.0 utf8#Event routingGroup { children [ Shape {
appearance Appearance { material Material { }}geometry Cone { }
} DEF TS TouchSensor { } # define the sensor "TS" DEF DL DirectionalLight { # define the light "DL"
color 1 0 0on FALSE
} ]ROUTE TS.isOver TO DL.set_on}
Animation and User Interaction
The translation field of the Transformation node is an exposedfield
set_:incoming event set_translation
_changed:outgoing event translation_changed
ROUTE Xform1.translation_changed TO Xform2.set_translation ROUTE Xform1.translation TO Xform2.translation
ROUTERouting should be done in same type (field)a set_ or _changed event is the same type as
the exposed field it’s associated withuse DEF & USEGroup {
children [ DEF LIGHT_CONTROL TouchSensor {} Inline { url [“lightswitch.wrl]}]}
DEF Light PointLight {location -6 4 2on FALSE}
Inline {url [“table.wrl”]}ROUTE LIGHT_CONTROL.isActive TO Light.on
The Animation Event Path
Trigger : generates an event. Usually sensorsLogic : processing on the event. Usually script
nodesTimer : startTime of TimeSensor node, then
generates time eventsEngine : route time events to nodes that animate.
Usually interpolator node
Trigger Logic Timer Engine Target
The Animation Event Path
Target : The browser sends the Engine’s output to a relevant node in the scene hierarchy, whose field values changes accordingly
Trigger Logic Timer Engine Target
Trigger Target
Pointing-device Sensors
The geometry corresponding to a sensor must be a sibling of the sensor
The objects controlled by the sensor can be anywhere
TouchSensor isOver isActive (on click) isActive + hitPoint_changed (on drop) touchTime (press remaining on same object)
Using a TouchSensor node
Trigger sends a time event to the Target (the audio clip)
Group {children [ DEF PUSH TouchSensor {} Inline { url [“doorbell.geom.wrl”]}]}
Sound {source DEF BUSS AudioClip {url [“doorbell.wav”]}maxFront 50minFront 5}
ROUTE PUSH.touchTime TO BUZZ.startTime
Drag SensorsInterpretation of 2D dragging
CylinderSensor : rotating around local y axis• spinning a globe
PlaneSensor : translating in the local xy plane
#VRML V2.0 utf8GROUP { children [
DEF SKULL_DRAG PlaneSensor {minPosition 0 0maxPosition 5 0 }
DEF SKULL Transform {translation 0 0 0children [ Inline {url [“skull.wrl”]}]}]}
ROUTE SKULL_DRAG.translation_changed TO SKULL.translation
ProximitySensor
Generates events whenever the user enters or leaves a defined box-shaped region
Sizes for box shapes can be difficult to estimate --> so, placing a Box node of the same size at the same location will give a good idea of the exact region
Timers
Time Sensor is triggered/initiated by setting startTime
cycleInterval sets the interval of animation fraction_changed is used to calculate time elapse
among the given interval
Trigger Logic Timer Engine Target
Viewpoint { position 0 0 15}DEF DETECTOR ProximitySensor {size 25 25 25}DEF TIMER TimeSensor {cycleInterval 2}DEF LIGHT PointLight {
intensity 0location 3 3 3}
Inline {url [“chacmool.wrl”]} #objects to be litROUTE DETECTOR.enterTime TO TIMER.startTimeROUTE TIME.fraction_changed TO LIGHT.intensity
Engines
Convert the output of a time sensor into a change in some other type of value
interpolator & keyframe PositionInterpolator OrientationInterpolator ColorInterpolator ScalarInterpolator CoordinateInterpolator
Trigger Logic Timer Engine Target
DEF Spark_mover PositionInterpolator {key [0,1]keyvalue [0 0 0, 0.8, 5,0]}
ROUTE TIME.fraction_changed TO Spark_mover.set_fractionROUTE Spark_mover.value_changed TO Spark.translation
Example (bike rider - bike.wrl)#VRML V2.0 utf8DEF BIKE Transform { translation 0 0 0 children [ DEF FW Transform {
translation -2 -4 0 children [ Inline { url "wheel2.wrl"}]}DEF BW Transform { translation 2 -4 0 children [ Inline { url "wheel2.wrl"}]}DEF FR Transform { translation 0.4 -3.5 2.1 children [ Inline { url "frame.wrl"}] } ]}
DEF RIDER Transform {translation 0 0 0children [ Inline { url "rider2.wrl"}]}
DEF T TimeSensor {loop TRUEenabled TRUEcycleInterval 5stopTime -1}
DEF P PositionInterpolator {key [ 0, 0.25, 0.5, 0.75, 1]keyValue [ -5 0 0, -1 0 0, 0 3 0, 2 0 0, 5 0 0]}
ROUTE T.fraction_changed TO P.set_fractionROUTE P.value_changed TO BIKE.translationROUTE BIKE.translation TO RIDER.translation
Scripting (Script node)Bridge between VRML & programming
languages. Acting as the Engine stage to control animation Processing input to act as the Logic stage Interacting with the browser in certain ways
• binding the browser to a Viewpoint node to animate the viewer along a path
Manipulating the scene hierarchy communicating with a server or another VRML
world across a network
What to know about Scripting
How the script node acts as a bridge between VRML & JAVA
Basic JAVA classes that interact with and manipulate VRML
How to compile and run java program
The script node act as a gateway to the script itself
A node
Scene
translation
color
size
rotation
Script node
url
eventOut
eventin
another node
translation
color
size
rotation
JAVA code
Example (ChangeColor.wrl)#VRML V2.0 utf8Transform { children [ DEF TS TouchSensor {} # TouchSensor Shape { appearance Appearance { material DEF SphereColor Material { diffuseColor 1 0 0 } # red } geometry Sphere {} } ]}
DEF ColorScript Script { url "ChangeColor.class" eventIn SFBool clicked eventOut SFColor newColor field SFBool on FALSE}# RoutingROUTE TS.isActive TO ColorScript.clickedROUTE ColorScript.newColor TO SphereColor.set_diffuseColor
Example (ChangeColor.java)import vrml.*;import vrml.field.*;import vrml.node.*;public class ChangeColor extends Script { private SFBool on; // status of on-off float red[] = { 1, 0, 0 }; // RGB(Red) float blue[] = { 0, 0, 1 }; // RGB(Blue) private SFColor newColor ; public void initialize() { newColor = (SFColor) getEventOut("newColor"); on = (SFBool) getField("on"); } public void processEvent(Event e) { ConstSFBool v = (ConstSFBool)e.getValue(); if(v.getValue()){ if (on.getValue()) { newColor.setValue(red); // set red to 'newColor' } else { newColor.setValue(blue); // set blue to 'newColor' } on.setValue(!on.getValue()); // = !on.getValue(); } }}
Example II (mover.wrl)#VRML V2.0 utf8DEF MOVER Transform { translation 0 0 10 children [ DEF TS TouchSensor {} # TouchSensor Shape { appearance Appearance { material DEF SphereColor Material { diffuseColor 1 0 0 } # red } geometry Sphere {} } ]}
DEF MoveIt Script { url "MoveIt.class" eventIn SFBool clicked field SFNode node USE MOVER field SFBool on FALSE}# RoutingROUTE TS.isActive TO MoveIt.clicked
Example II (moveit.java)import vrml.*;import vrml.field.*;import vrml.node.*;public class MoveIt extends Script { private SFBool on; // status of on-off float red[] = { 1, 0, 0 }; // RGB(Red) float blue[] = { 0, 0, 1 }; // RGB(Blue) private SFNode theNode ; private SFVec3f position; public void initialize() { theNode = (SFNode) getField("node"); }
public void processEvent(Event e) { ConstSFBool v = (ConstSFBool)e.getValue(); Node node; if(v.getValue()){ node = (Node)(theNode.getValue()); position = (SFVec3f)(node.getExposedField("translation")); position.setValue((position.getX() + 5), 0, 0); } }}
JAVA & The script nodegetSize()getValue()get1Value(int index)setValue(value)set1Value(int index, value)addValue(value)insertValue(int index, value)deleteValue(int index)clearValue()