Improved the handling of osgManipulator::Constraint, DraggerCallbacks and Command so that they now use a Visitor Pattern
to ensure the correct methods on constraints and callbaks are called for each Command. Also fixed the handling of Constraints when applied to composite Draggers.
This commit is contained in:
@@ -38,9 +38,45 @@
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Material>
|
||||
#include <osg/io_utils>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class PlaneConstraint : public osgManipulator::Constraint
|
||||
{
|
||||
public:
|
||||
PlaneConstraint() {}
|
||||
|
||||
virtual bool constrain(osgManipulator::TranslateInLineCommand& command) const
|
||||
{
|
||||
OSG_NOTICE<<"TranslateInLineCommand "<<command.getTranslation()<<std::endl;
|
||||
return true;
|
||||
}
|
||||
virtual bool constrain(osgManipulator::TranslateInPlaneCommand& command) const
|
||||
{
|
||||
//command.setTranslation(osg::Vec3(0.0f,0.0f,0.0f));
|
||||
OSG_NOTICE<<"TranslateInPlaneCommand "<<command.getTranslation()<<std::endl;
|
||||
return true;
|
||||
}
|
||||
virtual bool constrain(osgManipulator::Scale1DCommand& command) const
|
||||
{
|
||||
//command.setScale(1.0f);
|
||||
OSG_NOTICE<<"Scale1DCommand"<<command.getScale()<<std::endl;
|
||||
return true;
|
||||
}
|
||||
virtual bool constrain(osgManipulator::Scale2DCommand& command) const
|
||||
{
|
||||
//command.setScale(osg::Vec2d(1.0,1.0));
|
||||
OSG_NOTICE<<"Scale2DCommand "<<command.getScale()<<std::endl;
|
||||
return true;
|
||||
}
|
||||
virtual bool constrain(osgManipulator::ScaleUniformCommand& command) const
|
||||
{
|
||||
OSG_NOTICE<<"ScaleUniformCommand"<<command.getScale()<<std::endl;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
osgManipulator::Dragger* createDragger(const std::string& name)
|
||||
{
|
||||
osgManipulator::Dragger* dragger = 0;
|
||||
@@ -48,6 +84,7 @@ osgManipulator::Dragger* createDragger(const std::string& name)
|
||||
{
|
||||
osgManipulator::TabPlaneDragger* d = new osgManipulator::TabPlaneDragger();
|
||||
d->setupDefaultGeometry();
|
||||
d->addConstraint(new PlaneConstraint());
|
||||
dragger = d;
|
||||
}
|
||||
else if ("TabPlaneTrackballDragger" == name)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef OSGMANIPULATOR_COMMAND
|
||||
#define OSGMANIPULATOR_COMMAND 1
|
||||
|
||||
#include <osgManipulator/Export>
|
||||
#include <osgManipulator/Constraint>
|
||||
|
||||
#include <osg/LineSegment>
|
||||
#include <osg/Plane>
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
namespace osgManipulator {
|
||||
|
||||
class Constraint;
|
||||
|
||||
/** Base class for motion commands that are generated by draggers. */
|
||||
class OSGMANIPULATOR_EXPORT MotionCommand : public osg::Referenced
|
||||
@@ -59,6 +58,9 @@ class OSGMANIPULATOR_EXPORT MotionCommand : public osg::Referenced
|
||||
*/
|
||||
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.
|
||||
@@ -107,6 +109,9 @@ class OSGMANIPULATOR_EXPORT TranslateInLineCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
@@ -141,6 +146,9 @@ class OSGMANIPULATOR_EXPORT TranslateInPlaneCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
@@ -177,6 +185,9 @@ class OSGMANIPULATOR_EXPORT Scale1DCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
@@ -219,6 +230,9 @@ class OSGMANIPULATOR_EXPORT Scale2DCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
@@ -261,6 +275,9 @@ class OSGMANIPULATOR_EXPORT ScaleUniformCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
@@ -294,6 +311,9 @@ class OSGMANIPULATOR_EXPORT Rotate3DCommand : public MotionCommand
|
||||
|
||||
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; }
|
||||
|
||||
@@ -29,6 +29,32 @@ class TranslateInPlaneCommand;
|
||||
class Scale1DCommand;
|
||||
class Scale2DCommand;
|
||||
class ScaleUniformCommand;
|
||||
class Rotate3DCommand;
|
||||
|
||||
|
||||
class DraggerCallback : virtual public osg::Object
|
||||
{
|
||||
public:
|
||||
DraggerCallback():
|
||||
osg::Object(true) {}
|
||||
|
||||
DraggerCallback(const DraggerCallback&, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(true) {}
|
||||
|
||||
META_Object(osgManipulator, DraggerCallback);
|
||||
|
||||
/**
|
||||
* Receive motion commands. Returns true on success.
|
||||
*/
|
||||
virtual bool receive(const MotionCommand&) { return false; }
|
||||
virtual bool receive(const TranslateInLineCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const TranslateInPlaneCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Scale1DCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Scale2DCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const ScaleUniformCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Rotate3DCommand& command) { return receive((MotionCommand&)command); }
|
||||
};
|
||||
|
||||
|
||||
class OSGMANIPULATOR_EXPORT Constraint : public osg::Referenced
|
||||
{
|
||||
@@ -40,9 +66,11 @@ class OSGMANIPULATOR_EXPORT Constraint : public osg::Referenced
|
||||
virtual bool constrain(Scale1DCommand& command) const { return constrain((MotionCommand&)command); }
|
||||
virtual bool constrain(Scale2DCommand& command) const { return constrain((MotionCommand&)command); }
|
||||
virtual bool constrain(ScaleUniformCommand& command) const { return constrain((MotionCommand&)command); }
|
||||
virtual bool constrain(const Rotate3DCommand& command) { return constrain((MotionCommand&)command); }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
|
||||
Constraint() {}
|
||||
Constraint(osg::Node& refNode) : _refNode(&refNode) {}
|
||||
virtual ~Constraint() {}
|
||||
|
||||
|
||||
@@ -40,28 +40,6 @@ class Rotate3DCommand;
|
||||
/** Computes the nodepath from the given node all the way upto the root. */
|
||||
extern OSGMANIPULATOR_EXPORT void computeNodePathToRoot(osg::Node& node, osg::NodePath& np);
|
||||
|
||||
class DraggerCallback : virtual public osg::Object
|
||||
{
|
||||
public:
|
||||
DraggerCallback():
|
||||
osg::Object(true) {}
|
||||
|
||||
DraggerCallback(const DraggerCallback&, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY):
|
||||
osg::Object(true) {}
|
||||
|
||||
META_Object(osgManipulator, DraggerCallback);
|
||||
|
||||
/**
|
||||
* Receive motion commands. Returns true on success.
|
||||
*/
|
||||
virtual bool receive(const MotionCommand&) { return false; }
|
||||
virtual bool receive(const TranslateInLineCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const TranslateInPlaneCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Scale1DCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Scale2DCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const ScaleUniformCommand& command) { return receive((MotionCommand&)command); }
|
||||
virtual bool receive(const Rotate3DCommand& command) { return receive((MotionCommand&)command); }
|
||||
};
|
||||
|
||||
class OSGMANIPULATOR_EXPORT DraggerTransformCallback : public DraggerCallback
|
||||
{
|
||||
|
||||
@@ -44,7 +44,8 @@ void Constraint::computeLocalToWorldAndWorldToLocal() const
|
||||
{
|
||||
if (!_refNode)
|
||||
{
|
||||
OSG_INFO<<"osgManipulator::Constraint::computeLocalToWorldAndWorldToLocal() error, _refNode is null"<<std::endl;
|
||||
_localToWorld.makeIdentity();
|
||||
_worldToLocal.makeIdentity();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <osg/Material>
|
||||
#include <osgGA/EventVisitor>
|
||||
#include <osgViewer/View>
|
||||
|
||||
#include <osg/io_utils>
|
||||
using namespace osgManipulator;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -71,6 +71,8 @@ bool DraggerTransformCallback::receive(const MotionCommand& command)
|
||||
}
|
||||
case MotionCommand::MOVE:
|
||||
{
|
||||
//OSG_NOTICE<<"MotionCommand::MOVE "<<command.getMotionMatrix()<<std::endl;
|
||||
|
||||
// Transform the command's motion matrix into local motion matrix.
|
||||
osg::Matrix localMotionMatrix = _localToWorld * command.getWorldToLocal()
|
||||
* command.getMotionMatrix()
|
||||
@@ -394,18 +396,29 @@ void Dragger::dispatch(MotionCommand& command)
|
||||
itr != _constraints.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->constrain(command);
|
||||
command.accept(*(*itr));
|
||||
}
|
||||
|
||||
// apply any constraints of parent dragger.
|
||||
if (getParentDragger()!=this)
|
||||
{
|
||||
for(Constraints::iterator itr = getParentDragger()->getConstraints().begin();
|
||||
itr != getParentDragger()->getConstraints().end();
|
||||
++itr)
|
||||
{
|
||||
command.accept(*(*itr));
|
||||
}
|
||||
}
|
||||
|
||||
// move self
|
||||
getParentDragger()->receive(command);
|
||||
|
||||
|
||||
// pass on movement to any dragger callbacks
|
||||
for(DraggerCallbacks::iterator itr = getParentDragger()->getDraggerCallbacks().begin();
|
||||
itr != getParentDragger()->getDraggerCallbacks().end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->receive(command);
|
||||
command.accept(*(*itr));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user