From a388b2c30740aa98fc5203bf3f9843e7a976a87f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Mon, 7 Mar 2016 11:11:23 +0100 Subject: [PATCH 01/12] Two bugfixes and added removeFrame() method --- src/Vizkit3DWidget.cpp | 15 +++++++++++---- src/Vizkit3DWidget.hpp | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index 9148dc2..5b3862e 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -889,6 +889,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()); @@ -1060,19 +1067,19 @@ QObject* Vizkit3DWidget::loadPlugin(QString lib_name,QString plugin_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); diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp index 5f7eae1..80957b9 100644 --- a/src/Vizkit3DWidget.hpp +++ b/src/Vizkit3DWidget.hpp @@ -261,6 +261,9 @@ 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; + + /**Removes @p frame from the visualization */ + void removeFrame(const QString& frame); void setCameraLookAt(double x, double y, double z); void setCameraEye(double x, double y, double z); From f70ed7198fd7f995572fbd80d8eaf081f4777f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Wed, 6 Apr 2016 10:36:20 +0200 Subject: [PATCH 02/12] PickHandler: Fix indentation --- src/PickHandler.cpp | 338 ++++++++++++++++++++++---------------------- 1 file changed, 169 insertions(+), 169 deletions(-) diff --git a/src/PickHandler.cpp b/src/PickHandler.cpp index d3764c2..ec8b4ca 100644 --- a/src/PickHandler.cpp +++ b/src/PickHandler.cpp @@ -67,94 +67,94 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapt switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()=='w') { - 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; + this->wireFrameModeOn(viewer->getSceneData()); } - case(osgGA::GUIEventAdapter::KEYUP): - { - if (ea.getKey()=='p') - { - _usePolytopeIntersector = !_usePolytopeIntersector; - if (_usePolytopeIntersector) - { - osg::notify(osg::NOTICE)<<"Using PolytopeIntersector"<wireFrameModeOff(viewer->getSceneData()); + } + else + { + keyFunctionMap::iterator itr = keyFuncMap.find(ea.getKey()); + if (itr != keyFuncMap.end()) { - keyFunctionMap::iterator itr = keyFuncMap.find(ea.getKey()); - if (itr != keyFuncMap.end() ) + if ( (*itr).second.keyState == KEY_UP ) { - (*itr).second.keyState = KEY_UP; + (*itr).second.keyState = KEY_DOWN; + newKeyDownEvent = true; } - - itr = keyUPFuncMap.find(ea.getKey()); - if (itr != keyUPFuncMap.end()) + if (newKeyDownEvent) { (*itr).second.keyFunction(); - return true; + newKeyDownEvent = false; } + return true; } + } + return false; + } + case(osgGA::GUIEventAdapter::KEYUP): + { + if (ea.getKey()=='p') + { + _usePolytopeIntersector = !_usePolytopeIntersector; + if (_usePolytopeIntersector) + { + osg::notify(osg::NOTICE)<<"Using PolytopeIntersector"<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); - } - } + osgUtil::PolytopeIntersector* picker; + if (_useWindowCoordinates) + { + // use window coordinates + // remap the mouse x,y into viewport coordinates. + osg::Viewport* viewport = viewer->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; + 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(); + osg::Vec3 global = intersection.localIntersectionPoint * *intersection.matrix.get(); emit plugin_data->getPlugin()->picked(global.x(),global.y(),global.z()); break; - } - // setTrackedNode(viewer, node); - } + } + //setTrackedNode(viewer, node); + } } } From c150768479066133848e6688da2a6c4c0d48c31b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Wed, 6 Apr 2016 16:37:19 +0200 Subject: [PATCH 03/12] PickHandler: remove window space picker. projection space picker works exactly the same and is less code clutter. Also enable polytopeIntersector by default. For objects it works just as good and it also works for 2d drawings such as lines and points. --- src/PickHandler.cpp | 96 +++++++++++++-------------------------------- src/PickHandler.hpp | 1 - 2 files changed, 28 insertions(+), 69 deletions(-) diff --git a/src/PickHandler.cpp b/src/PickHandler.cpp index ec8b4ca..03e8e97 100644 --- a/src/PickHandler.cpp +++ b/src/PickHandler.cpp @@ -17,8 +17,7 @@ using namespace vizkit3d; PickHandler::PickHandler(): _mx(0.0),_my(0.0), - _usePolytopeIntersector(false), - _useWindowCoordinates(false) {} + _usePolytopeIntersector(true) {} PickHandler::~PickHandler() {} @@ -108,16 +107,6 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapt osg::notify(osg::NOTICE)<<"Using LineSegmentIntersector"<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); + //projection space is [-1 ... 1], thus we can directly use the normalized + //mouse coordinates + double mx = ea.getXnormalized(); + double my = ea.getYnormalized(); + double w = 0.01; + double h = 0.01; + osg::ref_ptr picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h ); + // Using this setting, a single drawable will appear at most once while calculating intersections. + picker->setIntersectionLimit(osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE); + osgUtil::IntersectionVisitor iv(picker); viewer->getCamera()->accept(iv); if (picker->containsIntersections()) @@ -198,44 +176,26 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer 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); + const osgUtil::PolytopeIntersector::Intersection &intersection = *it; + + const osg::NodePath& nodePath = intersection.nodePath; + node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0; + osg::notify(osg::NOTICE)<< "NODE2: " << node->getName() << std::endl; + //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 ); - } + osg::ref_ptr picker; + // use non dimensional coordinates - in projection/clip space + picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::PROJECTION, ea.getXnormalized(),ea.getYnormalized() ); + osgUtil::IntersectionVisitor iv(picker); viewer->getCamera()->accept(iv); @@ -246,7 +206,7 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer osg::NodePath& nodePath = intersection.nodePath; node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0; - + osg::notify(osg::NOTICE)<< "NODE: " << node->getName() << std::endl; // see if the object has a user object which is derived from pickcallback PickedCallback *pc = dynamic_cast(node->getUserData()); if( pc ) @@ -271,7 +231,7 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer emit plugin_data->getPlugin()->picked(global.x(),global.y(),global.z()); break; } - //setTrackedNode(viewer, node); + // setTrackedNode(viewer, node); } } } diff --git a/src/PickHandler.hpp b/src/PickHandler.hpp index 1835d1a..5934f1b 100644 --- a/src/PickHandler.hpp +++ b/src/PickHandler.hpp @@ -66,7 +66,6 @@ class PickHandler : public QObject, public osgGA::GUIEventHandler float _mx,_my; bool _usePolytopeIntersector; - bool _useWindowCoordinates; typedef std::map keyFunctionMap; keyFunctionMap keyFuncMap; From e7b5c6aaac6c868ceb7cd53bedaf8ab629a3c930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Thu, 7 Apr 2016 16:44:42 +0200 Subject: [PATCH 04/12] Vizkit3d: Added support for picking frames --- src/PickHandler.cpp | 102 ++++++++++++++++++++--------------------- src/PickHandler.hpp | 10 +++- src/Vizkit3DPlugin.hpp | 66 +++++++++++++------------- src/Vizkit3DWidget.cpp | 72 +++++++++++++++++++++++++++-- src/Vizkit3DWidget.hpp | 17 ++++++- 5 files changed, 174 insertions(+), 93 deletions(-) diff --git a/src/PickHandler.cpp b/src/PickHandler.cpp index 03e8e97..6e8628d 100644 --- a/src/PickHandler.cpp +++ b/src/PickHandler.cpp @@ -152,10 +152,6 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer osg::Node* scene = viewer->getSceneData(); if (!scene) return; - osg::notify(osg::NOTICE)< picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h ); - // Using this setting, a single drawable will appear at most once while calculating intersections. - picker->setIntersectionLimit(osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE); + osg::ref_ptr picker; + picker = new osgUtil::PolytopeIntersector( osgUtil::Intersector::PROJECTION, mx-w, my-h, mx+w, my+h ); + picker->setIntersectionLimit(osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE);// a single drawable will appear at most once while calculating intersections. 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; - - const osg::NodePath& nodePath = intersection.nodePath; - node = (nodePath.size()>=1)?nodePath[nodePath.size()-1]:0; - osg::notify(osg::NOTICE)<< "NODE2: " << node->getName() << std::endl; - //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); - } + const osgUtil::PolytopeIntersector::Intersection intersection = picker->getFirstIntersection(); + const osg::NodePath& nodePath = intersection.nodePath; + osg::Vec3 global = intersection.localIntersectionPoint * *intersection.matrix.get(); + pickNodePath(nodePath, global, viewer); } } else { osg::ref_ptr picker; + // use non dimensional coordinates - in projection/clip space picker = new osgUtil::LineSegmentIntersector( osgUtil::Intersector::PROJECTION, ea.getXnormalized(),ea.getYnormalized() ); - + // Using this setting, a single drawable will appear at most once while calculating intersections. + picker->setIntersectionLimit(osgUtil::Intersector::LIMIT_ONE_PER_DRAWABLE); 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; - osg::notify(osg::NOTICE)<< "NODE: " << node->getName() << std::endl; - // 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); + const osg::NodePath& nodePath = intersection.nodePath; + const osg::Vec3 global = intersection.localIntersectionPoint * *intersection.matrix.get(); + pickNodePath(nodePath, global, viewer); } } } +void PickHandler::pickNodePath(const osg::NodePath& nodePath, osg::Vec3 global, + osgViewer::View* viewer) const +{ + if(nodePath.empty()) + return; + + osg::Node* node = nodePath[nodePath.size()-1]; + osg::notify(osg::NOTICE)<< "NODE: " << node->getName() << std::endl; + // 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); + emit plugin_data->getPlugin()->picked(global.x(),global.y(),global.z()); + break; + } + + const QVector3D globalPoint( global.x(), global.y(), global.z()); + emit picked(globalPoint); + emit pickedNodePath(nodePath); +} + void PickHandler::setTrackedNode(osgViewer::View* viewer, osg::ref_ptr< osg::Node > node) { osgGA::KeySwitchMatrixManipulator *keyswitchManipulator = diff --git a/src/PickHandler.hpp b/src/PickHandler.hpp index 5934f1b..4eba673 100644 --- a/src/PickHandler.hpp +++ b/src/PickHandler.hpp @@ -56,10 +56,18 @@ class PickHandler : public QObject, public osgGA::GUIEventHandler void pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer); signals: - void picked(const QVector3D& coord); + void picked(const QVector3D& coord) const; + /**Is emitted whenenver the user picks a node. + * @p path The path from the root node to the picked node*/ + void pickedNodePath(const osg::NodePath& path) const; protected: void setTrackedNode(osgViewer::View* viewer, osg::ref_ptr< osg::Node > node); + + /** @param nodePath NodePath to the picked node + * @param global global coordinates of the clicked point*/ + void pickNodePath(const osg::NodePath& nodePath, osg::Vec3 global, + osgViewer::View* viewer) const; void wireFrameModeOn(osg::Node *srcNode); void wireFrameModeOff(osg::Node *srcNode); diff --git a/src/Vizkit3DPlugin.hpp b/src/Vizkit3DPlugin.hpp index 839e541..27aadf8 100644 --- a/src/Vizkit3DPlugin.hpp +++ b/src/Vizkit3DPlugin.hpp @@ -129,15 +129,15 @@ class VizPluginBase : public QObject */ 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. @@ -155,8 +155,8 @@ 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); /** @@ -176,11 +176,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 +189,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 * @@ -247,15 +247,15 @@ class VizPluginBase : public QObject void picked(float x, float y,float z); 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,19 +267,19 @@ 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); + 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 @@ -292,8 +292,8 @@ 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; unsigned int max_old_data; diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index 5b3862e..e33071d 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -13,7 +13,6 @@ #include "Vizkit3DBase.hpp" #include "Vizkit3DWidget.hpp" #include "Vizkit3DPlugin.hpp" -#include "PickHandler.hpp" #include "QPropertyBrowserWidget.hpp" #include "AxesNode.hpp" #include "OsgVisitors.hpp" @@ -35,6 +34,8 @@ #include #include #include +#include +#include using namespace vizkit3d; using namespace std; @@ -231,6 +232,14 @@ Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool a // create root scene node root = createSceneGraph(world_name); + + //create geode that will be used as marker for the current selection + selectorGeode = new osg::Geode(); + osg::ShapeDrawable* sphere = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 0.2f)); + sphere->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.3f)); + sphere->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON); + selectorGeode->addDrawable(sphere); + // create osg widget QWidget* widget = addViewWidget(createGraphicsWindow(0,0,800,600), root); @@ -252,7 +261,8 @@ Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool a //connect signals and slots connect(this, SIGNAL(addPlugins(QObject*,QObject*)), this, SLOT(addPluginIntern(QObject*,QObject*))); connect(this, SIGNAL(removePlugins(QObject*)), this, SLOT(removePluginIntern(QObject*))); - connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) ); + connect(&_timer, SIGNAL(timeout()), this, SLOT(update()) ); + connect(&pickHandler, SIGNAL(pickedNodePath(const osg::NodePath&)), this, SLOT(pickNodePath(const osg::NodePath&))); current_frame = QString(root->getName().c_str()); @@ -362,8 +372,7 @@ QWidget* Vizkit3DWidget::addViewWidget( osgQt::GraphicsWindowQt* gw, ::osg::Node setCameraManipulator(TERRAIN_MANIPULATOR); // pickhandler is for selecting objects in the opengl view - PickHandler* pickHandler = new PickHandler(); - view->addEventHandler(pickHandler); + view->addEventHandler(&pickHandler); return gw->getGLWidget(); } @@ -1197,3 +1206,58 @@ void Vizkit3DWidget::setCameraManipulator(CAMERA_MANIPULATORS manipulatorType, b } } +void Vizkit3DWidget::pickNodePath(const osg::NodePath& path) +{ + for(int i = 0; i < path.size(); ++i) + { + std::cout << path[i]->className() << " | " << path[i]->getName() << std::endl; + } + + const osg::Node* clickedNode = path.back(); + + //ignore links created by the transformer graph. + //if the user clicks on a link, nothing happens + if(strcmp(clickedNode->className(), "Geode") == 0 && clickedNode->getName() == "link") + { + return; + } + + //FIXME handle plugins as well + //walk backwards in the graph structure and search for the first interessting + //node + for(int i = path.size() - 1; i >= 0; --i) + { + const osg::Node* node = path[i]; + + //check if it is a plugin + const PickedUserData* plugin_data = dynamic_cast(node->getUserData()); + if(plugin_data != NULL) + { + //FIXME maybe emit something + } + + //check if it is a frame + if(strcmp(node->className(), "PositionAttitudeTransform") == 0 && + TransformerGraph::hasFrame(*getRootNode(), node->getName())) + { + emit framePicked(QString::fromStdString(node->getName())); + break; + } + } +} + +void Vizkit3DWidget::setFrameHighlight(const QString& frame, const bool highlight) +{ + osg::ref_ptr group = TransformerGraph::getFrameGroup(*getRootNode(), frame.toStdString()); + if(highlight) + { + group->addChild(selectorGeode); + } + else + { + //FIXME not sure if this breaks if + group->removeChild(selectorGeode); + } +} + + diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp index 80957b9..557362d 100644 --- a/src/Vizkit3DWidget.hpp +++ b/src/Vizkit3DWidget.hpp @@ -2,6 +2,7 @@ #define __VIZKIT_QVIZKITWIDGET__ #include "Vizkit3DPlugin.hpp" +#include "PickHandler.hpp" #include #include @@ -247,7 +248,10 @@ namespace vizkit3d QStringList* getVisualizationFramesRuby() const; QStringList getVisualizationFrames() const; QString getVisualizationFrame() const; - + + /**Highlight the given frame*/ + void setFrameHighlight(const QString& frame, const bool highlight); + /** * Sets frame plugin data for a given plugin. * The pluging data frame is the frame in which the @@ -352,11 +356,15 @@ namespace vizkit3d * remove the plugin itself */ void clearEnvironmentPlugin(); - + + signals: void addPlugins(QObject* plugin,QObject* parent); void removePlugins(QObject* plugin); void propertyChanged(QString propertyName); + + /**Emitted when the user picks (clicks on) a frame */ + void framePicked(const QString& frame) const; protected: virtual void paintEvent( QPaintEvent* event ); @@ -368,6 +376,7 @@ namespace vizkit3d void pluginActivityChanged(bool enabled); void pluginChildrenChanged(); void addProperties(QObject* plugin,QObject *parent=NULL); + void pickNodePath(const osg::NodePath& path); private: // Helper method for setPluginEnabled @@ -421,6 +430,10 @@ namespace vizkit3d osg::ref_ptr captureHandler; osg::ref_ptr captureOperation; + + //geode used to mark the currently highlighted node + osg::ref_ptr selectorGeode; + PickHandler pickHandler; }; } #endif From 53c91edd34ce8d177b4d5431f52712393c522da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Mon, 11 Apr 2016 10:52:01 +0200 Subject: [PATCH 05/12] Vizkit3dWidget: fix crash in qt-designer bug --- src/Vizkit3DWidget.cpp | 7 +++---- src/Vizkit3DWidget.hpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index e33071d..fdb7ae5 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -206,7 +206,7 @@ void Vizkit3DConfig::setCameraManipulator(QStringList const& manipulator) Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool auto_update) : QWidget(parent) - , env_plugin(NULL) + , env_plugin(NULL), pickHandler(new PickHandler()) { //create layout //objects will be owned by the parent widget (this) @@ -262,7 +262,7 @@ Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool a connect(this, SIGNAL(addPlugins(QObject*,QObject*)), this, SLOT(addPluginIntern(QObject*,QObject*))); connect(this, SIGNAL(removePlugins(QObject*)), this, SLOT(removePluginIntern(QObject*))); connect(&_timer, SIGNAL(timeout()), this, SLOT(update()) ); - connect(&pickHandler, SIGNAL(pickedNodePath(const osg::NodePath&)), this, SLOT(pickNodePath(const osg::NodePath&))); + connect(pickHandler.get(), SIGNAL(pickedNodePath(const osg::NodePath&)), this, SLOT(pickNodePath(const osg::NodePath&))); current_frame = QString(root->getName().c_str()); @@ -372,7 +372,7 @@ QWidget* Vizkit3DWidget::addViewWidget( osgQt::GraphicsWindowQt* gw, ::osg::Node setCameraManipulator(TERRAIN_MANIPULATOR); // pickhandler is for selecting objects in the opengl view - view->addEventHandler(&pickHandler); + view->addEventHandler(pickHandler.get()); return gw->getGLWidget(); } @@ -1255,7 +1255,6 @@ void Vizkit3DWidget::setFrameHighlight(const QString& frame, const bool highligh } else { - //FIXME not sure if this breaks if group->removeChild(selectorGeode); } } diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp index 557362d..b67c040 100644 --- a/src/Vizkit3DWidget.hpp +++ b/src/Vizkit3DWidget.hpp @@ -433,7 +433,7 @@ namespace vizkit3d //geode used to mark the currently highlighted node osg::ref_ptr selectorGeode; - PickHandler pickHandler; + osg::ref_ptr pickHandler; }; } #endif From 1ecb660eb7278512b4783352fe6c269ea36a0e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Tue, 12 Apr 2016 14:29:22 +0200 Subject: [PATCH 06/12] Vizkit3dWidget: throw if user wants to highlight frame that doesnt exist --- src/Vizkit3DWidget.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index fdb7ae5..acd4c96 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -1249,14 +1249,13 @@ void Vizkit3DWidget::pickNodePath(const osg::NodePath& path) void Vizkit3DWidget::setFrameHighlight(const QString& frame, const bool highlight) { osg::ref_ptr group = TransformerGraph::getFrameGroup(*getRootNode(), frame.toStdString()); + if(group == NULL) + throw std::runtime_error("Cannot highlight frame " + frame.toStdString() + ". Frame doesn't exist."); + if(highlight) - { group->addChild(selectorGeode); - } else - { group->removeChild(selectorGeode); - } } From e963cba46fd32f6590ab2593b494013773b12149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Tue, 12 Apr 2016 15:10:15 +0200 Subject: [PATCH 07/12] better error message --- src/Vizkit3DWidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index acd4c96..15fde56 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -1250,7 +1250,7 @@ void Vizkit3DWidget::setFrameHighlight(const QString& frame, const bool highligh { osg::ref_ptr group = TransformerGraph::getFrameGroup(*getRootNode(), frame.toStdString()); if(group == NULL) - throw std::runtime_error("Cannot highlight frame " + frame.toStdString() + ". Frame doesn't exist."); + throw std::runtime_error("Cannot un/highlight frame " + frame.toStdString() + ". Frame doesn't exist."); if(highlight) group->addChild(selectorGeode); From b2d09329c8d37209fcfdc55e08b8da27c01592a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Mon, 18 Apr 2016 15:15:59 +0200 Subject: [PATCH 08/12] Vizkit3dWidget: add setWorldName() --- src/TransformerGraph.cpp | 7 +++++++ src/TransformerGraph.hpp | 5 +++++ src/Vizkit3DWidget.cpp | 5 +++++ src/Vizkit3DWidget.hpp | 1 + 4 files changed, 18 insertions(+) diff --git a/src/TransformerGraph.cpp b/src/TransformerGraph.cpp index c215629..c33d5e1 100644 --- a/src/TransformerGraph.cpp +++ b/src/TransformerGraph.cpp @@ -407,6 +407,13 @@ std::string TransformerGraph::getWorldName(const osg::Node &transformer) return std::string(transformer.getName()); } +void TransformerGraph::setWorldName(osg::Node &transformer, const std::string &name) +{ + transformer.setName(name); + osgText::Text* text = getFrameText(&transformer); + text->setText(name); +} + void TransformerGraph::setTextSize(osg::Node &transformer, float size) { TextSizeSetter::set(transformer, size); diff --git a/src/TransformerGraph.hpp b/src/TransformerGraph.hpp index d7e67ac..9a1784a 100644 --- a/src/TransformerGraph.hpp +++ b/src/TransformerGraph.hpp @@ -34,6 +34,11 @@ namespace vizkit3d */ static std::string getWorldName(const osg::Node &transformer); + /** + * Sets the name of the world (root) frame. + */ + static void setWorldName(osg::Node &transformer, const std::string &name); + /** * Sets the size of the frame annotations */ diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index 15fde56..0b15fd0 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -924,6 +924,11 @@ QString Vizkit3DWidget::getWorldName()const return QString(TransformerGraph::getWorldName(*getRootNode()).c_str()); } +void Vizkit3DWidget::setWorldName(const QString& name) +{ + TransformerGraph::setWorldName(*getRootNode(), name.toStdString()); +} + bool Vizkit3DWidget::isTransformer() const { return TransformerGraph::areFrameAnnotationVisible(*getRootNode()); diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp index b67c040..c5f21f6 100644 --- a/src/Vizkit3DWidget.hpp +++ b/src/Vizkit3DWidget.hpp @@ -265,6 +265,7 @@ 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); From 8e4fd85addf3eb0b16ff9e39ee1e6f45a6e19a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Tue, 19 Apr 2016 16:13:43 +0200 Subject: [PATCH 09/12] Vizkit3dWidget: bugfix: setWorldName() --- src/Vizkit3DWidget.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index 0b15fd0..b401b29 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -926,7 +926,20 @@ QString Vizkit3DWidget::getWorldName()const 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); + } + } } bool Vizkit3DWidget::isTransformer() const From d3fd67eea9e4d548ae8700fa7161107cc66719ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Wed, 20 Apr 2016 13:52:36 +0200 Subject: [PATCH 10/12] vizkit3d: removed debug output --- src/PickHandler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PickHandler.cpp b/src/PickHandler.cpp index 6e8628d..1322279 100644 --- a/src/PickHandler.cpp +++ b/src/PickHandler.cpp @@ -203,7 +203,6 @@ void PickHandler::pickNodePath(const osg::NodePath& nodePath, osg::Vec3 global, return; osg::Node* node = nodePath[nodePath.size()-1]; - osg::notify(osg::NOTICE)<< "NODE: " << node->getName() << std::endl; // see if the object has a user object which is derived from pickcallback PickedCallback *pc = dynamic_cast(node->getUserData()); if( pc ) From c1311779090d0935eaf3bf2555d40a94b488aecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Wed, 20 Apr 2016 15:01:40 +0200 Subject: [PATCH 11/12] Vizkit3dWidget: added clear() method. It removes all plugins and frames --- src/Vizkit3DWidget.cpp | 16 ++++++++++++++++ src/Vizkit3DWidget.hpp | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index b401b29..443cad1 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -1276,4 +1276,20 @@ void Vizkit3DWidget::setFrameHighlight(const QString& frame, const bool highligh group->removeChild(selectorGeode); } +void Vizkit3DWidget::clear() +{ + //remove plugins, 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]); + } +} diff --git a/src/Vizkit3DWidget.hpp b/src/Vizkit3DWidget.hpp index c5f21f6..b884196 100644 --- a/src/Vizkit3DWidget.hpp +++ b/src/Vizkit3DWidget.hpp @@ -243,7 +243,10 @@ namespace vizkit3d /** Require the given frame to be directly attached to the root */ void setRootFrame(QString frame); - + + /*Removes all plugins and all frames except the world frame.*/ + void clear(); + // we have to use a pointer here otherwise qt ruby is crashing QStringList* getVisualizationFramesRuby() const; QStringList getVisualizationFrames() const; From 820a5f2e8037e03ff0e3b0885fd3f241888ff769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20B=C3=B6ckmann?= Date: Mon, 25 Apr 2016 10:09:23 +0200 Subject: [PATCH 12/12] vizkit3dwidget: better transparency for highlighting --- src/Vizkit3DWidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Vizkit3DWidget.cpp b/src/Vizkit3DWidget.cpp index 443cad1..c5201b5 100644 --- a/src/Vizkit3DWidget.cpp +++ b/src/Vizkit3DWidget.cpp @@ -239,7 +239,9 @@ Vizkit3DWidget::Vizkit3DWidget( QWidget* parent,const QString &world_name,bool a sphere->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 0.3f)); sphere->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON); selectorGeode->addDrawable(sphere); - + osg::StateSet* set = selectorGeode->getOrCreateStateSet(); + set->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + set->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA), osg::StateAttribute::ON); // create osg widget QWidget* widget = addViewWidget(createGraphicsWindow(0,0,800,600), root);