Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes needed for envire #31

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
Vizkit3d: Added support for picking frames
  • Loading branch information
Arne Böckmann committed Apr 7, 2016
commit e7b5c6aaac6c868ceb7cd53bedaf8ab629a3c930
102 changes: 49 additions & 53 deletions src/PickHandler.cpp
Original file line number Diff line number Diff line change
@@ -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)<<std::endl;

osg::Node* node = 0;

if (_usePolytopeIntersector)
{
//projection space is [-1 ... 1], thus we can directly use the normalized
@@ -164,78 +160,78 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea, osgViewer::View* viewer
double my = ea.getYnormalized();
double w = 0.01;
double h = 0.01;
osg::ref_ptr<osgUtil::PolytopeIntersector> 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<osgUtil::PolytopeIntersector> 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<osgUtil::PolytopeIntersector::Intersection>::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<osgUtil::LineSegmentIntersector> 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<PickedCallback*>(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<PickedUserData*>(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<PickedCallback*>(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<PickedUserData*>(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 =
10 changes: 9 additions & 1 deletion src/PickHandler.hpp
Original file line number Diff line number Diff line change
@@ -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);
66 changes: 33 additions & 33 deletions src/Vizkit3DPlugin.hpp
Original file line number Diff line number Diff line change
@@ -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<osg::Group> getVizNode() const;
osg::ref_ptr<osg::Group> getRootNode() const;
/** @return a pointer to the internal Group that is used to maintain the
* plugin's nodes */
osg::ref_ptr<osg::Group> getVizNode() const;
osg::ref_ptr<osg::Group> 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<osg::Node> createMainNode();
/** override this method to provide your own main node.
* @return node derived from osg::Group
*/
virtual osg::ref_ptr<osg::Node> 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<osg::Node> 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<QDockWidget*> dockWidgets;
QString vizkit3d_plugin_name;
VizPluginRubyAdapterCollection adapterCollection;

private:
class CallbackAdapter;
osg::ref_ptr<osg::NodeCallback> nodeCallback;
void updateCallback(osg::Node* node);
class CallbackAdapter;
osg::ref_ptr<osg::NodeCallback> nodeCallback;
void updateCallback(osg::Node* node);

osg::ref_ptr<osg::Node> mainNode; //node which is used by the child class
osg::ref_ptr<osg::Group> 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;
72 changes: 68 additions & 4 deletions src/Vizkit3DWidget.cpp
Original file line number Diff line number Diff line change
@@ -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 <osgGA/TerrainManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osg/ShapeDrawable>
#include <osg/BlendFunc>

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<const PickedUserData*>(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<osg::Group> group = TransformerGraph::getFrameGroup(*getRootNode(), frame.toStdString());
if(highlight)
{
group->addChild(selectorGeode);
}
else
{
//FIXME not sure if this breaks if
group->removeChild(selectorGeode);
}
}


Loading