Well I think my first mistake is in computing the selection bounding box. Now I use ea.getXnormalized() and ea.getYnormalized() to get normalized window device coordinates. After that I try to back project the 2D Point into 3D with the following code:
osg::Camera* cam = viewer->getCamera(); osg::Matrix inverseProjection = osg::Matrix::inverse(cam->getProjectionMatrix() * cam->getViewMatrix()); osg::Vec3 inverseProjVectorOld = osg::Vec3(m_X, m_Y, 0.0f) * inverseProjection; osg::Vec3 inverseProjVectorCurrent = osg::Vec3(currentX, currentY, 0.0f) * inverseProjection; osg::Vec3 bbMin(inverseProjVectorOld.x(), inverseProjVectorOld.y(), -1000.0f); osg::Vec3 bbMax(inverseProjVectorCurrent.x(), inverseProjVectorCurrent.y(), 1000.0f); osg::BoundingBox selectionBox(bbMin, bbMax); If this right then my selectionBox is a valid bounding box in world space. But before I can check I think I have to calculate the models bounding box that I want so select in worldspace. After that I would check selectionBox.contains(_minBBModel) || selectionBox.contains(_maxBBModel); It does not seem to work, yet. My SelectionBox coordinates seem strange. Any suggestions? Thanks. ________________________________________ Von: [email protected] [[email protected]] im Auftrag von Wuerfel, Hannes Gesendet: Samstag, 20. Oktober 2012 11:16 An: [email protected] Betreff: [osg-users] Multiple Node selection in a rectangular region Hi all, I'm currently working my way through the OpenSceneGraph 3.0 Beginner's Guide. But now I'm stucked with the 'Have a go hero' task in Chapter 9 (selecting geometries in a rectangular region). As proposed I tried to use osgUtil::PolytopeIntersector. But the visitor takes too long for me. So this was my first try. My root node contains several osgFX::Outline nodes which contain a 3d model each. Is there a trick I'm missing to get it faster since it is widly used 3d interaction? class BadGroupSelectHandler : public osgGA::GUIEventHandler { public: BadGroupSelectHandler() : m_X(0.0f), m_Y(0.0f) {} virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if(ea.getButton() != osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON || !(ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL)) { return false; } osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa); if(!viewer) return false; switch(ea.getEventType()) { case osgGA::GUIEventAdapter::PUSH: case osgGA::GUIEventAdapter::MOVE: { // record mouse location for the button press and move event m_X = ea.getX(); m_Y = ea.getY(); return false; } case osgGA::GUIEventAdapter::RELEASE: { if(m_X != ea.getX() && m_Y != ea.getY()) { if(select(ea.getX(), ea.getY(), viewer)) { return true; } } return false; } } return false; } protected: bool select(const double currentX, const double currentY, osgViewer::Viewer* viewer) { if(!viewer->getSceneData()) return false; float xMin = MIN(m_X, currentX); float yMin = MIN(m_Y, currentY); float xMax = MAX(m_X, currentX); float yMax = MAX(m_Y, currentY); osgUtil::PolytopeIntersector* intersector = new osgUtil::PolytopeIntersector(osgUtil::PolytopeIntersector::WINDOW, xMin, yMin, xMax, yMax); osgUtil::IntersectionVisitor iv(intersector); viewer->getCamera()->accept(iv); // too slow if(intersector->containsIntersections()) { // if I would iterate over all intersections, i would end up with too much intersection data // but I need more than the first intersection osgUtil::PolytopeIntersector::Intersection result = *(intersector->getIntersections().begin()); osg::NodePath path = result.nodePath; for(unsigned int i = 0; i < path.size(); ++i) { // do something } return true; } return false; } float m_X; float m_Y; }; My second try was to check against the bounding boxes but I was unable to select them: bool select(const double currentX, const double currentY, osgViewer::Viewer* viewer) { osg::Group* root = viewer->getSceneData()->asGroup(); if(!root) return false; double left_, right_, bottom_, top_, near_, far_; // I've tried to receive near and far plane viewer->getCamera()->getProjectionMatrixAsFrustum(left_, right_, bottom_, top_, near_, far_); // construct selection bounding box osg::Vec3 bMin(m_X, m_Y, near_); osg::Vec3 bMax(currentX, currentY, far_); osg::BoundingBox selectionBox(bMin, bMax); for(unsigned int i = 0; i < root->getNumChildren(); ++i) { osg::BoundingSphere bs = root->getChild(i)->getBound(); osg::Vec3 _min; osg::Vec3 _max; _min.set(bs.center().x() - bs.radius(), bs.center().y() - bs.radius(), bs.center().z() - bs.radius()); _max.set(bs.center().x() + bs.radius(), bs.center().y() + bs.radius(), bs.center().z() + bs.radius()); bool intersected = selectionBox.contains(_min) || selectionBox.contains(_max); if(intersected) { // do something } } return false; } _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

