How to customize OpenSceneGraph’s line intersector to select line segments
Problem statement
This tutorial is based on the section Designing customized intersectors of Chapter 10, OpenSceneGraph Cookbook1. The main difference between this tutorial and the reference material is that we demonstrate how to extend the point selector into line segment selector.
This tutorial is potentially not complete2 and aimed to only provide a base of line segment selection, i.e., the line segment selection is only possible by clicking next to the segment’s vertices, and not necessary next to the line itself. The selection of the line segment by clicking at any point next to the line will be covered in one of the future tutorials.
Line segment class
We define a line segment as two vertices connected by a line (edge).
Our line segment class should allow us to set up the coordinates for the segment ends, and also change the segment color, for example, when it is selected by user. It has the following interface:
Check the implementation details in the accompanying code.
User-defined intersector for selection of line segments
In order to avoid ambiguity with names (the base line intersector is already named osgUtil::LineSegmentIntersector
since it searches intersection between line segment cast by mouse and geometries), we will call our customized intersector as StrokeIntersector
. The StrokeIntersector
means finding intersections between line segment cast by mouse and stroke (or line segment) drawn by user on a scene.
For our task, we can follow the same steps as in tutorial of Chapter 10 of OpenSceneGraph Cookbook1. First, we define the StrokeIntersector
API. We have to override the constructors, method clone()
and the most important method intersect()
:
The constructors and method clone()
are straightforward to implement. For the intersect()
, we only have to process those osg::Geometry
s that are of the type LineSegment
(for this we use dynamic_cast
). All the rest of the implementation remains the same.
Line segment selection inside event handler
We use the customized intersector inside a customized event handler. The algorithm is as follows:
- If right mouse button is pressed,
- Initialize
StrokeIntersector
and pass the current camera view to it. - If the intersector contains any intersections as result,
- Get a drawable result and cast it to the
LineSegment
type. - If the cast was successful, change the color of that line segment. Also, make sure the previously selected line segment is unselected.
Conclusion
In this brief tutorial we demonstrated how to use point selector example of OpenSceneGraph Cookbook1 and derive your own line segment selector. This tutorial is not complete since it only allows stroke selection by clicking close to the stroke vertices (\(x_0\) and \(x_1\) on the figure below). The complete version would mean to perform selection when clicked close to any point \(x_i\) on the line segment.
For the moment, this part is out-of-scope of this tutorial. However, it is covered in the second part of the tutorial.
Codes
Check a bit more complex example - OSG intersectors where three different intersectors are presented: line, point and with a virtual plane (based on raycast algortihm). With OSG intersectors code, the fully functional line intersector is used when performing hovering over the wire in order to select it.
Leave a Comment