| 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_COMMAND |
|---|
| 16 | #define OSGMANIPULATOR_COMMAND 1 |
|---|
| 17 | |
|---|
| 18 | #include <osgManipulator/Constraint> |
|---|
| 19 | |
|---|
| 20 | #include <osg/LineSegment> |
|---|
| 21 | #include <osg/Plane> |
|---|
| 22 | #include <osg/Vec2> |
|---|
| 23 | |
|---|
| 24 | #include <vector> |
|---|
| 25 | |
|---|
| 26 | namespace osgManipulator { |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | /** Base class for motion commands that are generated by draggers. */ |
|---|
| 30 | class OSGMANIPULATOR_EXPORT MotionCommand : public osg::Referenced |
|---|
| 31 | { |
|---|
| 32 | public: |
|---|
| 33 | |
|---|
| 34 | /** |
|---|
| 35 | * Motion command are based on click-drag-release actions. So each |
|---|
| 36 | * command needs to indicate which stage of the motion the command |
|---|
| 37 | * represents. |
|---|
| 38 | */ |
|---|
| 39 | enum Stage |
|---|
| 40 | { |
|---|
| 41 | NONE, |
|---|
| 42 | /** Click or pick start. */ |
|---|
| 43 | START, |
|---|
| 44 | /** Drag or pick move. */ |
|---|
| 45 | MOVE, |
|---|
| 46 | /** Release or pick finish. */ |
|---|
| 47 | FINISH |
|---|
| 48 | }; |
|---|
| 49 | |
|---|
| 50 | MotionCommand(); |
|---|
| 51 | |
|---|
| 52 | /** create a MotionCommand that is the inverse of this command, and if applied will undo this commands changes. */ |
|---|
| 53 | virtual MotionCommand* createCommandInverse() = 0; |
|---|
| 54 | |
|---|
| 55 | /** |
|---|
| 56 | * Gets the matrix for transforming the object being dragged. This matrix is in the |
|---|
| 57 | * command's coordinate systems. |
|---|
| 58 | */ |
|---|
| 59 | virtual osg::Matrix getMotionMatrix() const = 0; |
|---|
| 60 | |
|---|
| 61 | virtual void accept(const Constraint& constraint) { constraint.constrain(*this); } |
|---|
| 62 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 63 | |
|---|
| 64 | /** |
|---|
| 65 | * Sets the matrix for transforming the command's local coordinate |
|---|
| 66 | * system to the world/object coordinate system. |
|---|
| 67 | */ |
|---|
| 68 | void setLocalToWorldAndWorldToLocal(const osg::Matrix& localToWorld, const osg::Matrix& worldToLocal) |
|---|
| 69 | { |
|---|
| 70 | _localToWorld = localToWorld; |
|---|
| 71 | _worldToLocal = worldToLocal; |
|---|
| 72 | } |
|---|
| 73 | |
|---|
| 74 | /** |
|---|
| 75 | * Gets the matrix for transforming the command's local coordinate |
|---|
| 76 | * system to the world/object coordinate system. |
|---|
| 77 | */ |
|---|
| 78 | inline const osg::Matrix& getLocalToWorld() const { return _localToWorld; } |
|---|
| 79 | |
|---|
| 80 | /** |
|---|
| 81 | * Gets the matrix for transforming the command's world/object |
|---|
| 82 | * coordinate system to the command's local coordinate system. |
|---|
| 83 | */ |
|---|
| 84 | inline const osg::Matrix& getWorldToLocal() const { return _worldToLocal; } |
|---|
| 85 | |
|---|
| 86 | void setStage(const Stage s) { _stage = s; } |
|---|
| 87 | Stage getStage() const { return _stage; } |
|---|
| 88 | |
|---|
| 89 | protected: |
|---|
| 90 | |
|---|
| 91 | virtual ~MotionCommand(); |
|---|
| 92 | |
|---|
| 93 | private: |
|---|
| 94 | osg::Matrix _localToWorld; |
|---|
| 95 | osg::Matrix _worldToLocal; |
|---|
| 96 | |
|---|
| 97 | Stage _stage; |
|---|
| 98 | }; |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | /** |
|---|
| 102 | * Command for translating in a line. |
|---|
| 103 | */ |
|---|
| 104 | class OSGMANIPULATOR_EXPORT TranslateInLineCommand : public MotionCommand |
|---|
| 105 | { |
|---|
| 106 | public: |
|---|
| 107 | |
|---|
| 108 | TranslateInLineCommand(); |
|---|
| 109 | |
|---|
| 110 | TranslateInLineCommand(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e); |
|---|
| 111 | |
|---|
| 112 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 113 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 114 | |
|---|
| 115 | virtual MotionCommand* createCommandInverse(); |
|---|
| 116 | |
|---|
| 117 | inline void setLine(const osg::LineSegment::vec_type& s, const osg::LineSegment::vec_type& e) { _line->start() = s; _line->end() = e; } |
|---|
| 118 | inline const osg::LineSegment::vec_type& getLineStart() const { return _line->start(); } |
|---|
| 119 | inline const osg::LineSegment::vec_type& getLineEnd() const { return _line->end(); } |
|---|
| 120 | |
|---|
| 121 | inline void setTranslation(const osg::Vec3& t) { _translation = t; } |
|---|
| 122 | inline const osg::Vec3d& getTranslation() const { return _translation; } |
|---|
| 123 | |
|---|
| 124 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 125 | { |
|---|
| 126 | return osg::Matrix::translate(_translation); |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | protected: |
|---|
| 130 | |
|---|
| 131 | virtual ~TranslateInLineCommand(); |
|---|
| 132 | |
|---|
| 133 | private: |
|---|
| 134 | osg::ref_ptr<osg::LineSegment> _line; |
|---|
| 135 | osg::Vec3d _translation; |
|---|
| 136 | }; |
|---|
| 137 | |
|---|
| 138 | /** |
|---|
| 139 | * Command for translating in a plane. |
|---|
| 140 | */ |
|---|
| 141 | class OSGMANIPULATOR_EXPORT TranslateInPlaneCommand : public MotionCommand |
|---|
| 142 | { |
|---|
| 143 | public: |
|---|
| 144 | |
|---|
| 145 | TranslateInPlaneCommand(); |
|---|
| 146 | |
|---|
| 147 | TranslateInPlaneCommand(const osg::Plane& plane); |
|---|
| 148 | |
|---|
| 149 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 150 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 151 | |
|---|
| 152 | virtual MotionCommand* createCommandInverse(); |
|---|
| 153 | |
|---|
| 154 | inline void setPlane(const osg::Plane& plane) { _plane = plane; } |
|---|
| 155 | inline const osg::Plane& getPlane() const { return _plane; } |
|---|
| 156 | |
|---|
| 157 | inline void setTranslation(const osg::Vec3d& t) { _translation = t; } |
|---|
| 158 | inline const osg::Vec3d& getTranslation() const { return _translation; } |
|---|
| 159 | |
|---|
| 160 | /** ReferencePoint is used only for snapping. */ |
|---|
| 161 | inline void setReferencePoint(const osg::Vec3d& rp) { _referencePoint = rp; } |
|---|
| 162 | inline const osg::Vec3d& getReferencePoint() const { return _referencePoint; } |
|---|
| 163 | |
|---|
| 164 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 165 | { |
|---|
| 166 | return osg::Matrix::translate(_translation); |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | protected: |
|---|
| 170 | |
|---|
| 171 | virtual ~TranslateInPlaneCommand(); |
|---|
| 172 | |
|---|
| 173 | private: |
|---|
| 174 | osg::Plane _plane; |
|---|
| 175 | osg::Vec3d _translation; |
|---|
| 176 | osg::Vec3d _referencePoint; |
|---|
| 177 | }; |
|---|
| 178 | |
|---|
| 179 | /** |
|---|
| 180 | * Command for 1D scaling. |
|---|
| 181 | */ |
|---|
| 182 | class OSGMANIPULATOR_EXPORT Scale1DCommand : public MotionCommand |
|---|
| 183 | { |
|---|
| 184 | public: |
|---|
| 185 | |
|---|
| 186 | Scale1DCommand(); |
|---|
| 187 | |
|---|
| 188 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 189 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 190 | |
|---|
| 191 | virtual MotionCommand* createCommandInverse(); |
|---|
| 192 | |
|---|
| 193 | inline void setScale(double s) { _scale = s; } |
|---|
| 194 | inline double getScale() const { return _scale; } |
|---|
| 195 | |
|---|
| 196 | inline void setScaleCenter(double center) { _scaleCenter = center; } |
|---|
| 197 | inline double getScaleCenter() const { return _scaleCenter; } |
|---|
| 198 | |
|---|
| 199 | /** ReferencePoint is used only for snapping. */ |
|---|
| 200 | inline void setReferencePoint(double rp) { _referencePoint = rp; } |
|---|
| 201 | inline double getReferencePoint() const { return _referencePoint; } |
|---|
| 202 | |
|---|
| 203 | inline void setMinScale(double min) { _minScale = min; } |
|---|
| 204 | inline double getMinScale() const { return _minScale; } |
|---|
| 205 | |
|---|
| 206 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 207 | { |
|---|
| 208 | return (osg::Matrix::translate(-_scaleCenter,0.0,0.0) |
|---|
| 209 | * osg::Matrix::scale(_scale,1.0,1.0) |
|---|
| 210 | * osg::Matrix::translate(_scaleCenter,0.0,0.0)); |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | protected: |
|---|
| 214 | |
|---|
| 215 | virtual ~Scale1DCommand(); |
|---|
| 216 | |
|---|
| 217 | private: |
|---|
| 218 | double _scale; |
|---|
| 219 | double _scaleCenter; |
|---|
| 220 | double _referencePoint; |
|---|
| 221 | double _minScale; |
|---|
| 222 | }; |
|---|
| 223 | |
|---|
| 224 | /** |
|---|
| 225 | * Command for 2D scaling. |
|---|
| 226 | */ |
|---|
| 227 | class OSGMANIPULATOR_EXPORT Scale2DCommand : public MotionCommand |
|---|
| 228 | { |
|---|
| 229 | public: |
|---|
| 230 | |
|---|
| 231 | Scale2DCommand(); |
|---|
| 232 | |
|---|
| 233 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 234 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 235 | |
|---|
| 236 | virtual MotionCommand* createCommandInverse(); |
|---|
| 237 | |
|---|
| 238 | inline void setScale(const osg::Vec2d& s) { _scale = s; } |
|---|
| 239 | inline const osg::Vec2d& getScale() const { return _scale; } |
|---|
| 240 | |
|---|
| 241 | inline void setScaleCenter(const osg::Vec2d& center) { _scaleCenter = center; } |
|---|
| 242 | inline const osg::Vec2d& getScaleCenter() const { return _scaleCenter; } |
|---|
| 243 | |
|---|
| 244 | /** ReferencePoint is used only for snapping. */ |
|---|
| 245 | inline void setReferencePoint(const osg::Vec2d& rp) { _referencePoint = rp; } |
|---|
| 246 | inline const osg::Vec2d& getReferencePoint() const { return _referencePoint; } |
|---|
| 247 | |
|---|
| 248 | inline void setMinScale(const osg::Vec2d& min) { _minScale = min; } |
|---|
| 249 | inline const osg::Vec2d& getMinScale() const { return _minScale; } |
|---|
| 250 | |
|---|
| 251 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 252 | { |
|---|
| 253 | return (osg::Matrix::translate(-_scaleCenter[0],0.0,-_scaleCenter[1]) |
|---|
| 254 | * osg::Matrix::scale(_scale[0],1.0,_scale[1]) |
|---|
| 255 | * osg::Matrix::translate(_scaleCenter[0],0.0,_scaleCenter[1])); |
|---|
| 256 | } |
|---|
| 257 | |
|---|
| 258 | protected: |
|---|
| 259 | |
|---|
| 260 | virtual ~Scale2DCommand(); |
|---|
| 261 | |
|---|
| 262 | private: |
|---|
| 263 | osg::Vec2d _scale; |
|---|
| 264 | osg::Vec2d _scaleCenter; |
|---|
| 265 | osg::Vec2d _referencePoint; |
|---|
| 266 | osg::Vec2d _minScale; |
|---|
| 267 | }; |
|---|
| 268 | |
|---|
| 269 | /** |
|---|
| 270 | * Command for uniform 3D scaling. |
|---|
| 271 | */ |
|---|
| 272 | class OSGMANIPULATOR_EXPORT ScaleUniformCommand : public MotionCommand |
|---|
| 273 | { |
|---|
| 274 | public: |
|---|
| 275 | |
|---|
| 276 | ScaleUniformCommand(); |
|---|
| 277 | |
|---|
| 278 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 279 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 280 | |
|---|
| 281 | virtual MotionCommand* createCommandInverse(); |
|---|
| 282 | |
|---|
| 283 | inline void setScale(double s) { _scale = s; } |
|---|
| 284 | inline double getScale() const { return _scale; } |
|---|
| 285 | |
|---|
| 286 | inline void setScaleCenter(const osg::Vec3d& center) { _scaleCenter = center; } |
|---|
| 287 | inline const osg::Vec3d& getScaleCenter() const { return _scaleCenter; } |
|---|
| 288 | |
|---|
| 289 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 290 | { |
|---|
| 291 | return (osg::Matrix::translate(-_scaleCenter) |
|---|
| 292 | * osg::Matrix::scale(_scale,_scale,_scale) |
|---|
| 293 | * osg::Matrix::translate(_scaleCenter)); |
|---|
| 294 | } |
|---|
| 295 | |
|---|
| 296 | protected: |
|---|
| 297 | |
|---|
| 298 | virtual ~ScaleUniformCommand(); |
|---|
| 299 | |
|---|
| 300 | private: |
|---|
| 301 | double _scale; |
|---|
| 302 | osg::Vec3d _scaleCenter; |
|---|
| 303 | }; |
|---|
| 304 | |
|---|
| 305 | /** |
|---|
| 306 | * Command for rotation in 3D. |
|---|
| 307 | */ |
|---|
| 308 | class OSGMANIPULATOR_EXPORT Rotate3DCommand : public MotionCommand |
|---|
| 309 | { |
|---|
| 310 | public: |
|---|
| 311 | |
|---|
| 312 | Rotate3DCommand(); |
|---|
| 313 | |
|---|
| 314 | virtual void accept(const Constraint& constraint) {constraint.constrain(*this); } |
|---|
| 315 | virtual void accept(DraggerCallback& callback) { callback.receive(*this); } |
|---|
| 316 | |
|---|
| 317 | virtual MotionCommand* createCommandInverse(); |
|---|
| 318 | |
|---|
| 319 | inline void setRotation(const osg::Quat& rotation) { _rotation = rotation; } |
|---|
| 320 | inline const osg::Quat& getRotation() const { return _rotation; } |
|---|
| 321 | |
|---|
| 322 | virtual osg::Matrix getMotionMatrix() const |
|---|
| 323 | { |
|---|
| 324 | return osg::Matrix::rotate(_rotation); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | protected: |
|---|
| 328 | |
|---|
| 329 | virtual ~Rotate3DCommand(); |
|---|
| 330 | |
|---|
| 331 | private: |
|---|
| 332 | osg::Quat _rotation; |
|---|
| 333 | }; |
|---|
| 334 | |
|---|
| 335 | |
|---|
| 336 | } |
|---|
| 337 | |
|---|
| 338 | #endif |
|---|