Command 9.32 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
/* -*-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 <osgManipulator/Export>

#include <osg/LineSegment>
#include <osg/Plane>
#include <osg/Vec2>

#include <vector>

namespace osgManipulator {

class Constraint;

/** 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;

        /**
         * 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 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<osg::LineSegment>  _line;
        osg::Vec3d                      _translation;
};

/**
 * Command for translating in a plane.
 */
class OSGMANIPULATOR_EXPORT TranslateInPlaneCommand : public MotionCommand
{
    public:

        TranslateInPlaneCommand();

        TranslateInPlaneCommand(const osg::Plane& plane);

        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 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 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 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 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