openscenegraph
IntersectVisitor
Go to the documentation of this file.
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version. The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14#ifndef OSGUTIL_INTERSECTVISITOR
15#define OSGUTIL_INTERSECTVISITOR 1
16
17#include <osg/NodeVisitor>
18#include <osg/LineSegment>
19#include <osg/Geode>
20#include <osg/Matrix>
21#include <osg/Transform>
22
23#include <osgUtil/Export>
24
25#include <map>
26#include <set>
27#include <vector>
28
29namespace osgUtil {
30
31
32/** Deprecated */
33class OSGUTIL_EXPORT Hit
34{
35 public:
36
37 Hit();
38 Hit(const Hit& hit);
39 ~Hit();
40
41 Hit& operator = (const Hit& hit);
42
43 typedef std::vector<int> VecIndexList;
44
45 bool operator < (const Hit& hit) const
46 {
47 if (_originalLineSegment<hit._originalLineSegment) return true;
48 if (hit._originalLineSegment<_originalLineSegment) return false;
49 return _ratio<hit._ratio;
50 }
51
52
53 const osg::Vec3& getLocalIntersectPoint() const { return _intersectPoint; }
54 const osg::Vec3& getLocalIntersectNormal() const { return _intersectNormal; }
55
56 const osg::Vec3 getWorldIntersectPoint() const { if (_matrix.valid()) return _intersectPoint*(*_matrix); else return _intersectPoint; }
57 const osg::Vec3 getWorldIntersectNormal() const ;
58
59 float getRatio() const { return _ratio; }
60 const osg::LineSegment* getOriginalLineSegment() const { return _originalLineSegment.get(); }
61 const osg::LineSegment* getLocalLineSegment() const { return _localLineSegment.get(); }
62 osg::NodePath& getNodePath() { return _nodePath; }
63 const osg::NodePath& getNodePath() const { return _nodePath; }
64 osg::Geode* getGeode() { return _geode.get(); }
65 const osg::Geode* getGeode() const { return _geode.get(); }
66 osg::Drawable* getDrawable() { return _drawable.get(); }
67 const osg::Drawable* getDrawable() const { return _drawable.get(); }
68 const osg::RefMatrix* getMatrix() const { return _matrix.get(); }
69 const osg::RefMatrix* getInverseMatrix() const { return _inverse.get(); }
70 const VecIndexList& getVecIndexList() const { return _vecIndexList; }
71 int getPrimitiveIndex() const { return _primitiveIndex; }
72
73
74 float _ratio;
75 osg::ref_ptr<osg::LineSegment> _originalLineSegment;
76 osg::ref_ptr<osg::LineSegment> _localLineSegment;
77 osg::NodePath _nodePath;
78 osg::ref_ptr<osg::Geode> _geode;
79 osg::ref_ptr<osg::Drawable> _drawable;
80 osg::ref_ptr<osg::RefMatrix> _matrix;
81 osg::ref_ptr<osg::RefMatrix> _inverse;
82
83 VecIndexList _vecIndexList;
84 int _primitiveIndex;
85 osg::Vec3 _intersectPoint;
86 osg::Vec3 _intersectNormal;
87
88
89};
90
91
92/** Deprecated - use IntersectionVisitor instead.*/
93class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor
94{
95 public:
96
97 IntersectVisitor();
98 virtual ~IntersectVisitor();
99
100 META_NodeVisitor(osgUtil, IntersectVisitor)
101
102 void reset();
103
104 /** Add a line segment to use for intersection testing during scene traversal.
105 * Note, a maximum of 32 line segments can be added to a IntersectVistor,
106 * adding more than this will result in warning being emitted to the console
107 * and the excess segments being ignored.*/
108 void addLineSegment(osg::LineSegment* seg);
109
110 typedef std::vector<Hit> HitList;
111 typedef std::map<const osg::LineSegment*,HitList > LineSegmentHitListMap;
112
113 HitList& getHitList(const osg::LineSegment* seg) { return _segHitList[seg]; }
114
115 int getNumHits(const osg::LineSegment* seg) { return _segHitList[seg].size(); }
116
117 LineSegmentHitListMap& getSegHitList() { return _segHitList; }
118
119 bool hits();
120
121 enum LODSelectionMode
122 {
123 USE_HIGHEST_LEVEL_OF_DETAIL,
124 USE_SEGMENT_START_POINT_AS_EYE_POINT_FOR_LOD_LEVEL_SELECTION
125 };
126
127 void setLODSelectionMode(LODSelectionMode mode) { _lodSelectionMode = mode; }
128 LODSelectionMode getLODSelectionMode() const { return _lodSelectionMode; }
129
130 /** Set the eye point in local coordinates.
131 * This is a pseudo-EyePoint for billboarding and LOD purposes.
132 * It is copied from the Start point of the most-recently-added segment
133 * of the intersection ray set (IntersectState::_segList). */
134 void setEyePoint(const osg::Vec3& eye) { _pseudoEyePoint = eye; }
135
136 virtual osg::Vec3 getEyePoint() const;
137
138
139 /** Get the distance from a point to the eye point, distance value in local coordinate system.
140 * This is calculated using the pseudo-EyePoint (above) when doing LOD calculcations. */
141 virtual float getDistanceToEyePoint(const osg::Vec3& pos, bool withLODScale) const;
142
143 virtual void apply(osg::Node&);
144 virtual void apply(osg::Drawable&);
145 virtual void apply(osg::Geode& node);
146 virtual void apply(osg::Billboard& node);
147
148 virtual void apply(osg::Group& node);
149 virtual void apply(osg::Transform& node);
150 virtual void apply(osg::Switch& node);
151 virtual void apply(osg::LOD& node);
152
153 protected:
154
155 class IntersectState : public osg::Referenced
156 {
157 public:
158
159 IntersectState();
160
161 osg::ref_ptr<osg::RefMatrix> _view_matrix;
162 osg::ref_ptr<osg::RefMatrix> _view_inverse;
163 osg::ref_ptr<osg::RefMatrix> _model_matrix;
164 osg::ref_ptr<osg::RefMatrix> _model_inverse;
165
166 typedef std::pair<osg::ref_ptr<osg::LineSegment>,osg::ref_ptr<osg::LineSegment> > LineSegmentPair;
167 typedef std::vector< LineSegmentPair > LineSegmentList;
168 LineSegmentList _segList;
169
170 typedef unsigned int LineSegmentMask;
171 typedef std::vector<LineSegmentMask> LineSegmentMaskStack;
172 LineSegmentMaskStack _segmentMaskStack;
173
174 bool isCulled(const osg::BoundingSphere& bs,LineSegmentMask& segMaskOut);
175 bool isCulled(const osg::BoundingBox& bb,LineSegmentMask& segMaskOut);
176
177 void addLineSegment(osg::LineSegment* seg);
178
179 protected:
180
181 ~IntersectState();
182
183 };
184
185 bool intersect(osg::Drawable& gset);
186
187 void pushMatrix(osg::RefMatrix* matrix, osg::Transform::ReferenceFrame rf);
188 void popMatrix();
189
190 bool enterNode(osg::Node& node);
191 void leaveNode();
192
193 typedef std::vector<osg::ref_ptr<IntersectState> > IntersectStateStack;
194
195 IntersectStateStack _intersectStateStack;
196
197 LineSegmentHitListMap _segHitList;
198
199 LODSelectionMode _lodSelectionMode;
200 osg::Vec3 _pseudoEyePoint;
201};
202
203/** Deprecated Use LineSegmentIntersector/IntersectionVisitor or View::computeIntersections(..).*/
204class OSGUTIL_EXPORT PickVisitor : public osgUtil::IntersectVisitor
205{
206 public:
207
208 PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj, const osg::Matrixd& view, float mx, float my);
209
210 void runNestedPickVisitor(osg::Node& node, const osg::Viewport* viewport, const osg::Matrix& proj, const osg::Matrix& view, float mx, float my);
211
212 void apply(osg::Projection& projection);
213
214 void apply(osg::Camera& camera);
215
216 protected:
217
218 float _mx;
219 float _my;
220
221 osg::ref_ptr<const osg::Viewport> _lastViewport;
222 osg::Matrixd _lastProjectionMatrix;
223 osg::Matrixd _lastViewMatrix;
224};
225
226}
227
228#endif
229