Touch me
tested with
+
+
Today I talk about the TouchSensor and
how to ROUTE events from it. The TouchSensor is one of five
pointing device sensors (speak: mouse). It is used as a child of the
triggering parent node.
Let's say you modeled a light switch and you want it to do something
when clicked on. You would place a TouchSensor node into the
lightSwitch group. The lightSwitch is the parent and the TouchSensor
is one of it's children.
DEF lightSwitch Group {
children [
lots of children ...
DEF touchSwitch TouchSensor { }
]
}
Most of the time you will need to name your TouchSensor in order to
ROUTE from it. The TouchSensor has several eventOuts
and one of them is isActive. When clicked on the TouchSensor's
parent node the TouchSensor will emit the event TRUE since it is
active now. OK, now I have that 'TRUE' floating around, so what? The
solution is 'ROUTEing'. A ROUTE simply takes the
eventOut value and ROUTEs it to an eventIn.
Wou wou wou, not that fast, what eventIn are you tallking about?
Without a Script node there are not many interesting eventIns
to ROUTE to. Viewpoint for example has an eventIn of
type boolean.
Viewpoints let the user view your world from different locations.
It is sometimes easy to get lost in VR space so it is a good idea to provide
your visitors with central orientation points. Let's add two of them to our
Hello World file and rename it to
'touchme.wrl':
DEF view1 Viewpoint {
position 0 0 20
description "view1"
}
DEF view2 Viewpoint {
position 5 0 20
description "view2"
}
The Viewpoints are named and the names appear as a string in the
field description. This has the benefit that a visitor can directly
change viewpoints from the browser's menu (hopefully). The position
field locates view1 at x=0 y=0 z=20. This is 20 units (meters) in front of
the sphere. View2 is 5 units to the right, thus in front of the red cube.
Back to our main topic: place a TouchSensor as a child into the
box Transform.
DEF box Transform {
children [
Shape { ... Box ... }
DEF touchBox TouchSensor { }
]
}
....
Check the Touch me source
and look at Touch me.wrl. Clicking
on the TouchSensor will do not much (nothing visible, only
sending 'isActive'-eventOuts out).
That is what we need the ROUTE for. It will take the 'touchBox'
eventOut (TRUE) and ROUTE it to the eventIn of 'view2'.
The eventIn we need is set_bind which deactivates the current
Viewpoint and activates the one we ROUTEd to.
ROUTE touchBox.isActive TO view2.set_bind
After loading the scene
(Touch me.wrl) click on the box and
keep the mouse button down.
This will ROUTE the 'touchBox' eventOut to the 'view2'
eventIn. The technical term is 'a viewpoint is bound to the current
view'.
Hmm, interesting, but I want to jump to the new viewpoint and stay there.
How can I accomplish this?
We need a Script for this. A Script node has like any other
nodes eventIn, eventOut, and field values. For our purpose we
need to feed an eventIn from the TouchSensor node to the
Script node. I call it 'touchBoxIsActive'. We also need an
eventOut from the Script node which we feed to the
Viewpoint node. I call it 'bindView2'.
DEF touchScript Script {
eventIn SFBool touchBoxIsActive
eventOut SFBool bindView2
....
}
Think of a Script as a black box. You send it an eventIn
(touchBoxIsActive) and you will receive an eventOut (bindView2).
Let's go back to the ROUTE for a minute. We used the following
ROUTE in the previous example:
ROUTE touchBox.isActive TO view2.set_bind
Now we take a detour through the Script node instead:
ROUTE touchBox.isActive TO touchScript.touchBoxIsActive
ROUTE touchScript.bindView2 TO view2.set_bind
Still, our scene won't do much. The Script node isn't written yet.
All what we need for that is a statement which sets on receiving an
eventIn the eventOut to TRUE.
function touchBoxIsActive(active) {
bindView2 = TRUE;
}
When node 'touchScript' receives an eventIn (touchBoxIsActive), it
calls the function 'touchBoxIsActive' and executes it. Here it simply sets
'bindView2' to TRUE. Now there is an eventOut available and can be
ROUTEd to the Viewpoint node.
The function itself is written in 'javascript'.
url "javascript:
function touchBoxIsActive(active) {
bindView2 = TRUE;
}"
Please note that the name of the eventIn is identical to the name
of the function. Every eventIn to a Script has a corresponding
function.
As a result, the Touch me.wrl scene
will change it's viewpoint permanently. You can change the viewpiont back via
the browser menu. Touch me source
shows today's work as a whole.
I hope that I could bring some light to this topic. ROUTEing and
Scripting are important features in VRML2.0 and once you understand
the concept of eventIns and eventOuts you will have a solid base
for further experiments.

Copyright © 1996-98
Markus Roskothen. All rights reserved.