From 89b1365b2bad5a207e3af2df47cab7e92535fbb6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 25 Apr 2003 13:47:33 +0000 Subject: [PATCH] Added support for gather information on which vertices have been intersected with. --- examples/osgpick/osgpick.cpp | 40 +++++++++++++---------- src/osgProducer/Viewer.cpp | 4 +-- src/osgUtil/IntersectVisitor.cpp | 54 +++++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 22 deletions(-) diff --git a/examples/osgpick/osgpick.cpp b/examples/osgpick/osgpick.cpp index 2ef52cc1f..19de0e4cb 100644 --- a/examples/osgpick/osgpick.cpp +++ b/examples/osgpick/osgpick.cpp @@ -28,6 +28,7 @@ #include +#include // class to handle events with a pick class PickHandler : public osgGA::GUIEventHandler { @@ -80,21 +81,26 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea) hitr!=hlist.end(); ++hitr) { - //osg::Vec3 ip = hitr->getLocalIntersectPoint(); - //osg::Vec3 in = hitr->getLocalIntersectNormal(); - osg::Geode* geode = hitr->_geode.get(); - // the geodes are identified by name. - if (geode) + std::ostringstream os; + if (hitr->_geode.valid() && !hitr->_geode->getName().empty()) { - if (!geode->getName().empty()) - { - gdlist=gdlist+" "+geode->getName(); - } - else - { - gdlist=gdlist+" geode"; - } - } + // the geodes are identified by name. + os<<"Object \""<_geode->getName()<<"\""<_drawable.valid()) + { + os<<"Object \""<_drawable->className()<<"\""<getLocalIntersectPoint()<<")"<<" normal("<getLocalIntersectNormal()<<")"<getWorldIntersectPoint()<<")"<<" normal("<getWorldIntersectNormal()<<")"<_vecIndexList; + for(unsigned int i=0;isetName("The text label"); geode->addDrawable( updateText ); modelview_abs->addChild(geode); + updateText->setCharacterSize(20.0f); updateText->setFont(timesFont); - updateText->setText("whatis will tell you what is under the mouse"); + updateText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f)); + updateText->setText(""); updateText->setPosition(position); position += delta; diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index 6fca77a9b..04a358a78 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -39,8 +39,8 @@ public: _lineSegment = new osg::LineSegment; _lineSegment->set(nr,fr); // make a line segment - std::cout<<"near "< #include #include +#include #include #include @@ -304,6 +305,29 @@ void IntersectVisitor::apply(Node& node) } +struct TriangleHit +{ + TriangleHit(unsigned int index, const osg::Vec3& normal, float r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3, const osg::Vec3* v3): + _index(index), + _normal(normal), + _r1(r1), + _v1(v1), + _r2(r2), + _v2(v2), + _r3(r3), + _v3(v3) {} + + unsigned int _index; + const osg::Vec3 _normal; + float _r1; + const osg::Vec3* _v1; + float _r2; + const osg::Vec3* _v2; + float _r3; + const osg::Vec3* _v3; +}; + + struct TriangleIntersect { osg::ref_ptr _seg; @@ -315,8 +339,11 @@ struct TriangleIntersect int _index; float _ratio; bool _hit; + + - typedef std::multimap > TriangleHitList; + typedef std::multimap TriangleHitList; + TriangleHitList _thl; TriangleIntersect() @@ -439,7 +466,7 @@ struct TriangleIntersect return; } - _thl.insert(std::pair > (r,std::pair(_index-1,normal))); + _thl.insert(std::pair(r,TriangleHit(_index-1,normal,r1,&v1,r2,&v2,r3,&v3))); _hit = true; } @@ -466,11 +493,15 @@ bool IntersectVisitor::intersect(Drawable& drawable) drawable.accept(ti); if (ti._hit) { + + osg::Geometry* geometry = drawable.asGeometry(); + for(TriangleIntersect::TriangleHitList::iterator thitr=ti._thl.begin(); thitr!=ti._thl.end(); ++thitr) { + Hit hit; hit._nodePath = _nodePath; hit._matrix = cis->_matrix; @@ -479,15 +510,30 @@ bool IntersectVisitor::intersect(Drawable& drawable) if (_nodePath.empty()) hit._geode = NULL; else hit._geode = dynamic_cast(_nodePath.back()); + TriangleHit& triHit = thitr->second; + hit._ratio = thitr->first; - hit._primitiveIndex = thitr->second.first; + hit._primitiveIndex = triHit._index; hit._originalLineSegment = sitr->first; hit._localLineSegment = sitr->second; hit._intersectPoint = sitr->second->start()*(1.0f-hit._ratio)+ sitr->second->end()*hit._ratio; - hit._intersectNormal = thitr->second.second; + hit._intersectNormal = triHit._normal; + + if (geometry) + { + osg::Vec3Array* vertices = geometry->getVertexArray(); + if (vertices) + { + osg::Vec3* first = &(vertices->front()); + if (triHit._v1) hit._vecIndexList.push_back(triHit._v1-first); + if (triHit._v2) hit._vecIndexList.push_back(triHit._v2-first); + if (triHit._v2) hit._vecIndexList.push_back(triHit._v3-first); + } + } + _segHitList[sitr->first.get()].push_back(hit);