311 lines
9.8 KiB
C++
311 lines
9.8 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
|
|
*
|
|
* This library is open source and may be redistributed and/or modified under
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
* included with this distribution, and on the openscenegraph.org website.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* OpenSceneGraph Public License for more details.
|
|
*/
|
|
//osgManipulator - Copyright (C) 2007 Fugro-Jason B.V.
|
|
|
|
#ifndef OSGMANIPULATOR_PROJECTOR
|
|
#define OSGMANIPULATOR_PROJECTOR 1
|
|
|
|
#include <osgManipulator/Export>
|
|
|
|
#include <osg/LineSegment>
|
|
#include <osgUtil/SceneView>
|
|
|
|
#include <osgManipulator/Dragger>
|
|
|
|
namespace osgManipulator {
|
|
|
|
/**
|
|
* Base class for Projectors. Projectors maps 2D cursor motions to 3D motions.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT Projector : public osg::Referenced
|
|
{
|
|
public:
|
|
|
|
Projector();
|
|
|
|
/**
|
|
* Calculates the object/world coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto some shape or
|
|
* geometry (implemented in derived classes). SceneView in used for i
|
|
* projecting window coordinates into object coordinates and vice versa.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const = 0;
|
|
|
|
/**
|
|
* Sets the matrix for transforming the projector's local coordinate
|
|
* system to the world/object coordinate system.
|
|
*/
|
|
void setLocalToWorld(const osg::Matrix& localToWorld)
|
|
{
|
|
_localToWorld = localToWorld;
|
|
_worldToLocalDirty = true;
|
|
}
|
|
|
|
/**
|
|
* Gets the matrix for transforming the projector's local coordinate
|
|
* system to the world/object coordinate system.
|
|
*/
|
|
inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; }
|
|
|
|
/**
|
|
* Gets the matrix for transforming the world/object coordinate
|
|
* system to the command's local coordinate system.
|
|
*/
|
|
inline const osg::Matrix& getWorldToLocal() const
|
|
{
|
|
if (_worldToLocalDirty)
|
|
{
|
|
_worldToLocal.invert(_localToWorld);
|
|
_worldToLocalDirty = false;
|
|
}
|
|
return _worldToLocal;
|
|
}
|
|
|
|
protected:
|
|
|
|
virtual ~Projector();
|
|
|
|
osg::Matrix _localToWorld;
|
|
mutable osg::Matrix _worldToLocal;
|
|
|
|
mutable bool _worldToLocalDirty;
|
|
};
|
|
|
|
|
|
/**
|
|
* LineProjector projects points onto the closest point on the given line.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT LineProjector : public Projector
|
|
{
|
|
public:
|
|
|
|
LineProjector();
|
|
|
|
LineProjector(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e);
|
|
|
|
inline void setLine(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e) { _line->start() = s; _line->end() = e; }
|
|
|
|
inline const osg::LineSegment::vec_type& getLineStart() const { return _line->start(); }
|
|
inline osg::LineSegment::vec_type& getLineStart() { return _line->start(); }
|
|
|
|
inline const osg::LineSegment::vec_type& getLineEnd() const { return _line->end(); }
|
|
inline osg::LineSegment::vec_type& getLineEnd() { return _line->end(); }
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given line.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
protected:
|
|
|
|
virtual ~LineProjector();
|
|
|
|
osg::ref_ptr<osg::LineSegment> _line;
|
|
};
|
|
|
|
/**
|
|
* PlaneProjector projects points onto the given line.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT PlaneProjector : public Projector
|
|
{
|
|
public:
|
|
|
|
PlaneProjector();
|
|
|
|
PlaneProjector(const osg::Plane& plane);
|
|
|
|
inline void setPlane(const osg::Plane& plane) { _plane = plane; }
|
|
inline const osg::Plane& getPlane() const { return _plane; }
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given plane.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
protected:
|
|
|
|
virtual ~PlaneProjector();
|
|
|
|
osg::Plane _plane;
|
|
};
|
|
|
|
/**
|
|
* SphereProjector projects points onto the given sphere.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT SphereProjector : public Projector
|
|
{
|
|
public:
|
|
|
|
SphereProjector();
|
|
|
|
SphereProjector(osg::Sphere* sphere);
|
|
|
|
inline void setSphere(osg::Sphere* sphere) { _sphere = sphere; }
|
|
inline const osg::Sphere* getSphere() const { return _sphere.get(); }
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given sphere.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
/**
|
|
* Returns true is the point is in front of the cylinder given the eye
|
|
* direction.
|
|
*/
|
|
bool isPointInFront(const PointerInfo& pi, const osg::Matrix& localToWorld) const;
|
|
|
|
void setFront(bool front) { _front = front; }
|
|
|
|
protected:
|
|
|
|
virtual ~SphereProjector();
|
|
|
|
osg::ref_ptr<osg::Sphere> _sphere;
|
|
bool _front;
|
|
};
|
|
|
|
/**
|
|
* SpherePlaneProjector projects points onto a sphere, failing which it project
|
|
* onto a plane oriented to the viewing direction.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT SpherePlaneProjector : public SphereProjector
|
|
{
|
|
public:
|
|
|
|
SpherePlaneProjector();
|
|
|
|
SpherePlaneProjector(osg::Sphere* sphere);
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given sphere.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
/**
|
|
* Returns true if the previous projection was on the sphere and false
|
|
* if the projection was on the plane.
|
|
*/
|
|
bool isProjectionOnSphere() const { return _onSphere; }
|
|
|
|
osg::Quat getRotation(const osg::Vec3d& p1, bool p1OnSphere,
|
|
const osg::Vec3d& p2, bool p2OnSphere,
|
|
float radialFactor = 0.0f) const;
|
|
|
|
protected:
|
|
|
|
virtual ~SpherePlaneProjector();
|
|
|
|
mutable osg::Plane _plane;
|
|
mutable bool _onSphere;
|
|
};
|
|
|
|
/**
|
|
* CylinderProjector projects points onto the given cylinder.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT CylinderProjector : public Projector
|
|
{
|
|
public:
|
|
|
|
CylinderProjector();
|
|
|
|
CylinderProjector(osg::Cylinder* cylinder);
|
|
|
|
inline void setCylinder(osg::Cylinder* cylinder)
|
|
{
|
|
_cylinder = cylinder;
|
|
_cylinderAxis = osg::Vec3d(0.0,0.0,1.0) * osg::Matrix(cylinder->getRotation());
|
|
_cylinderAxis.normalize();
|
|
}
|
|
inline const osg::Cylinder* getCylinder() const { return _cylinder.get(); }
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given plane.
|
|
* Returns true on successful projection.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
|
|
/**
|
|
* Returns true is the point is in front of the cylinder given the eye
|
|
* direction.
|
|
*/
|
|
bool isPointInFront(const PointerInfo& pi, const osg::Matrix& localToWorld) const;
|
|
|
|
void setFront(bool front) { _front = front; }
|
|
|
|
protected:
|
|
|
|
virtual ~CylinderProjector();
|
|
|
|
osg::ref_ptr<osg::Cylinder> _cylinder;
|
|
osg::Vec3d _cylinderAxis;
|
|
bool _front;
|
|
};
|
|
|
|
/**
|
|
* CylinderPlaneProjector projects a point onto a plane relative to the
|
|
* given cylinder. For most cases, the plane will be parallel to the
|
|
* cylinder axis oriented towards the eyepoint. When the eyepoint and
|
|
* cylinder axis are close to parallel, then it will project onto a plane
|
|
* perpendicular to the cylinder.
|
|
*/
|
|
class OSGMANIPULATOR_EXPORT CylinderPlaneProjector : public CylinderProjector
|
|
{
|
|
public:
|
|
|
|
CylinderPlaneProjector();
|
|
|
|
CylinderPlaneProjector(osg::Cylinder* cylinder);
|
|
|
|
/**
|
|
* Calculates the object coordinates (projectedPoint) of a window
|
|
* coordinate (pointToProject) when projected onto the given plane.
|
|
* Returns true on successful projection.
|
|
* \param[in] pi Incoming intersection information
|
|
* \param[out] projectedPoint Point located on the given plane
|
|
* \return bool Whether the projection onto the plane was successful.
|
|
*/
|
|
virtual bool project(const PointerInfo& pi, osg::Vec3d& projectedPoint) const;
|
|
|
|
/**
|
|
* Generates a rotation about the cylinder axis based upon the incoming
|
|
* projected points on the plane computed from project().
|
|
* \param[in] p1 Initial projection point
|
|
* \param[in] p2 Second projection point
|
|
* \return osg::Quat Rotation about cylinder axis
|
|
*/
|
|
osg::Quat getRotation(const osg::Vec3d& p1, const osg::Vec3d& p2) const;
|
|
|
|
protected:
|
|
|
|
virtual ~CylinderPlaneProjector();
|
|
|
|
mutable osg::Plane _plane;
|
|
mutable osg::Vec3d _planeLineStart, _planeLineEnd;
|
|
mutable bool _parallelPlane;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|