diff --git a/manifest.xml b/manifest.xml
index c6cf22b..fdfc339 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -12,5 +12,6 @@
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 921f563..c073992 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,7 +19,6 @@ rock_library(vizkit3d
${PROPERTY_BROWSER_RESOURCES}
MOC
Vizkit3DPlugin.cpp
- PickHandler.cpp
Vizkit3DWidget.cpp
QVizkitMainWindow.cpp
qtpropertybrowser/qteditorfactory.cpp
@@ -44,7 +43,6 @@ rock_library(vizkit3d
Vizkit3DPlugin.hpp
Vizkit3DWidget.hpp
QVizkitMainWindow.hpp
- PickHandler.hpp
ColorConversionHelper.hpp
CoordinateFrame.hpp
EnvPluginBase.hpp
@@ -52,7 +50,8 @@ rock_library(vizkit3d
${HEADERS_EXTRA}
LIBS ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY}
DEPS_CMAKE OpenGL
- DEPS_PKGCONFIG openscenegraph openscenegraph-osgQt ${DEPS_EXTRA})
+ DEPS_PKGCONFIG openscenegraph openscenegraph-osgQt osgViz
+ PrimitivesFactory ManipulationClickHandler ${DEPS_EXTRA})
rock_library(vizkitwidgetloader
MOC QVizkitWidgetLoader.cpp
diff --git a/src/ConnexionPlugin.cpp b/src/ConnexionPlugin.cpp
deleted file mode 100644
index c1b28b0..0000000
--- a/src/ConnexionPlugin.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "ConnexionPlugin.h"
-
-#include
-
-namespace vizkit3d{
-
-
-ConnexionPlugin::ConnexionPlugin(){
- //Different Values for this Plugin
- scale[RX] = 5000.0;
- scale[RY] = 5000.0;
- scale[RZ] = 5000.0;
- scale[TX] = 10.0;
- scale[TY] = 10.0;
- scale[TZ] = 10.0;
- matrix.makeIdentity();
-}
-
-ConnexionPlugin::~ConnexionPlugin(){
-}
-
-bool ConnexionPlugin::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us){
- //Do Nothing, otherwise the screen would be resettet, but if needed in future here could be an addtional mouse handler registered
- return false;
-}
-
-bool ConnexionPlugin::init(osgGA::MatrixManipulator *manipulator){
- this->manipulator = manipulator;
- if(!manipulator)
- return false;
-
- if(!ConnexionHID::init()) return false;
-
- timer.setSingleShot(false);
- timer.setInterval(20);
- manipulator->setByMatrix(osg::Matrixd::identity());
- timer.start();
- connect(&timer,SIGNAL(timeout()), this, SLOT(handleMouse()));
- return true;
-}
-
-void ConnexionPlugin::handleMouse(){
- controldev::connexionValues motion;
-
- //Maybe in future the buttons could also be handelt, currently not used but already requested
- controldev::connexionValues newValues;
-
- //Getting actual readings
- getValue(motion, newValues);
-
- //Save processing power if mouse is not moved
- if(motion.rx == 0.0 && motion.ry == 0.0 && motion.rz == 0.0 && motion.tx == 0.0 && motion.ty == 0.0 && motion.tz == 0.0) return;
-
- //Get current Camera matrix
- osg::Matrixd m = manipulator->getMatrix();
-
- //Create Quaternion from current Camera Orientation
- osg::Quat q;
- q.set(m);
- Eigen::Quaterniond qu(q.w(),q.x(),q.y(),q.z());
-
- //Create Quaternion from Rotation request
- Eigen::Quaterniond q2 =
- Eigen::AngleAxisd(motion.rx,Eigen::Vector3d::UnitX()) *
- Eigen::AngleAxisd(motion.ry,Eigen::Vector3d::UnitY()) *
- Eigen::AngleAxisd(-motion.rz,Eigen::Vector3d::UnitZ());
-
- //Be sure that the rotation does not include an scake
- qu.normalize();
-
- //Create vector from Translation request
- Eigen::Vector3d v(motion.tx,motion.ty,-motion.tz);
-
- //Rotation translation Request into current Camra frame
- v = qu * v;
-
- //Apply Translation request to current Camera matrix
- m *= osg::Matrix::translate(v[0],v[1],v[2]);
-
- //Apply Rotation Request to current Camera matrix (after translation!)
- m = osg::Matrix::rotate(osg::Quat(q2.x(),q2.y(),q2.z(),q2.w())) * m;
-
- //Apply matrix to camera(-maipulator)
- manipulator->setByMatrix(m);
-
- //LOG_DEBUG("Got called! %f,%f,%f, %f, %f, %f\n",v[0],v[1],v[2],rx,ry,rz);
-}
-
-}
diff --git a/src/ConnexionPlugin.h b/src/ConnexionPlugin.h
deleted file mode 100644
index 6792427..0000000
--- a/src/ConnexionPlugin.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef _CONNEXIONPLUGIN_H_
-#define _CONNEXIONPLUGIN_H_
-
-#include
-#include
-#include
-#include
-
-namespace vizkit3d{
-
-
-class ConnexionPlugin : public QObject,public controldev::ConnexionHID, public osgGA::MatrixManipulator{
- Q_OBJECT
-public:
-
- ConnexionPlugin();
- ~ConnexionPlugin();
-
- /* Scan all devices in /dev/input/ to find the SpaceMouse.
- * Returns the true if an SpaceMouse could be found.
- */
- bool init(osgGA::MatrixManipulator *manipulator);
-
- /**
- * Needed functions for osgGA::MatrixManipulator
- */
- virtual osg::Matrixd getInverseMatrix() const {
- return osg::Matrixd::inverse(matrix);
- };
-
- /**
- * Needed functions for osgGA::MatrixManipulator
- */
- virtual osg::Matrixd getMatrix() const {
- return matrix;
- }
-
- /**
- * Needed functions for osgGA::MatrixManipulator
- */
- virtual void setByInverseMatrix(const osg::Matrixd& matrix) {
- this->matrix = osg::Matrixd::inverse(matrix);
- };
-
- /**
- * Needed functions for osgGA::MatrixManipulator
- */
- virtual void setByMatrix(const osg::Matrixd& matrix) {
- this->matrix = matrix;
- };
-
- /**
- * Needed functions for osgGA::MatrixManipulator
- * Do Nothing, otherwise the screen would be resettet, but if needed in future here could be an addtional mouse handler registered
- */
- virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
-
-protected:
- osg::ref_ptr manipulator;
- QTimer timer;
- osg::Matrixd matrix;
-
-public slots:
- /**
- * In this method is the real handling for the mouse values
- * this method need to called periodicly, this is normally done
- * via an QT-Timer which is initialized in the init() function
- */
- void handleMouse();
-
-};
-
-#endif
-
-};
diff --git a/src/NodeLink.cpp b/src/NodeLink.cpp
index 2df7527..4485075 100644
--- a/src/NodeLink.cpp
+++ b/src/NodeLink.cpp
@@ -1,6 +1,9 @@
#include "NodeLink.hpp"
+#include
+
#include
+#include
#include
#include
#include
@@ -52,7 +55,7 @@ namespace vizkit
::osg::Node* NodeLink::create(::osg::Node *node1, ::osg::Node *node2, const ::osg::Vec4 &color)
{
assert(node1 && node2);
-
+ osgviz::Object* object = new osgviz::NullClickObject(); //click events should not propagate through nodelinks
::osg::Geode* geode = new ::osg::Geode();
geode->setName(node2->getName());
::osg::Geometry* geometry = new ::osg::Geometry();
@@ -89,6 +92,8 @@ namespace vizkit
NodeCallback *callback = new NodeCallback(node1,node2);
geode->setUpdateCallback(callback);
- return (::osg::Node*)geode;
+ object->addChild(geode);
+
+ return (::osg::Node*)object;
}
}
diff --git a/src/PickHandler.cpp b/src/PickHandler.cpp
deleted file mode 100644
index d3764c2..0000000
--- a/src/PickHandler.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include "PickHandler.hpp"
-
-using namespace vizkit3d;
-
-PickHandler::PickHandler():
- _mx(0.0),_my(0.0),
- _usePolytopeIntersector(false),
- _useWindowCoordinates(false) {}
-
-PickHandler::~PickHandler() {}
-
-bool PickHandler::addFunction(int whatKey, functionType newFunction)
-{
- if ( keyFuncMap.end() != keyFuncMap.find( whatKey ))
- {
- std::cout << "duplicate key '" << whatKey << "' ignored." << std::endl;
- return false;
- }
- else
- {
- keyFuncMap[whatKey].keyFunction = newFunction;
- return true;
- }
-}
-
-bool PickHandler::addFunction (int whatKey, keyStatusType keyPressStatus, functionType newFunction)
-{
- if (keyPressStatus == KEY_DOWN)
- {
- return addFunction(whatKey,newFunction);
- }
- else
- {
- if ( keyUPFuncMap.end() != keyUPFuncMap.find( whatKey ))
- {
- std::cout << "duplicate key '" << whatKey << "' ignored." << std::endl;
- return false;
- }
- else
- {
- keyUPFuncMap[whatKey].keyFunction = newFunction;
- return true;
- }
- } // KEY_UP
-}
-
-bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
-{
- osgViewer::View* viewer = dynamic_cast(&aa);
- if (!viewer) return false;
-
- bool newKeyDownEvent = false;
-
- switch(ea.getEventType())
- {
- case(osgGA::GUIEventAdapter::KEYDOWN):
- {
- if (ea.getKey()=='w')
- {
- this->wireFrameModeOn(viewer->getSceneData());
- }
- else if (ea.getKey()=='n')
- {
- this->wireFrameModeOff(viewer->getSceneData());
- }
- else
- {
- keyFunctionMap::iterator itr = keyFuncMap.find(ea.getKey());
- if (itr != keyFuncMap.end())
- {
- if ( (*itr).second.keyState == KEY_UP )
- {
- (*itr).second.keyState = KEY_DOWN;
- newKeyDownEvent = true;
- }
- if (newKeyDownEvent)
- {
- (*itr).second.keyFunction();
- newKeyDownEvent = false;
- }
- return true;
- }
- }
- return false;
- }
- case(osgGA::GUIEventAdapter::KEYUP):
- {
- if (ea.getKey()=='p')
- {
- _usePolytopeIntersector = !_usePolytopeIntersector;
- if (_usePolytopeIntersector)
- {
- osg::notify(osg::NOTICE)<<"Using PolytopeIntersector"<getSceneData();
- if (!scene) return;
-
- osg::notify(osg::NOTICE)<getCamera()->getViewport();
- double mx = viewport->x() + (int)((double )viewport->width()*(ea.getXnormalized()*0.5+0.5));
- double my = viewport->y() + (int)((double )viewport->height()*(ea.getYnormalized()*0.5+0.5));
-
- // half width, height.
- double w = 5.0f;
- double h = 5.0f;
- picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::WINDOW, mx-w, my-h, mx+w, my+h );
- } else {
- double mx = ea.getXnormalized();
- double my = ea.getYnormalized();
- double w = 0.05;
- double h = 0.05;
- picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h );
- }
- osgUtil::IntersectionVisitor iv(picker);
-
- viewer->getCamera()->accept(iv);
-
- if (picker->containsIntersections())
- {
- for(std::multiset::iterator it = picker->getIntersections().begin();
- it != picker->getIntersections().end(); it++)
- {
- const osgUtil::PolytopeIntersector::Intersection &intersection = *it;
-
- /*
- osg::notify(osg::NOTICE)<<"Picked "<=1)?nodePath[nodePath.size()-1]:0;
-
- //osg::Matrixd l2w = osg::computeLocalToWorld( nodePath );
- //osg::Vec3 global = *intersection.matrix.get() * intersection.localIntersectionPoint;
- osg::Vec3 global = intersection.localIntersectionPoint * *intersection.matrix.get();
-
- QVector3D globalPoint( global.x(), global.y(), global.z());
- emit picked(globalPoint);
- }
- }
- }
- else
- {
- osgUtil::LineSegmentIntersector* picker;
- if (!_useWindowCoordinates)
- {
- // use non dimensional coordinates - in projection/clip space
- picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::PROJECTION, ea.getXnormalized(),ea.getYnormalized() );
- } else {
- // use window coordinates
- // remap the mouse x,y into viewport coordinates.
- osg::Viewport* viewport = viewer->getCamera()->getViewport();
- float mx = viewport->x() + (int)((float)viewport->width()*(ea.getXnormalized()*0.5f+0.5f));
- float my = viewport->y() + (int)((float)viewport->height()*(ea.getYnormalized()*0.5f+0.5f));
- picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::WINDOW, mx, my );
- }
- osgUtil::IntersectionVisitor iv(picker);
-
- viewer->getCamera()->accept(iv);
-
- if (picker->containsIntersections())
- {
- osgUtil::LineSegmentIntersector::Intersection intersection = picker->getFirstIntersection();
-
- osg::NodePath& nodePath = intersection.nodePath;
- node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0;
-
- // see if the object has a user object which is derived from pickcallback
- PickedCallback *pc = dynamic_cast(node->getUserData());
- if( pc )
- pc->picked();
-
- for(int i = nodePath.size()-1; i >= 0; i--)
- {
- osg::Node *node = nodePath[i];
- osg::Referenced *user_data = node->getUserData();
- if (!user_data)
- continue;
- PickedUserData *plugin_data = dynamic_cast(user_data);
- if(!plugin_data)
- continue;
-
- // Transform OSG viewport coordinates to QWidget coordinates (invert y axis)
- float wy = (float)viewer->getCamera()->getViewport()->height() - _my;
- float wx = _mx;
- plugin_data->getPlugin()->click(wx, wy);
-
- osg::Vec3 global = intersection.localIntersectionPoint * *intersection.matrix.get();
- emit plugin_data->getPlugin()->picked(global.x(),global.y(),global.z());
- break;
- }
- // setTrackedNode(viewer, node);
- }
- }
-}
-
-void PickHandler::setTrackedNode(osgViewer::View* viewer, osg::ref_ptr< osg::Node > node)
-{
- osgGA::KeySwitchMatrixManipulator *keyswitchManipulator =
- dynamic_cast(viewer->getCameraManipulator());
-
- if( !keyswitchManipulator )
- return;
-
- osgGA::NodeTrackerManipulator *tracker =
- dynamic_cast(keyswitchManipulator->getMatrixManipulatorWithIndex( 2 ));
- if( tracker )
- {
- tracker->setTrackerMode( osgGA::NodeTrackerManipulator::NODE_CENTER );
- tracker->setTrackNode( node );
- }
-}
-
-void PickHandler::wireFrameModeOn(osg::Node *srcNode)
-{
- //Quick sanity check , we need a node
- if( srcNode == NULL )
- return;
-
- //Grab the state set of the node, this will a StateSet if one does not exist
- osg::StateSet *state = srcNode->getOrCreateStateSet();
-
- //We need to retrieve the Polygon mode of the state set, and create one if does not have one
- osg::PolygonMode *polyModeObj;
-
- polyModeObj = dynamic_cast< osg::PolygonMode* >( state->getAttribute( osg::StateAttribute::POLYGONMODE ));
-
- if ( !polyModeObj )
- {
- polyModeObj = new osg::PolygonMode;
- state->setAttribute( polyModeObj );
- }
-
- //Now we can set the state to WIREFRAME
- polyModeObj->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE );
-
-}
-
-void PickHandler::wireFrameModeOff(osg::Node *srcNode)
-{
- //Quick sanity check , we need a node
- if( srcNode == NULL )
- return;
-
- //Grab the state set of the node, this will a StateSet if one does not exist
- osg::StateSet *state = srcNode->getOrCreateStateSet();
-
- //We need to retrieve the Polygon mode of the state set, and create one if does not have one
- osg::PolygonMode *polyModeObj;
-
- polyModeObj = dynamic_cast< osg::PolygonMode* >( state->getAttribute( osg::StateAttribute::POLYGONMODE ));
-
- if ( !polyModeObj )
- {
- polyModeObj = new osg::PolygonMode;
- state->setAttribute( polyModeObj );
- }
-
- //Now we can set the state to FILL
- polyModeObj->setMode( osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL );
-}
-
diff --git a/src/PickHandler.hpp b/src/PickHandler.hpp
deleted file mode 100644
index 1835d1a..0000000
--- a/src/PickHandler.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#ifndef __VIZKIT_PICKHANDLER_HPP__
-#define __VIZKIT_PICKHANDLER_HPP__
-
-#include
-#include
-#include
-#include
-
-#include "Vizkit3DPlugin.hpp"
-
-namespace vizkit3d
-{
-class PickedCallback : public osg::Referenced
-{
- public:
- virtual void picked() = 0;
-};
-
-class PickedUserData : public osg::Referenced
-{
- public:
- PickedUserData(VizPluginBase* plugin){ this->plugin = plugin; }
- VizPluginBase* getPlugin() { return plugin; }
- private:
- VizPluginBase* plugin;
-};
-
-// class to handle events with a pick
-class PickHandler : public QObject, public osgGA::GUIEventHandler
-{
- Q_OBJECT
- public:
- typedef void (*functionType) ();
-
- enum keyStatusType
- {
- KEY_UP, KEY_DOWN
- };
-
- struct functionStatusType
- {
- functionStatusType() {keyState = KEY_UP; keyFunction = NULL;}
- functionType keyFunction;
- keyStatusType keyState;
- };
-
-
- public:
- PickHandler();
- ~PickHandler();
-
- bool addFunction(int whatKey, functionType newFunction);
- bool addFunction(int whatKey, keyStatusType keyPressStatus, functionType newFunction);
-
- bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
- void pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer);
-
- signals:
- void picked(const QVector3D& coord);
-
- protected:
- void setTrackedNode(osgViewer::View* viewer, osg::ref_ptr< osg::Node > node);
-
- void wireFrameModeOn(osg::Node *srcNode);
- void wireFrameModeOff(osg::Node *srcNode);
-
- float _mx,_my;
- bool _usePolytopeIntersector;
- bool _useWindowCoordinates;
-
- typedef std::map keyFunctionMap;
- keyFunctionMap keyFuncMap;
- keyFunctionMap keyUPFuncMap;
-};
-}
-
-#endif
diff --git a/src/QPropertyBrowserWidget.cpp b/src/QPropertyBrowserWidget.cpp
index 7bfb176..3b739bc 100644
--- a/src/QPropertyBrowserWidget.cpp
+++ b/src/QPropertyBrowserWidget.cpp
@@ -199,24 +199,24 @@ void QPropertyBrowserWidget::removeProperties(QObject* obj)
void QPropertyBrowserWidget::propertyChangedInGUI(QtProperty* property, const QVariant& val)
{
QHash::const_iterator i = propertyToObject.find(property);
-
if (i == propertyToObject.end())
return;
-
- //std::cout << "accessing from map: " << property->propertyName().toStdString() << " -> " << i.value() << std::endl;
-
+
QtVariantProperty* prop = dynamic_cast(property);
if(prop && prop->propertyType() == QtVariantPropertyManager::enumTypeId())
{
// emulate string list by using enums
QStringList list;
- list << prop->attributeValue("enumNames").toStringList().at(val.toInt());
+ const QStringList names = prop->attributeValue("enumNames").toStringList();
+ if(names.size() > 0)
+ {
+ list << names.at(val.toInt());
+ }
i.value()->setProperty(property->propertyName().toStdString().c_str(), QVariant(list));
}
else
- {
i.value()->setProperty(property->propertyName().toStdString().c_str(), val);
- }
+
}
/**
diff --git a/src/QVizkitMainWindow.hpp b/src/QVizkitMainWindow.hpp
index c3e258f..bc626b5 100644
--- a/src/QVizkitMainWindow.hpp
+++ b/src/QVizkitMainWindow.hpp
@@ -1,7 +1,11 @@
#ifndef QVIZKITMAINWINDOW_H
#define QVIZKITMAINWINDOW_H
-#include "Vizkit3DPlugin.hpp"
-#include "Vizkit3DWidget.hpp"
+
+#ifndef Q_MOC_RUN
+ #include "Vizkit3DPlugin.hpp"
+ #include "Vizkit3DWidget.hpp"
+#endif
+
#include
#include
diff --git a/src/TransformerGraph.cpp b/src/TransformerGraph.cpp
index c215629..0cbb2d0 100644
--- a/src/TransformerGraph.cpp
+++ b/src/TransformerGraph.cpp
@@ -7,6 +7,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -37,7 +38,8 @@ osg::PositionAttitudeTransform *getTransform(osg::Node *node,bool raise=true)
osg::PositionAttitudeTransform *createFrame(const std::string &name,bool root=false,float textSize=0.1)
{
- osg::PositionAttitudeTransform* node = new osg::PositionAttitudeTransform();
+// osg::PositionAttitudeTransform* node = new osg::PositionAttitudeTransform();
+ osgviz::Object* node = new osgviz::Object();
node->setName(name.c_str());
// always add a group as first child which will used to hold custom nodes
@@ -381,6 +383,31 @@ osg::Node *TransformerGraph::getFrame(osg::Node &transformer,osg::Node *node)
return FindFrame::find(transformer,node);
}
+osgviz::Object *TransformerGraph::getFrameOsgVizObject(osg::Node &transformer,const std::string &frame)
+{
+ osg::Node *frameNode = TransformerGraph::getFrame(transformer, frame);
+ if(frameNode == NULL)
+ {
+ std::cerr << "Unknown frame: " << frame << std::endl;
+ return NULL;
+ }
+
+ osg::PositionAttitudeTransform *transform = NULL;
+ try
+ {
+ transform = getTransform(frameNode);
+ }
+ catch(const std::runtime_error& ex)
+ {
+ std::cerr << ex.what() << std::endl;
+ return NULL;
+ }
+
+ osgviz::Object *obj = dynamic_cast(transform);
+ if(obj == NULL)
+ std::cerr << "Frame is not an osgViz object" << std::endl;
+ return obj;
+}
osg::Group *TransformerGraph::getFrameGroup(osg::Node &transformer,const std::string &frame)
{
@@ -617,3 +644,11 @@ void TransformerGraph::detachNode(osg::Node &transformer,osg::Node &node)
NodeRemover::remove(transformer,&node);
}
+void TransformerGraph::setWorldName(osg::Node &transformer, const std::string &name)
+{
+ transformer.setName(name);
+ osgText::Text* text = getFrameText(&transformer);
+ text->setText(name);
+}
+
+
diff --git a/src/TransformerGraph.hpp b/src/TransformerGraph.hpp
index d7e67ac..3210192 100644
--- a/src/TransformerGraph.hpp
+++ b/src/TransformerGraph.hpp
@@ -8,6 +8,11 @@
#include
#include
+namespace osgviz
+{
+ class Object;
+}
+
namespace vizkit3d
{
/**
@@ -33,6 +38,8 @@ namespace vizkit3d
* Returns the name of the wold (root) frame.
*/
static std::string getWorldName(const osg::Node &transformer);
+
+ static void setWorldName(osg::Node &transformer, const std::string &name);
/**
* Sets the size of the frame annotations
@@ -85,6 +92,17 @@ namespace vizkit3d
* @param node The node
*/
static osg::Group *getFrameGroup(osg::Node &transformer,const std::string &frame="");
+
+ /**
+ * Returns the osgviz object for the given frame. Use this node if you
+ * want to attach event handlers etc.
+ * If no name is given it will return the top level osg viz object.
+ *
+ * Returns NULL and prints error message to stderr in case of error.
+ *
+ * @param transformer the osg node of the transformer graph
+ * @param frame Name of the frame*/
+ static osgviz::Object *getFrameOsgVizObject(osg::Node &transformer,const std::string &frame="");
/**
* Returns the name of the osg frame node for the given custom node. Returns an empty string if the given node
diff --git a/src/Vizkit3DPlugin.cpp b/src/Vizkit3DPlugin.cpp
index 94c1f7e..da1fb0d 100644
--- a/src/Vizkit3DPlugin.cpp
+++ b/src/Vizkit3DPlugin.cpp
@@ -1,13 +1,48 @@
#include
#include
#include
+#include
+#include
+#include
#include "Vizkit3DPlugin.hpp"
#include "Vizkit3DWidget.hpp"
-#include "PickHandler.hpp"
-using namespace vizkit3d;
+namespace vizkit3d{
+ class ClickHandler : public osgviz::Clickable
+ {
+ VizPluginBase& plugin;
+ public:
+ ClickHandler(VizPluginBase& plugin) : plugin(plugin), enabled(true){};
+
+ virtual bool clicked(const int &buttonMask, const osg::Vec2d &cursor,
+ const osg::Vec3d &world, const osg::Vec3d &local,
+ Clickable* object, const int modifierMask,
+ osgviz::WindowInterface* window = NULL)
+ {
+ if (enabled){
+ plugin.click((float)cursor.x(), (float)cursor.y(), buttonMask, modifierMask);
+ plugin.pick((float)world.x(), (float)world.y(), (float)world.z(), buttonMask, modifierMask);
+ return true;
+ }
+ return false;
+ }
+
+ bool isEnabled(){
+ return enabled;
+ }
+
+ void enable(bool val = true){
+ enabled = val;
+ }
+
+ private:
+ bool enabled;
+
+ };
+}
+using namespace vizkit3d;
/** this adapter is used to forward the update call to the plugin
*/
class VizPluginBase::CallbackAdapter : public osg::NodeCallback
@@ -26,17 +61,15 @@ VizPluginBase::VizPluginBase(QObject *parent)
: QObject(parent), oldNodes(NULL), isAttached(false), dirty( false ), plugin_enabled(true),
keep_old_data(false),max_old_data(100)
{
- rootNode = new osg::Group();
+ rootNode = new osgviz::Object();
+ click_handler = std::shared_ptr(new ClickHandler(*this));
+ rootNode->addClickableCallback(click_handler);
nodeCallback = new CallbackAdapter(this);
rootNode->setUpdateCallback(nodeCallback);
vizNode = new osg::PositionAttitudeTransform();
rootNode->addChild(vizNode);
oldNodes = new osg::Group();
rootNode->addChild(oldNodes);
-
- // reference counter we do not have to delete the data
- // add picker callback
- vizNode->setUserData(new PickedUserData(this));
}
VizPluginBase::~VizPluginBase()
@@ -67,7 +100,7 @@ osg::ref_ptr VizPluginBase::getRootNode() const
return rootNode;
}
-void VizPluginBase::click(float x,float y)
+void VizPluginBase::click(float x,float y, int buttonMask, int modifierMask)
{
QWidget *osg_widget = dynamic_cast(parent()); // widget displaying the osg scene.
@@ -86,6 +119,7 @@ void VizPluginBase::click(float x,float y)
QPoint container_coords = osg_widget->mapTo(container, QPoint(x,y));
//std::cout << "grandparent coords: (" << container_coords.x() << "," << container_coords.y() << ")" << std::endl;
emit clicked(container_coords.x(), container_coords.y());
+ emit clicked(container_coords.x(), container_coords.y(), buttonMask, modifierMask);
break;
}
else
@@ -94,9 +128,25 @@ void VizPluginBase::click(float x,float y)
container = container->parentWidget();
}
}
+}
+void VizPluginBase::pick(float x, float y, float z, int buttonMask, int modifierMask)
+{
+ emit picked(x, y, z);
+ emit picked(x, y, z, buttonMask, modifierMask);
+
+ for(std::function f : pickCallbacks)
+ {
+ f(x, y, z);
+ }
+}
+
+void VizPluginBase::addPickHandler(std::function f)
+{
+ pickCallbacks.push_back(f);
}
+
void VizPluginBase::setPose(const QVector3D &position, const QQuaternion &orientation)
{
boost::mutex::scoped_lock lock(updateMutex);
@@ -148,7 +198,7 @@ void VizPluginBase::updateCallback(osg::Node* node)
{
mainNode = createMainNode();
vizNode->addChild(mainNode);
- isAttached = true;
+ isAttached = true;
}
if(isDirty())
@@ -157,7 +207,7 @@ void VizPluginBase::updateCallback(osg::Node* node)
vizNode->setPosition(osg::Vec3d(position.x(), position.y(), position.z()));
vizNode->setAttitude(osg::Quat(orientation.x(), orientation.y(), orientation.z(), orientation.scalar()));
- updateMainNode(mainNode);
+ updateMainNode(mainNode);
if(keep_old_data)
{
oldNodes->addChild(cloneCurrentViz());
@@ -165,11 +215,11 @@ void VizPluginBase::updateCallback(osg::Node* node)
oldNodes->removeChild(0,oldNodes->getNumChildren() -max_old_data);
}
if(!isAttached)
- {
- vizNode->addChild(mainNode);
- isAttached = true;
- }
- dirty = false;
+ {
+ vizNode->addChild(mainNode);
+ isAttached = true;
+ }
+ dirty = false;
}
}
@@ -262,7 +312,7 @@ void VizPluginBase::setVisualizationFrameFromList(const QStringList &frames)
if (frames.empty())
return;
if (!getWidget())
- return;
+ return;
getWidget()->setPluginDataFrameIntern(frames.front(),this);
current_frame = frames.front();
}
@@ -275,3 +325,12 @@ void VizPluginBase::setVisualizationFrame(const QString &frame)
current_frame = frame;
emit propertyChanged("frame");
}
+
+bool VizPluginBase::getEvaluatesClicks() const{
+ return click_handler->isEnabled();
+}
+
+void VizPluginBase::setEvaluatesClicks (const bool &value){
+ click_handler->enable(value);
+}
+
diff --git a/src/Vizkit3DPlugin.hpp b/src/Vizkit3DPlugin.hpp
index 839e541..54dc74c 100644
--- a/src/Vizkit3DPlugin.hpp
+++ b/src/Vizkit3DPlugin.hpp
@@ -9,9 +9,18 @@
#include
#include
+#include
+#include
+
+namespace osgviz
+{
+ class Object;
+}
namespace vizkit3d
{
+class ClickHandler;
+
/**
* Interface class for all ruby adapters of the visualization plugins
* Ruby adapters are usefull to get incoming data via ruby.
@@ -109,16 +118,17 @@ class Vizkit3DWidget;
*/
class VizPluginBase : public QObject
{
- friend class PickHandler;
Q_OBJECT
Q_PROPERTY(QString vizkit3d_plugin_name READ getPluginName)
Q_PROPERTY(bool enabled READ isPluginEnabled WRITE setPluginEnabled)
Q_PROPERTY(bool KeepOldData READ isKeepOldDataEnabled WRITE setKeepOldData)
+ Q_PROPERTY(bool evaluatesClicks READ getEvaluatesClicks WRITE setEvaluatesClicks)
Q_PROPERTY(int MaxOldData READ getMaxOldData WRITE setMaxOldData)
Q_PROPERTY(QStringList frame READ getVisualizationFrames WRITE setVisualizationFrameFromList)
Q_PROPERTY(double scale READ getScale WRITE setScale)
+
public:
VizPluginBase(QObject *parent=NULL);
virtual ~VizPluginBase();
@@ -128,21 +138,22 @@ class VizPluginBase : public QObject
* May be NULL if the plugin is e.g. built as a child of another plugin
*/
Vizkit3DWidget* getWidget() const;
+
+ /** @return true if the plugins internal state has been updated */
+ virtual bool isDirty() const;
+ /** mark the internal state as modified */
+ void setDirty();
- /** @return true if the plugins internal state has been updated */
- virtual bool isDirty() const;
- /** mark the internal state as modified */
- void setDirty();
-
- /** @return a pointer to the internal Group that is used to maintain the
- * plugin's nodes */
- osg::ref_ptr getVizNode() const;
- osg::ref_ptr getRootNode() const;
+ /** @return a pointer to the internal Group that is used to maintain the
+ * plugin's nodes */
+ osg::ref_ptr getVizNode() const;
+ osg::ref_ptr getRootNode() const;
/**
* @return a vector of QDockWidgets provided by this class.
*/
std::vector getDockWidgets();
+ void addPickHandler(std::function f);
public slots:
/**
@@ -155,14 +166,17 @@ class VizPluginBase : public QObject
*/
virtual void setPluginEnabled(bool enabled);
- /** @return the name of the plugin */
- virtual const QString getPluginName() const;
+ /** @return the name of the plugin */
+ virtual const QString getPluginName() const;
virtual void setPluginName(const QString &name);
/**
* Emits signal 'clicked(float, float)' if the plugin has a Vizkit3DWidget as an ancestor.
*/
- virtual void click(float x,float y);
+ virtual void click(float x,float y, int buttonMask, int modifierMask);
+
+ /**Emits signal picked() */
+ virtual void pick(float x, float y, float z, int buttonMask, int modifierMask);
/**
* @return an instance of the ruby adapter collection.
@@ -176,11 +190,11 @@ class VizPluginBase : public QObject
void setKeepOldData(bool value);
bool isKeepOldDataEnabled();
- /**
- * Clears the visualization of the plugin
- * */
- virtual void clearVisualization();
-
+ /**
+ * Clears the visualization of the plugin
+ * */
+ virtual void clearVisualization();
+
/**
* deletes all copies of the osg graph which were genereted by keepCurrentViz
*/
@@ -189,7 +203,7 @@ class VizPluginBase : public QObject
int getMaxOldData()const {return max_old_data;};
void setMaxOldData(int value);
- void setPose(const QVector3D &position, const QQuaternion &orientation);
+ void setPose(const QVector3D &position, const QQuaternion &orientation);
/** Returns the list of available visualization frames
*
@@ -219,6 +233,17 @@ class VizPluginBase : public QObject
*/
void setScale(double scale);
+ /**
+ * @return whether click events should be evaluated by this plugin or not
+ */
+ bool getEvaluatesClicks() const;
+
+ /**
+ * enable or disable click evaluation by this plugin
+ * @param value
+ */
+ void setEvaluatesClicks (const bool &value);
+
signals:
/**
* must be emitted if a property of an inherited plugin changes
@@ -240,22 +265,27 @@ class VizPluginBase : public QObject
* That is the container widget of the OSG viewer and the property browser.
*/
void clicked(float x, float y);
+ void clicked(float x, float y, int buttonMask, int modifierMask);
/**
* Signals when this plugin has been clicked. x,y,z are in world coordinates.
*/
void picked(float x, float y,float z);
+ /** @param buttonMask Mouse button that has been pressed
+ * @param modifierMask Modifier key(s) that have been pressed
+ */
+ void picked(float x, float y,float z, int buttonMask, int modifierMask);
protected:
- /** override this function to update the visualisation.
- * @param node contains a point to the node which can be modified.
- */
- virtual void updateMainNode(osg::Node* node) = 0;
+ /** override this function to update the visualisation.
+ * @param node contains a point to the node which can be modified.
+ */
+ virtual void updateMainNode(osg::Node* node) = 0;
- /** override this method to provide your own main node.
- * @return node derived from osg::Group
- */
- virtual osg::ref_ptr createMainNode();
+ /** override this method to provide your own main node.
+ * @return node derived from osg::Group
+ */
+ virtual osg::ref_ptr createMainNode();
/** override this method to provide your own QDockWidgets.
* The QDockWidgets will automatically attached to the main window.
@@ -267,22 +297,24 @@ class VizPluginBase : public QObject
*/
virtual osg::ref_ptr cloneCurrentViz();
- /** lock this mutex outside updateMainNode if you update the internal
- * state of the visualization.
- */
- boost::mutex updateMutex;
+ /** lock this mutex outside updateMainNode if you update the internal
+ * state of the visualization.
+ */
+ boost::mutex updateMutex;
std::vector dockWidgets;
QString vizkit3d_plugin_name;
VizPluginRubyAdapterCollection adapterCollection;
private:
- class CallbackAdapter;
- osg::ref_ptr nodeCallback;
- void updateCallback(osg::Node* node);
+ std::vector> pickCallbacks;
+
+ class CallbackAdapter;
+ osg::ref_ptr nodeCallback;
+ void updateCallback(osg::Node* node);
osg::ref_ptr mainNode; //node which is used by the child class
- osg::ref_ptr rootNode; //node which is the osg root node of the pluign
+ osg::ref_ptr rootNode; //node which is the osg root node of the pluign
osg::ref_ptr vizNode; //node which describes the transformation between rootNode and mainNode
osg::ref_ptr oldNodes; //node which is the root node for all old visualization graphs of the plugin
@@ -292,10 +324,11 @@ class VizPluginBase : public QObject
//orientation of the viznode
QQuaternion orientation;
- bool isAttached;
- bool dirty;
+ bool isAttached;
+ bool dirty;
bool plugin_enabled;
bool keep_old_data;
+ std::shared_ptr click_handler;
unsigned int max_old_data;
QString current_frame;
};
@@ -328,11 +361,11 @@ class VizPluginAddType
virtual ~VizPluginAddType() {}
protected:
- /** overide this method and set your internal state such that the next
- * call to updateMainNode will reflect that update.
- * @param data data to be updated
- */
- virtual void updateDataIntern(const T &data) = 0;
+ /** overide this method and set your internal state such that the next
+ * call to updateMainNode will reflect that update.
+ * @param data data to be updated
+ */
+ virtual void updateDataIntern(const T &data) = 0;
};
/**
@@ -350,21 +383,21 @@ class Vizkit3DPlugin : public VizPluginBase,
virtual ~Vizkit3DPlugin() {}
- /** updates the data to be visualised and marks the visualisation dirty
- * @param data const ref to data that is visualised
- */
+ /** updates the data to be visualised and marks the visualisation dirty
+ * @param data const ref to data that is visualised
+ */
template
- void updateData(const Type &data) {
- boost::mutex::scoped_lock lockit(this->updateMutex);
- this->setDirty();
- VizPluginAddType *type = dynamic_cast*>(this);
- if(type)
- type->updateDataIntern(data);
- else
- {
- throw std::runtime_error("Wrong type given to visualizer");
- }
- };
+ void updateData(const Type &data) {
+ boost::mutex::scoped_lock lockit(this->updateMutex);
+ this->setDirty();
+ VizPluginAddType *type = dynamic_cast*>(this);
+ if(type)
+ type->updateDataIntern(data);
+ else
+ {
+ throw std::runtime_error("Wrong type given to visualizer");
+ }
+ };
};
/**
@@ -409,8 +442,8 @@ class VizkitPluginFactory : public QObject
void* ptr = data.value();\
dataType* pluginData = reinterpret_cast(ptr);\
vizPlugin->methodName(*pluginData);\
- if (pass_ownership) \
- delete pluginData; \
+ if (pass_ownership) \
+ delete pluginData; \
}\
public slots:\
QString getDataType() \
@@ -477,32 +510,32 @@ template
class VizPluginAdapter : public Vizkit3DPlugin
{
protected:
- virtual void operatorIntern( osg::Node* node, osg::NodeVisitor* nv ) = 0;
+ virtual void operatorIntern( osg::Node* node, osg::NodeVisitor* nv ) = 0;
VizPluginAdapter()
- : groupNode(new osg::Group())
+ : groupNode(new osg::Group())
{
}
- osg::ref_ptr createMainNode()
- {
- return groupNode;
- }
+ osg::ref_ptr createMainNode()
+ {
+ return groupNode;
+ }
- void updateMainNode( osg::Node* node )
- {
- // NULL for nodevisitor is ok here, since its not used anywhere
- operatorIntern( node, NULL );
- }
+ void updateMainNode( osg::Node* node )
+ {
+ // NULL for nodevisitor is ok here, since its not used anywhere
+ operatorIntern( node, NULL );
+ }
- void setMainNode( osg::Node* node )
- {
- groupNode->addChild( node );
- }
+ void setMainNode( osg::Node* node )
+ {
+ groupNode->addChild( node );
+ }
protected:
- osg::ref_ptr groupNode;
- osg::ref_ptr ownNode;
+ osg::ref_ptr groupNode;
+ osg::ref_ptr ownNode;
};
}
diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp
index d96caca..35af2fc 100644
--- a/src/Vizkit3DWidget.cpp
+++ b/src/Vizkit3DWidget.cpp
@@ -1,5 +1,3 @@
-#include
-#include
#include
#include
#include
@@ -13,12 +11,12 @@
#include "Vizkit3DBase.hpp"
#include "Vizkit3DWidget.hpp"
#include "Vizkit3DPlugin.hpp"
-#include "PickHandler.hpp"
#include "QPropertyBrowserWidget.hpp"
#include "AxesNode.hpp"
#include "OsgVisitors.hpp"
#include "TransformerGraph.hpp"
#include "EnableGLDebugOperation.hpp"
+#include
#include
#include
@@ -27,6 +25,7 @@
#include
#include
+#include
#include
#include
#include
@@ -203,52 +202,86 @@ void Vizkit3DConfig::setCameraManipulator(QStringList const& manipulator)
return getWidget()->setCameraManipulator(id);
}
-Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool auto_update)
- : QWidget(parent)
- , env_plugin(NULL)
+Vizkit3DWidget::Vizkit3DWidget(QWidget* parent,const QString &world_name,bool auto_update)
+ : QMainWindow(parent)
+ , env_plugin(NULL), clickHandler(new osgviz::ManipulationClickHandler),
+ movedHandler(*this), movingHandler(*this), selectedHandler(*this)
{
- //create layout
- //objects will be owned by the parent widget (this)
- QVBoxLayout* layout = new QVBoxLayout;
- layout->setObjectName("main_layout");
- layout->setContentsMargins(2,2,2,2);
- QSplitter* splitter = new QSplitter(Qt::Horizontal);
- splitter->setObjectName("splitter");
+ setEnabledManipulators(false);
+ clickHandler->objectMoved.connect(movedHandler);
+ clickHandler->objectMoving.connect(movingHandler);
+ selectedObjectConnection = clickHandler->objectSelected.connect(selectedHandler);
+ //currently only this is supported
+ current_manipulator = TERRAIN_MANIPULATOR;
+
+
+ last_manipulator = vizkit3d::DEFAULT_MANIPULATOR;
+
+ graphicsWindowQt = createGraphicsWindow(0,0,800,600);
+ graphicsWindowQtgc = dynamic_cast(graphicsWindowQt.get());
+
+
+ osgviz = osgviz::OsgViz::getInstance();
+
+
+ osgviz::WindowConfig windowConfig;
+ windowConfig.width = 800;
+ windowConfig.height = 600;
+ windowConfig.title = "rock-display";
+
+
+ int osgvizWindowID = osgviz->createWindow(windowConfig,graphicsWindowQtgc);
+ window = osgviz->getWindowManager()->getWindowByID(osgvizWindowID);
- layout->addWidget(splitter);
- this->setLayout(layout);
// set threading model
- setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
+ window->setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
if (getenv("VIZKIT_GL_DEBUG") && (std::string(getenv("VIZKIT_GL_DEBUG")) == "1"))
{
osg::setNotifyLevel(osg::DEBUG_INFO);
- setRealizeOperation(new EnableGLDebugOperation());
+ window->setRealizeOperation(new EnableGLDebugOperation());
}
// disable the default setting of viewer.done() by pressing Escape.
- setKeyEventSetsDone(0);
+ window->setKeyEventSetsDone(0);
// create root scene node
root = createSceneGraph(world_name);
+ window->addChild(root);
// create osg widget
- QWidget* widget = addViewWidget(createGraphicsWindow(0,0,800,600), root);
+ QWidget* widget = graphicsWindowQt->getGLWidget();
widget->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
widget->setObjectName(QString("View Widget"));
- splitter->addWidget(widget);
+
+ setCentralWidget(widget);
+
// create propertyBrowserWidget
- QPropertyBrowserWidget *propertyBrowserWidget = new QPropertyBrowserWidget( parent );
+ propertyBrowserWidget = new QPropertyBrowserWidget( parent );
propertyBrowserWidget->setObjectName("PropertyBrowser");
propertyBrowserWidget->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
propertyBrowserWidget->resize(200,600);
- splitter->addWidget(propertyBrowserWidget);
+
+ propertyDocker = new QDockWidget("Properties");
+ //prop browser should be closed
+ propertyDocker->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
+ propertyDocker->setWidget(propertyBrowserWidget);
+ addDockWidget(Qt::RightDockWidgetArea, propertyDocker);
+
// add config object to the property browser
Vizkit3DConfig *config = new Vizkit3DConfig(this);
addProperties(config,NULL);
+ //setup camera
+ osg::Camera* camera = window->getView()->getCamera();
+ camera->setClearColor(::osg::Vec4(0.2, 0.2, 0.6, 1.0) );
+ //camera->setViewport( new ::osg::Viewport(0, 0, traits->width, traits->height) );
+ //camera->setProjectionMatrixAsPerspective(30.0f, static_cast(traits->width)/static_cast(traits->height), 1.0f, 10000.0f );
+ camera->setCullMask(~INVISIBLE_NODE_MASK);
+ camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+
//connect signals and slots
connect(this, SIGNAL(addPlugins(QObject*,QObject*)), this, SLOT(addPluginIntern(QObject*,QObject*)));
connect(this, SIGNAL(removePlugins(QObject*)), this, SLOT(removePluginIntern(QObject*)));
@@ -261,7 +294,9 @@ Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool a
_timer.start(10);
}
-Vizkit3DWidget::~Vizkit3DWidget() {}
+Vizkit3DWidget::~Vizkit3DWidget() {
+ osgviz->destroyWindow(0);
+}
//qt ruby is crashing if we use none pointer here
QStringList* Vizkit3DWidget::getVisualizationFramesRuby() const
@@ -329,7 +364,7 @@ void Vizkit3DWidget::disableGrabbing()
captureHandler = NULL;
}
-QImage Vizkit3DWidget::grab()
+QImage Vizkit3DWidget::grab(unsigned int viewIndex)
{
if (!captureHandler)
{
@@ -337,35 +372,11 @@ QImage Vizkit3DWidget::grab()
return QImage();
}
- dynamic_cast(*captureHandler).captureNextFrame(*this);
- frame();
+ dynamic_cast(*captureHandler).captureNextFrame(*window);
+ osgviz->update();
return static_cast(*captureOperation).image;
};
-QWidget* Vizkit3DWidget::addViewWidget( osgQt::GraphicsWindowQt* gw, ::osg::Node* scene )
-{
- osgViewer::View* view = new osgViewer::View;
- addView(view);
-
- ::osg::Camera* camera = view->getCamera();
- camera->setGraphicsContext( gw );
-
- const ::osg::GraphicsContext::Traits* traits = gw->getTraits();
-
- camera->setClearColor(::osg::Vec4(0.2, 0.2, 0.6, 1.0) );
- camera->setViewport( new ::osg::Viewport(0, 0, traits->width, traits->height) );
- camera->setProjectionMatrixAsPerspective(30.0f, static_cast(traits->width)/static_cast(traits->height), 1.0f, 10000.0f );
- camera->setCullMask(~INVISIBLE_NODE_MASK);
-
- view->setSceneData(scene);
- view->addEventHandler( new osgViewer::StatsHandler );
- setCameraManipulator(TERRAIN_MANIPULATOR);
-
- // pickhandler is for selecting objects in the opengl view
- PickHandler* pickHandler = new PickHandler();
- view->addEventHandler(pickHandler);
- return gw->getGLWidget();
-}
osgQt::GraphicsWindowQt* Vizkit3DWidget::createGraphicsWindow( int x, int y, int w, int h, const std::string& name, bool windowDecoration)
{
@@ -385,9 +396,10 @@ osgQt::GraphicsWindowQt* Vizkit3DWidget::createGraphicsWindow( int x, int y, int
return new osgQt::GraphicsWindowQt(traits.get());
}
-void Vizkit3DWidget::paintEvent( QPaintEvent* event )
+void Vizkit3DWidget::update()
{
- frame();
+ QWidget::update();
+ osgviz->update();
}
QSize Vizkit3DWidget::sizeHint() const
@@ -400,14 +412,14 @@ osg::Group* Vizkit3DWidget::getRootNode() const
return root;
}
-void Vizkit3DWidget::setTrackedNode( VizPluginBase* plugin )
+void Vizkit3DWidget::setTrackedNode(VizPluginBase* plugin)
{
- return setTrackedNode(plugin->getRootNode(), QString("").arg(plugin->getPluginName()));
+ return setTrackedNode(plugin->getRootNode(), QString("").arg(plugin->getPluginName()));
}
-void Vizkit3DWidget::setTrackedNode( osg::Node* node, QString tracked_object_name )
+void Vizkit3DWidget::setTrackedNode(osg::Node* node,const QString& tracked_object_name)
{
- osgViewer::View *view = getView(0);
+ osgViewer::View *view = window->getView(0);
assert(view);
osgGA::NodeTrackerManipulator* manipulator = new osgGA::NodeTrackerManipulator;
@@ -484,6 +496,16 @@ void Vizkit3DWidget::registerDataHandler(VizPluginBase* viz)
plugins.insert(make_pair(viz, VizPluginInfo(viz, initial_parent)));
}
+void Vizkit3DWidget::registerClickHandler(const string& frame)
+{
+ osgviz::Object* obj = TransformerGraph::getFrameOsgVizObject(*getRootNode(), frame);
+ if(obj == NULL)
+ throw std::runtime_error("Cannot register click handler");
+
+ if(!obj->hasClickableCallback(clickHandler))
+ obj->addClickableCallback(clickHandler);
+}
+
void Vizkit3DWidget::deregisterDataHandler(VizPluginBase* viz)
{
PluginMap::iterator it = plugins.find(viz);
@@ -571,11 +593,10 @@ void Vizkit3DWidget::setEnvironmentPluginEnabled(bool enabled)
if (!env_plugin)
return;
- osgViewer::View *view = getView(0);
if (enabled)
- view->setSceneData(env_plugin->getRootNode());
+ osgviz->setScene(env_plugin->getRootNode());
else
- view->setSceneData(root);
+ osgviz->setScene(root);
emit propertyChanged("environment");
}
@@ -583,7 +604,7 @@ bool Vizkit3DWidget::isEnvironmentPluginEnabled() const
{
if (!env_plugin)
return false;
- return getView(0)->getSceneData() != root;
+ return osgviz->getChild() != root;
}
void Vizkit3DWidget::clearEnvironmentPlugin()
@@ -619,27 +640,18 @@ void Vizkit3DWidget::setCameraUp(double x, double y, double z)
void Vizkit3DWidget::collapsePropertyBrowser()
{
- QSplitter *splitter = findChild("splitter");
- if(!splitter)
- return;
- QList sizes;
- sizes.push_front(0);
- splitter->setSizes(sizes);
+ removeDockWidget(propertyDocker);
+ propertyBrowserWidget->close();
}
-void Vizkit3DWidget::setSmallFeatureCullingPixelSize(float val)
-{
- osgViewer::View *view = getView(0);
- assert(view);
- view->getCamera()->setSmallFeatureCullingPixelSize(val);
-}
+
void Vizkit3DWidget::getCameraView(QVector3D& lookAtPos, QVector3D& eyePos, QVector3D& upVector)
{
osg::Vec3d eye, lookAt, up;
- osgViewer::View *view = getView(0);
+ osgViewer::View *view = window->getView(0);
assert(view);
view->getCamera()->getViewMatrixAsLookAt(eye, lookAt, up);
@@ -656,7 +668,7 @@ void Vizkit3DWidget::getCameraView(QVector3D& lookAtPos, QVector3D& eyePos, QVec
void Vizkit3DWidget::changeCameraView(const osg::Vec3* lookAtPos, const osg::Vec3* eyePos, const osg::Vec3* upVector)
{
- osgViewer::View *view = getView(0);
+ osgViewer::View *view = window->getView(0);
assert(view);
osgGA::CameraManipulator* manipulator = dynamic_cast(view->getCameraManipulator());
@@ -692,7 +704,7 @@ void Vizkit3DWidget::changeCameraView(const osg::Vec3* lookAtPos, const osg::Vec
QColor Vizkit3DWidget::getBackgroundColor()const
{
- const osgViewer::View *view = getView(0);
+ const osgViewer::View *view = window->getView();
assert(view);
osg::Vec4 color = view->getCamera()->getClearColor();
return QColor(color.r()*255,color.g()*255,color.b()*255,color.a()*255);
@@ -700,7 +712,7 @@ QColor Vizkit3DWidget::getBackgroundColor()const
void Vizkit3DWidget::setBackgroundColor(QColor color)
{
- osgViewer::View *view = getView(0);
+ osgViewer::View *view = window->getView();
assert(view);
view->getCamera()->setClearColor(::osg::Vec4(color.red()/255.0,color.green()/255.0,color.blue()/255.0,1.0));
}
@@ -759,6 +771,13 @@ void Vizkit3DWidget::addPluginIntern(QObject* plugin,QObject *parent)
connect(viz_plugin, SIGNAL(pluginActivityChanged(bool)), this, SLOT(pluginActivityChanged(bool)));
connect(viz_plugin, SIGNAL(childrenChanged()), this, SLOT(pluginChildrenChanged()));
connect(viz_plugin, SIGNAL(destroyed(QObject*)), this, SLOT(removePluginIntern(QObject*)));
+
+ const std::vector dockWidgets = viz_plugin->getDockWidgets();
+ for(QDockWidget* dockWidget : dockWidgets)
+ {
+ dockWidget->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
+ addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
+ }
}
// add sub plugins if object has some
@@ -788,12 +807,18 @@ void Vizkit3DWidget::removePluginIntern(QObject* plugin)
propertyBrowserWidget->removeProperties(viz_plugin);
disconnect(viz_plugin, SIGNAL(pluginActivityChanged(bool)), this, SLOT(pluginActivityChanged(bool)));
disconnect(viz_plugin, SIGNAL(childrenChanged()), this, SLOT(pluginChildrenChanged()));
+
+ const std::vector dockWidgets = viz_plugin->getDockWidgets();
+ for(QDockWidget* dockWidget : dockWidgets)
+ {
+ removeDockWidget(dockWidget);
+ }
}
}
QWidget* Vizkit3DWidget::getPropertyWidget() const
{
- return findChild("PropertyBrowser");
+ return propertyBrowserWidget;
}
void Vizkit3DWidget::setPluginDataFrame(const QString& frame, QObject* plugin)
@@ -822,6 +847,7 @@ void Vizkit3DWidget::setPluginDataFrameIntern(const QString& frame, QObject* plu
throw std::runtime_error("setPluginDataFrame called with something that is not a vizkit3d plugin");
TransformerGraph::addFrame(*getRootNode(),frame.toStdString());
+ registerClickHandler(frame.toStdString());
osg::Group* node = TransformerGraph::getFrameGroup(*getRootNode(),frame.toStdString());
assert(node);
PluginMap::iterator it = plugins.find(viz);
@@ -854,8 +880,6 @@ void Vizkit3DWidget::setVisualizationFrame(const QString& frame)
return;
}
- osgViewer::View *view = getView(0);
- assert(view);
// the following is not working if the directly track the transformation
// therefore use a child
osg::Node *node = TransformerGraph::getFrameGroup(*getRootNode(),frame.toStdString());
@@ -881,8 +905,14 @@ void Vizkit3DWidget::setTransformation(const QString &source_frame,const QString
osg::Quat(quat.x(),quat.y(),quat.z(),quat.scalar()),
osg::Vec3d(position.x(),position.y(),position.z()));
+ //if a new frame was added
if(count != getVisualizationFrames().size())
{
+ //there is no way to determine which frame was new
+ //checking for duplicate handlers will be done elsewhere
+ registerClickHandler(source_frame.toStdString());
+ registerClickHandler(target_frame.toStdString());
+
emit propertyChanged("frame");
// first: VizPluginBase*
// second: osg::ref_ptr
@@ -903,6 +933,13 @@ void Vizkit3DWidget::setTransformation(const QString &source_frame,const QString
TransformerGraph::makeRoot(*getRootNode(), root_frame.toStdString());
}
+void Vizkit3DWidget::removeFrame(const QString& frame)
+{
+ const bool worked = TransformerGraph::removeFrame(*getRootNode(), frame.toStdString());
+ if(!worked)
+ std::cerr << "WARN: Unable to remove frame " << frame.toStdString() << std::endl;
+}
+
void Vizkit3DWidget::setRootFrame(QString frame)
{
TransformerGraph::makeRoot(*getRootNode(), frame.toStdString());
@@ -1068,25 +1105,25 @@ QStringList* Vizkit3DWidget::getAvailablePlugins()
return plugins_str_list;
}
-QObject* Vizkit3DWidget::loadPlugin(QString lib_name,QString plugin_name)
+QObject* Vizkit3DWidget::createPlugin(QString lib_name, QString plugin_name)
{
//check if the plugin name is encoded into the lib_name
QStringList plugin_strings = lib_name.split("@");
if(plugin_strings.size() == 2)
{
- lib_name = plugin_strings.at(0);
- plugin_name = plugin_strings.at(1);
+ plugin_name = plugin_strings.at(0);
+ lib_name = plugin_strings.at(1);
}
//if no lib_name is given try to find it from plugin_name
if(lib_name.isEmpty() && !plugin_name.isEmpty())
lib_name = findPluginPath(plugin_name);
-
+
//check if the lib name is a path
QFileInfo file_info(lib_name);
QString path;
if(file_info.isFile())
- path = file_info.absolutePath();
+ path = file_info.absoluteFilePath();
else
path = findLibPath(lib_name);
@@ -1115,6 +1152,13 @@ QObject* Vizkit3DWidget::loadPlugin(QString lib_name,QString plugin_name)
lib->getAvailablePlugins()->join(", ").toStdString() << std::endl;
return NULL;
}
+ return plugin;
+}
+
+
+QObject* Vizkit3DWidget::loadPlugin(QString lib_name, QString plugin_name)
+{
+ QObject* plugin = createPlugin(lib_name, plugin_name);
addPlugin(plugin);
return plugin;
}
@@ -1134,7 +1178,7 @@ CAMERA_MANIPULATORS Vizkit3DWidget::getCameraManipulator() const
void Vizkit3DWidget::setCameraManipulator(osg::ref_ptr manipulator, bool resetToDefaultHome)
{
- osgViewer::View *view = getView(0);
+ osgViewer::View *view = window->getView(0);
assert(view);
osg::Vec3d
@@ -1204,3 +1248,130 @@ void Vizkit3DWidget::setCameraManipulator(CAMERA_MANIPULATORS manipulatorType, b
}
}
+void Vizkit3DWidget::ObjectMovedHandler::operator()(const osgviz::Object* obj,
+ const osg::Matrix& motion)
+{
+ const std::string frame = obj->getName();
+ if(TransformerGraph::hasFrame(*widget.getRootNode(), frame))
+ {
+ const osg::Vec3d trans = motion.getTrans();
+ const osg::Quat rot = motion.getRotate();
+ const QVector3D qTrans(trans.x(), trans.y(), trans.z());
+ const QQuaternion qRot(rot.w(), rot.x(), rot.y(), rot.z());
+ emit widget.frameMoved(QString::fromStdString(frame), qTrans, qRot);
+ }
+ else
+ {
+ std::cerr << "Dragged object is not a frame: " << frame << std::endl;
+ }
+}
+
+void Vizkit3DWidget::ObjectMovingHandler::operator()(const osgviz::Object* obj,
+ const osg::Matrix& motion)
+{
+ const std::string frame = obj->getName();
+ if(TransformerGraph::hasFrame(*widget.getRootNode(), frame))
+ {
+ const osg::Vec3d trans = motion.getTrans();
+ const osg::Quat rot = motion.getRotate();
+ const QVector3D qTrans(trans.x(), trans.y(), trans.z());
+ const QQuaternion qRot(rot.w(), rot.x(), rot.y(), rot.z());
+ emit widget.frameMoving(QString::fromStdString(frame), qTrans, qRot);
+ }
+ else
+ {
+ std::cerr << "Dragged object is not a frame: " << frame << std::endl;
+ }
+}
+
+void Vizkit3DWidget::ObjectSelectedHandler::operator()(const osgviz::Object* obj)
+{
+ const std::string frame = obj->getName();
+ if(TransformerGraph::hasFrame(*widget.getRootNode(), frame))
+ {
+ emit widget.frameSelected(QString::fromStdString(frame));
+ }
+ else
+ {
+ std::cerr << "Selected object that is not a frame: " << frame << std::endl;
+ }
+}
+
+bool Vizkit3DWidget::ObjectSelectedHandler::operator==(const Vizkit3DWidget::ObjectSelectedHandler& other) const
+{
+ //to disconnect slots we need to be able to identify them, therefore they
+ //need to be comparable
+ return this == &other;
+}
+
+
+void Vizkit3DWidget::selectFrame(const QString& frame, const bool suppressSignal)
+{
+ if(TransformerGraph::hasFrame(*getRootNode(), frame.toStdString()))
+ {
+ osgviz::Object* obj = TransformerGraph::getFrameOsgVizObject(*getRootNode(),
+ frame.toStdString());
+ if(obj != NULL)
+ {
+ if(suppressSignal)
+ {
+ boost::signals2::shared_connection_block block(selectedObjectConnection);
+ clickHandler->selectObject(obj);
+ }
+ else
+ {
+ clickHandler->selectObject(obj);
+ }
+ }
+ else
+ std::cerr << "Cannot select frame: " << frame.toStdString() << std::endl;
+ }
+ else
+ {
+ std::cerr << frame.toStdString() << " doesn't exist!" << std::endl;
+ }
+}
+
+void Vizkit3DWidget::clear()
+{
+ //remove plugins, is while loop because removing invalidates iterators
+ while(plugins.size() > 0)
+ {
+ removePlugin(plugins.begin()->first);
+ }
+
+ //remove frames
+ const std::vector frames = TransformerGraph::getFrameNames(*getRootNode());
+ for(unsigned i = 0; i < frames.size(); ++i)
+ {
+ //removeFrame internally skips the world frame
+ TransformerGraph::removeFrame(*getRootNode(), frames[i]);
+ }
+}
+
+void Vizkit3DWidget::setWorldName(const QString& name)
+{
+ const QString oldWorldName = getWorldName();
+ TransformerGraph::setWorldName(*getRootNode(), name.toStdString());
+ PluginMap::iterator it = plugins.begin();
+
+ //find all plugins that use the old world name as visualization frame
+ //and update them. Otherwise the old world name might be re-added when
+ //setting transformations
+ for(;it != plugins.end();++it)
+ {
+ if(it->first->getVisualizationFrame() == oldWorldName)
+ {
+ it->first->setVisualizationFrame(name);
+ }
+ }
+}
+
+void Vizkit3DWidget::setEnabledManipulators(const bool value)
+{
+ clickHandler->setEnabled(value);
+}
+
+
+
+
diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp
index af14f64..cb971fd 100644
--- a/src/Vizkit3DWidget.hpp
+++ b/src/Vizkit3DWidget.hpp
@@ -6,6 +6,16 @@
#include
#include
#include
+#include
+#include
+
+#ifndef Q_MOC_RUN
+ #include
+ #include
+ #include
+ #include
+#endif
+
// disable tons of waringins in osg
// this is only valid for the rest of this
@@ -18,9 +28,12 @@
#include
#include
+
+namespace osgviz { class ManipulationClickHandler;}
namespace osgQt { class GraphicsWindowQt;}
namespace vizkit3d
{
+ class QPropertyBrowserWidget;
class EnvPluginBase;
class Vizkit3DWidget;
@@ -186,7 +199,7 @@ namespace vizkit3d
QStringList getAvailableCameraManipulators() const;
};
- class QDESIGNER_WIDGET_EXPORT Vizkit3DWidget : public QWidget, public osgViewer::CompositeViewer
+ class QDESIGNER_WIDGET_EXPORT Vizkit3DWidget : public QMainWindow
{
Q_OBJECT
public:
@@ -211,7 +224,7 @@ namespace vizkit3d
* to be reported in getCameraManipulatorName (and therefore in
* the property browser view)
*/
- void setTrackedNode(osg::Node* node, QString tracked_object_name);
+ void setTrackedNode(osg::Node* node, const QString& tracked_object_name);
/** @overload sets the camera to track this plugins's root position
*
* The tracked object name is
@@ -229,6 +242,7 @@ namespace vizkit3d
void setCameraManipulator(osg::ref_ptr manipulator, bool resetToDefaultHome = false);
public slots:
+ void update();
void addPlugin(QObject* plugin, QObject* parent = NULL);
void removePlugin(QObject* plugin);
@@ -269,14 +283,21 @@ namespace vizkit3d
const QVector3D &position, const QQuaternion &orientation);
void getTransformation(const QString &source_frame,const QString &target_frame, QVector3D &position, QQuaternion &orientation)const;
QString getWorldName()const;
+ void setWorldName(const QString& name);
+
+ /**Removes @p frame from the visualization */
+ void removeFrame(const QString& frame);
+
+ /**Select @p frame. This is the same as if the user clicked the frame.
+ * @param suppressSignal If true the frameSelected signal will not be
+ * emitted.*/
+ void selectFrame(const QString& frame, const bool suppressSignal);
void setCameraLookAt(double x, double y, double z);
void setCameraEye(double x, double y, double z);
void setCameraUp(double x, double y, double z);
void getCameraView(QVector3D& eye, QVector3D& lookAt, QVector3D& up);
- void setSmallFeatureCullingPixelSize(float val);
-
QColor getBackgroundColor()const;
void setBackgroundColor(QColor color);
@@ -308,10 +329,13 @@ namespace vizkit3d
* You must call enableGrabbing() first. Will return an empty image
* if you did not do so.
*/
- QImage grab();
+ QImage grab(unsigned int viewIndex = 0);
QString findPluginPath(QString plugin_name);
QString findLibPath(QString lib_name);
+
+ /**Creates the specified plugin but dos **not** add it to this widget */
+ QObject* createPlugin(QString lib_name,QString plugin_name);
QObject* loadPlugin(QString lib_name,QString plugin_name);
QStringList* getAvailablePlugins();
@@ -357,14 +381,36 @@ namespace vizkit3d
* remove the plugin itself
*/
void clearEnvironmentPlugin();
+
+ /*Removes all plugins and all frames except the world frame.*/
+ void clear();
+
+ /**If set to true rotation and translation manipulators will be shown
+ * when a frame is clicked. Default: false*/
+ void setEnabledManipulators(const bool value);
signals:
void addPlugins(QObject* plugin,QObject* parent);
void removePlugins(QObject* plugin);
void propertyChanged(QString propertyName);
-
- protected:
- virtual void paintEvent( QPaintEvent* event );
+
+ /** This signal is emitted when the user wants to move a frame.
+ * The actual moving of the frame has to be done by the handler
+ * of this event.
+ * @p translation the translation relative to @p frame.
+ * @p rotation the rotation relative to @p frame.*/
+ void frameMoved(const QString& frame, const QVector3D& translation,
+ const QQuaternion& rotation);
+
+ /** This signal is emitted while the user is dragging or rotating a
+ * frame. This event is intendet to update gui elements. Do
+ * **not** update transformations while handling this event.*/
+ void frameMoving(const QString& frame, const QVector3D& translation,
+ const QQuaternion& rotation);
+
+ /** This signal is emitted when the user selects a frame in the
+ * 3d view.*/
+ void frameSelected(const QString frame);
private slots:
void setPluginDataFrameIntern(const QString &frame, QObject *plugin);
@@ -373,8 +419,12 @@ namespace vizkit3d
void pluginActivityChanged(bool enabled);
void pluginChildrenChanged();
void addProperties(QObject* plugin,QObject *parent=NULL);
-
+
private:
+
+ /**Register the click handler to the given frame */
+ void registerClickHandler(const std::string& frame);
+
// Helper method for setPluginEnabled
void enableEnvironmentPlugin();
// Helper method for setPluginEnabled
@@ -389,9 +439,13 @@ namespace vizkit3d
void disableDataHandler(VizPluginBase *viz);
osg::Group *createSceneGraph(const QString &world_name);
- QWidget* addViewWidget( osgQt::GraphicsWindowQt* gw, ::osg::Node* scene );
osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false );
+
+ osgviz::OsgViz* osgviz;
+ osgviz::Window* window;
+
+
private:
//holds the scene
osg::ref_ptr root;
@@ -436,6 +490,47 @@ namespace vizkit3d
osg::ref_ptr captureHandler;
osg::ref_ptr captureOperation;
+ osg::ref_ptr graphicsWindowQt;
+ osg::ref_ptr graphicsWindowQtgc;
+
+ std::shared_ptr clickHandler;
+
+ //TODO replace with lambda once c++11 is used
+ struct ObjectMovedHandler
+ {
+ ObjectMovedHandler(Vizkit3DWidget& widget) : widget(widget){}
+ /** @param obj The object that has been moved.
+ * @param motionMatrix Motion of the object relative to the
+ * current object position. */
+ void operator()(const osgviz::Object* obj,
+ const osg::Matrix& motionMatrix);
+ Vizkit3DWidget& widget;//the widget that this handler belongs to
+ }movedHandler;
+
+ struct ObjectMovingHandler
+ {
+ ObjectMovingHandler(Vizkit3DWidget& widget) : widget(widget){}
+ void operator()(const osgviz::Object* obj,
+ const osg::Matrix& motionMatrix);
+ Vizkit3DWidget& widget;//the widget that this handler belongs to
+ }movingHandler;
+
+ struct ObjectSelectedHandler
+ {
+ ObjectSelectedHandler(Vizkit3DWidget& widget) : widget(widget){}
+ void operator()(const osgviz::Object* obj);
+ /**Does address comparision */
+ bool operator==(const ObjectSelectedHandler& other) const;
+ Vizkit3DWidget& widget;//the widget that this handler belongs to
+ }selectedHandler;
+
+ /**Connection between selectedHandler and it's signal.
+ * Used to temporarly block the slot*/
+ boost::signals2::connection selectedObjectConnection;
+
+ QPropertyBrowserWidget* propertyBrowserWidget;
+ QDockWidget* propertyDocker;
+
};
}
#endif