Updates to the osgpick code.

Updates to osgGA::CameraManipulors.
This commit is contained in:
Robert Osfield 2003-04-14 15:44:30 +00:00
parent b66f464a1b
commit 5df7118d6d
10 changed files with 134 additions and 111 deletions

View File

@ -1166,6 +1166,9 @@ Package=<4>
Begin Project Dependency Begin Project Dependency
Project_Dep_Name Core osgUtil Project_Dep_Name Core osgUtil
End Project Dependency End Project Dependency
Begin Project Dependency
Project_Dep_Name Core osgText
End Project Dependency
}}} }}}
############################################################################### ###############################################################################

View File

@ -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 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 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 # SUBTRACT LINK32 /incremental:no

View File

@ -97,6 +97,10 @@ SOURCE=..\..\src\osgUtil\CubeMapGenerator.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\src\osgUtil\PickVisitor.cpp
# End Source File
# Begin Source File
SOURCE=..\..\src\osgUtil\HalfWayMapGenerator.cpp SOURCE=..\..\src\osgUtil\HalfWayMapGenerator.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -81,18 +81,14 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
{ {
float x=ea.getXnormalized(); float x=ea.getXnormalized();
float y=ea.getYnormalized(); float y=ea.getYnormalized();
osgUtil::PickVisitor iv;
const float *matView;
const float *matProj;
Producer::Camera *cmm=_cg->getCamera(0); Producer::Camera *cmm=_cg->getCamera(0);
matView=cmm->getViewMatrix(); osg::Matrix vum(osg::Matrix(cmm->getViewMatrix()) *
matProj=cmm->getProjectionMatrix(); osg::Matrix(cmm->getProjectionMatrix())/* *
osg::Matrix vum; osg::Matrix::translate(1.0f,1.0f,1.0f) *
vum.set(matView); osg::Matrix::scale(0.5f,0.5f,0.5f)*/);
vum.postMult(osg::Matrix(matProj));
osg::Matrix windowmatrix=osg::Matrix::translate(1.0f,1.0f,1.0f)* osgUtil::PickVisitor iv;
osg::Matrix::scale(0.5f,0.5f,0.5f);
vum.postMult(windowmatrix);
osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, x,y); osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, x,y);
std::string gdlist=""; std::string gdlist="";
if (iv.hits()) if (iv.hits())
@ -105,8 +101,16 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
//osg::Vec3 in = hitr->getLocalIntersectNormal(); //osg::Vec3 in = hitr->getLocalIntersectNormal();
osg::Geode* geode = hitr->_geode.get(); osg::Geode* geode = hitr->_geode.get();
// the geodes are identified by name. // the geodes are identified by name.
if (geode) { if (geode)
gdlist=gdlist+" "+geode->getName(); {
if (!geode->getName().empty())
{
gdlist=gdlist+" "+geode->getName();
}
else
{
gdlist=gdlist+" geode";
}
} }
} }
} }

View File

@ -32,10 +32,10 @@ static Producer::CameraConfig *BuildConfig(void)
camera2->setOffset( -1.0, 0.0 ); camera2->setOffset( -1.0, 0.0 );
Producer::InputArea *ia = new Producer::InputArea; Producer::InputArea *ia = new Producer::InputArea;
// ia->addInputRectangle( rs1, Producer::InputRectangle(0.0,0.5,0.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( 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( 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( rs2, Producer::InputRectangle(0.0,1.0,-1.0,1.0));
Producer::CameraConfig *cfg = new Producer::CameraConfig; Producer::CameraConfig *cfg = new Producer::CameraConfig;

View File

@ -26,38 +26,42 @@
namespace osgUtil { namespace osgUtil {
// PickIntersectVisitor simplifies picking - routines take x,y mouse pixel & detect hits // PickIntersectVisitor simplifies picking - routines take x,y mouse pixel & detect hits
class OSGUTIL_EXPORT PickIntersectVisitor : public IntersectVisitor { class OSGUTIL_EXPORT PickIntersectVisitor : public IntersectVisitor
{
public: public:
PickIntersectVisitor() { PickIntersectVisitor()
setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions {
} setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions
~PickIntersectVisitor() { } }
HitList& getHits(osgUtil::SceneView *, int x, int y); ~PickIntersectVisitor() { }
HitList& PickIntersectVisitor::getIntersections(osg::Node *scene, osg::Vec3 nr, osg::Vec3 fr); HitList& getHits(osgUtil::SceneView *, int x, int y);
HitList& PickIntersectVisitor::getIntersections(osg::Node *scene, osg::Vec3 nr, osg::Vec3 fr);
private: private:
osg::ref_ptr<osg::LineSegment> _lineSegment; osg::ref_ptr<osg::LineSegment> _lineSegment;
friend class osgUtil::IntersectVisitor; friend class osgUtil::IntersectVisitor;
}; };
// PickVisitor traverses whole scene and checks below all Projection nodes // 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: public:
PickVisitor() { PickVisitor()
xp=yp=0; {
setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions xp=yp=0;
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN); setNodeMaskOverride(0xffffffff); // need to make the visitor override the nodemask to visit invisible actions
} setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
~PickVisitor() { } }
~PickVisitor() { }
virtual void apply(osg::Projection& pr); 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(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(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(osg::Node *nd, const osg::Vec3 near_point, const osg::Vec3 far_point);
osgUtil::IntersectVisitor::HitList& getHits(void); osgUtil::IntersectVisitor::HitList& getHits(void);
inline void setxy(float xpt, float ypt) { xp=xpt; yp=ypt; } inline void setxy(float xpt, float ypt) { xp=xpt; yp=ypt; }
inline bool hits() { return _PIVsegHitList.size()>0;} inline bool hits() { return _PIVsegHitList.size()>0;}
private: private:
PickIntersectVisitor _piv; PickIntersectVisitor _piv;
float xp, yp; // start point in viewport fraction coordiantes float xp, yp; // start point in viewport fraction coordiantes
osgUtil::IntersectVisitor::HitList _PIVsegHitList; osgUtil::IntersectVisitor::HitList _PIVsegHitList;
}; };
}// namespace osgUtil }// namespace osgUtil

View File

@ -68,15 +68,11 @@ class TransformVisitor : public NodeVisitor
{ {
if (_coordMode==LOCAL_TO_WORLD) if (_coordMode==LOCAL_TO_WORLD)
{ {
osg::Matrix localToWorldMat; transform.getLocalToWorldMatrix(_matrix,_nodeVisitor);
transform.getLocalToWorldMatrix(localToWorldMat,_nodeVisitor);
_matrix.preMult(localToWorldMat);
} }
else // worldToLocal else // worldToLocal
{ {
osg::Matrix worldToLocalMat; transform.getWorldToLocalMatrix(_matrix,_nodeVisitor);
transform.getWorldToLocalMatrix(worldToLocalMat,_nodeVisitor);
_matrix.postMult(worldToLocalMat);
} }
} }

View File

@ -295,11 +295,11 @@ bool TrackballManipulator::calcMovement()
// pan model. // pan model.
float scale = 0.5f*focalLength; float scale = -0.5f*focalLength;
osg::Vec3 uv = _camera->getUpVector(); osg::Vec3 uv = _camera->getUpVector();
osg::Vec3 sv = _camera->getSideVector(); 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; _center += dv;
@ -314,7 +314,7 @@ bool TrackballManipulator::calcMovement()
// zoom model. // zoom model.
float fd = focalLength; float fd = focalLength;
float scale = 1.0f-dy; float scale = 1.0f+dy;
if (fd*scale>_modelScale*_minimumZoomScale) if (fd*scale>_modelScale*_minimumZoomScale)
{ {
@ -328,7 +328,7 @@ bool TrackballManipulator::calcMovement()
// notify(DEBUG_INFO) << "Pushing forward"<<std::endl; // notify(DEBUG_INFO) << "Pushing forward"<<std::endl;
// push the camera forward. // push the camera forward.
float scale = fd; float scale = -fd;
osg::Vec3 dv = _camera->getLookVector()*(dy*scale); osg::Vec3 dv = _camera->getLookVector()*(dy*scale);
_center += dv; _center += dv;

View File

@ -308,6 +308,7 @@ void Viewer::requestWarpPointer(float x,float y)
{ {
if (_kbmcb) if (_kbmcb)
{ {
cout << "x="<<x<<" y="<<y<<endl;
EventAdapter::_s_mx = x; EventAdapter::_s_mx = x;
EventAdapter::_s_my = y; EventAdapter::_s_my = y;
_kbmcb->getKeyboardMouse()->positionPointer(x,y); _kbmcb->getKeyboardMouse()->positionPointer(x,y);

View File

@ -21,96 +21,107 @@ using namespace osgUtil;
osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getHits(osgUtil::SceneView *scv, int x, int y) osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getHits(osgUtil::SceneView *scv, int x, int y)
{ // High level get intersection with sceneview using a ray from x,y on the screen { // High level get intersection with sceneview using a ray from x,y on the screen
int x0,y0,width,height; int x0,y0,width,height;
scv->getViewport(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); // 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 // 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; 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)) if (!scv->projectWindowXYIntoObject(x,height-y,near_point,far_point))
{ {
osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl; osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl;
return getHitList(NULL); // empty; return getHitList(NULL); // empty;
} }
return getIntersections(scv->getSceneData(),near_point,far_point); return getIntersections(scv->getSceneData(),near_point,far_point);
} }
osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getIntersections(osg::Node *scene, osgUtil::IntersectVisitor::HitList & PickIntersectVisitor::getIntersections(osg::Node *scene,
osg::Vec3 near_point,osg::Vec3 far_point) 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 // option for non-sceneView users: you need to get the screen perp line and call getIntersections
// the ray transformed by Projection // if you are using Projection nodes you should also call setxy to define the xp,yp positions for use with
_lineSegment = new osg::LineSegment; // the ray transformed by Projection
_lineSegment->set(near_point,far_point); // make a line segment _lineSegment = new osg::LineSegment;
_lineSegment->set(near_point,far_point); // make a line segment
addLineSegment(_lineSegment.get()); addLineSegment(_lineSegment.get());
scene->accept(*this); scene->accept(*this);
return getHitList(_lineSegment.get()); return getHitList(_lineSegment.get());
} }
// pickvisitor - top level; test main scenegraph than traverse to lower Projections // 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) 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 // first get the standard hits in un-projected nodes
_PIVsegHitList=_piv.getIntersections(nd,near_point,far_point); // fill hitlist _PIVsegHitList=_piv.getIntersections(nd,near_point,far_point); // fill hitlist
// then get hits in projection nodes // then get hits in projection nodes
traverse(*(nd)); // check for projection nodes traverse(*(nd)); // check for projection nodes
return _PIVsegHitList; return _PIVsegHitList;
} }
osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(osgUtil::SceneView *scv, const double x, const double y) 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; // High level get intersection with sceneview using a ray from x,y on the screen
scv->getViewport(x0, y0, width, height); int x0,y0,width,height;
setxy(-1+2*(float)(x-x0)/(float)width, 1-2*(float)(y-y0)/(float)height); scv->getViewport(x0, y0, width, height);
// sets xp,yp as pixels scaled to a mapping of (-1,1, -1,1); needed for Projection from x,y pixels 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; 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)) if (!scv->projectWindowXYIntoObject(x,height-y,near_point,far_point))
{ {
osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl; osg::notify(osg::NOTICE) << "PickIntersect failed to calculate intersection ray."<< std::endl;
return _piv.getHitList(NULL); // empty; return _piv.getHitList(NULL); // empty;
} }
osg::Node *nd=scv->getSceneData(); osg::Node *nd=scv->getSceneData();
getHits(nd, near_point,far_point); getHits(nd, near_point,far_point);
return _PIVsegHitList; return _PIVsegHitList;
} }
osgUtil::IntersectVisitor::HitList & PickVisitor::getHits(void) 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, osgUtil::IntersectVisitor::HitList& PickVisitor::getHits(osg::Node *scene,
const osg::Matrix &projm, const float x, const float y) const osg::Matrix &projm, const float x, const float y)
{ // utility for non=sceneview viewers {
// x,y are values returned by // utility for non=sceneview viewers
osg::Matrix inverseMVPW; // x,y are values returned by
inverseMVPW.invert(projm); osg::Matrix inverseMVPW;
double ix=0.5+0.5*x, iy=0.5-0.5*y; // for this purpose, range from 0-1 inverseMVPW.invert(projm);
osg::Vec3 near_point = osg::Vec3(ix,iy,0.0f)*inverseMVPW; // float ix=0.5f+0.5f*x, iy=0.5f+0.5f*y; // for this purpose, range from 0-1
osg::Vec3 far_point = osg::Vec3(ix,iy,1.0f)*inverseMVPW; osg::Vec3 near_point = osg::Vec3(x,y,1.0f)*inverseMVPW;
setxy(x,-y); osg::Vec3 far_point = osg::Vec3(x,y,-1.0f)*inverseMVPW;
getHits(scene,near_point,far_point); setxy(x,y);
return _PIVsegHitList; getHits(scene,near_point,far_point);
return _PIVsegHitList;
} }
void PickVisitor::apply(osg::Projection& pr) void PickVisitor::apply(osg::Projection& pr)
{ // stack the intersect rays, transform to new projection, traverse { // stack the intersect rays, transform to new projection, traverse
// Assumes that the Projection is an absolute projection // Assumes that the Projection is an absolute projection
osg::Matrix mt=osg::Matrix::inverse(pr.getMatrix()); osg::Matrix mt=osg::Matrix::inverse(pr.getMatrix());
osg::Vec3 npt=osg::Vec3(xp,yp,1) * mt, farpt=osg::Vec3(xp,yp,-1) * mt; 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 // traversing the nodes children, using the projection direction
for (unsigned int i=0; i<pr.getNumChildren(); i++) { for (unsigned int i=0; i<pr.getNumChildren(); i++)
osg::Node *nodech=pr.getChild(i); {
osgUtil::IntersectVisitor::HitList &hli=_piv.getIntersections(nodech,npt, farpt); osg::Node *nodech=pr.getChild(i);
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hli.begin(); osgUtil::IntersectVisitor::HitList &hli=_piv.getIntersections(nodech,npt, farpt);
hitr!=hli.end(); for(osgUtil::IntersectVisitor::HitList::iterator hitr=hli.begin();
++hitr) { // add the projection hits to the scene hits. hitr!=hli.end();
// This is why _lineSegment is retained as a member of PickIntersectVisitor ++hitr)
_PIVsegHitList.push_back(*hitr); { // add the projection hits to the scene hits.
} // This is why _lineSegment is retained as a member of PickIntersectVisitor
traverse(*nodech); _PIVsegHitList.push_back(*hitr);
}
traverse(*nodech);
} }
} }