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 <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 to handle events with a pick
|
||||||
class PickHandler : public osgGA::GUIEventHandler {
|
class PickHandler : public osgGA::GUIEventHandler {
|
||||||
@ -106,77 +71,10 @@ bool PickHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapte
|
|||||||
|
|
||||||
void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
|
void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
|
||||||
{
|
{
|
||||||
// OK here is the interesting bit - How To Pick a Geode
|
osgUtil::IntersectVisitor::HitList hlist;
|
||||||
// including geodes in a HUD under a Projection Matrix
|
|
||||||
osg::Node *scene=_viewer->getSceneData();//main node of the scene.
|
|
||||||
if (scene)
|
|
||||||
{
|
|
||||||
float x=ea.getX();
|
|
||||||
float y=ea.getY();
|
|
||||||
|
|
||||||
|
|
||||||
Producer::KeyboardMouse* km = _viewer->getKeyboardMouse();
|
|
||||||
|
|
||||||
|
|
||||||
std::string gdlist="";
|
std::string gdlist="";
|
||||||
|
if (_viewer->computeIntersections(ea.getX(),ea.getY(),hlist))
|
||||||
for(unsigned int i=0;i<_viewer->getNumberOfCameras();++i)
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
//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)
|
|
||||||
{
|
|
||||||
vum.set((*(sh->getModelViewMatrix())) *
|
|
||||||
(*(sh->getProjectionMatrix())));
|
|
||||||
}
|
|
||||||
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)*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
osgUtil::PickVisitor iv;
|
|
||||||
osgUtil::IntersectVisitor::HitList& hlist=iv.getHits(scene, vum, rx,ry);
|
|
||||||
if (iv.hits())
|
|
||||||
{
|
{
|
||||||
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
|
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
|
||||||
hitr!=hlist.end();
|
hitr!=hlist.end();
|
||||||
@ -199,11 +97,7 @@ void PickHandler::pick(const osgGA::GUIEventAdapter& ea)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setLabel(gdlist);
|
setLabel(gdlist);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* createHUD(osgText::Text* updateText)
|
osg::Node* createHUD(osgText::Text* updateText)
|
||||||
@ -311,8 +205,7 @@ int main( int argc, char **argv )
|
|||||||
|
|
||||||
|
|
||||||
// construct the viewer.
|
// construct the viewer.
|
||||||
//osgProducer::Viewer viewer(arguments);
|
osgProducer::Viewer viewer(arguments);
|
||||||
osgProducer::Viewer viewer(BuildConfig());
|
|
||||||
|
|
||||||
// set up the value with sensible default event handlers.
|
// set up the value with sensible default event handlers.
|
||||||
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include <osg/ApplicationUsage>
|
#include <osg/ApplicationUsage>
|
||||||
#include <osg/AnimationPath>
|
#include <osg/AnimationPath>
|
||||||
|
|
||||||
|
#include <osgUtil/IntersectVisitor>
|
||||||
|
|
||||||
#include <osgGA/GUIActionAdapter>
|
#include <osgGA/GUIActionAdapter>
|
||||||
#include <osgGA/GUIEventHandler>
|
#include <osgGA/GUIEventHandler>
|
||||||
#include <osgGA/KeySwitchCameraManipulator>
|
#include <osgGA/KeySwitchCameraManipulator>
|
||||||
@ -92,15 +94,28 @@ class OSGPRODUCER_EXPORT Viewer : public OsgCameraGroup, public osgGA::GUIAction
|
|||||||
virtual void requestContinuousUpdate(bool) {}
|
virtual void requestContinuousUpdate(bool) {}
|
||||||
virtual void requestWarpPointer(float x,float y);
|
virtual void requestWarpPointer(float x,float y);
|
||||||
|
|
||||||
Producer::KeyboardMouse* getKeyboardMouse() { 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);
|
||||||
|
|
||||||
|
/** 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(); }
|
const Producer::KeyboardMouse* getKeyboardMouse() const { return _kbmcb==0?0:_kbmcb->getKeyboardMouse(); }
|
||||||
|
|
||||||
KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; }
|
KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; }
|
||||||
|
|
||||||
const KeyboardMouseCallback* getKeyboardMouseCallback() const { return _kbmcb; }
|
const KeyboardMouseCallback* getKeyboardMouseCallback() const { return _kbmcb; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlerList;
|
typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlerList;
|
||||||
EventHandlerList& getEventHandlerList() { return _eventHandlerList; }
|
EventHandlerList& getEventHandlerList() { return _eventHandlerList; }
|
||||||
const EventHandlerList& getEventHandlerList() const { return _eventHandlerList; }
|
const EventHandlerList& getEventHandlerList() const { return _eventHandlerList; }
|
||||||
|
@ -10,6 +10,9 @@ osgviewer cow.osg
|
|||||||
echo osgkeyboard
|
echo osgkeyboard
|
||||||
osgkeyboard
|
osgkeyboard
|
||||||
|
|
||||||
|
echo osgpick fountain.osg
|
||||||
|
osgpick fountain.osg
|
||||||
|
|
||||||
echo osgwindows glider.osg
|
echo osgwindows glider.osg
|
||||||
osgwindows glider.osg
|
osgwindows glider.osg
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <osg/ApplicationUsage>
|
#include <osg/ApplicationUsage>
|
||||||
|
|
||||||
#include <osgUtil/UpdateVisitor>
|
#include <osgUtil/UpdateVisitor>
|
||||||
|
#include <osgUtil/PickVisitor>
|
||||||
|
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
|
|
||||||
@ -299,6 +300,116 @@ void Viewer::frame()
|
|||||||
OsgCameraGroup::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)
|
void Viewer::selectCameraManipulator(unsigned int no)
|
||||||
{
|
{
|
||||||
|
@ -33,9 +33,10 @@ public:
|
|||||||
image->readPixels(x,y,width,height,
|
image->readPixels(x,y,width,height,
|
||||||
GL_RGB,GL_UNSIGNED_BYTE);
|
GL_RGB,GL_UNSIGNED_BYTE);
|
||||||
|
|
||||||
osgDB::writeImageFile(*image,_filename);
|
if (osgDB::writeImageFile(*image,_filename))
|
||||||
|
{
|
||||||
osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
|
osg::notify(osg::NOTICE) << "Saved screen image to `"<<_filename<<"`"<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
_snapImageOnNextFrame = false;
|
_snapImageOnNextFrame = false;
|
||||||
}
|
}
|
||||||
@ -802,8 +803,10 @@ bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActio
|
|||||||
osg::Node* node = _cg->getSceneData();
|
osg::Node* node = _cg->getSceneData();
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
std::cout<<"writing file "<<_writeNodeFileName<<std::endl;
|
if (osgDB::writeNodeFile(*node,_writeNodeFileName.c_str()))
|
||||||
osgDB::writeNodeFile(*node,_writeNodeFileName.c_str());
|
{
|
||||||
|
std::cout<<"writen nodes to file "<<_writeNodeFileName<<std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -107,7 +107,8 @@ osgUtil::IntersectVisitor::HitList& PickVisitor::getHits(osg::Node *scene,
|
|||||||
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;
|
||||||
|
mt.invert(pr.getMatrix());
|
||||||
osg::Vec3 npt=osg::Vec3(xp,yp,1.0f) * mt, farpt=osg::Vec3(xp,yp,-1.0f) * 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
|
||||||
|
Loading…
Reference in New Issue
Block a user