diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index 42f81eea4..15978e0e1 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -347,6 +347,53 @@ bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const return false; } +osg::ref_ptr CSVRender::WorldspaceWidget::mousePick (QMouseEvent *event) +{ + // (0,0) is considered the lower left corner of an OpenGL window + int x = event->x(); + int y = height() - event->y(); + + osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y)); + + intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); + osgUtil::IntersectionVisitor visitor(intersector); + + visitor.setTraversalMask(getInteractionMask() << 1); + + mView->getCamera()->accept(visitor); + + for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); + it != intersector->getIntersections().end(); ++it) + { + osgUtil::LineSegmentIntersector::Intersection intersection = *it; + + // reject back-facing polygons + osg::Vec3f normal = intersection.getWorldIntersectNormal(); + normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix()); + if (normal.z() < 0) + continue; + + for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + { + osg::Node* node = *it; + if (osg::ref_ptr tag = dynamic_cast(node->getUserData())) + { + if (!(tag->getElement() & mInteractionMask)) + break; // not interested -> continue looking + + return tag; + } + } + +// ignoring terrain for now + // must be terrain, report coordinates +// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; +// return; + } + + return osg::ref_ptr(); +} + void CSVRender::WorldspaceWidget::dropEvent (QDropEvent* event) { const CSMWorld::TableMimeData* mime = dynamic_cast (event->mimeData()); @@ -436,54 +483,16 @@ void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) if (event->button() != Qt::RightButton) return; - // (0,0) is considered the lower left corner of an OpenGL window - int x = event->x(); - int y = height() - event->y(); - - osg::ref_ptr intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y)); - - intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); - osgUtil::IntersectionVisitor visitor(intersector); - - visitor.setTraversalMask(getInteractionMask() << 1); - - mView->getCamera()->accept(visitor); + osg::ref_ptr tag = mousePick (event); - for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); - it != intersector->getIntersections().end(); ++it) + if (tag) { - osgUtil::LineSegmentIntersector::Intersection intersection = *it; - - // reject back-facing polygons - osg::Vec3f normal = intersection.getWorldIntersectNormal(); - normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix()); - if (normal.z() < 0) - continue; - - for (std::vector::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) + if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag.get())) { - osg::Node* node = *it; - if (CSVRender::TagBase* tag = dynamic_cast(node->getUserData())) - { - if (!(tag->getElement() & mInteractionMask)) - break; // not interested -> continue looking - - // hit something marked with a tag - if (CSVRender::ObjectTag *objectTag = dynamic_cast (tag)) - { - // hit an Object, toggle its selection state - CSVRender::Object* object = objectTag->mObject; - object->setSelected (!object->getSelected()); - } - - return; - } + // hit an Object, toggle its selection state + CSVRender::Object* object = objectTag->mObject; + object->setSelected (!object->getSelected()); } - -// ignoring terrain for now - // must be terrain, report coordinates -// std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; -// return; } } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 23f672fbd..90a85006f 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -25,6 +25,8 @@ namespace CSVWidget namespace CSVRender { + class TagBase; + class WorldspaceWidget : public SceneWidget { Q_OBJECT @@ -126,6 +128,8 @@ namespace CSVRender /// \return Is \a key a button mapping setting? (ignored otherwise) bool storeMappingSetting (const QString& key, const QString& value); + osg::ref_ptr mousePick (QMouseEvent *event); + virtual std::string getStartupInstruction() = 0; private slots: