Extensible 3D (X3D)
Part 1: Architecture and base components
38 Picking component
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).
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.
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 document 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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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. |