diff --git a/include/osgGA/GUIEventHandlerVisitor b/include/osgGA/GUIEventHandlerVisitor index 44c0441d4..b363ac311 100644 --- a/include/osgGA/GUIEventHandlerVisitor +++ b/include/osgGA/GUIEventHandlerVisitor @@ -9,6 +9,7 @@ namespace osgGA{ // Some forward declarations class GUIActionAdapter; +class GUIEventHandler; class CompositeGUIEventHandler; class CameraManipulator; class StateSetManipulator; @@ -26,6 +27,7 @@ class OSGGA_EXPORT GUIEventHandlerVisitor { public: + virtual void visit(GUIEventHandler&) {} virtual void visit(CompositeGUIEventHandler&); virtual void visit(CameraManipulator&) {}; virtual void visit(StateSetManipulator&) {}; diff --git a/include/osgGA/KeySwitchCameraManipulator b/include/osgGA/KeySwitchCameraManipulator index 484f7dd29..c614fef77 100644 --- a/include/osgGA/KeySwitchCameraManipulator +++ b/include/osgGA/KeySwitchCameraManipulator @@ -24,17 +24,8 @@ class OSGGA_EXPORT KeySwitchCameraManipulator : public CameraManipulator void addCameraManipulator(int key, std::string name, CameraManipulator *cm); - //typedef void (* Callback)(KeySwitchCameraManipulator *); + void addNumberedCameraManipulator(CameraManipulator *cm); -// class Callback: public osgUtil::CallbackList::Callback { -// public: -// virtual ~Callback() {}; -// virtual void operator()(KeySwitchCameraManipulator *) = 0; -// }; -// -// void addCallback(Callback*); -// -// void removeCallback(Callback*); // Overrides from CameraManipulator... @@ -64,9 +55,6 @@ class OSGGA_EXPORT KeySwitchCameraManipulator : public CameraManipulator osg::ref_ptr _current; - // Callbacks - //CallbackList _cameraManipChangeCallbacks; - }; }; diff --git a/include/osgGLUT/Viewer b/include/osgGLUT/Viewer index e9d08fd11..d92292354 100644 --- a/include/osgGLUT/Viewer +++ b/include/osgGLUT/Viewer @@ -81,6 +81,8 @@ class OSGGLUT_EXPORT Viewer : public Window, public osgGA::GUIActionAdapter void selectCameraManipulator(unsigned int pos, unsigned int viewport = 0); + void setEventHandler(osgGA::GUIEventHandler* handler,unsigned int viewport = 0); + // derived from osgGA::GUIActionAdapter virtual void requestRedraw() {} // redraw always by idle callback done. virtual void requestContinuousUpdate(bool /*needed*/) {} // continuous update always @@ -119,8 +121,11 @@ class OSGGLUT_EXPORT Viewer : public Window, public osgGA::GUIActionAdapter osg::ref_ptr sceneView; float viewport[4]; // Win-size-relative [0,1] - osg::ref_ptr _cameraManipulator; + osg::ref_ptr _cameraManipulator; CameraManipList _cameraManipList; + + osg::ref_ptr _eventHandler; + }; typedef std::vector ViewportList; diff --git a/src/Demos/osgoccluder/osgoccluder.cpp b/src/Demos/osgoccluder/osgoccluder.cpp index 99b04e974..3ba08dd7b 100644 --- a/src/Demos/osgoccluder/osgoccluder.cpp +++ b/src/Demos/osgoccluder/osgoccluder.cpp @@ -7,15 +7,18 @@ #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include @@ -27,6 +30,13 @@ void write_usage(std::ostream& out,const std::string& name) out <<" "< _sceneview; + osg::ref_ptr _rootnode; + osg::ref_ptr _occluders; + osg::ref_ptr _convexPlanerOccluder; +}; + +bool OccluderEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) +{ + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYBOARD): + { + if (ea.getKey()=='a') + { + + int x = ea.getX(); + int y = ea.getY(); + + osg::Vec3 near_point,far_point; + if (!_sceneview->projectWindowXYIntoObject(x,ea.getYmax()-y,near_point,far_point)) + { + return true; + } + + osg::ref_ptr lineSegment = osgNew osg::LineSegment; + lineSegment->set(near_point,far_point); + + osgUtil::IntersectVisitor iv; + iv.addLineSegment(lineSegment.get()); + + _rootnode->accept(iv); + + if (iv.hits()) + { + + osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(lineSegment.get()); + if (!hitList.empty()) + { + + osgUtil::Hit& hit = hitList.front(); + addPoint(hit.getWorldIntersectPoint()); + } + + } + + return true; + } + else if (ea.getKey()=='e') + { + endOccluder(); + return true; + } + else if (ea.getKey()=='O') + { + if (_occluders.valid()) + { + std::cout<<"saving occluders to 'saved_occluders.osg'"<getOccluder(); + occluder.add(pos); + +} + +void OccluderEventHandler::endOccluder() +{ + if (_convexPlanerOccluder.valid()) + { + if (_convexPlanerOccluder->getOccluder().getVertexList().size()>=3) + { + osg::OccluderNode* occluderNode = osgNew osg::OccluderNode; + occluderNode->setOccluder(_convexPlanerOccluder.get()); + + if (!_occluders.valid()) + { + _occluders = new osg::Group; + _rootnode->addChild(_occluders.get()); + } + _occluders->addChild(occluderNode); + + std::cout<<"created occluder"<setName("rootgroup"); @@ -187,6 +333,14 @@ int main( int argc, char **argv ) std::vector commandLine; for(int i=1;i::iterator itr=std::find(commandLine.begin(),commandLine.end(),std::string("-c")); + if (itr!=commandLine.end()) + { + manuallyCreateImpostors = true; + commandLine.erase(itr); + } // initialize the viewer. osgGLUT::Viewer viewer; @@ -208,12 +362,23 @@ int main( int argc, char **argv ) return 1; } - // add the occluders to the loaded model. - osg::Node* rootnode = createOccludersAroundModel(loadedmodel); - // run optimization over the scene graph osgUtil::Optimizer optimzer; - optimzer.optimize(rootnode); + optimzer.optimize(loadedmodel); + + // add the occluders to the loaded model. + osg::Group* rootnode = NULL; + + if (manuallyCreateImpostors) + { + rootnode = new osg::Group; + rootnode->addChild(loadedmodel); + } + else + { + rootnode = createOccludersAroundModel(loadedmodel); + } + // add a viewport to the viewer and attach the scene graph. viewer.addViewport( rootnode ); @@ -223,6 +388,11 @@ int main( int argc, char **argv ) viewer.registerCameraManipulator(new osgGA::FlightManipulator); viewer.registerCameraManipulator(new osgGA::DriveManipulator); + if (manuallyCreateImpostors) + { + viewer.setEventHandler(new OccluderEventHandler(viewer.getViewportSceneView(0),rootnode)); + } + // open the viewer window. viewer.open(); diff --git a/src/osgGA/KeySwitchCameraManipulator.cpp b/src/osgGA/KeySwitchCameraManipulator.cpp index 315a2a829..9f87189cc 100644 --- a/src/osgGA/KeySwitchCameraManipulator.cpp +++ b/src/osgGA/KeySwitchCameraManipulator.cpp @@ -13,6 +13,13 @@ void KeySwitchCameraManipulator::addCameraManipulator(int key, std::string name, } } +void KeySwitchCameraManipulator::addNumberedCameraManipulator(CameraManipulator *cm) +{ + if(!cm) return; + addCameraManipulator('1'+_manips.size(),"camera",cm); +} + + bool KeySwitchCameraManipulator::handle(const GUIEventAdapter& ea,GUIActionAdapter& aa) { if(ea.getEventType()==GUIEventAdapter::KEYBOARD){ diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index b02d638fd..71f10eea7 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -290,6 +290,11 @@ unsigned int Viewer::registerCameraManipulator(osgGA::CameraManipulator* cm, return pos; } +void Viewer::setEventHandler(osgGA::GUIEventHandler* handler,unsigned int viewport = 0) +{ + ViewportDef &viewp = _viewportList[viewport]; + viewp._eventHandler = handler; +} void Viewer::setFocusedViewport(unsigned int pos) { @@ -337,11 +342,16 @@ float Viewer::app(unsigned int viewport) osg::ref_ptr ea = osgNew GLUTEventAdapter; ea->adaptFrame(_frameStamp->getReferenceTime()); - if (_viewportList[viewport]._cameraManipulator->handle(*ea,*this)) + if (_viewportList[viewport]._eventHandler.valid() && _viewportList[viewport]._eventHandler->handle(*ea,*this)) + { + // event handler handle this call. + } + else if (_viewportList[viewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled update frame"<< std::endl; } + // do app traversal. getViewportSceneView(viewport)->setFrameStamp(_frameStamp.get()); @@ -704,6 +714,11 @@ void Viewer::reshape(GLint w, GLint h) { // osg::notify(osg::INFO) << "Handled reshape "<< std::endl; } + if (itr->_eventHandler.valid() && itr->_eventHandler->handle(*ea,*this)) + { + // event handler handle this call. + } + } } @@ -713,7 +728,11 @@ void Viewer::mouseMotion(int x, int y) osg::ref_ptr ea = osgNew GLUTEventAdapter; ea->adaptMouseMotion(clockSeconds(),x,y); - if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) + if (_viewportList[_focusedViewport]._eventHandler.valid() && _viewportList[_focusedViewport]._eventHandler->handle(*ea,*this)) + { + // event handler handle this call. + } + else if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mouseMotion "<_buttonMask<<" x="<_mx<<" y="<_my<< std::endl; } @@ -737,7 +756,11 @@ void Viewer::mousePassiveMotion(int x, int y) setFocusedViewport(focus); } - if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) + if (_viewportList[_focusedViewport]._eventHandler.valid() && _viewportList[_focusedViewport]._eventHandler->handle(*ea,*this)) + { + // event handler handle this call. + } + else if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mousePassiveMotion "<_buttonMask<<" x="<_mx<<" y="<_my<< std::endl; } @@ -761,7 +784,11 @@ void Viewer::mouse(int button, int state, int x, int y) setFocusedViewport(focus); } - if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) + if (_viewportList[_focusedViewport]._eventHandler.valid() && _viewportList[_focusedViewport]._eventHandler->handle(*ea,*this)) + { + // event handler handle this call. + } + else if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) { // osg::notify(osg::INFO) << "Handled mouse "<_buttonMask<<" x="<_mx<<" y="<_my<< std::endl; } @@ -775,8 +802,14 @@ void Viewer::keyboard(unsigned char key, int x, int y) osg::ref_ptr ea = osgNew GLUTEventAdapter; ea->adaptKeyboard(clockSeconds(),key,x,y); - if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) - return; + if (_viewportList[_focusedViewport]._eventHandler.valid() && _viewportList[_focusedViewport]._eventHandler->handle(*ea,*this)) + { + return; + } + else if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) + { + return; + } diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 3b2425dc5..a3a1dd68e 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -72,9 +73,11 @@ void Optimizer::optimize(osg::Node* node, unsigned int options) if (options & SHARE_DUPLICATE_STATE) { #if (defined(_MSC_VER) && _MSC_VER<1300 && !defined(_STLPORT_VERSION)) - osg::notify(osg::NOTICE)<<"Warning: VisualStudio 6.0 native STL build, unable to run state optimizer due to bugs in its STL."<accept(osv); @@ -931,7 +934,8 @@ void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group) { if (group.getNumParents()>0) { - if (group.getNumChildren()==0) + // only remove empty groups, but not empty occluders. + if (group.getNumChildren()==0 && !dynamic_cast(&group)) { _redundentNodeList.insert(&group); }