Added support for multiple cameras into osgpick.

This commit is contained in:
Robert Osfield 2003-04-15 20:54:10 +00:00
parent 4c6686eaee
commit fc4a2ab191
2 changed files with 118 additions and 30 deletions

View File

@ -32,12 +32,44 @@
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 {
public:
PickHandler(osgProducer::OsgCameraGroup* cg,osgText::Text* updateText):
_cg(cg),
PickHandler(osgProducer::Viewer* viewer,osgText::Text* updateText):
_viewer(viewer),
_updateText(updateText) {}
~PickHandler() {}
@ -53,7 +85,7 @@ public:
protected:
osgProducer::OsgCameraGroup *_cg;
osgProducer::Viewer* _viewer;
osg::ref_ptr<osgText::Text> _updateText;
};
@ -76,44 +108,90 @@ 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=_cg->getSceneData();//main node of the scene.
osg::Node *scene=_viewer->getSceneData();//main node of the scene.
if (scene)
{
float x=ea.getXnormalized();
float y=ea.getYnormalized();
float x=ea.getX();
float y=ea.getY();
Producer::KeyboardMouse* km = _viewer->getKeyboardMouse();
Producer::Camera *cmm=_cg->getCamera(0);
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())
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;
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, rx,ry);
if (iv.hits())
{
if (!geode->getName().empty())
for(osgUtil::IntersectVisitor::HitList::iterator hitr=hlist.begin();
hitr!=hlist.end();
++hitr)
{
gdlist=gdlist+" "+geode->getName();
//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";
}
}
}
else
{
gdlist=gdlist+" geode";
}
}
}
}
}
setLabel(gdlist);
}
}
@ -223,7 +301,8 @@ int main( int argc, char **argv )
// construct the viewer.
osgProducer::Viewer viewer(arguments);
//osgProducer::Viewer viewer(arguments);
osgProducer::Viewer viewer(BuildConfig());
// set up the value with sensible default event handlers.
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);

View File

@ -92,6 +92,15 @@ 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(); }
KeyboardMouseCallback* getKeyboardMouseCallback() { return _kbmcb; }
const KeyboardMouseCallback* getKeyboardMouseCallback() const { return _kbmcb; }
typedef std::list< osg::ref_ptr<osgGA::GUIEventHandler> > EventHandlerList;
EventHandlerList& getEventHandlerList() { return _eventHandlerList; }
const EventHandlerList& getEventHandlerList() const { return _eventHandlerList; }