|
|
Sensors
In order to implement the behaviour of a virtual world, we need to pass events between nodes. In VRML, data (events) flow from the eventOut field of one node to an eventIn field of the same datatype of another node. The receiving node may respond to the event by processing it, and generating further events, and/or use it to update one of it's fields. For example:
However, events need to come from somewhere, and this is where sensors come in. Sensors generate events. The TimeSensor, which is commonly used to control animations (see the Animation module of this course) generates fraction values that can be passed to an interpolator. Most of the other VRML sensors generate events as the result of a user action (e.g. clicking on an object) or user proximity: The standard VRML97 sensors are:
In addition to these, the Collision group node and the Anchor node can also be used to detect user interaction and generate events. TouchSensorA TouchSensor detects a mouse (actually, any pointing device) event over any of the shapes in the same group (including the group's children) as the sensor. The TouchSensor has six eventOut fields that generate events depending on what user actions are sensed. The most commonly used of these are:
In addition to the eventOut fields above, the TouchSensor has an 'exposedField' called 'enabled' which can be set to TRUE or FALSE. This can be used to turn the sensor on/off by routing SFBool events to it. The default value is TRUE so to create an active TouchSensor, you just need to add DEF a_name TouchSensor{} to a Group's children in order to add an active sensor to the group. Note that you need to name the sensor, otherwise you will not be able to route events to or from it. For example (to use a TouchSensor to activate a TimeSensor using the TouchSensor's touchTime):
DEF Clock TimeSensor {
enabled FALSE
cycleInterval 5.0
}
DEF Touch TouchSensor {}
ROUTE Touch.touchTime TO Clock.set_startTime
Route diagram for the code above:
TimeSensorThe TimeSensor is a clock that generates events. The node's exposed fields are:
The fields above are used to configure the TimeSensor, to determine when events should be generated. The TimeSensor's eventOut fields are used to route events from the TimeSensor to other nodes.
We can build on the previous example by routing the fraction_changed value of the TimeSensor to an interpolator, which in turn outputs values that are routed to a Transform group, thus playing the animation every time the TouchSensor detects a mouse click. A complete VRML example of how to start an animation when the user touches a shape:
#VRML V2.0 utf8
Group {
children [
DEF GreenBox Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.0 1.0 0.0
}
}
geometry Box {}
}
]
},
DEF Touch TouchSensor {},
DEF Clock TimeSensor {
cycleInterval 2.0
},
DEF Path OrientationInterpolator {
key [ 0.0 0.5 1.0 ]
keyValue [
0.0 1.0 1.0 0.0,
0.0 1.0 1.0 3.14,
0.0 1.0 1.0 6.28
]
}
]
}
ROUTE Touch.touchTime TO Clock.set_startTime
ROUTE Clock.fraction_changed TO Path.set_fraction
ROUTE Path.value_changed TO GreenBox.set_rotation
Route diagram for the code above:
Advanced interactive simulations can be created using a combination of TouchSensors (to generate initial events), Scripts (to determine what to do with them) and TimeSensors to play resulting animations. For example, to create an interactive door, you could attach a TouchSensor to a door shape and route the touchTime to a Script so that the Script generates an event to start an animation to either open or close the door depending on whether the door was open or closed when it was clicked on. We will look at how scripts can be used to do this a little later in this module. CylinderSensor, PlaneSensor, and SphereSensorThese sensors are are used to detect mouse drag motion that can (for example) be used to translate objects depending on user actions. The CylinderSensor generates SFRotation values around the Y axis, as if the user is rotating a cylinder. The SphereSensor generates SFRotation values, as if the user is rotating a ball. The PlaneSensor outputs values in the XY plane of the sensor's parent coordinate system when the sensor is active. The values outputed from these sensors can be routed directly to a Transform group, enabling the user to drag the sensed shape around (PlaneSensor), rotate it freely (SphereSensor) or rotate it around the Y axis (CylinderSensor). CylinderSensor VRML Example:
#VRML V2.0 utf8
Group {
children [
DEF GreenBox Transform {
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0.0 1.0 0.0
}
}
geometry Box {
}
}
]
},
DEF Drag CylinderSensor { }
]
}
ROUTE Drag.rotation_changed TO GreenBox.rotation
A PlanseSensor can be used to translate a Transform group in planes other than XY by rotating the coordinate system of a group containing the sensor and the Transform group, and rotating the Transform group to compensate for the previous rotation.
Using PlaneSensor to move objects in XZ plane VRML Example:
#VRML V2.0 utf8
Group {
children [
Transform {
# rotate coord system around X-axis so XY is in parents XZ
rotation 1.0 0.0 0.0 1.57
children [
DEF TheObject Transform {
# rotate back around X-axis to compensate for rotated
# coord system of parent group
rotation 1.0 0.0 0.0 -1.57
children [
Shape {
geometry Box {}
appearance Appearance {
material Material {
diffuseColor 1 0 0
}
}
}
]
},
DEF TheSensor PlaneSensor {}
]
}
]
}
ROUTE TheSensor.translation_changed TO TheObject.set_translation
These sensors have a number of exposedFields that can be used to set constraints, which we will come back to in the next section of this module. ProximitySensor, VisibilitySensor, and CollisionThese sensor nodes generate events based on the user's location in the virtual environment as opposed to mouse clicks or mouse drag motion. The Proximity sensor generates events if the user is within a user defined distance from a sensed group. It's eventOut fields include isActive, enterTime, exitTime, position_changed, and orientation_changed. The position and orientation changed values are positions within the sensed region, in the coordinate system of the ProximitySensor. The VisiblitySensor senses whether a boxed shape area is visible to the user. EventOut fields are isActive, enterTime, and exitTime. The Collision node is a group node that generates a collideTime event when the user collides with any shape within the group. |
|
|
Michael Louka, October 31, 2001 |