Sensors are used to detect one of the following:
Time passing.
Pointer device events.
Sensors are often implemented to perform one of the following tasks:
This chapter explains how to implement sensors in the following sections:
csTimeSensor generates timer events either once or repeatedly for a specified interval. A csTimeSensor is typically used to drive animations or periodic events.
A csTimeSensor has five inputs:
enabled
loop
startTime
stopTime
cycleInterval
A csTimeSensor's has four output events:
cycleTime
fractionChanged
isActive
time
To generate time sensor events, you must first enable csTimeSensor by setting the argument of the following method to TRUE:
csTimeSensor::setEnabled(); |
If the argument evaluates FALSE, time sensor events are not generated.
To determine whether or not a csTimeSensor is enabled, use the following method:
csTimeSensor::getEnabled(); |
csTimeSensors are not automatically evaluated. The following method triggers the evaluation of all instantiated csTimeSensors:
csTimeSensor::updateSensors(); |
This method should be called at regular intervals, usually once per frame, for csTimeSensors to function as expected.
By default, if there are instantiated csTimeSensors, csWindow calls csTimeSensor::updateSensors() at regular intervals; the default interval is 16 milliseconds. The frequency of updates can be modified using the following method:
csWindow::enableTimer(float ms); |
where the argument, ms, specifies the frequency of updates in milliseconds. This method enables a timer event, which is fired every ms milliseconds. When the timer event is handled csWindow calls csTimeSensor::updateSensors().
The timer event can be disabled by calling:
csWindow::disableTimer(); |
![]() | Note: The Optimizer class, opViewer, also calls csTimeSensor::updateSensors() by default if there are instantiated time sensors. opViewer also contains the methods enableTimer() and disableTimer() for enabling and disabling timer events. |
csTimeSensor::startTime() and csTimeSensor::stopTime() are csTime values representing the times at which the csTimeSensor should start and stop generating time sensor events.
If stopTime is less than startTime, the csTimeSensor generates events indefinitely, or terminates at the end of one cycle if csTimeSensor:loop() is FALSE. For more information about loop(), see “Continuing Timer Events”.
You can, for example, trigger events based on the time of day using csTime::getTimeOfDay(), which returns the current time of day. Your application can then determine whether or not that time falls between startTime and stopTime.
The following methods are used to get and set the values of startTime and stopTime:
csTimeSensor::getStartTime(); csTimeSensor::setStartTime(); csTimeSensor::getStopTime(); csTimeSensor::setStopTime(); |
A csTimeSensor generates an isActive event when the csTimeSensor is first activated or deactivated. A csTimeSensor is activated if:
Time sensors are updated.
The current time is between startTime and stopTime.
A csTimeSensor is deactivated when the current time is past stopTime or when the argument of loop() is FALSE and the time sensor has completed one cycle.
You can retrieve the current value of isActive by calling:
csTimeSensor::getIsActive(); |
cycleInterval is a float representing the duration of a single cycle in seconds.
For example, if csTimeSensor is driving an animation, a cycle generally represents the number of times you want an animation to run. To run an animation once, set cycleInterval to the length of the animation. To run an animation twice, set cycleInterval to twice the length of the animation.
The following two methods are used to get and set the value of cycleInterval:
csTimeSensor::getCycleInterval(); csTimeSensor::setCycleInterval(); |
csTimeSensor::loop() takes a boolean value. If it is TRUE, the csTimeSensor continues to generate events after the completion of one cycle. If the boolean value is FALSE, csTimeSensor only generates events for a single cycle.
The following two methods are used to get and set the value of loop():
csTimeSensor::getLoop(); csTimeSensor::setLoop(); |
A csTimeSensor generates a cycleTime event whenever the csTimeSensor begins a new cycle. cycleTime is an absolute csTime value. If the csTimeSensor runs for only a single loop, the cycleTime event is only generated at the beginning of the loop.
The current value of cycleTime can be retrieved by calling:
csTimeSensor::getCycleTime(); |
A csTimeSensor generates a fractionChanged event on every update while the csTimeSensor is active. fractionChanged is a float value in the range [0.0, 1.0] representing the percentage of the current cycle completed. If the argument of loop() is TRUE, at the beginning of the first cycle the value of fractionChanged is 0.0. However, the beginning of all subsequent cycles generate a value of 1.0. The different value is a result of the beginning of one cycle coinciding with the end of the previous cycle.
The value of fractionChanged is returned using the following method:
csTimeSensor::getFractionChanged(); |
csSphereSensor maps the drag motion of a pointer device into a spherical rotation about a virtual sphere. The rotation gives the impression that the geometry is attached to the surface of a spinning sphere.
The center of the virtual sphere is located at the center of either the local or world coordinate system, based on whether the argument of csSphereSensor::coordFrame() is LOCAL or WORLD, respectively.
The virtual sphere's radius is determined by the distance between the center and the initial point of intersection.
You can offset the rotation of the virtual sphere using the following method:
csSphereSensor::setOffset(csRotation offset); |
This method adds offset to the rotation value derived from the motion of the pointer device.
setAutoOffet() sets the value of offset in setOffset() to the value of the rotation when the csSphereSensor is deactivated.
To enable autoOffset, call the following method with an argument that evaluates TRUE:
csSphereSensor::setAutoOffet(csBool autoOffset); |
In the case where a csSphereSensor is used to rotate its associated geometry, setting autoOffset to TRUE keeps the geometry from snapping back to its original orientation when the csSphereSensor is activated a second time.
A csSphereSensor begins generating events when both of the following conditions are met:
The pointer device cursor is depressed over geometry associated with a csSphereSensor.
csSphereSensors are updated to determine whether the pointer device cursor is depressed while over a geometry associated with a csSphereSensor.
While the csSphereSensor is active, it generates rotation and trackPoint events. Rotation events represent the orientation of a geometry on the virtual sphere. trackPoint represents the position of the pointer device cursor on the virtual sphere, as shown in Figure 11-1.
The csSphereSensor stops generating events when the pointer device is released.
csSphereSensor is not updated automatically. You customarily update it explicitly when pointer device events are detected, using one of the following methods:
csSphereSensor::updateSensors(); csWindow::updateSensors(); |
The difference between the methods is that the arguments to the csSphereSensor version includes pointer device coordinates.
![]() | Note: csSphereSensor inherits updateSensors() from its abstract, base class, csPickSensor. |
The typical use of a csSphereSensor is to connect it with a transformation node. The effect of the sensor when combined with a transformation node is to rotate associated geometries spherically in local or world space according to the dragging motion of a pointer device: dragging the pointer device to the right spins the front of the geometry to the right; dragging the pointer device up spins the front of the geometry up.
A csSphereSensor is associated with all geometry in the scene graph “below” the parent node of the csSphereSensor, as shown in Figure 11-2.
A csSphereSensor is activated when the pointer device is depressed over its associated geometry. However, its output events, rotation and trackPoint, can be connected to any field in a scene graph. The effects of csSphereSensor, therefore, are not limited to its associated geometry.
To enable csSphereSensor to rotate geometry spherically, you must complete the following two tasks:
Connect a csSphereSensor node to a csTransform node, as follows:
csSphereSensor *sphereSensor = new csSphereSensor; csTransform *transform = new csTransform; sphereSensor->connect(csSphereSensor::ROTATION, transform, csTransform::ROTATION); |
Rotation events are generated by csSphereSensor.
Add the csSphereSensor node as a child to the parent node of the transformation node associated with the geometry to rotate, as shown in Figure 11-2.
A csPlaneSensor maps the drag motion of a pointer device's events into a translation in the XY plane of the local or world coordinate space, depending on the value specified by csPlaneSensor::coordFrame().
A typical use of csPlaneSensor is to connect its output event, translation, to a transformation node. The effect of the sensor when combined with a transformation node is to translate associated geometry in local or world space along the XY plane according to the dragging motion of a pointer device: dragging the pointer device to the right moves the geometry to the right; dragging the pointer device up moves the geometry up.
To enable csPlaneSensor to translate geometry, you must complete the following two tasks:
Connect a csPlaneSensor node to a csTransform node, as follows:
csPlaneSensor *planeSensor = new csPlaneSensor; csTransform *transform = new csTransform; planeSensor->connect(csPlaneSensor::TRANSLATION, transform, csTransform::TRANSLATION); |
Translation events are generated by csPlaneSensor.
Add the csPlaneSensor node as a child to the parent node of the transformation node associated with the geometry to translate, as shown in Figure 11-2.
A csPlaneSensor translates all geometries in the scene graph “below” the parent node of the csPlaneSensor.
A csPlaneSensor is activated when the pointer device is depressed over its associated geometry. However, its output events, translation and trackPoint, can be connected to any field in a scene graph. The effects of csPlaneSensor, therefore, are not limited to its associated geometry.
A csPlaneSensor begins generating events when both of the following conditions are met:
The pointer device cursor is depressed over geometry associated with a csPlaneSensor.
csPlaneSensors are updated to determine whether the pointer device cursor is depressed while over a geometry associated with a csPlaneSensor.
The csPlaneSensor stops generating events when the pointer device is released.
csPlaneSensor is not updated automatically. You customarily update it explicitly when pointer device events are detected, using one of the following methods:
csPlaneSensor::updateSensors(); csWindow::updateSensors(); |
The difference between the methods is that the csPlaneSensor version includes pointer device coordinates.
![]() | Note: csPlaneSensor inherits updateSensors() from the abstract, base class, csPickSensor. |
While the csPlaneSensor is active, it generates translation and trackPoint events. Translation events represent two-dimensional translations in the XY plane based on the motion of the pointer device. The translation value is clamped to the range defined in the following methods:
csPlaneSensor::minPosition(); csPlaneSensor::maxPosition(); |
If the X or Y component of maxPosition is equal to the corresponding component in minPosition, that component is constrained to the specified value.
You can create unclamped translations in two ways:
Setting maxPosition component values less than minPosition values.
Using trackPoint events.
If the X or Y component values of csPlaneSensor::maxPosition() are less than the corresponding component values in csPlaneSensor::minPosition(), the translations in that component's direction are unclamped.
TrackPoint events represent unclamped drag positions of the geometry in the XY plane of local or world space, depending on the value set in csPlaneSensor::setCoordFrame(). For more information about setCoordFrame(), see “Local or World Translations”
To return trackPoint events, use the following method:
csPlaneSensor::getTrackPoint(); |
The translation of geometry associated with a csPlaneSensor occurs either in local or world space according to the value set in the following method:
csPlaneSensor::setCoordFrame(); |
The argument of the method can be either LOCAL or WORLD.
You can offset the translation of the geometry using the following method:
csPlaneSensor::setOffset(csVec3f offset); |
This method adds offset to the translation value derived from the motion of the pointer device.
setAutoOffet() sets the value of offset in setOffset() to the value of the translation when the csSphereSensor is deactivated.
To enable autoOffset, call the following method with an argument that evaluates TRUE:
csPlaneSensor::setAutoOffset(csBool autoOffset); |
In the case where a csPlaneSensor is used to translate its associated geometry, setting autoOffset to TRUE keeps the geometry from snapping back to its original position when the csPlaneSensor is activated for a second time.
csTouchSensor tracks the location of the pointer device cursor and generates up to five outputs when the cursor is over the geometry associated with csTouchSensor. If the pointer device cursor passes over multiple geometry, events are generated based on the geometry nearest the camera.
A geometry is associated with a csTouchSensor when the geometry and csTouchSensor nodes are descendants of the same node, as shown in Figure 11-4.
A csTouchSensor monitors all geometries in the scene graph “below” the parent node of the csTouchSensor. Not only does it monitor the children of csTouchSensor's parent node, it also monitors all the descendants of the children.
csTouchSensor generates up to five of the following events, each with their own preconditions:
isOver returns a boolean value indicating whether the pointing device is over a geometry associated with a csTouchSensor. csTouchSensor generates the isOver event when the isOver state has just changed.
The isOver state changes whenever the pointer device cursor first passes over geometry associated with a csTouchSensor or whenever the pointer device first passes off of the geometry it was previously over. The isOver event is not generated constantly while the pointer device is over a geometry.
When the pointer device cursor is over an associated geometry, the following method evaluates TRUE:
csTouchSensor::getIsOver(); |
csTouchSensor generates the following three hit events whenever the pointing device is over a geometry associated with a csTouchSensor:
hitPoint—represents the coordinates where the pointer device cursor intersects the geometry.
hitNormal—represents the surface normal vector where the pointer device cursor intersects the geometry.
hitTexCoord—represents the surface texture coordinates where the pointer device cursor intersects the geometry.
The touchTime event represents the current time. csTouchSensor generates touchTime events when any of the following conditions are true:
The pointer device cursor is over the geometry when the pointer device button is depressed.
The pointer device cursor is currently over the geometry and isOver is TRUE.
The pointer device button is released.