Added convinence methods to osgProducer::Viewer:
/** compute, from normalized mouse coords, for sepecified Camera, the pixel coords relative to that Camera's RenderSurface.*/ bool computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y); /** compute, from normalized mouse coords, for sepecified Camera, the near and far points in worlds coords.*/ bool computeNearFar(float x,float y,unsigned int cameraNum,osg::Vec3& near, osg::Vec3& far); /** compute, from normalized mouse coords, for sepecified Camera, intersections with the scene.*/ bool computeIntersections(float x,float y,unsigned int cameraNum,osgUtil::IntersectVisitor::HitList& hits); /** compute, from normalized mouse coords, for all Cameras, intersections with the scene.*/ bool computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits);
This commit is contained in:
parent
48cb15015f
commit
904aceec22
@ -28,41 +28,6 @@
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
#include <osgUtil/PickVisitor>
|
||||
|
||||
|
||||
|
||||
static Producer::CameraConfig *BuildConfig(void)
|
||||
{
|
||||
Producer::RenderSurface *rs1 = new Producer::RenderSurface;
|
||||
rs1->setScreenNum(0);
|
||||
//rs1->useBorder(false);
|
||||
rs1->setWindowRect(0,0,640,480);
|
||||
Producer::Camera *camera1 = new Producer::Camera;
|
||||
camera1->setRenderSurface(rs1);
|
||||
camera1->setOffset( 1.0, 0.0 );
|
||||
|
||||
Producer::RenderSurface *rs2 = new Producer::RenderSurface;
|
||||
rs2->setScreenNum(0);
|
||||
//rs2->useBorder(false);
|
||||
rs2->setWindowRect(640,0,640,480);
|
||||
Producer::Camera *camera2 = new Producer::Camera;
|
||||
camera2->setRenderSurface(rs2);
|
||||
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));
|
||||
|
||||
|
||||
Producer::CameraConfig *cfg = new Producer::CameraConfig;
|
||||
cfg->addCamera("Camera 1",camera1);
|
||||
cfg->addCamera("Camera 2", camera2);
|
||||
cfg->setInputArea(ia);
|
||||
return cfg;
|
||||
}
|
||||
|
||||
// class to handle events with a pick
|
||||
class PickHandler : public osgGA::GUIEventHandler {
|
||||
@ -106,104 +71,33 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
|
||||
|
||||
void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
|
||||
{
|
||||
// OK here is the interesting bit - How To Pick a Geode
|
||||
// including geodes in a HUD under a Projection Matrix
|
||||
osg::Node *scene=_viewer->getSceneData();//main node of the scene.
|
||||
if (scene)
|
||||
osgUtil::IntersectVisitor::HitList hlist;
|
||||
|
||||
std::string gdlist="";
|
||||
if (_viewer->computeIntersections(ea.getX(),ea.getY(),hlist))
|
||||
{
|
||||
float x=ea.getX();
|
||||
float y=ea.getY();
|
||||
|
||||
|
||||
Producer::KeyboardMouse* km = _viewer->getKeyboardMouse();
|
||||
|
||||
|
||||
std::string gdlist="";
|
||||
|
||||
for(unsigned int i=0;i<_viewer->getNumberOfCameras();++i)
|
||||
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
|
||||
hitr!=hlist.end();
|
||||
++hitr)
|
||||
{
|
||||
Producer::Camera* cmm=_viewer->getCamera(i);
|
||||
Producer::RenderSurface* rs = cmm->getRenderSurface();
|
||||
|
||||
//std::cout << "checking camara "<<i<<std::endl;
|
||||
|
||||
float pixel_x,pixel_y;
|
||||
if (km->computePixelCoords(x,y,rs,pixel_x,pixel_y))
|
||||
//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::cout << " compute pixel coords "<<pixel_x<<" "<<pixel_y<<std::endl;
|
||||
|
||||
int pr_wx, pr_wy;
|
||||
unsigned int pr_width, pr_height;
|
||||
cmm->getProjectionRect( pr_wx, pr_wy, pr_width, pr_height );
|
||||
|
||||
int rs_wx, rs_wy;
|
||||
unsigned int rs_width, rs_height;
|
||||
rs->getWindowRect( rs_wx, rs_wy, rs_width, rs_height );
|
||||
|
||||
pr_wx += rs_wx;
|
||||
pr_wy += rs_wy;
|
||||
|
||||
//std::cout << " wx = "<<pr_wx<<" wy = "<<pr_wy<<" width="<<pr_width<<" height="<<pr_height<<std::endl;
|
||||
|
||||
|
||||
|
||||
if (pixel_x<(float)pr_wx) break;
|
||||
if (pixel_x>(float)(pr_wx+pr_width)) break;
|
||||
|
||||
if (pixel_y<(float)pr_wy) break;
|
||||
if (pixel_y>(float)(pr_wy+pr_height)) break;
|
||||
|
||||
|
||||
float rx = 2.0f*(pixel_x - (float)pr_wx)/(float)pr_width-1.0f;
|
||||
float ry = 2.0f*(pixel_y - (float)pr_wy)/(float)pr_height-1.0f;
|
||||
|
||||
//std::cout << " rx "<<rx<<" "<<ry<<std::endl;
|
||||
|
||||
osgProducer::OsgSceneHandler* sh = dynamic_cast<osgProducer::OsgSceneHandler*>(cmm->getSceneHandler());
|
||||
osg::Matrix vum;
|
||||
if (sh!=0 && sh->getModelViewMatrix()!=0 && sh->getProjectionMatrix()!=0)
|
||||
if (!geode->getName().empty())
|
||||
{
|
||||
vum.set((*(sh->getModelViewMatrix())) *
|
||||
(*(sh->getProjectionMatrix())));
|
||||
gdlist=gdlist+" "+geode->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
vum.set(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)*/);
|
||||
gdlist=gdlist+" geode";
|
||||
}
|
||||
|
||||
osgUtil::PickVisitor iv;
|
||||
osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, rx,ry);
|
||||
if (iv.hits())
|
||||
{
|
||||
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
|
||||
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)
|
||||
{
|
||||
if (!geode->getName().empty())
|
||||
{
|
||||
gdlist=gdlist+" "+geode->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
gdlist=gdlist+" geode";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setLabel(gdlist);
|
||||
}
|
||||
setLabel(gdlist);
|
||||
}
|
||||
|
||||
osg::Node* createHUD(osgText::Text* updateText)
|
||||
@ -311,8 +205,7 @@ int main( int argc, char **argv )
|
||||
|
||||
|
||||
// construct the viewer.
|
||||
//osgProducer::Viewer viewer(arguments);
|
||||
osgProducer::Viewer viewer(BuildConfig());
|
||||
osgProducer::Viewer viewer(arguments);
|
||||
|
||||
// set up the value with sensible default event handlers.
|
||||
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <osg/ApplicationUsage>
|
||||
#include <osg/AnimationPath>
|
||||
|
||||
#include <osgUtil/IntersectVisitor>
|
||||
|
||||
#include <osgGA/GUIActionAdapter>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
#include <osgGA/KeySwitchCameraManipulator>
|
||||
@ -92,14 +94,27 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction
|
||||
virtual void requestContinuousUpdate(bool) {}
|
||||
virtual void requestWarpPointer(float x,float y);
|
||||
|
||||
Producer::KeyboardMouse* getKeyboardMouse() { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); }
|
||||
|
||||
const Producer::KeyboardMouse* getKeyboardMouse() const { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); }
|
||||
/** compute, from normalized mouse coords, for sepecified Camera, the pixel coords relative to that Camera's RenderSurface.*/
|
||||
bool computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y);
|
||||
|
||||
/** compute, from normalized mouse coords, for sepecified Camera, the near and far points in worlds coords.*/
|
||||
bool computeNearFar(float x,float y,unsigned int cameraNum,osg::Vec3& near, osg::Vec3& far);
|
||||
|
||||
KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; }
|
||||
/** compute, from normalized mouse coords, for sepecified Camera, intersections with the scene.*/
|
||||
bool computeIntersections(float x,float y,unsigned int cameraNum,osgUtil::IntersectVisitor::HitList& hits);
|
||||
|
||||
/** compute, from normalized mouse coords, for all Cameras, intersections with the scene.*/
|
||||
bool computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits);
|
||||
|
||||
|
||||
Producer::KeyboardMouse* getKeyboardMouse() { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); }
|
||||
const Producer::KeyboardMouse* getKeyboardMouse() const { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); }
|
||||
|
||||
KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; }
|
||||
const KeyboardMouseCallback* getKeyboardMouseCallback() const { return _kbmcb; }
|
||||
|
||||
|
||||
|
||||
typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlerList;
|
||||
EventHandlerList& getEventHandlerList() { return _eventHandlerList; }
|
||||
|
@ -10,6 +10,9 @@ osgviewer cow.osg
|
||||
echo osgkeyboard
|
||||
osgkeyboard
|
||||
|
||||
echo osgpick fountain.osg
|
||||
osgpick fountain.osg
|
||||
|
||||
echo osgwindows glider.osg
|
||||
osgwindows glider.osg
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <osg/ApplicationUsage>
|
||||
|
||||
#include <osgUtil/UpdateVisitor>
|
||||
#include <osgUtil/PickVisitor>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
@ -299,6 +300,116 @@ void Viewer::frame()
|
||||
OsgCameraGroup::frame();
|
||||
}
|
||||
|
||||
bool Viewer::computePixelCoords(float x,float y,unsigned int cameraNum,float& pixel_x,float& pixel_y)
|
||||
{
|
||||
Producer::KeyboardMouse* km = getKeyboardMouse();
|
||||
if (!km) return false;
|
||||
|
||||
if (cameraNum>=getNumberOfCameras()) return false;
|
||||
|
||||
Producer::Camera* camera=getCamera(cameraNum);
|
||||
Producer::RenderSurface* rs = camera->getRenderSurface();
|
||||
|
||||
//std::cout << "checking camara "<<i<<std::endl;
|
||||
|
||||
if (km->computePixelCoords(x,y,rs,pixel_x,pixel_y))
|
||||
{
|
||||
//std::cout << " compute pixel coords "<<pixel_x<<" "<<pixel_y<<std::endl;
|
||||
|
||||
int pr_wx, pr_wy;
|
||||
unsigned int pr_width, pr_height;
|
||||
camera->getProjectionRect( pr_wx, pr_wy, pr_width, pr_height );
|
||||
|
||||
int rs_wx, rs_wy;
|
||||
unsigned int rs_width, rs_height;
|
||||
rs->getWindowRect( rs_wx, rs_wy, rs_width, rs_height );
|
||||
|
||||
pixel_x -= (float)rs_wx;
|
||||
pixel_y -= (float)rs_wy;
|
||||
|
||||
//std::cout << " wx = "<<pr_wx<<" wy = "<<pr_wy<<" width="<<pr_width<<" height="<<pr_height<<std::endl;
|
||||
|
||||
if (pixel_x<(float)pr_wx) return false;
|
||||
if (pixel_x>(float)(pr_wx+pr_width)) return false;
|
||||
|
||||
if (pixel_y<(float)pr_wy) return false;
|
||||
if (pixel_y>(float)(pr_wy+pr_height)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Viewer::computeNearFar(float x,float y,unsigned int cameraNum,osg::Vec3& near, osg::Vec3& far)
|
||||
{
|
||||
if (cameraNum>=getSceneHandlerList().size()) return false;
|
||||
|
||||
OsgSceneHandler* scenehandler = getSceneHandlerList()[cameraNum].get();
|
||||
|
||||
float pixel_x,pixel_y;
|
||||
if (computePixelCoords(x,y,cameraNum,pixel_x,pixel_y))
|
||||
{
|
||||
return scenehandler->projectWindowXYIntoObject(pixel_x,pixel_y,near,far);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool Viewer::computeIntersections(float x,float y,unsigned int cameraNum,osgUtil::IntersectVisitor::HitList& hits)
|
||||
{
|
||||
float pixel_x,pixel_y;
|
||||
if (computePixelCoords(x,y,cameraNum,pixel_x,pixel_y))
|
||||
{
|
||||
|
||||
Producer::Camera* camera=getCamera(cameraNum);
|
||||
|
||||
int pr_wx, pr_wy;
|
||||
unsigned int pr_width, pr_height;
|
||||
camera->getProjectionRect( pr_wx, pr_wy, pr_width, pr_height );
|
||||
|
||||
// convert into clip coords.
|
||||
float rx = 2.0f*(pixel_x - (float)pr_wx)/(float)pr_width-1.0f;
|
||||
float ry = 2.0f*(pixel_y - (float)pr_wy)/(float)pr_height-1.0f;
|
||||
|
||||
//std::cout << " rx "<<rx<<" "<<ry<<std::endl;
|
||||
|
||||
osgProducer::OsgSceneHandler* sh = dynamic_cast<osgProducer::OsgSceneHandler*>(camera->getSceneHandler());
|
||||
osg::Matrix vum;
|
||||
if (sh!=0 && sh->getModelViewMatrix()!=0 && sh->getProjectionMatrix()!=0)
|
||||
{
|
||||
vum.set((*(sh->getModelViewMatrix())) *
|
||||
(*(sh->getProjectionMatrix())));
|
||||
}
|
||||
else
|
||||
{
|
||||
vum.set(osg::Matrix(camera->getViewMatrix()) *
|
||||
osg::Matrix(camera->getProjectionMatrix()));
|
||||
}
|
||||
|
||||
osgUtil::PickVisitor iv;
|
||||
|
||||
osgUtil::IntersectVisitor::HitList localHits;
|
||||
localHits = iv.getHits(getSceneData(), vum, rx,ry);
|
||||
|
||||
if (localHits.empty()) return false;
|
||||
|
||||
hits.insert(hits.begin(),localHits.begin(),localHits.end());
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Viewer::computeIntersections(float x,float y,osgUtil::IntersectVisitor::HitList& hits)
|
||||
{
|
||||
bool hitFound = false;
|
||||
osgUtil::IntersectVisitor::HitList hlist;
|
||||
for(unsigned int i=0;i<getNumberOfCameras();++i)
|
||||
{
|
||||
if (computeIntersections(x,y,i,hits)) hitFound = true;
|
||||
}
|
||||
return hitFound;
|
||||
}
|
||||
|
||||
void Viewer::selectCameraManipulator(unsigned int no)
|
||||
{
|
||||
|
@ -33,9 +33,10 @@ public:
|
||||
image->readPixels(x,y,width,height,
|
||||
GL_RGB,GL_UNSIGNED_BYTE);
|
||||
|
||||
osgDB::writeImageFile(*image,_filename);
|
||||
|
||||
osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
|
||||
if (osgDB::writeImageFile(*image,_filename))
|
||||
{
|
||||
osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
|
||||
}
|
||||
|
||||
_snapImageOnNextFrame = false;
|
||||
}
|
||||
@ -802,8 +803,10 @@ bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActio
|
||||
osg::Node* node = _cg->getSceneData();
|
||||
if (node)
|
||||
{
|
||||
std::cout<<"writing file "<<_writeNodeFileName<<std::endl;
|
||||
osgDB::writeNodeFile(*node,_writeNodeFileName.c_str());
|
||||
if (osgDB::writeNodeFile(*node,_writeNodeFileName.c_str()))
|
||||
{
|
||||
std::cout<<"writen nodes to file "<<_writeNodeFileName<<std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -107,7 +107,8 @@ osgUtil::IntersectVisitor::HitList& PickVisitor::getHits(osg::Node *scene,
|
||||
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::Matrix mt;
|
||||
mt.invert(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
|
||||
|
Loading…
Reference in New Issue
Block a user