Projector 9.8 KB

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