/* -*-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_COMMAND #define OSGMANIPULATOR_COMMAND 1 #include #include #include #include #include namespace osgManipulator { /** Base class for motion commands that are generated by draggers. */ class OSGMANIPULATOR_EXPORT MotionCommand : public osg::Referenced { public: /** * Motion command are based on click-drag-release actions. So each * command needs to indicate which stage of the motion the command * represents. */ enum Stage { NONE, /** Click or pick start. */ START, /** Drag or pick move. */ MOVE, /** Release or pick finish. */ FINISH }; MotionCommand(); /** create a MotionCommand that is the inverse of this command, and if applied will undo this commands changes. */ virtual MotionCommand* createCommandInverse() = 0; /** * Gets the matrix for transforming the object being dragged. This matrix is in the * command's coordinate systems. */ virtual osg::Matrix getMotionMatrix() const = 0; virtual void accept(const Constraint& constraint) { constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } /** * Sets the matrix for transforming the command's local coordinate * system to the world/object coordinate system. */ void setLocalToWorldAndWorldToLocal(const osg::Matrix& localToWorld, const osg::Matrix& worldToLocal) { _localToWorld = localToWorld; _worldToLocal = worldToLocal; } /** * Gets the matrix for transforming the command's local coordinate * system to the world/object coordinate system. */ inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; } /** * Gets the matrix for transforming the command's world/object * coordinate system to the command's local coordinate system. */ inline const osg::Matrix& getWorldToLocal() const { return _worldToLocal; } void setStage(const Stage s) { _stage = s; } Stage getStage() const { return _stage; } protected: virtual ~MotionCommand(); private: osg::Matrix _localToWorld; osg::Matrix _worldToLocal; Stage _stage; }; /** * Command for translating in a line. */ class OSGMANIPULATOR_EXPORT TranslateInLineCommand : public MotionCommand { public: TranslateInLineCommand(); TranslateInLineCommand(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); 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 const osg::LineSegment::vec_type& getLineEnd() const { return _line->end(); } inline void setTranslation(const osg::Vec3& t) { _translation = t; } inline const osg::Vec3d& getTranslation() const { return _translation; } virtual osg::Matrix getMotionMatrix() const { return osg::Matrix::translate(_translation); } protected: virtual ~TranslateInLineCommand(); private: osg::ref_ptr _line; osg::Vec3d _translation; }; /** * Command for translating in a plane. */ class OSGMANIPULATOR_EXPORT TranslateInPlaneCommand : public MotionCommand { public: TranslateInPlaneCommand(); TranslateInPlaneCommand(const osg::Plane& plane); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); inline void setPlane(const osg::Plane& plane) { _plane = plane; } inline const osg::Plane& getPlane() const { return _plane; } inline void setTranslation(const osg::Vec3d& t) { _translation = t; } inline const osg::Vec3d& getTranslation() const { return _translation; } /** ReferencePoint is used only for snapping. */ inline void setReferencePoint(const osg::Vec3d& rp) { _referencePoint = rp; } inline const osg::Vec3d& getReferencePoint() const { return _referencePoint; } virtual osg::Matrix getMotionMatrix() const { return osg::Matrix::translate(_translation); } protected: virtual ~TranslateInPlaneCommand(); private: osg::Plane _plane; osg::Vec3d _translation; osg::Vec3d _referencePoint; }; /** * Command for 1D scaling. */ class OSGMANIPULATOR_EXPORT Scale1DCommand : public MotionCommand { public: Scale1DCommand(); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); inline void setScale(double s) { _scale = s; } inline double getScale() const { return _scale; } inline void setScaleCenter(double center) { _scaleCenter = center; } inline double getScaleCenter() const { return _scaleCenter; } /** ReferencePoint is used only for snapping. */ inline void setReferencePoint(double rp) { _referencePoint = rp; } inline double getReferencePoint() const { return _referencePoint; } inline void setMinScale(double min) { _minScale = min; } inline double getMinScale() const { return _minScale; } virtual osg::Matrix getMotionMatrix() const { return (osg::Matrix::translate(-_scaleCenter,0.0,0.0) * osg::Matrix::scale(_scale,1.0,1.0) * osg::Matrix::translate(_scaleCenter,0.0,0.0)); } protected: virtual ~Scale1DCommand(); private: double _scale; double _scaleCenter; double _referencePoint; double _minScale; }; /** * Command for 2D scaling. */ class OSGMANIPULATOR_EXPORT Scale2DCommand : public MotionCommand { public: Scale2DCommand(); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); inline void setScale(const osg::Vec2d& s) { _scale = s; } inline const osg::Vec2d& getScale() const { return _scale; } inline void setScaleCenter(const osg::Vec2d& center) { _scaleCenter = center; } inline const osg::Vec2d& getScaleCenter() const { return _scaleCenter; } /** ReferencePoint is used only for snapping. */ inline void setReferencePoint(const osg::Vec2d& rp) { _referencePoint = rp; } inline const osg::Vec2d& getReferencePoint() const { return _referencePoint; } inline void setMinScale(const osg::Vec2d& min) { _minScale = min; } inline const osg::Vec2d& getMinScale() const { return _minScale; } virtual osg::Matrix getMotionMatrix() const { return (osg::Matrix::translate(-_scaleCenter[0],0.0,-_scaleCenter[1]) * osg::Matrix::scale(_scale[0],1.0,_scale[1]) * osg::Matrix::translate(_scaleCenter[0],0.0,_scaleCenter[1])); } protected: virtual ~Scale2DCommand(); private: osg::Vec2d _scale; osg::Vec2d _scaleCenter; osg::Vec2d _referencePoint; osg::Vec2d _minScale; }; /** * Command for uniform 3D scaling. */ class OSGMANIPULATOR_EXPORT ScaleUniformCommand : public MotionCommand { public: ScaleUniformCommand(); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); inline void setScale(double s) { _scale = s; } inline double getScale() const { return _scale; } inline void setScaleCenter(const osg::Vec3d& center) { _scaleCenter = center; } inline const osg::Vec3d& getScaleCenter() const { return _scaleCenter; } virtual osg::Matrix getMotionMatrix() const { return (osg::Matrix::translate(-_scaleCenter) * osg::Matrix::scale(_scale,_scale,_scale) * osg::Matrix::translate(_scaleCenter)); } protected: virtual ~ScaleUniformCommand(); private: double _scale; osg::Vec3d _scaleCenter; }; /** * Command for rotation in 3D. */ class OSGMANIPULATOR_EXPORT Rotate3DCommand : public MotionCommand { public: Rotate3DCommand(); virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } virtual void accept(DraggerCallback& callback) { callback.receive(*this); } virtual MotionCommand* createCommandInverse(); inline void setRotation(const osg::Quat& rotation) { _rotation = rotation; } inline const osg::Quat& getRotation() const { return _rotation; } virtual osg::Matrix getMotionMatrix() const { return osg::Matrix::rotate(_rotation); } protected: virtual ~Rotate3DCommand(); private: osg::Quat _rotation; }; } #endif