Extensible 3D (X3D)
Part 1: Architecture and base components
20 Pointing device sensor component
The name of this component is "PointingDeviceSensor". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).
This clause describes the Pointing Device Sensor component of this part of ISO/IEC 19775. This includes how pointing device sensors operate conceptually as well as which varieties of pointing device sensors are provided. Table 20.1 provides links to the major topics in this clause.
Pointing device sensors detect user pointing events such as the user clicking on a piece of geometry (i.e., TouchSensor). The following node types are pointing device sensors:
The Anchor node is also considered a pointing device sensor for the purpose of detecting user picking. However, it does not extend from the X3DPointingDeviceSensorNode interface.
Other components may add additional pointing device sensors.
A pointing device sensor is activated when the user locates the pointing device over geometry that is influenced by that specific pointing device sensor. Pointing device sensors have influence over all geometry that is descended from the sensor's parent groups. In the case of the Anchor node, the Anchor node itself is considered to be the parent group. Typically, the pointing device sensor is a sibling to the geometry that it influences. In other cases, the sensor is a sibling to groups which contain geometry (i.e., are influenced by the pointing device sensor).
The appearance properties of the geometry do not affect activation of the sensor. In particular, transparent materials or textures shall be treated as opaque with respect to activation of pointing device sensors.
For a given user activation, the lowest enabled pointing device sensor in the hierarchy is activated. All other pointing device sensors above the lowest enabled pointing device sensor are ignored. The hierarchy is defined by the geometry node over which the pointing device sensor is located and the entire hierarchy upward. If there are multiple pointing device sensors tied for lowest, each of these is activated simultaneously and independently, possibly resulting in multiple sensors activating and generating output simultaneously. This feature allows combinations of pointing device sensors (e.g., TouchSensor and PlaneSensor). If a pointing device sensor appears in the transformation hierarchy multiple times (DEF/USE), it shall be tested for activation in all of the coordinate systems in which it appears.
If a pointing device sensor is not enabled when the pointing device button is activated, it will not generate events related to the pointing device until after the pointing device is deactivated and the sensor is enabled (i.e., enabling a sensor in the middle of dragging does not result in the sensor activating immediately).
Drag sensors are a subset of pointing device sensors. There are three types of drag sensors: CylinderSensor, PlaneSensor, and SphereSensor. Drag sensors have two outputOnly fields in common, trackPoint_changed and <value>_changed. These outputOnly fields send events for each movement of the activated pointing device according to their "virtual geometry" (e.g., cylinder for CylinderSensor). The trackPoint_changed outputOnly field sends the intersection point of the bearing with the drag sensor's virtual geometry. The <value>_changed outputOnly field sends the sum of the relative change since activation plus the sensor's offset field. The type and name of <value>_changed depends on the drag sensor type: rotation_changed for CylinderSensor, translation_changed for PlaneSensor, and rotation_changed for SphereSensor.
To simplify the application of these sensors, each node has an offset
and an autoOffset exposed field. When the sensor generates events as
a response to the activated pointing device motion, <value>_changed
sends the sum of the relative change since the initial activation plus the offset
field value. If autoOffset is TRUE when
the pointing device is deactivated, the offset field is set to the sensor's
last <value>_changed value and offset sends an offset_changed
output event. This enables subsequent grabbing operations to accumulate the changes.
If autoOffset is FALSE
, the sensor does
not set the offset field value at deactivation (or any other time).
The pointing device controls a pointer in the virtual world. While activated by the pointing device, a sensor will generate events as the pointer moves. Typically the pointing device may be categorized as either 2D (e.g., conventional mouse) or 3D (e.g., wand). It is suggested that the pointer controlled by a 2D device is mapped onto a plane a fixed distance from the viewer and perpendicular to the line of sight. The mapping of a 3D device may describe a 1:1 relationship between movement of the pointing device and movement of the pointer.
The position of the pointer defines a bearing which is used to determine which geometry is being indicated. When implementing a 2D pointing device it is suggested that the bearing is defined by the vector from the viewer position through the location of the pointer. When implementing a 3D pointing device it is suggested that the bearing is defined by extending a vector from the current position of the pointer in the direction indicated by the pointer.
In all cases the pointer is considered to be indicating a specific geometry when that geometry is intersected by the bearing. If the bearing intersects multiple sensors' geometries, only the sensor nearest to the pointer will be eligible for activation.
X3DDragSensorNode : X3DPointingDeviceSensorNode { SFBool [in,out] autoOffset TRUE SFString [in,out] description "" SFBool [in,out] enabled TRUE SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [out] isActive SFBool [out] isOver SFVec3f [out] trackPoint_changed }
This abstract node type is the base type for all drag-style pointing device sensors.
X3DPointingDeviceSensorNode : X3DSensorNode { SFString [in,out] description "" SFBool [in,out] enabled TRUE SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [out] isActive SFBool [out] isOver }
This abstract node type is the base type for all pointing device sensors.
X3DTouchSensorNode : X3DPointingDeviceSensorNode { SFString [in,out] description "" SFBool [in,out] enabled TRUE SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [out] isActive SFBool [out] isOver SFTime [out] touchTime }
This abstract node type is the base type for all touch-style pointing device sensors.
CylinderSensor : X3DDragSensorNode { SFBool [in,out] autoOffset TRUE SFRotation [in,out] axisRotation 0 1 0 0 SFString [in,out] description "" SFFloat [in,out] diskAngle π/12 [0,π/2] SFBool [in,out] enabled TRUE SFFloat [in,out] maxAngle -1 [-2π,2π] SFNode [in,out] metadata NULL [X3DMetadataObject] SFFloat [in,out] minAngle 0 [-2π,2π] SFFloat [in,out] offset 0 (-∞,∞) SFBool [out] isActive SFBool [out] isOver SFRotation [out] rotation_changed SFVec3f [out] trackPoint_changed }
The CylinderSensor node maps pointer motion (e.g., a mouse or wand) into a rotation on an invisible cylinder that is aligned with the Y-axis of the local sensor coordinate system. The local sensor coordinate system is created by applying the axisRotation field value to the local coordinate system. The CylinderSensor uses the descendent geometry of its parent node to determine whether it is liable to generate events.
The description field in the CylinderSensor node specifies a textual description of the CylinderSensor node. This may be used by browser-specific user interfaces that wish to present users with more detailed information about the CylinderSensor.
The enabled field enables and disables the CylinderSensor node.
If TRUE
,
the sensor reacts appropriately to user events. If FALSE
,
the sensor does not track user input or send events. If enabled receives
a FALSE
event and isActive is TRUE
,
the sensor becomes disabled and deactivated, and outputs an isActive
FALSE
event.
If enabled receives a TRUE
event the sensor is enabled and ready for user activation.
A CylinderSensor node generates events when the pointing device is activated while the pointer is indicating any descendent geometry nodes of the sensor's parent group. See 20.2.3 Activating and manipulating pointing device sensors, for more details on using the pointing device to activate the CylinderSensor.
Upon activation of the pointing device while indicating the sensor's geometry,
an isActive TRUE
event is sent. The initial
acute angle between the bearing vector and the local sensor coordinate system Y-axis of the CylinderSensor
node determines whether the sides of the invisible cylinder or the caps (disks)
are used for manipulation. If the initial angle is less than the diskAngle,
the geometry is treated as an infinitely large disk lying in the Y=0 plane
of the local sensor coordinate system
and coincident with the initial intersection point. Dragging motion is mapped
into a rotation around the +Y-axis vector of the local sensor coordinate system.
The perpendicular vector from the initial intersection point to this Y-axis defines
zero rotation about the Y-axis of the local sensor coordinate system. For each subsequent position of the bearing,
a rotation_changed event is sent that equals the sum of the rotation
about the +Y-axis vector of the local sensor coordinate system (from the initial intersection to the new intersection)
plus the offset value. trackPoint_changed events reflect the unclamped
drag position on the surface of this disk. When the pointing device is deactivated
and autoOffset is TRUE
, offset
is set to the last rotation angle and an offset_changed
event is generated. See 20.2.2 Drag sensors, for
a more general description of autoOffset and offset fields.
If the initial acute angle between the bearing vector and the local sensor
coordinate system Y-axis
of the CylinderSensor node is greater than or equal to diskAngle, the sensor behaves like a cylinder. The shortest distance between the point
of intersection (between the bearing and the sensor's geometry) and the Y-axis
of the parent group's local coordinate system determines the radius of an invisible
cylinder used to map pointing device motion and marks the zero rotation value.
For each subsequent position of the bearing, a rotation_changed event
is sent that equals the sum of the right-handed rotation from the original intersection
about the +Y-axis vector plus the offset value. trackPoint_changed
events reflect the unclamped drag position on the surface of the invisible cylinder.
When the pointing device is deactivated and autoOffset is TRUE
,
offset is set to the last rotation angle and an offset_changed
event is generated. More details are available in 20.2.2
Drag sensors.
When the sensor generates an isActive TRUE
event, it grabs all further motion events from the pointing device until it
is released and generates an isActive FALSE
event (other pointing device sensors shall not generate events during this time).
Motion of the pointing device while isActive is TRUE
is referred to as a "drag" operation. If a 2D pointing device is in use, isActive
events will typically reflect the state of the primary button associated with
the device (i.e., isActive is TRUE
when the primary button is pressed and FALSE
when it is released). If a 3D pointing device (e.g., a wand) is in use,
isActive events will typically reflect whether the pointer is within
or in contact with the sensor's geometry.
While the pointing device is activated, trackPoint_changed
and rotation_changed
events are output and are interpreted from pointing device motion based on the
sensor's local coordinate system at the time of activation. trackPoint_changed
events represent the unclamped intersection points on the surface of the invisible
cylinder or disk. If the initial angle results in cylinder rotation (as opposed
to disk behaviour) and if the pointing device is dragged off the cylinder while
activated, browsers may interpret this in a variety of ways (e.g., clamp all
values to the cylinder and continuing to rotate as the point is dragged away
from the cylinder). Each movement of the pointing device while isActive
is TRUE
generates trackPoint_changed
and rotation_changed events.
The minAngle and maxAngle fields clamp rotation_changed events to a range of values. If minAngle is greater than maxAngle, rotation_changed events are not clamped. The minAngle and maxAngle fields are restricted to the range [-2π, 2π].
More information about this behaviour is described in 20.2 Concepts.
PlaneSensor : X3DDragSensorNode { SFBool [in,out] autoOffset TRUE SFRotation [in,out] axisRotation 0 0 1 0 SFString [in,out] description "" SFBool [in,out] enabled TRUE SFVec2f [in,out] maxPosition -1 -1 (-∞,∞) SFNode [in,out] metadata NULL [X3DMetadataObject] SFVec2f [in,out] minPosition 0 0 (-∞,∞) SFVec3f [in,out] offset 0 0 0 (-∞,∞) SFBool [out] isActive SFBool [out] isOver SFVec3f [out] trackPoint_changed SFVec3f [out] translation_changed }
The PlaneSensor node maps pointing device motion into two-dimensional translation in a plane parallel to the Z=0 plane of the local sensor coordinate system. The local sensor coordinate system is created by applying the axisRotation field value to the local coordinate system. The PlaneSensor node uses the descendent geometry of its parent node to determine whether it is liable to generate events.
The description field in the PlaneSensor node specifies a textual description of the PlaneSensor node. This may be used by browser-specific user interfaces that wish to present users with more detailed information about the PlaneSensor.
The enabled field enables and disables the PlaneSensor. If enabled
is TRUE
, the sensor reacts appropriately to
user events. If enabled is FALSE
, the
sensor does not track user input or send events. If enabled receives
a FALSE
event and isActive is TRUE
,
the sensor becomes disabled and deactivated, and outputs an isActive
FALSE
event.
If enabled receives a TRUE
event, the sensor is enabled and made ready for user activation.
The PlaneSensor node generates events when the pointing device is activated while the pointer is indicating any descendent geometry nodes of the sensor's parent group. See 20.2.3 Activating and manipulating pointing device sensors, for details on using the pointing device to activate the PlaneSensor.
Upon activation of the pointing device (e.g., mouse button down) while
indicating the sensor's geometry, an isActive TRUE
event is sent. Pointer motion is mapped into relative translation in the tracking
plane, (a plane parallel to the local sensor coordinate system Z=0 plane and coincident
with the initial point of intersection). For each subsequent movement of the
bearing, a translation_changed event is output which corresponds to the
sum of the relative translation from the original intersection point to the
intersection point of the new bearing in the plane plus the offset value.
The sign of the translation is defined by the Z=0 plane of the local sensor coordinate
system. trackPoint_changed events reflect the unclamped drag position
on the surface of this plane. When the pointing device is deactivated and autoOffset
is TRUE
, offset is set to the last translation_changed
value and an offset_changed event is generated. More details are provided
in 20.2.2 Drag sensors.
When the sensor generates an isActive TRUE
event, it grabs all further motion events from the pointing device until it
is deactivated and generates an isActive FALSE
event. Other pointing device sensors shall not generate events during this time.
Motion of the pointing device while isActive is TRUE
is referred to as a "drag" operation. If a 2D pointing device is in use, isActive
events typically reflect the state of the primary button associated with the
device (i.e., isActive is TRUE
when
the primary button is pressed, and is FALSE
when it is released). If a 3D pointing device (e.g., wand) is in use, isActive
events typically reflect whether the pointer is within or in contact with the
sensor's geometry.
minPosition and maxPosition may be set to clamp translation_changed events to a range of values as measured from the origin of the Z=0 plane of the local sensor coordinate system. If the X or Y component of minPosition is greater than the corresponding component of maxPosition, translation_changed events are not clamped in that dimension. If the X or Y component of minPosition is equal to the corresponding component of maxPosition, that component is constrained to the given value. This technique provides a way to implement a line sensor that maps dragging motion into a translation in one dimension.
While the pointing device is activated and moved, trackPoint_changed
and translation_changed events are sent. trackPoint_changed events
represent the unclamped intersection points on the surface of the tracking plane.
If the pointing device is dragged off of the tracking plane while activated
(e.g., above horizon line), browsers may interpret this in a variety ways
(e.g., clamp all values to the horizon). Each movement of the pointing device,
while isActive is TRUE
, generates trackPoint_changed
and translation_changed events.
Further information about this behaviour can be found in 20.2 Concepts.
SphereSensor : X3DDragSensorNode { SFBool [in,out] autoOffset TRUE SFString [in,out] description "" SFBool [in,out] enabled TRUE SFNode [in,out] metadata NULL [X3DMetadataObject] SFRotation [in,out] offset 0 1 0 0 [-1,1],(-∞,∞) SFBool [out] isActive SFBool [out] isOver SFRotation [out] rotation_changed SFVec3f [out] trackPoint_changed }
The SphereSensor node maps pointing device motion into spherical rotation about the origin of the local coordinate system. The SphereSensor node uses the descendent geometry of its parent node to determine whether it is liable to generate events.
The description field in the SphereSensor node specifies a textual description of the SphereSensor node. This may be used by browser-specific user interfaces that wish to present users with more detailed information about the SphereSensor.
The enabled field enables and disables the SphereSensor node. If enabled
is TRUE
, the sensor reacts appropriately to
user events. If enabled is FALSE
, the
sensor does not track user input or send events. If enabled receives
a FALSE
event and isActive is TRUE
,
the sensor becomes disabled and deactivated, and outputs an isActive
FALSE
event. If enabled receives a TRUE
event the sensor is enabled and ready for user activation.
The SphereSensor node generates events when the pointing device is activated while the pointer is indicating any descendent geometry nodes of the sensor's parent group. See 20.2.3 Activating and manipulating pointing device sensors, for details on using the pointing device to activate the SphereSensor.
Upon activation of the pointing device (e.g., mouse button down) over the sensor's geometry, an isActive TRUE event is sent. The vector defined by the initial point of intersection on the SphereSensor's geometry and the local origin determines the radius of the sphere that is used to map subsequent pointing device motion while dragging. The virtual sphere defined by this radius and the local origin at the time of activation is used to interpret subsequent pointing device motion and is not affected by any changes to the sensor's coordinate system while the sensor is active. For each position of the bearing, a rotation_changed event is sent which corresponds to the sum of the relative rotation from the original intersection point plus the offset value. trackPoint_changed events reflect the unclamped drag position on the surface of this sphere. When the pointing device is deactivated and autoOffset is TRUE, offset is set to the last rotation_changed value and an offset_changed event is generated. See 20.2 Concepts, for more details.
When the sensor generates an isActive TRUE
event, it grabs all further motion events from the pointing device until it
is released and generates an isActive FALSE
event (other pointing device sensors shall not generate events during this time).
Motion of the pointing device while isActive is TRUE
is termed a "drag" operation. If a 2D pointing device is in use, isActive
events will typically reflect the state of the primary button associated with
the device (i.e., isActive is TRUE
when the primary button is pressed and FALSE
when it is released). If a 3D pointing device (e.g., wand) is in use, isActive
events will typically reflect whether the pointer is within (or in contact with)
the sensor's geometry.
While the pointing device is activated, trackPoint_changed and rotation_changed
events are output. trackPoint_changed events represent the unclamped
intersection points on the surface of the invisible sphere. If the pointing
device is dragged off the sphere while activated, browsers may interpret this
in a variety of ways (e.g., clamp all values to the sphere or continue to rotate
as the point is dragged away from the sphere). Each movement of the pointing
device while isActive is TRUE
generates
trackPoint_changed and rotation_changed events.
Further information about this behaviour can be found in 20.2 Concepts.
TouchSensor : X3DTouchSensorNode { SFString [in,out] description "" SFBool [in,out] enabled TRUE SFNode [in,out] metadata NULL [X3DMetadataObject] SFVec3f [out] hitNormal_changed SFVec3f [out] hitPoint_changed SFVec2f [out] hitTexCoord_changed SFBool [out] isActive SFBool [out] isOver SFTime [out] touchTime }
A TouchSensor node tracks the location and state of the pointing device and detects when the user points at geometry contained by the TouchSensor node's parent group.
The description field in the TouchSensor node specifies a textual description of the TouchSensor node. This may be used by browser-specific user interfaces that wish to present users with more detailed information about the TouchSensor.
A TouchSensor node can be enabled or disabled by sending it an
enabled event with a value of TRUE
or
FALSE
. If the TouchSensor node is disabled,
it does not track user input or send events.
The TouchSensor generates events when the pointing device points toward any geometry nodes that are descendants of the TouchSensor's parent group. See 20.2.3 Activating and manipulating pointing device sensors, for more details on using the pointing device to activate the TouchSensor.
The isOver field reflects the state of the pointing device with regard
to whether it is pointing towards the TouchSensor node's geometry or not. When
the pointing device changes state from a position such that its bearing does
not intersect any of the TouchSensor node's geometry to one in which it does
intersect geometry, an isOver TRUE
event
is generated. When the pointing device moves from a position such that its bearing
intersects geometry to one in which it no longer intersects the geometry, or
some other geometry is obstructing the TouchSensor node's geometry, an isOver
FALSE
event is generated. These events are generated
only when the pointing device has moved and changed `over' state. Events are
not generated if the geometry itself is animating and moving underneath the
pointing device.
As the user moves the bearing over the TouchSensor node's geometry, the point
of intersection (if any) between the bearing and the geometry is determined.
Each movement of the pointing device, while isOver is TRUE
,
generates hitPoint_changed, hitNormal_changed and hitTexCoord_changed
events. hitPoint_changed events contain the 3D point on the surface
of the underlying geometry, given in the TouchSensor node's coordinate system.
hitNormal_changed events contain the surface normal vector at the hitPoint.
hitTexCoord_changed events contain the texture coordinates of that surface
at the hitPoint. The values of hitTexCoord_changed and hitNormal_changed
events are computed as appropriate for the associated shape.
If isOver is TRUE
, the user may activate
the pointing device to cause the TouchSensor node to
generate isActive
events (e.g., by pressing the primary mouse button). When the TouchSensor
node generates an isActive TRUE
event,
it grabs all further motion events from the pointing device until it is released
and generates an isActive FALSE
event
(other pointing device sensors will not generate events during this time). Motion
of the pointing device while isActive is TRUE
is termed a "drag" operation. If a 2D pointing device is in use, isActive
events reflect the state of the primary button
associated with the device (i.e., isActive
is TRUE
when the primary button is pressed and
FALSE
when it is released). If a 3D pointing
device is in use, isActive events will typically reflect whether the
pointing device is within (or in contact with) the TouchSensor node's geometry.
The field touchTime is generated when all three of the following conditions are true:
TRUE
).TRUE
).FALSE
event is also generated).More information about this behaviour is described in 20.2 Concepts.
The Pointing Device Sensor component provides one level of support as specified in Table 20.2.
Table 20.2 — Pointing device sensor component support levels
Level | Prerequisites | Nodes/Features | Support |
---|---|---|---|
1 | Core 1 Grouping 1 Shape 1 |
||
DragSensorNodeType (abstract) | n/a | ||
PointingDeviceSensorNodeType (abstract) | n/a | ||
TouchSensorNodeType (abstract) | n/a | ||
CylinderSensor | All fields fully supported. | ||
PlaneSensor | All fields fully supported. | ||
SphereSensor | All fields fully supported. | ||
TouchSensor | All fields fully supported. |