Normalerweise ist ein Trigger ein Sensor der einen "Event" abschickt,
sobald der Benutzer eine bestimmte Aktion ausführt (z.B. einen Schalter
anklickt oder einen Bereich betritt).
Die Grundlage für das Zusammenspiel zwischen Trigger und anderen
Nodes bilden "Routes". Diese definieren, welche Events von welchem Node
an welchen Node verschickt werden sollen. Über eine Route kann z.B.
direkt ein Feldwert eines Nodes verändert werden.
Für das Ansprechen der Felder ist es nötig, den Nodes mittels
DEF Namen zuzuweisen. Dann kann man die Felder über Nodename.Feldname
referenzieren.
Hier sollen einmal beispielhaft 3 Trigger vorgestellt werden:
Beispiel:
#VRML V2.0 utf8
Group {
children [
DEF Schalter TouchSensor { }
Shape {
appearance Appearance {
material Material {
diffuseColor
0 0 1
}
}
geometry Box {
size 5 5 5
}
}
]
}
DEF Licht PointLight {
on FALSE
intensity 1
location 8 8 8
}
ROUTE Schalter.isOver TO Licht.on
Zuerst wird der Sensor zusammen mit der Sensorfläche (einem Würfel)
in einem Group-Node kombiniert. Anschließend wird eine Lichtquelle
definiert, die zunächst inaktiv ist (on=FALSE). Die ROUTE zwischen
Sensor und Lichtquelle bewirkt, daß das Licht aktiviert wird, sobald
sich der Mauszeiger über dem Sensor befindet (d.h. der Würfel
wird angestrahlt). Hier erkennt man gut, wie die Nodenamen (Schalter, Licht)
beim Routen eingesetzt werden.
Anmerkung: Bei diesem Beispiel muß das "Headlight" im Browser
abgeschaltet werden, sonst ist der Effekt nicht zu sehen!
Die Routen einer Szenerie kann man sich grafisch in Diagrammen aufzeichnen:
Der Proximity Sensor arbeitet im Prinzip wie der TouchSensor. Der Hauptunterschied
besteht darin, daß der Proximity Sensor aktiv wird, sobald sich der
Benutzer in einen definierten Bereich (quaderförmiger Bereich) der
Szene hineinbewegt.
Beispiel:
#VRML V2.0 utf8
Group {
children [
DEF Schalter TouchSensor { }
Shape {
appearance Appearance {
material Material {
diffuseColor
0 0 1
}
}
geometry Box {
size 5 5 5
}
}
]
}
DEF Licht PointLight {
on TRUE
intensity 0
location 8 8 8
}
DEF Timer TimeSensor { cycleInterval 2 }
ROUTE Schalter.touchTime TO Timer.startTime
ROUTE Timer.fraction_changed TO Licht.intensity
Hier wird der Timer durch anklicken des Würfels gestartet
und schickt dann 2 Sekunden lang eine aufsteigende Zahlenfolge (von 0 -
1) an das intensity Feld des Light-Nodes. D.h. der Würfel wird innerhalb
von 2 Sekunden langsam heller bis zur vollen Intensität.
Hier sieht das Routing wie folgt aus:
Beispiel:
#VRML V2.0 utf8
Group {
children [
DEF SensorA TouchSensor {}
DEF SensorB TimeSensor {cycleInterval 5}
DEF GravInterpolator Script {
url "GravInterp.class"
eventOut SFVec3f value_changed
eventIn SFTime set_time
}
DEF TransformA Transform {
translation 0 10 0
children [
Shape {
appearance
Appearance {
material Material {
ambientIntensity 0
diffuseColor 1 0 0
shininess 0.9
}
}
geometry
Sphere {radius 2.5}
}
]
}
]
}
ROUTE SensorA.touchTime TO SensorB.startTime
ROUTE SensorB.time TO GravInterpolator.set_time
ROUTE GravInterpolator.value_changed TO TransformA.translation
Dieses Beispiel erzeugt eine Kugel die, nachdem sie angeklickt wurde, 5 Sekunden lang nach unten "fällt" und dabei immer schneller wird (Gravitation). Da der Timer immer linear hochzählt, kann er hier nicht für die Bewegung der Kugel eingesetzt werden. Die Bewegung übernimmt in diesem Fall ein JAVA-Programm. Die Kommunikation mit dem Programm erfolgt über den Script Node. In diesem wird die URL des JAVA/JAVAScript Programms angegeben und die Felder eventIn / eventOut. EventIn gibt an, welche Werte an das Programm übergeben werden können (hier time), eventOut dementsprechend, was vom Programm an den Browser zurückgeliefert wird (hier value_changed, ein Feld mit 3 Werten für x,y,z).
Grafik des Routing: