From 5df7118d6df635afacd9802d59906a9588b99c83 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 14 Apr 2003 15:44:30 +0000 Subject: [PATCH] Updates to the osgpick code. Updates to osgGA::CameraManipulors. --- VisualStudio/VisualStudio.dsw | 3 + VisualStudio/examples/osgpick/osgpick.dsp | 4 +- VisualStudio/osgUtil/osgUtil.dsp | 4 + examples/osgpick/osgpick.cpp | 30 ++--- examples/osgwindows/osgwindows.cpp | 8 +- include/osgUtil/PickVisitor | 52 +++++---- src/osg/NodeVisitor.cpp | 8 +- src/osgGA/TrackballManipulator.cpp | 8 +- src/osgProducer/Viewer.cpp | 1 + src/osgUtil/PickVisitor.cpp | 127 ++++++++++++---------- 10 files changed, 134 insertions(+), 111 deletions(-) diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index d4e273460..055db8515 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -1166,6 +1166,9 @@ Package=<4> Begin Project Dependency Project_Dep_Name Core osgUtil End Project Dependency + Begin Project Dependency + Project_Dep_Name Core osgText + End Project Dependency }}} ############################################################################### diff --git a/VisualStudio/examples/osgpick/osgpick.dsp b/VisualStudio/examples/osgpick/osgpick.dsp index cbc920fa7..bb38510c1 100644 --- a/VisualStudio/examples/osgpick/osgpick.dsp +++ b/VisualStudio/examples/osgpick/osgpick.dsp @@ -102,7 +102,7 @@ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 opengl32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgpick.exe" /libpath:"../../../lib" +# ADD LINK32 opengl32.lib Producer.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgpick.exe" /libpath:"../../../lib" @@ -150,7 +150,7 @@ LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgpickd.exe" /pdbtype:sept /libpath:"../../../lib" +# ADD LINK32 opengl32.lib Producerd.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgpickd.exe" /pdbtype:sept /libpath:"../../../lib" # SUBTRACT LINK32 /incremental:no diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index 9a7c0171b..42430f529 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -97,6 +97,10 @@ SOURCE=..\..\src\osgUtil\CubeMapGenerator.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgUtil\PickVisitor.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgUtil\HalfWayMapGenerator.cpp # End Source File # Begin Source File diff --git a/examples/osgpick/osgpick.cpp b/examples/osgpick/osgpick.cpp index 988afcb2f..55f7c8bde 100644 --- a/examples/osgpick/osgpick.cpp +++ b/examples/osgpick/osgpick.cpp @@ -81,18 +81,14 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea) { float x=ea.getXnormalized(); float y=ea.getYnormalized(); - osgUtil::PickVisitor iv; - const float *matView; - const float *matProj; + Producer::Camera *cmm=_cg->getCamera(0); - matView=cmm->getViewMatrix(); - matProj=cmm->getProjectionMatrix(); - osg::Matrix vum; - vum.set(matView); - vum.postMult(osg::Matrix(matProj)); - osg::Matrix windowmatrix=osg::Matrix::translate(1.0f,1.0f,1.0f)* - osg::Matrix::scale(0.5f,0.5f,0.5f); - vum.postMult(windowmatrix); + osg::Matrix vum(osg::Matrix(cmm->getViewMatrix()) * + osg::Matrix(cmm->getProjectionMatrix())/* * + osg::Matrix::translate(1.0f,1.0f,1.0f) * + osg::Matrix::scale(0.5f,0.5f,0.5f)*/); + + osgUtil::PickVisitor iv; osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, x,y); std::string gdlist=""; if (iv.hits()) @@ -105,8 +101,16 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea) //osg::Vec3 in = hitr->getLocalIntersectNormal(); osg::Geode* geode = hitr->_geode.get(); // the geodes are identified by name. - if (geode) { - gdlist=gdlist+" "+geode->getName(); + if (geode) + { + if (!geode->getName().empty()) + { + gdlist=gdlist+" "+geode->getName(); + } + else + { + gdlist=gdlist+" geode"; + } } } } diff --git a/examples/osgwindows/osgwindows.cpp b/examples/osgwindows/osgwindows.cpp index 1095cb71d..bedbe9863 100644 --- a/examples/osgwindows/osgwindows.cpp +++ b/examples/osgwindows/osgwindows.cpp @@ -32,10 +32,10 @@ static Producer::CameraConfig *BuildConfig(void) camera2->setOffset( -1.0, 0.0 ); Producer::InputArea *ia = new Producer::InputArea; -// ia->addInputRectangle( rs1, Producer::InputRectangle(0.0,0.5,0.0,1.0)); -// ia->addInputRectangle( rs2, Producer::InputRectangle(0.5,1.0,0.0,1.0)); - ia->addInputRectangle( rs1, Producer::InputRectangle(-1.0,0.0,-1.0,1.0)); - ia->addInputRectangle( rs2, Producer::InputRectangle(0.0,1.0,-1.0,1.0)); + ia->addInputRectangle( rs1, Producer::InputRectangle(0.0,0.5,0.0,1.0)); + ia->addInputRectangle( rs2, Producer::InputRectangle(0.5,1.0,0.0,1.0)); +// ia->addInputRectangle( rs1, Producer::InputRectangle(-1.0,0.0,-1.0,1.0)); +// ia->addInputRectangle( rs2, Producer::InputRectangle(0.0,1.0,-1.0,1.0)); Producer::CameraConfig *cfg = new Producer::CameraConfig; diff --git a/include/osgUtil/PickVisitor b/include/osgUtil/PickVisitor index 959e32d72..c51877418 100644 --- a/include/osgUtil/PickVisitor +++ b/include/osgUtil/PickVisitor @@ -26,40 +26,44 @@ namespace osgUtil { // PickIntersectVisitor simplifies picking - routines take x,y mouse pixel & detect hits -class OSGUTIL_EXPORT PickIntersectVisitor : public IntersectVisitor { +class OSGUTIL_EXPORT PickIntersectVisitor : public IntersectVisitor +{ public: - PickIntersectVisitor() { - setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions - } - ~PickIntersectVisitor() { } - HitList& getHits(osgUtil::SceneView *, int x, int y); - HitList& PickIntersectVisitor::getIntersections(osg::Node *scene, osg::Vec3 nr, osg::Vec3 fr); + PickIntersectVisitor() + { + setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions + } + ~PickIntersectVisitor() { } + HitList& getHits(osgUtil::SceneView *, int x, int y); + HitList& PickIntersectVisitor::getIntersections(osg::Node *scene, osg::Vec3 nr, osg::Vec3 fr); private: - osg::ref_ptr _lineSegment; + osg::ref_ptr _lineSegment; friend class osgUtil::IntersectVisitor; }; // PickVisitor traverses whole scene and checks below all Projection nodes -class OSGUTIL_EXPORT PickVisitor : public osg::NodeVisitor { +class OSGUTIL_EXPORT PickVisitor : public osg::NodeVisitor +{ public: - PickVisitor() { - xp=yp=0; - setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions - setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); - } - ~PickVisitor() { } + PickVisitor() + { + xp=yp=0; + setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions + setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); + } + ~PickVisitor() { } virtual void apply(osg::Projection& pr); - osgUtil::IntersectVisitor::HitList& getHits(osg::Node *nd, const osg::Matrix &projm, const float x, const float y); - osgUtil::IntersectVisitor::HitList& getHits(osgUtil::SceneView *, double x, double y); - osgUtil::IntersectVisitor::HitList & getHits(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point); - osgUtil::IntersectVisitor::HitList& getHits(void); - inline void setxy(float xpt, float ypt) { xp=xpt; yp=ypt; } - inline bool hits() { return _PIVsegHitList.size()>0;} + osgUtil::IntersectVisitor::HitList& getHits(osg::Node *nd, const osg::Matrix &projm, const float x, const float y); + osgUtil::IntersectVisitor::HitList& getHits(osgUtil::SceneView *, double x, double y); + osgUtil::IntersectVisitor::HitList & getHits(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point); + osgUtil::IntersectVisitor::HitList& getHits(void); + inline void setxy(float xpt, float ypt) { xp=xpt; yp=ypt; } + inline bool hits() { return _PIVsegHitList.size()>0;} private: - PickIntersectVisitor _piv; - float xp, yp; // start point in viewport fraction coordiantes + PickIntersectVisitor _piv; + float xp, yp; // start point in viewport fraction coordiantes osgUtil::IntersectVisitor::HitList _PIVsegHitList; }; }// namespace osgUtil -#endif // match OSGUTIL_PICKINTERSECTVISITOR \ No newline at end of file +#endif // match OSGUTIL_PICKINTERSECTVISITOR diff --git a/src/osg/NodeVisitor.cpp b/src/osg/NodeVisitor.cpp index 71bdb455f..047002f57 100644 --- a/src/osg/NodeVisitor.cpp +++ b/src/osg/NodeVisitor.cpp @@ -68,15 +68,11 @@ class TransformVisitor : public NodeVisitor { if (_coordMode==LOCAL_TO_WORLD) { - osg::Matrix localToWorldMat; - transform.getLocalToWorldMatrix(localToWorldMat,_nodeVisitor); - _matrix.preMult(localToWorldMat); + transform.getLocalToWorldMatrix(_matrix,_nodeVisitor); } else // worldToLocal { - osg::Matrix worldToLocalMat; - transform.getWorldToLocalMatrix(worldToLocalMat,_nodeVisitor); - _matrix.postMult(worldToLocalMat); + transform.getWorldToLocalMatrix(_matrix,_nodeVisitor); } } diff --git a/src/osgGA/TrackballManipulator.cpp b/src/osgGA/TrackballManipulator.cpp index 1fa2777de..496307477 100644 --- a/src/osgGA/TrackballManipulator.cpp +++ b/src/osgGA/TrackballManipulator.cpp @@ -295,11 +295,11 @@ bool TrackballManipulator::calcMovement() // pan model. - float scale = 0.5f*focalLength; + float scale = -0.5f*focalLength; osg::Vec3 uv = _camera->getUpVector(); osg::Vec3 sv = _camera->getSideVector(); - osg::Vec3 dv = uv*(dy*scale)-sv*(dx*scale); + osg::Vec3 dv = uv*(dy*scale)+sv*(dx*scale); _center += dv; @@ -314,7 +314,7 @@ bool TrackballManipulator::calcMovement() // zoom model. float fd = focalLength; - float scale = 1.0f-dy; + float scale = 1.0f+dy; if (fd*scale>_modelScale*_minimumZoomScale) { @@ -328,7 +328,7 @@ bool TrackballManipulator::calcMovement() // notify(DEBUG_INFO) << "Pushing forward"<getLookVector()*(dy*scale); _center += dv; diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp index 185be75cc..a65cbc1fb 100644 --- a/src/osgProducer/Viewer.cpp +++ b/src/osgProducer/Viewer.cpp @@ -308,6 +308,7 @@ void Viewer::requestWarpPointer(float x,float y) { if (_kbmcb) { + cout << "x="<getSceneData(),near_point,far_point); + return getIntersections(scv->getSceneData(),near_point,far_point); } osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getIntersections(osg::Node *scene, - osg::Vec3 near_point,osg::Vec3 far_point) -{ // option for non-sceneView users: you need to get the screen perp line and call getIntersections - // if you are using Projection nodes you should also call setxy to define the xp,yp positions for use with - // the ray transformed by Projection - _lineSegment = new osg::LineSegment; - _lineSegment->set(near_point,far_point); // make a line segment + osg::Vec3 near_point,osg::Vec3 far_point) +{ + // option for non-sceneView users: you need to get the screen perp line and call getIntersections + // if you are using Projection nodes you should also call setxy to define the xp,yp positions for use with + // the ray transformed by Projection + _lineSegment = new osg::LineSegment; + _lineSegment->set(near_point,far_point); // make a line segment addLineSegment(_lineSegment.get()); - - scene->accept(*this); - return getHitList(_lineSegment.get()); + + scene->accept(*this); + return getHitList(_lineSegment.get()); } // pickvisitor - top level; test main scenegraph than traverse to lower Projections osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point) -{ // High level get intersection with sceneview using a ray from x,y on the screen - // sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels +{ + // High level get intersection with sceneview using a ray from x,y on the screen + // sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels - // first get the standard hits in un-projected nodes - _PIVsegHitList=_piv.getIntersections(nd,near_point,far_point); // fill hitlist + // first get the standard hits in un-projected nodes + _PIVsegHitList=_piv.getIntersections(nd,near_point,far_point); // fill hitlist - // then get hits in projection nodes - traverse(*(nd)); // check for projection nodes - return _PIVsegHitList; + // then get hits in projection nodes + traverse(*(nd)); // check for projection nodes + return _PIVsegHitList; } + osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(osgUtil::SceneView *scv, const double x, const double y) -{ // High level get intersection with sceneview using a ray from x,y on the screen - int x0,y0,width,height; - scv->getViewport(x0, y0, width, height); - setxy(-1+2*(float)(x-x0)/(float)width, 1-2*(float)(y-y0)/(float)height); - // sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels +{ + // High level get intersection with sceneview using a ray from x,y on the screen + int x0,y0,width,height; + scv->getViewport(x0, y0, width, height); + setxy(-1+2*(float)(x-x0)/(float)width, 1-2*(float)(y-y0)/(float)height); + // sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels osg::Vec3 near_point,far_point; - // get ends of line segment perpendicular to screen: + // get ends of line segment perpendicular to screen: if (!scv->projectWindowXYIntoObject(x,height-y,near_point,far_point)) { osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl; return _piv.getHitList(NULL); // empty; } - osg::Node *nd=scv->getSceneData(); - getHits(nd, near_point,far_point); - return _PIVsegHitList; + osg::Node *nd=scv->getSceneData(); + getHits(nd, near_point,far_point); + return _PIVsegHitList; } + osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(void) -{ // High level return current intersections - return _PIVsegHitList; +{ + // High level return current intersections + return _PIVsegHitList; } + osgUtil::IntersectVisitor::HitList& PickVisitor::getHits(osg::Node *scene, - const osg::Matrix &projm, const float x, const float y) -{ // utility for non=sceneview viewers - // x,y are values returned by - osg::Matrix inverseMVPW; - inverseMVPW.invert(projm); - double ix=0.5+0.5*x, iy=0.5-0.5*y; // for this purpose, range from 0-1 - osg::Vec3 near_point = osg::Vec3(ix,iy,0.0f)*inverseMVPW; - osg::Vec3 far_point = osg::Vec3(ix,iy,1.0f)*inverseMVPW; - setxy(x,-y); - getHits(scene,near_point,far_point); - return _PIVsegHitList; + const osg::Matrix &projm, const float x, const float y) +{ + // utility for non=sceneview viewers + // x,y are values returned by + osg::Matrix inverseMVPW; + inverseMVPW.invert(projm); +// float ix=0.5f+0.5f*x, iy=0.5f+0.5f*y; // for this purpose, range from 0-1 + osg::Vec3 near_point = osg::Vec3(x,y,1.0f)*inverseMVPW; + osg::Vec3 far_point = osg::Vec3(x,y,-1.0f)*inverseMVPW; + setxy(x,y); + getHits(scene,near_point,far_point); + return _PIVsegHitList; } + void PickVisitor::apply(osg::Projection& pr) { // stack the intersect rays, transform to new projection, traverse - // Assumes that the Projection is an absolute projection - osg::Matrix mt=osg::Matrix::inverse(pr.getMatrix()); - osg::Vec3 npt=osg::Vec3(xp,yp,1) * mt, farpt=osg::Vec3(xp,yp,-1) * mt; + // Assumes that the Projection is an absolute projection + osg::Matrix mt=osg::Matrix::inverse(pr.getMatrix()); + osg::Vec3 npt=osg::Vec3(xp,yp,1.0f) * mt, farpt=osg::Vec3(xp,yp,-1.0f) * mt; - // traversing the nodes children, using the projection direction - for (unsigned int i=0; i