Extensible 3D (X3D)
Part 1: Architecture and base components

38 Picking component

--- X3D separator bar ---

cube 38.1 Introduction

38.1.1 Name

The name of this component is "Picking". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).

38.1.2 Overview

This component provides the ability to test for arbitrary object collision in a somewhat limited form. In traditional 3D graphics terminology, this is termed picking. The intention is not to support full n-body object collision, but to provide an extended set of basic capabilities to provide some limited custom interactions, such as terrain following. Table 38.1 provides links to the major topics in this clause.

Table 38.1 — Topics

cube 38.2 Concepts

38.2.1 Overview

This component provides a means of testing for object intersection that permits a greater degree of programmable interaction of content. Various types of geometrical elements may be used to test for intersection between the renderable scene graph and the nodes provided by this component. When one or more intersections are found, the results are reported using the sensor model of this International Standard and are then available for further processing by the event model.

Intersection testing consists of two parts: an object representing the type of intersection to be created and a scene graph tree to be tested. The intersecting object is represented by nodes that extend the X3DPickSensorNode abstract type. Instances of X3DPickableObject mark a scene graph subtree as a target for testing.

38.2.2 Event model interaction

Picking is performed between rendered frames of the event model. A user sets up the picking request in one frame by placing, in the desired location, a node derived from X3DPickSensorNode. Such a node is termed a pick sensor. At the start of the next frame any intersections are reported from the pick sensor.

Picking notification is performed at the start of the frame for all enabled pick sensors when all other sensors are processed (see 4.4.8.3 Execution model step b).  Disabled pick sensors do not need to be evaluated. This allows the user to manipulate geometry and have the pick results returned at the start of the frame, thus ensuring a fixed, known state at all times.

38.2.3 Transformation Hierarchy

Testing for intersection tests is a global action within each execution context. pick sensors may report intersections with contained contexts, but only to the wrapper and not the contents of that context.

EXAMPLE  Picking against a scene that contains an Inline node will return the Inline node as the picked geometry rather than a node from the contents of the geometry.

A pick sensor is located at the desired position and orientation in the scene graph using the transformation hierarchy. The pick sensor is affected by translation, orientation and scale operations. If a non-uniform scale is applied to the pick sensor, the results are dependent on the selected component level.

The picked objects are those that have been given to that specific pick sensor instance in its pickTarget field.  All transformations above those picked objects are applied to the picking process. Picking is performed in world coordinate space after transformations have been applied to both the pick sensor and the target nodes.

Sections of the scene graph contained by a X3DPickableObject are used for additional filtering of the picking operations. The pickable object has a set of flags defined in the objectType field that can be used to classify sections of the scene graph so that picking will only report intersections in those classifications.

EXAMPLE  A pickable object classifies itself as a "WATER" object and the pick sensor declares that it is picking for "GROUND" objects. Even though the pick sensor intersects with the picking object, no result is returned because the pickable object and the pick sensor do not have the same object type category.

When reporting results requires specific geometry intersection points, the results are reported in the local coordinate space of the pick sensor.

cube 38.3 Abstract types

38.3.1 X3DPickableObject

X3DPickableObject {
  MFString [in,out] objectType "ALL" ["ALL","NONE","TERRAIN",...]
  SFBool   [in,out] pickable   TRUE
}

The X3DPickableObject abstract interface marks a node as being capable of having customized picking performed on its contents or children.

The pickable field is used to independently control whether picking may be performed on this node or its children. Setting the value to FALSE will remove the children from the list of potential matches for picking. This only affects children that are accessed through the transformation hierarchy of the parent. If one or more of the children of this instance is accessible through another transformation hierarchy through DEF/USE that still has picking enabled, they shall still be pickable through that path only. Object picking according to the pickable field occurs even if the object is not rendered visibly.

The objectType field specifies a label that is used in the picking process. Each string specified is treated as an independent label that needs to be matched against the same type in one of the pick sensor instances.

EXAMPLE  Labeling a group with the value "WATER" and then attempting to intersect a pick sensor with objectType "GROUND" would fail as the objectType values are not matching.

The special object type "ALL" means that it is available for picking regardless of the type specified by the pick sensor. The special value "NONE" overrides the presence of any other string values in this objectType field, thereby disabling picking for this node. The presence of special value "ALL" indicates that all objectType values defined within the scope defined by the construct derived from X3DPickableObject are eligible. If both "NONE" and "ALL" are specified, the special value "NONE" applies. The user may define any values for objectType.

38.3.2 X3DPickSensorNode

X3DPickSensorNode : X3DSensorNode {
  SFString [in,out] description      ""
  SFBool   [in,out] enabled          TRUE
  SFNode   [in,out] metadata         NULL        [X3DMetadataObject]
  SFString [in,out] matchCriterion   "MATCH_ANY" ["MATCH_ANY"|"MATCH_EVERY"|"MATCH_ONLY_ONE"]
  MFString [in,out] objectType       "ALL"       ["ALL","NONE","TERRAIN",...]
  SFNode   [in,out] pickingGeometry  NULL        [X3DGeometryNode]
  MFNode   [in,out] pickTarget       []          [X3DGroupingNode|X3DShapeNode|Inline]
  MFNode   [out]    pickedGeometry
  SFBool   [out]    isActive
  SFString []       intersectionType "BOUNDS"    ["GEOMETRY"|"BOUNDS"|...]
  SFString []       sortOrder        "CLOSEST"   ["ANY"|"CLOSEST"|"ALL"|"ALL_SORTED"|...] 
}

The X3DPickSensorNode abstract node type is the base type that represents the lowest common denominator of picking capabilities. An X3DPickSensorNode is a type of X3DSensorNode. The field isActive is TRUE whenever there is a picked item available. If the intersecting object is not picked by the picking geometry, the pick sensor is not active.

The intersectionType field specifies the precision of the collision computation. When testing intersections, "BOUNDS" indicates that the pickingGeometry is intersected with the bounding box of the pickable object, whereas "GEOMETRY" indicates that the pickingGeometry is intersected with the geometry of the pickable object. The intersectionType constants may be extended by the individual concrete node to provide additional options.

EXAMPLE 1  An intersectionType may be used to specify the specific algorithm used for the detection.

The objectType field lists the types of object that are to be tested for intersections. The special value "NONE" overrides the presence of any other string values in this objectType field, thereby disabling picking for this node. The presence of the "ALL" special value indicates that all objectTypes are potential pick targets. If both "NONE" and "ALL" are specified, the value "NONE" applies. An arbitrary label (such as "TERRAIN") may be specified here as well as the predefined types. Such a label indicates that only pickable objects with an identical label may be picked.

The matchCriterion field defines whether the X3DPickSensorNode pick matches one or more objectType value(s), as follows:

The pickingGeometry field specifies the exact coordinates of the geometry that will be performing the intersection testing. The acceptable range of node types and how they are to be interpreted shall be defined by the individual concrete nodes.

The pickTarget field specifies the list of nodes against which the picking operation should be performed. All nodes declared in this field and their descendents shall be evaluated for intersections based on the specific sensor definition. If a descendent of the nodes declared in this field includes another X3DPickSensorNode instance, the children of the descendent X3DPickSensorNode's pickTarget field are not considered for picking.

The pickedGeometry field communicates the node or nodes that have been found to intersect with the picking geometry from the last time this node performed a picking operation. The values provided shall be dependent on the setting of the sortOrder field.

The sortOrder field has four predefined values. Browser implementations may define additional values and algorithms beyond these four required values.

cube 38.4 Node reference

38.4.1 LinePickSensor

LinePickSensor : X3DPickSensorNode {
  SFString [in,out] description             ""
  SFBool   [in,out] enabled                 TRUE
  SFString [in,out] matchCriterion          "MATCH_ANY" ["MATCH_ANY"|"MATCH_EVERY"|"MATCH_ONLY_ONE"]
  SFNode   [in,out] metadata                NULL        [X3DMetadataObject]
  MFString [in,out] objectType              "ALL"       ["ALL","NONE","TERRAIN",...]
  SFNode   [in,out] pickingGeometry         NULL        [IndexedLineSet|LineSet]
  MFNode   [in,out] pickTarget              []          [X3DGroupingNode|X3DShapeNode|Inline]
  SFBool   [out]    isActive
  MFNode   [out]    pickedGeometry
  MFVec3f  [out]    pickedNormal
  MFVec3f  [out]    pickedPoint
  MFVec3f  [out]    pickedTextureCoordinate
  SFString []       intersectionType        "BOUNDS"    ["GEOMETRY"|"BOUNDS"|...]
  SFString []       sortOrder               "CLOSEST"   ["ANY"|"CLOSEST"|"ALL"|"ALL_SORTED"|...] 
}

The LinePickSensor node picks one or more line segments as the test object with which to pick. As a line intersect generates a known point in space, normal, geometry and texCoord information can be returned that is useful.

Line picking, for sort order determination is based on the pair of coordinates that defines the line segment. The first declared vertex of the segment is defined to be the start of the line to which the intersection points are closest.

When the picking line segment intersects a coplanar polygon and one vertex lies outside the polygon, the intersection point(s) will be those on the edge(s) of the polygon (see Figure 38.1 (a)). If the entire segment lies entirely within the polygon then the intersection point shall be defined to be the start point of the segment. For concave polygons where both ends of the segment lie in the polygon but the line exits the polygon for some portion (see Figure 38.1 (b)), the intersection points are the intersecting edges of the polygon, where sort order is defined as in the previous paragraph.

Illustration of Line Intersection conditions

Figure 38.1 — Illustration of the different conditions of intersections of lines and coplanar polygons. (a) One end point contained in the polygon and one external. (b)Both end points internal to the polygon. Point A is the start point of the line and the numbers indicate the sort order that shall be returned.

Picked texture coordinates are in three dimensions. If the target object has multiple textures defined, only the texture coordinates for the first texture are returned. All other textures are ignored. If the target texture coordinate has two dimensions, the third coordinate (z component of an SFVec3f) shall be zero.

38.4.2 PickableGroup

PickableGroup : X3DGroupingNode, X3DPickableObject {
  MFNode   [in]     addChildren
  MFNode   [in]     removeChildren
  SFBool   [in,out] bboxDisplay    FALSE
  MFNode   [in,out] children       []       [X3DChildNode]
  SFString [in,out] description    ""
  SFNode   [in,out] metadata       NULL     [X3DMetadataObject]
  MFString [in,out] objectType     "ALL"    ["ALL","NONE","TERRAIN",...]
  SFBool   [in,out] pickable       TRUE
  SFBool   [in,out] visible        TRUE
  SFVec3f  []       bboxCenter     0 0 0    (-∞,∞)
  SFVec3f  []       bboxSize       -1 -1 -1 [0,∞) or -1 -1 -1
}

A PickableGroup node is an X3DGroupingNode that contains children that are marked as being of a given classification of picking types, as well as the ability to enable or disable picking of the children.

For field definitions, see 38.3.1 X3DPickableObject and 10.3.2 X3DGroupingNode.

38.4.3 PointPickSensor

PointPickSensor : X3DPickSensorNode {
  SFString [in,out] description      ""
  SFBool   [in,out] enabled          TRUE
  SFString [in,out] matchCriterion   "MATCH_ANY" ["MATCH_ANY"|"MATCH_EVERY"|"MATCH_ONLY_ONE"]
  SFNode   [in,out] metadata         NULL        [X3DMetadataObject]
  MFString [in,out] objectType       "ALL"       ["ALL","NONE","TERRAIN",...]
  SFNode   [in,out] pickingGeometry  NULL        [PointSet]
  MFNode   [in,out] pickTarget       []          [X3DGroupingNode|X3DShapeNode|Inline]
  SFBool   [out]    isActive
  MFNode   [out]    pickedGeometry
  MFVec3f  [out]    pickedPoint
  SFString []       intersectionType "BOUNDS"    ["GEOMETRY"|"BOUNDS"|...]
  SFString []       sortOrder        "CLOSEST"   ["ANY"|"CLOSEST"|"ALL"|"ALL_SORTED"|...] 
}
The PointPickSensor node tests one or more points in space as lying inside the provided target geometry. For each of the picked points intersecting the geometry, the point coordinate is returned as an element in the pickedPoint field, and the corresponding geometry node (inside which each intersection point lies) is returned as an element of the pickedGeometry field.

Because points represent an infinitely small location in space, the "CLOSEST" and "ALL_SORTED" sort orders are defined to mean "ANY" and "ALL" respectively.

38.4.4 PrimitivePickSensor

PrimitivePickSensor : X3DPickSensorNode {
  SFString [in,out] description      ""
  SFBool   [in,out] enabled          TRUE
  SFString [in,out] matchCriterion   "MATCH_ANY" ["MATCH_ANY"|"MATCH_EVERY"|"MATCH_ONLY_ONE"]
  SFNode   [in,out] metadata         NULL        [X3DMetadataObject]
  MFString [in,out] objectType       "ALL"       ["ALL","NONE","TERRAIN",...]
  SFNode   [in,out] pickingGeometry  NULL        [Cone|Cylinder|Sphere|Box]
  MFNode   [in,out] pickTarget       []          [X3DGroupingNode|X3DShapeNode|Inline]
  SFBool   [out]    isActive
  MFNode   [out]    pickedGeometry
  SFString []       intersectionType "BOUNDS"    ["GEOMETRY"|"BOUNDS"|...]
  SFString []       sortOrder        "CLOSEST"   ["ANY"|"CLOSEST"|"ALL"|"ALL_SORTED"|...] 
}
The PrimitivePickSensor node picks against the target geometry using one of the basic primitive object types specified in the pickingGeometry field.

Boolean fields used to control visibility of subsections of a primitive are ignored when evaluating the picking routines.

EXAMPLE  A cylinder missing the end caps is still treated as an enclosed cylinder.

Sorting is defined based on the primitive type as follows:

  1. For Cone, the closest picked primitive is defined to be that closest to the vertex point.
  2. For Cylinder, Box, and Sphere, the closest picked primitive is defined to be that closest to the centre.

38.4.5 VolumePickSensor

VolumePickSensor : X3DPickSensorNode {
  SFString [in,out] description      ""
  SFBool   [in,out] enabled          TRUE
  SFString [in,out] matchCriterion   "MATCH_ANY" ["MATCH_ANY"|"MATCH_EVERY"|"MATCH_ONLY_ONE"]
  SFNode   [in,out] metadata         NULL        [X3DMetadataObject]
  MFString [in,out] objectType       "ALL"       ["ALL","NONE","TERRAIN",...]
  SFNode   [in,out] pickingGeometry  NULL        [X3DGeometryNode]
  MFNode   [in,out] pickTarget       []          [X3DGroupingNode|X3DShapeNode|Inline]
  SFBool   [out]    isActive
  MFNode   [out]    pickedGeometry
  SFString []       intersectionType "BOUNDS"    ["GEOMETRY"|"BOUNDS"|...]
  SFString []       sortOrder        "CLOSEST"   ["ANY"|"CLOSEST"|"ALL"|"ALL_SORTED"|...] 
}

The VolumePickSensor picks against an arbitrary volume defined by the geometry. The volume is defined by the convex hull of the enclosing planes of the provided geometry. If the provided volume is not manifold, the pick results are undefined.

A pick is successful if any vertex of the pickTarget geometry intersects the volume defined by the pickingGeometry.  The sort order is based on the distance between the centers of the bounds of the picking geometry and the picked geometry.

cube 38.5 Support levels

The Picking component provides three levels of support as specified in Table 38.2.

Table 38.2 — Picking component support levels

Level Prerequisites Nodes/Features Support
1 Core 1
Grouping 1
Shape 1
Rendering 1
X3DPickSensorNode n/a
X3DPickableObject n/a
LinePickSensor All fields fully supported.
PickableGroup All fields fully supported.
PointPickSensor All fields fully supported.
2 Core 1
Grouping 1
Shape 1
Rendering 1
   
    All Level 1 nodes All fields fully supported.
    PrimitivePickSensor All fields fully supported. Non uniform scale not supported.
3 Core 1
Grouping 1
Shape 1
Rendering 1
   
    All Level 2 nodes All fields fully supported.
    PrimitivePickSensor All fields fully supported. Non-uniform scale supported.
    VolumePickSensor All fields fully supported.
--- X3D separator bar ---