openscenegraph
Projector
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//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
14
15#ifndef OSGMANIPULATOR_PROJECTOR
16#define OSGMANIPULATOR_PROJECTOR 1
17
18#include <osgManipulator/Export>
19
20#include <osg/LineSegment>
21#include <osgUtil/SceneView>
22
23#include <osgManipulator/Dragger>
24
25namespace osgManipulator {
26
27/**
28 * Base class for Projectors. Projectors maps 2D cursor motions to 3D motions.
29 */
30class OSGMANIPULATOR_EXPORT Projector : public osg::Referenced
31{
32 public:
33
34 Projector();
35
36 /**
37 * Calculates the object/world coordinates (projectedPoint) of a window
38 * coordinate (pointToProject) when projected onto some shape or
39 * geometry (implemented in derived classes). SceneView in used for i
40 * projecting window coordinates into object coordinates and vice versa.
41 * Returns true on successful projection.
42 */
43 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const = 0;
44
45 /**
46 * Sets the matrix for transforming the projector's local coordinate
47 * system to the world/object coordinate system.
48 */
49 void setLocalToWorld(const osg::Matrix& localToWorld)
50 {
51 _localToWorld = localToWorld;
52 _worldToLocalDirty = true;
53 }
54
55 /**
56 * Gets the matrix for transforming the projector's local coordinate
57 * system to the world/object coordinate system.
58 */
59 inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; }
60
61 /**
62 * Gets the matrix for transforming the world/object coordinate
63 * system to the command's local coordinate system.
64 */
65 inline const osg::Matrix& getWorldToLocal() const
66 {
67 if (_worldToLocalDirty)
68 {
69 _worldToLocal.invert(_localToWorld);
70 _worldToLocalDirty = false;
71 }
72 return _worldToLocal;
73 }
74
75 protected:
76
77 virtual ~Projector();
78
79 osg::Matrix _localToWorld;
80 mutable osg::Matrix _worldToLocal;
81
82 mutable bool _worldToLocalDirty;
83};
84
85
86/**
87 * LineProjector projects points onto the closest point on the given line.
88 */
89class OSGMANIPULATOR_EXPORT LineProjector : public Projector
90{
91 public:
92
93 LineProjector();
94
95 LineProjector(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e);
96
97 inline void setLine(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e) { _line->start() = s; _line->end() = e; }
98
99 inline const osg::LineSegment::vec_type& getLineStart() const { return _line->start(); }
100 inline osg::LineSegment::vec_type& getLineStart() { return _line->start(); }
101
102 inline const osg::LineSegment::vec_type& getLineEnd() const { return _line->end(); }
103 inline osg::LineSegment::vec_type& getLineEnd() { return _line->end(); }
104
105 /**
106 * Calculates the object coordinates (projectedPoint) of a window
107 * coordinate (pointToProject) when projected onto the given line.
108 * Returns true on successful projection.
109 */
110 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
111
112 protected:
113
114 virtual ~LineProjector();
115
116 osg::ref_ptr<osg::LineSegment> _line;
117};
118
119/**
120 * PlaneProjector projects points onto the given line.
121 */
122class OSGMANIPULATOR_EXPORT PlaneProjector : public Projector
123{
124 public:
125
126 PlaneProjector();
127
128 PlaneProjector(const osg::Plane& plane);
129
130 inline void setPlane(const osg::Plane& plane) { _plane = plane; }
131 inline const osg::Plane& getPlane() const { return _plane; }
132
133 /**
134 * Calculates the object coordinates (projectedPoint) of a window
135 * coordinate (pointToProject) when projected onto the given plane.
136 * Returns true on successful projection.
137 */
138 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
139
140 protected:
141
142 virtual ~PlaneProjector();
143
144 osg::Plane _plane;
145};
146
147/**
148 * SphereProjector projects points onto the given sphere.
149 */
150class OSGMANIPULATOR_EXPORT SphereProjector : public Projector
151{
152 public:
153
154 SphereProjector();
155
156 SphereProjector(osg::Sphere* sphere);
157
158 inline void setSphere(osg::Sphere* sphere) { _sphere = sphere; }
159 inline const osg::Sphere* getSphere() const { return _sphere.get(); }
160
161 /**
162 * Calculates the object coordinates (projectedPoint) of a window
163 * coordinate (pointToProject) when projected onto the given sphere.
164 * Returns true on successful projection.
165 */
166 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
167
168 /**
169 * Returns true is the point is in front of the cylinder given the eye
170 * direction.
171 */
172 bool isPointInFront(const PointerInfo& pi, const osg::Matrix& localToWorld) const;
173
174 void setFront(bool front) { _front = front; }
175
176 protected:
177
178 virtual ~SphereProjector();
179
180 osg::ref_ptr<osg::Sphere> _sphere;
181 bool _front;
182};
183
184/**
185 * SpherePlaneProjector projects points onto a sphere, failing which it project
186 * onto a plane oriented to the viewing direction.
187 */
188class OSGMANIPULATOR_EXPORT SpherePlaneProjector : public SphereProjector
189{
190 public:
191
192 SpherePlaneProjector();
193
194 SpherePlaneProjector(osg::Sphere* sphere);
195
196 /**
197 * Calculates the object coordinates (projectedPoint) of a window
198 * coordinate (pointToProject) when projected onto the given sphere.
199 * Returns true on successful projection.
200 */
201 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
202
203 /**
204 * Returns true if the previous projection was on the sphere and false
205 * if the projection was on the plane.
206 */
207 bool isProjectionOnSphere() const { return _onSphere; }
208
209 osg::Quat getRotation(const osg::Vec3d& p1, bool p1OnSphere,
210 const osg::Vec3d& p2, bool p2OnSphere,
211 float radialFactor = 0.0f) const;
212
213 protected:
214
215 virtual ~SpherePlaneProjector();
216
217 mutable osg::Plane _plane;
218 mutable bool _onSphere;
219};
220
221/**
222 * CylinderProjector projects points onto the given cylinder.
223 */
224class OSGMANIPULATOR_EXPORT CylinderProjector : public Projector
225{
226 public:
227
228 CylinderProjector();
229
230 CylinderProjector(osg::Cylinder* cylinder);
231
232 inline void setCylinder(osg::Cylinder* cylinder)
233 {
234 _cylinder = cylinder;
235 _cylinderAxis = osg::Vec3d(0.0,0.0,1.0) * osg::Matrix(cylinder->getRotation());
236 _cylinderAxis.normalize();
237 }
238 inline const osg::Cylinder* getCylinder() const { return _cylinder.get(); }
239
240 /**
241 * Calculates the object coordinates (projectedPoint) of a window
242 * coordinate (pointToProject) when projected onto the given plane.
243 * Returns true on successful projection.
244 */
245 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
246
247
248 /**
249 * Returns true is the point is in front of the cylinder given the eye
250 * direction.
251 */
252 bool isPointInFront(const PointerInfo& pi, const osg::Matrix& localToWorld) const;
253
254 void setFront(bool front) { _front = front; }
255
256 protected:
257
258 virtual ~CylinderProjector();
259
260 osg::ref_ptr<osg::Cylinder> _cylinder;
261 osg::Vec3d _cylinderAxis;
262 bool _front;
263};
264
265/**
266 * CylinderPlaneProjector projects a point onto a plane relative to the
267 * given cylinder. For most cases, the plane will be parallel to the
268 * cylinder axis oriented towards the eyepoint. When the eyepoint and
269 * cylinder axis are close to parallel, then it will project onto a plane
270 * perpendicular to the cylinder.
271 */
272class OSGMANIPULATOR_EXPORT CylinderPlaneProjector : public CylinderProjector
273{
274 public:
275
276 CylinderPlaneProjector();
277
278 CylinderPlaneProjector(osg::Cylinder* cylinder);
279
280 /**
281 * Calculates the object coordinates (projectedPoint) of a window
282 * coordinate (pointToProject) when projected onto the given plane.
283 * Returns true on successful projection.
284 * \param[in] pi Incoming intersection information
285 * \param[out] projectedPoint Point located on the given plane
286 * \return bool Whether the projection onto the plane was successful.
287 */
288 virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
289
290 /**
291 * Generates a rotation about the cylinder axis based upon the incoming
292 * projected points on the plane computed from project().
293 * \param[in] p1 Initial projection point
294 * \param[in] p2 Second projection point
295 * \return osg::Quat Rotation about cylinder axis
296 */
297 osg::Quat getRotation(const osg::Vec3d& p1, const osg::Vec3d& p2) const;
298
299 protected:
300
301 virtual ~CylinderPlaneProjector();
302
303 mutable osg::Plane _plane;
304 mutable osg::Vec3d _planeLineStart, _planeLineEnd;
305 mutable bool _parallelPlane;
306};
307
308}
309
310#endif