diff --git a/examples/osglauncher/osglauncher.cpp b/examples/osglauncher/osglauncher.cpp index 22b43fcad..ca7c48b8b 100644 --- a/examples/osglauncher/osglauncher.cpp +++ b/examples/osglauncher/osglauncher.cpp @@ -92,20 +92,18 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte std::string PickHandler::pick(float x, float y) { -#if 0 - osgUtil::IntersectVisitor::HitList hlist; - if (_viewer->computeIntersections(x, y, hlist)) + osgUtil::LineSegmentIntersector::Intersections intersections; + if (_viewer->computeIntersections(x, y, intersections)) { - for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin(); - hitr!=hlist.end(); + for(osgUtil::LineSegmentIntersector::Intersections::iterator hitr = intersections.begin(); + hitr != intersections.end(); ++hitr) { - if (hitr->_geode.valid() && !hitr->_geode->getName().empty()) return hitr->_geode->getName(); + osg::Node* node = hitr->nodePath.empty() ? 0 : hitr->nodePath.back(); + if (node && !node->getName().empty()) return node->getName(); } } -#else - osg::notify(osg::NOTICE)<<"Picking not implemented yet "<(&aa); - osgUtil::IntersectVisitor::HitList hlist; - if (viewer->computeIntersections(ea.getX(),ea.getY(), nv->getNodePath().back(), hlist)) + + osgViewer::View* view = dynamic_cast(&aa); + osg::notify(osg::NOTICE)<<"osgmovie - view = "<computeIntersections(ea.getX(), ea.getY(), nv->getNodePath().back(), intersections)) { - if (!hlist.empty()) +#if 1 + osg::notify(osg::NOTICE)<<"osgmovie - Vertex interpolation not implemented yet"<asGeometry() : 0; + osg::Vec3Array* vertices = geometry ? dynamic_cast(geometry->getVertexArray()) : 0; + if (vertices) { - // use the nearest intersection - osgUtil::Hit& hit = hlist.front(); - osg::Drawable* drawable = hit.getDrawable(); - osg::Geometry* geometry = drawable ? drawable->asGeometry() : 0; - osg::Vec3Array* vertices = geometry ? dynamic_cast(geometry->getVertexArray()) : 0; + // get the vertex indices. + const osgUtil::LineSegmentIntersector::Intersection::IndexList& vil = intersection.indexList; - if (vertices) + if (vil.size()==3) { - // get the vertex indices. - const osgUtil::Hit::VecIndexList& vil = hit.getVecIndexList(); + int i1 = vil[0]; + int i2 = vil[1]; + int i3 = vil[2]; + osg::Vec3 v1 = (*vertices)[i1]; + osg::Vec3 v2 = (*vertices)[i2]; + osg::Vec3 v3 = (*vertices)[i3]; + osg::Vec3 v = intersection.localIntersectionPoint; - if (vil.size()==3) + osg::Vec3 p1 = intersection.getLocalLineSegment()->start(); + osg::Vec3 p2 = intersection.getLocalLineSegment()->end(); + + osg::Vec3 p12 = p1-p2; + osg::Vec3 v13 = v1-v3; + osg::Vec3 v23 = v2-v3; + osg::Vec3 p1v3 = p1-v3; + + osg::Matrix matrix(p12.x(), v13.x(), v23.x(), 0.0, + p12.y(), v13.y(), v23.y(), 0.0, + p12.z(), v13.z(), v23.z(), 0.0, + 0.0, 0.0, 0.0, 1.0); + + osg::Matrix inverse; + inverse.invert(matrix); + + osg::Vec3 ratio = inverse*p1v3; + + // extract the baricentric coordinates. + float r1 = ratio.y(); + float r2 = ratio.z(); + float r3 = 1.0f-r1-r2; + + osg::Array* texcoords = (geometry->getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; + osg::Vec2Array* texcoords_Vec2Array = dynamic_cast(texcoords); + if (texcoords_Vec2Array) { + // we have tex coord array so now we can compute the final tex coord at the point of intersection. + osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1]; + osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2]; + osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3]; + osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3; - int i1 = vil[0]; - int i2 = vil[1]; - int i3 = vil[2]; - osg::Vec3 v1 = (*vertices)[i1]; - osg::Vec3 v2 = (*vertices)[i2]; - osg::Vec3 v3 = (*vertices)[i3]; - osg::Vec3 v = hit.getLocalIntersectPoint(); - osg::Vec3 p1 = hit.getLocalLineSegment()->start(); - osg::Vec3 p2 = hit.getLocalLineSegment()->end(); - - osg::Vec3 p12 = p1-p2; - osg::Vec3 v13 = v1-v3; - osg::Vec3 v23 = v2-v3; - osg::Vec3 p1v3 = p1-v3; - - osg::Matrix matrix(p12.x(), v13.x(), v23.x(), 0.0, - p12.y(), v13.y(), v23.y(), 0.0, - p12.z(), v13.z(), v23.z(), 0.0, - 0.0, 0.0, 0.0, 1.0); - - osg::Matrix inverse; - inverse.invert(matrix); - - osg::Vec3 ratio = inverse*p1v3; + osg::notify(osg::NOTICE)<<"We hit tex coords "<getNumTexCoordArrays()>0) ? geometry->getTexCoordArray(0) : 0; - osg::Vec2Array* texcoords_Vec2Array = dynamic_cast(texcoords); - if (texcoords_Vec2Array) - { - // we have tex coord array so now we can compute the final tex coord at the point of intersection. - osg::Vec2 tc1 = (*texcoords_Vec2Array)[i1]; - osg::Vec2 tc2 = (*texcoords_Vec2Array)[i2]; - osg::Vec2 tc3 = (*texcoords_Vec2Array)[i3]; - osg::Vec2 tc = tc1*r1 + tc2*r2 + tc3*r3; - - osg::notify(osg::NOTICE)<<"We hit tex coords "< _convexPlanarOccluder; }; -bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) +bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) { -#if 0 switch(ea.getEventType()) { case(osgGA::GUIEventAdapter::KEYDOWN): { if (ea.getKey()=='a') + { - float x = ea.getXnormalized(); - float y = ea.getYnormalized(); - - osgUtil::IntersectVisitor::HitList hitList; - if (!_viewer->computeIntersections(x,y,hitList)) + osgViewer::View* view = dynamic_cast(&aa); + osgUtil::LineSegmentIntersector::Intersections intersections; + if (view && view->computeIntersections(ea.getX(), ea.getY(), intersections)) { - return true; - } - - if (!hitList.empty()) - { - - osgUtil::Hit& hit = hitList.front(); - addPoint(hit.getWorldIntersectPoint()); + const osgUtil::LineSegmentIntersector::Intersection& hit = *(intersections.begin()); + if (hit.matrix.valid()) addPoint(hit.localIntersectionPoint * (*hit.matrix)); + else addPoint(hit.localIntersectionPoint); } return true; @@ -97,10 +90,6 @@ bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIAct default: return false; } -#else - osg::notify(osg::NOTICE)<<"Computre intersections not implemented yet."< + +#include +#include +#include + #include #include -#include - namespace osgViewer { /** View holds a single view on a scene, this view may be composed of one or more slave cameras.*/ @@ -53,6 +56,22 @@ class OSGVIEWER_EXPORT View : public osg::View, public osgGA::GUIActionAdapter /** Convinience method for a single Camara associated with a single full screen GraphicsWindow.*/ void setUpViewOnSingleScreen(unsigned int screenNum=0); + + /** Compute intersections between a ray through the specified master cameras window/eye coords and a specified node. + * Note, when a master cameras has slaves and no viewport itself its coordinate frame will be in clip space i.e. -1,-1 to 1,1, + * while if its has a viewport the coordintates will be relative to its viewport dimensions. + * Mouse events handled by the view will automatically be attached into the master camera window/clip coords so can be passed + * directly on to the computeIntersections method. */ + bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); + + /** Compute intersections between a ray through the specified master cameras window/eye coords and a specified node. + * Note, when a master cameras has slaves and no viewport itself its coordinate frame will be in clip space i.e. -1,-1 to 1,1, + * while if its has a viewport the coordintates will be relative to its viewport dimensions. + * Mouse events handled by the view will automatically be attached into the master camera window/clip coords so can be passed + * directly on to the computeIntersections method. */ + bool computeIntersections(float x,float y, osg::Node* node, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff); + + virtual void requestRedraw(); virtual void requestContinuousUpdate(bool needed=true); virtual void requestWarpPointer(float x,float y); diff --git a/src/osgViewer/CompositeViewer.cpp b/src/osgViewer/CompositeViewer.cpp index 5ceb5c1fd..27b1da027 100644 --- a/src/osgViewer/CompositeViewer.cpp +++ b/src/osgViewer/CompositeViewer.cpp @@ -30,7 +30,7 @@ void CompositeViewer::init() void CompositeViewer::addView(osgViewer::View* view) { - osg::notify(osg::NOTICE)<<"CompositeViewer::addView(View*) not implemented yet."<y = 0; traits->width = width; traits->height = height; -#if 1 traits->windowDecoration = false; -#else - traits->windowDecoration = true; -#endif traits->doubleBuffer = true; traits->sharedContext = 0; @@ -250,7 +244,7 @@ void View::setUpViewOnSingleScreen(unsigned int screenNum) osgViewer::GraphicsWindow* gw = dynamic_cast(gc.get()); if (gw) { - osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height ); } else @@ -391,3 +385,35 @@ void View::requestWarpPointer(float x,float y) } + +bool View::computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask) +{ + if (!_camera.valid()) return false; + + osgUtil::LineSegmentIntersector::CoordinateFrame cf = _camera->getViewport() ? osgUtil::Intersector::WINDOW : osgUtil::Intersector::PROJECTION; + osgUtil::LineSegmentIntersector* picker = new osgUtil::LineSegmentIntersector(cf, x, y); + + osgUtil::IntersectionVisitor iv(picker); + iv.setTraversalMask(traversalMask); + _camera->accept(iv); + + if (picker->containsIntersections()) + { + intersections = picker->getIntersections(); + return true; + } + else + { + intersections.clear(); + return false; + } +} + +bool View::computeIntersections(float x,float y, osg::Node* node, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask) +{ + if (!_camera.valid()) return false; + + osg::notify(osg::NOTICE)<<"View::computeIntersections(x,y,node,intersections) not implemented"<