Intersects objects with a ray cast into scene. More...
#include <Inventor/actions/SoRayPickAction.h>
Public Types | |
enum | PickingMode { DEFAULT, POINT_PICKING } |
Public Member Functions | |
virtual SoType | getTypeId () const |
SoRayPickAction (const SbViewportRegion &viewportRegion) | |
virtual void | clearApplyResult () |
void | setPickingMode (PickingMode pickingMode) |
PickingMode | getPickingMode () const |
void | setPoint (const SbVec2s &viewportPoint) |
void | setPoint (const SbVec2f &viewportPoint) |
const SbVec2s & | getPoint () const |
const SbVec2f & | getPointFloat () const |
void | setNormalizedPoint (const SbVec2f &normPoint) |
const SbVec2f | getNormalizedPoint () const |
void | setRadius (float radius) |
float | getRadius () const |
void | setRay (const SbVec3f &start, const SbVec3f &direction, float nearDistance=-1.0, float farDistance=-1.0) |
void | setRay (float fovy, const SbVec3f &start, const SbVec3f &direction, float nearDistance=-1.0, float farDistance=-1.0) |
void | setPickAll (SbBool flag) |
SbBool | isPickAll () const |
const SoPickedPointList & | getPickedPointList () const |
SoPickedPoint * | getPickedPoint (int index=0) const |
SoDEPRECATED void | clearPickedPointList () |
void | enableRadiusForTriangles (SbBool flag) |
SbBool | isRadiusEnableForTriangles () |
void | enableTexCoordsGeneration (const SbBool enable) |
void | enableNormalsGeneration (const SbBool enable) |
SbBool | isTexCoordsGenerationEnabled () const |
SbBool | isNormalsGenerationEnabled () const |
void | enableConicPickVolume (SbBool flag) |
SbBool | isConicPickVolume () |
Static Public Member Functions | |
static SoType | getClassTypeId () |
static void | setStereoMode (SoCamera::StereoMode stereoMode) |
static SoCamera::StereoMode | getStereoMode () |
static void | enableTriangleCulling (SbBool flag) |
static SbBool | isTriangleCulling () |
Intersects objects with a ray cast into scene.
This class performs picking by casting a ray into a scene and performing intersection tests with each object. The ray is extended to be a frustum a pyramid or a rectangular prism, a cone or a cylinder, depending on the camera type and client inputs (refer to setRay and enableConicPickVolume) for intersection with points and lines. Each intersection is returned as an SoPickedPoint instance.
The picking ray can be specified as either a ray from the camera location through a particular viewport pixel, or as a world-space ray. Calling any of the setPoint, setNormalizedPoint, or setRadius methods tells the action to compute the picking ray from a viewport pixel. In this case, a camera node must be encountered during traversal of the scene graph in order to determine the location of the ray in world space.
Callers can request the action to compute all intersections along the ray (sorted closest to farthest) by setting the pickAll flag to TRUE. By default, the action computes only the closest intersection. In either case, the intersections are returned in an SoPickedPointList. Each intersection can be examined by accessing the appropriate SoPickedPoint in the list. The SoPickedPoint object provides methods to get the path (SoPath) to the picked geometry in the scene graph, the intersection point in 3D space and other info.
The SoPickedPoint object can also return one of the subclasses of SoDetail, which contains more information about the picked geometry. For example, if a polygonal geometry node like SoIndexedFaceSet was picked, an SoFaceDetail object is returned which provides methods to get the index of the face in the primitive, the vertices of the face and so on. For vertex based geometry each vertex can then be queried as an SoPointDetail.
Note: Texture coordinates for the picked point are not computed by default (to save time). If you need this information, use enableTexCoordsGeneration(). Or set the environment variable OIV_PICK_GENERATE_ALL_PROPERTIES. You can also disable computing the normal vector for the picked if you do not need this information. See enableNormalsGeneration().
Open Inventor does true geometric picking in 3D coordinates (it does not use OpenGL for picking), so there are no limits on the number of objects in the scene or the number of objects that can be picked. Geometric picking means that precise intersections with the geometry are computed. It also means that picking works for any type of primitive, including polygonal geometry, meshes (MeshViz) and volumes (VolumeViz). The picking volume can be projected through the scene using orthogonal or perspective projection. See setRay for details. The shape of the picking volume can be rectangular (prism if orthogonal, frustum if perspective) or conic (cylinder if orthogonal, cone if perspective). See enableConicPickVolume().
In the default mode, Inventor computes the intersection of the pick ray with geometry nodes (face, line, point, volume, mesh, etc). In this case SoPickedPoint::getPoint() returns the coordinate of the intersection and SoPickedPoint::getDetail() typically returns an SoDetail class specific to the picked geometry. Since Open Inventor 9.0, SoRayPickAction also supports a POINT_PICKING mode (see PickingMode). In this mode, Inventor finds all the vertices inside the pick radius. This is only supported for SoBufferedShape and classes derived from SoIndexedShape. This mode can be much faster because, for example, it does not need to check for intersection with all the triangles of an SoIndexedFaceSet.
Applications can use the SoPickStyle node to control if and how geometry can be picked. For example application might want to specify that annotation geometry, e.g. a legend, is not pickable. It can also specify that geometry should be picked using its bounding box rather than exact geometry. This may be more efficient for text strings when it is not necessary to know which character in the string was picked.
The application can get platform independent input events, e.g. mouse button press, as SoEvent objects using the SoEventCallback node. In the callback function the application can create an SoRayPickAction and apply it to the scene graph. Note however that the application can also simply call the node's getPickedPoint() method. In this case Open Inventor automatically applies a pick action to the scene graph and returns the result, so the application does not need to use SoRayPickAction directly. Creating and using an SoRayPickAction explicitly does allow more options to be set. In this case the application will normally call setPoint with the position obtained from the event object. If using system events directly, remember that Open Inventor expects Y pixel values to start from zero at the bottom of the window.
The SoSelection node provides an even higher level way to manage selecting and de-selecting objects in the scene. This node automatically applies a pick action and maintains a list of currently selected objects (paths). Using SoSelection the application does not need to use SoRayPickAction directly. The SoExtSelection node provides more complex picking algorithms. For example it allows the user to select objects using a "rubberband" rectangle or a freeform shape (lasso). Open Inventor provides special render actions that can automatically highlight objects selected using an SoSelection or SoExtSelection node. See SoBoxHighlightRenderAction and SoLineHighlightRenderAction.
Optimization
Traversing the camera node:
Picking SoVolumeRender nodes:
Picking shape nodes:
Hidden references:
Shapes that redefine the rayPick method:
Sets: SoPickRayElement, SoViewportRegionElement
void mouseBtnCB(void *userData, SoEventCallback *node ) { const SoEvent* evt = node->getEvent(); // If this is a mouse button1 press event if (SO_MOUSE_PRESS_EVENT( evt, BUTTON1 )) { SoHandleEventAction* action = node->getAction(); // Do picking using event's cursor position SoRayPickAction rayPick( action->getViewportRegion() ); rayPick.setPoint( evt->getPosition() ); rayPick.setRadius( 10 ); // Optional: Use larger pick radius rayPick.apply( action->getPickRoot() ); const SoPickedPoint* pickedPt = rayPick.getPickedPoint(); if (pickedPt != NULL) { SoFullPath* pickedPath = (SoFullPath*)pickedPt->getPath(); SoNode* pickedNode = pickedPath->getTail(); } } }
SoPickedPoint, SoPickedPointList, SoPickStyle
BufferedShapePicking, TicTacToe, MedicalVolumePickingGpu, EditingFeature, EditingPicking
DEFAULT |
In the default mode, Inventor computes the intersection of the pick ray with geometry nodes (face, line, point, volume, mesh, etc). SoPickedPoint::getPoint() returns the coordinate of the intersection and SoPickedPoint::getDetail() returns (usually) an SoDetail class specific to the picked geometry. |
POINT_PICKING |
In this mode, Inventor finds all the vertices inside the pick radius. However this is only supported for SoBufferedShape and classes derived from SoIndexedShape. This mode can be much faster because, for example, it does not need to check for intersection with the triangles of an SoIndexedFaceSet. For pick radius see setRadius(). Specific different behaviors include:
|
SoRayPickAction::SoRayPickAction | ( | const SbViewportRegion & | viewportRegion | ) |
Constructor takes viewport region to use for picking.
Even though the picking operation may not involve a window per se, some nodes need this information to determine their size and placement.
virtual void SoRayPickAction::clearApplyResult | ( | ) | [virtual] |
Clears the picked point list.
The picked point list is automatically cleared when the action is destroyed or re-applied. However it may be useful to clear the list explicitly in order to remove references to picked node(s).
Reimplemented from SoAction.
SoDEPRECATED void SoRayPickAction::clearPickedPointList | ( | ) |
Clears the picked point list.
The picked point list is automatically cleared when the action is destroyed or re-applied. However it may be useful to clear the list explicitly in order to remove references to picked node(s).
void SoRayPickAction::enableConicPickVolume | ( | SbBool | flag | ) |
Controls the pick volume shape for picking with setRay().
The default is FALSE, meaning that the picking volume is a rectangular shape, either a prism or a frustum (depending on which version of setRay was called). When enableConicPickVolume is TRUE the picking volume is a conic shape, either a cylinder or a cone (depending on which version of setRay was called).
Setting enableConicPickVolume to TRUE ensures that the entities picked using setRay() will be the same as picking using an equivalent call to setPoint(), but this mode is slightly more costly than frustum picking.
void SoRayPickAction::enableNormalsGeneration | ( | const SbBool | enable | ) |
Enables generation of normal vectors for picked points.
Default is TRUE.
void SoRayPickAction::enableRadiusForTriangles | ( | SbBool | flag | ) | [inline] |
Enable radius for triangle-based shape.
If TRUE, the radius of the ray specified by setRadius is taken in account when checking for a ray intersection with triangle-based shapes (e.g., SoCylinder). Otherwise, the pick radius for these shapes is 1 pixel regardless of the specified pick radius. Default is FALSE for performance.
void SoRayPickAction::enableTexCoordsGeneration | ( | const SbBool | enable | ) |
Enables generation of texture coordinates for picked points.
Default is FALSE for performance (unless environment variable OIV_PICK_GENERATE_ALL_PROPERTIES envvar is set to TRUE).
static void SoRayPickAction::enableTriangleCulling | ( | SbBool | flag | ) | [static] |
Enables culling of triangles relative to the ray frustum.
Enabling culling improves performance for shapes containing a large number of triangles. Default is FALSE.
static SoType SoRayPickAction::getClassTypeId | ( | ) | [static] |
Returns the type identifier for this class.
Reimplemented from SoPickAction.
Reimplemented in ScRayPickAction.
const SbVec2f SoRayPickAction::getNormalizedPoint | ( | ) | const [inline] |
Gets the viewport point in normalized coordinates [0..1] (returns the last value passed to setNormalizedPoint).
A point is inside the viewport if its coordinates are in the range [0, 1]. If the setRay method was called instead of one of the setXXXPoint methods, this method returns (NaN, NaN).
SoPickedPoint* SoRayPickAction::getPickedPoint | ( | int | index = 0 |
) | const |
Returns the indexed picked point from the list.
Returns NULL if index is larger than the number of picked points.
Note: Each SoPickedPoint object contains an SoPath with the path to the picked node; therefore the picked node's ref count has been incremented and will remain incremented until the SoPickedPoint object is destroyed.
The SoPickedPoint object is owned by the pick action. It will be destroyed when the action is destroyed or when either apply() or clearApplyResult() is called.
const SoPickedPointList& SoRayPickAction::getPickedPointList | ( | ) | const |
Returns list of picked points.
This results in a copy of the picked point list and a copy of every SoPickedPoint object in the list.
PickingMode SoRayPickAction::getPickingMode | ( | ) | const |
Returns the PickingMode used for the ray pick action.
const SbVec2s& SoRayPickAction::getPoint | ( | ) | const [inline] |
Gets the viewport point in pixels (returns the last value passed to setPoint).
const SbVec2f& SoRayPickAction::getPointFloat | ( | ) | const [inline] |
Float version of getPoint().
It can be used when a desktop is magnified on a wall of screens using ScaleViz with a tracker device calibrated for this wall.
float SoRayPickAction::getRadius | ( | ) | const [inline] |
Gets the radius (in pixels) around the point.
static SoCamera::StereoMode SoRayPickAction::getStereoMode | ( | ) | [static] |
Returns the view used to perform pick when stereo is active.
virtual SoType SoRayPickAction::getTypeId | ( | ) | const [virtual] |
Returns the type identifier for this specific instance.
Reimplemented from SoPickAction.
Reimplemented in ScRayPickAction.
SbBool SoRayPickAction::isConicPickVolume | ( | ) | [inline] |
Returns TRUE if the picking volume is a conic shape (not a frustum).
SbBool SoRayPickAction::isNormalsGenerationEnabled | ( | ) | const |
Returns whether generation of normal vectors is enabled for picked points.
SbBool SoRayPickAction::isPickAll | ( | ) | const [inline] |
Returns whether the action will return all objects intersected or just the closest one.
SbBool SoRayPickAction::isRadiusEnableForTriangles | ( | ) | [inline] |
Returns whether the pick radius specified by setRadius is taken into account for picking on triangle-based shapes.
SbBool SoRayPickAction::isTexCoordsGenerationEnabled | ( | ) | const |
Returns whether texture coordinate generation is enabled for picked points.
static SbBool SoRayPickAction::isTriangleCulling | ( | ) | [inline, static] |
Returns whether triangle culling is enabled.
void SoRayPickAction::setNormalizedPoint | ( | const SbVec2f & | normPoint | ) |
Sets the viewport point in normalized coordinates, which range from (0,0) at the lower left to (1,1) at the upper right.
NOTE: You can use this method or setPoint or setRay. Whichever method you call last is the one that takes effect.
Reimplemented in ScRayPickAction.
void SoRayPickAction::setPickAll | ( | SbBool | flag | ) | [inline] |
Sets whether the action will return all objects intersected or just the closest one.
Default is FALSE (only closest intersection).
void SoRayPickAction::setPickingMode | ( | PickingMode | pickingMode | ) |
Sets the picking mode.
Use enum PickingMode. Default value is PickingMode::DEFAULT
void SoRayPickAction::setPoint | ( | const SbVec2f & | viewportPoint | ) |
Float version of setPoint.
It can be used when a desktop is magnified on a wall of screens using ScaleViz with a tracker device calibrated for this wall.
NOTE: You can use this method or setNormalizedPoint or setRay. Whichever method you call last is the one that takes effect.
Reimplemented in ScRayPickAction.
void SoRayPickAction::setPoint | ( | const SbVec2s & | viewportPoint | ) |
Sets the viewport point through which the ray passes, starting at the camera position.
Viewport coordinates range from (0,0) at the lower left to (width-1,height-1) at the upper right. Default is (0,0).
NOTE: You can use this method or setNormalizedPoint or setRay. Whichever method you call last is the one that takes effect.
Reimplemented in ScRayPickAction.
void SoRayPickAction::setRadius | ( | float | radius | ) |
Sets the radius around the point.
The radius is defined in pixels when defining a ray using the setPoint or setNormalizedPoint method, and is defined in world coordinates, when the ray is defined using the setRay method. By default, for the setPoint and setNormalizedPoint method the radius is 5 pixels.
For the setRay method, by default, the radius is not taken into account for triangle based shapes, only for points and lines. To enable this use the enableRadiusForTriangles method. When radius is taken into account, the ray is extended in 3D space. For perspectivecameras, the ray is extended to be a cone. For orthographic cameras, the ray is extended to be a cylinder.
Specifying a radius of 0 may give better performance. In particular, some shapes like MoMeshSkin and SoIndexedFaceSet implement a fast GPU picking algorithm that can only be used when radius is 0.
See also SoQtViewer::setPickRadius(), SoWinViewer::setPickRadius(), SoXtViewer::setPickRadius.
void SoRayPickAction::setRay | ( | float | fovy, | |
const SbVec3f & | start, | |||
const SbVec3f & | direction, | |||
float | nearDistance = -1.0 , |
|||
float | farDistance = -1.0 | |||
) |
Sets a world-space ray along which to pick in the the same way as the other version of setRay(), but allows you to set a view angle value.
The ray is defined as a world space starting point and direction vector. The direction vector will be normalized automatically. The last two arguments specify optional near and far plane clipping during the pick operation. These values are distances from the start point along the direction vector, similar to nearDistance and farDistance in SoCamera. A negative distance (such as the default values) means disable clipping to that plane.
If fovy is non-zero, perspective ray-picking is used. This means the pick volume is a frustum intersecting the plane passing through the point specified as start argument and having normal vector specified by the direction argument and whose base is a square having edges of length setRadius * 2 or else a circle of radius setRadius if enableConicPickVolume is set to TRUE.
NOTE: You can use this method or the setPoint / setNormalizedPoint Whichever method you call last is the one that takes effect.
Reimplemented in ScRayPickAction.
void SoRayPickAction::setRay | ( | const SbVec3f & | start, | |
const SbVec3f & | direction, | |||
float | nearDistance = -1.0 , |
|||
float | farDistance = -1.0 | |||
) |
Sets a world-space ray along which to pick.
The ray is defined as a world space starting point and direction vector. The direction vector will be normalized automatically. The last two arguments specify optional near and far plane clipping during the pick operation. These values are distances from the start point along the direction vector, similar to nearDistance and farDistance in SoCamera. A negative distance (such as the default values) means disable clipping to that plane.
The ray-picking is orthogonal. This means the pick volume is a rectangular prism with a square base having edges of length setRadius * 2 or else a cylinder having radius setRadius if enableConicPickVolume is set to TRUE.
NOTE: You can use this method or the setPoint / setNormalizedPoint Whichever method you call last is the one that takes effect.
Reimplemented in ScRayPickAction.
static void SoRayPickAction::setStereoMode | ( | SoCamera::StereoMode | stereoMode | ) | [static] |
Tells ray pick action in which view the pick occurs.
When stereo mode is active, user can choose between left, right, or normal view to perform the action. Only applicable when stereo is active. Default is LEFT_VIEW.