diff --git a/examples/osgcluster/osgcluster.cpp b/examples/osgcluster/osgcluster.cpp index 0f8ea3e3b..1d1f30d17 100644 --- a/examples/osgcluster/osgcluster.cpp +++ b/examples/osgcluster/osgcluster.cpp @@ -300,9 +300,13 @@ class DataConverter writeUInt(event.getEventType()); writeUInt(event.getKey()); writeUInt(event.getButton()); + writeInt(event.getWindowX()); + writeInt(event.getWindowY()); + writeUInt(event.getWindowWidth()); + writeUInt(event.getWindowHeight()); writeFloat(event.getXmin()); - writeFloat(event.getXmax()); writeFloat(event.getYmin()); + writeFloat(event.getXmax()); writeFloat(event.getYmax()); writeFloat(event.getX()); writeFloat(event.getY()); @@ -316,10 +320,16 @@ class DataConverter event.setEventType((osgGA::GUIEventAdapter::EventType)readUInt()); event.setKey(readUInt()); event.setButton(readUInt()); - event.setXmin(readFloat()); - event.setXmax(readFloat()); - event.setYmin(readFloat()); - event.setYmax(readFloat()); + int x = readInt(); + int y = readInt(); + int width = readUInt(); + int height = readUInt(); + event.setWindowRectangle(x,y,width,height); + float xmin = readFloat(); + float ymin = readFloat(); + float xmax = readFloat(); + float ymax = readFloat(); + event.setInputRange(xmin,ymin,xmax,ymax); event.setX(readFloat()); event.setY(readFloat()); event.setButtonMask(readUInt()); diff --git a/examples/osgkeyboardmouse/GNUmakefile b/examples/osgkeyboardmouse/GNUmakefile index daf2c61a2..7a942a863 100644 --- a/examples/osgkeyboardmouse/GNUmakefile +++ b/examples/osgkeyboardmouse/GNUmakefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ osgkeyboardmouse.cpp\ -LIBS += -lProducer -losgFX -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads +LIBS += -lProducer -losgFX -losgGA -losgDB -losgUtil -losg $(X_LIBS) $(OTHER_LIBS) -lOpenThreads INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osgkeyboardmouse/osgkeyboardmouse.cpp b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp index 7245190a9..e2de56b37 100644 --- a/examples/osgkeyboardmouse/osgkeyboardmouse.cpp +++ b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp @@ -17,8 +17,7 @@ #include #include -#include -#include +#include #include #include @@ -285,132 +284,50 @@ int main( int argc, char **argv ) // create the view of the scene. - osg::ref_ptr sceneView = new osgUtil::SceneView; - sceneView->setDefaults(); - sceneView->setSceneData(loadedModel.get()); + osgGA::SimpleViewer viewer; + viewer.setSceneData(loadedModel.get()); + + // create the event queue, - // create the event queue, note that Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits, so - // we need to construct the event queue so that it knows about this convention. - osg::ref_ptr eventQueue = new osgGA::EventQueue(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS); - // set up a KeyboardMouse to manage the events comming in from the RenderSurface osg::ref_ptr kbm = new Producer::KeyboardMouse(renderSurface.get()); // create a KeyboardMouseCallback to handle the mouse events within this applications - osg::ref_ptr kbmcb = new MyKeyboardMouseCallback(eventQueue.get()); + osg::ref_ptr kbmcb = new MyKeyboardMouseCallback(viewer.getEventQueue()); // create a tracball manipulator to move the camera around in response to keyboard/mouse events - osg::ref_ptr cameraManipulator = new osgGA::TrackballManipulator; + viewer.setCameraManipulator( new osgGA::TrackballManipulator ); - // keep a list of event handlers to manipulate the application/scene with in response to keyboard/mouse events - typedef std::list< osg::ref_ptr > EventHandlers; - EventHandlers eventHandlers; - osg::ref_ptr statesetManipulator = new osgGA::StateSetManipulator; - statesetManipulator->setStateSet(sceneView->getGlobalStateSet()); - eventHandlers.push_back(statesetManipulator.get()); - eventHandlers.push_back(new PickHandler(sceneView.get())); + statesetManipulator->setStateSet(viewer.getSceneView()->getGlobalStateSet()); + viewer.addEventHandler(statesetManipulator.get()); + + // add the pick handler + viewer.addEventHandler(new PickHandler(viewer.getSceneView())); - // create an event visitor to pass the events down to the scene graph nodes - osg::ref_ptr eventVisitor = new osgGA::EventVisitor; + // set the window dimensions + viewer.getEventQueue()->getCurrentEventState()->setWindowRectangle(100,100,800,600); - // create an action adapter to allow event handlers to request actions from the GUI. - osg::ref_ptr actionAdapter = new MyActionAdapter; - - // record the timer tick at the start of rendering. - osg::Timer_t start_tick = osg::Timer::instance()->tick(); - - unsigned int frameNum = 0; - - eventQueue->setStartTick(start_tick); - - // set the mouse input range (note WindowSize name in appropriate here so osgGA::GUIEventAdapter API really needs looking at, Robert Osfield, June 2006). + // set the mouse input range. // Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead. - eventQueue->getCurrentEventState()->setWindowSize(-1.0, -1.0, 1.0, 1.0); + viewer.getEventQueue()->getCurrentEventState()->setInputRange(-1.0, -1.0, 1.0, 1.0); + // Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits. + // we need to construct the event queue so that it knows about this convention. + viewer.getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS); - // home the manipulator. - osg::ref_ptr dummyEvent = eventQueue->createEvent(); - cameraManipulator->setNode(sceneView->getSceneData()); - cameraManipulator->home(*dummyEvent, *actionAdapter); - + viewer.init(); // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) while( renderSurface->isRealized() && !kbmcb->done()) { - // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly - osg::FrameStamp* frameStamp = new osg::FrameStamp; - frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); - frameStamp->setFrameNumber(frameNum++); - - // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp - sceneView->setFrameStamp(frameStamp); + // update the window dimensions, in case the window has been resized. + viewer.getEventQueue()->windowResize(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight(), false); // pass any keyboard mouse events onto the local keyboard mouse callback. kbm->update( *kbmcb ); - // create an event to signal the new frame. - eventQueue->frame(frameStamp->getReferenceTime()); - - // get the event since the last frame. - osgGA::EventQueue::Events events; - eventQueue->takeEvents(events); - - if (eventVisitor.valid()) - { - eventVisitor->setTraversalNumber(frameStamp->getFrameNumber()); - } - - // dispatch the events in order of arrival. - for(osgGA::EventQueue::Events::iterator event_itr = events.begin(); - event_itr != events.end(); - ++event_itr) - { - bool handled = false; - - if (eventVisitor.valid() && sceneView->getSceneData()) - { - eventVisitor->reset(); - eventVisitor->addEvent(event_itr->get()); - sceneView->getSceneData()->accept(*eventVisitor); - if (eventVisitor->getEventHandled()) - handled = true; - } - - if (cameraManipulator.valid() && !handled) - { - /*handled =*/ cameraManipulator->handle(*(*event_itr), *actionAdapter); - } - - for(EventHandlers::iterator handler_itr=eventHandlers.begin(); - handler_itr!=eventHandlers.end() && !handled; - ++handler_itr) - { - handled = (*handler_itr)->handle(*(*event_itr),*actionAdapter,0,0); - } - - // osg::notify(osg::NOTICE)<<" Handled event "<<(*event_itr)->getTime()<<" "<< handled<setViewMatrix(cameraManipulator->getInverseMatrix()); - } - - // update the viewport dimensions, incase the window has been resized. - sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); - - // do the update traversal the scene graph - such as updating animations - sceneView->update(); - - // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins - sceneView->cull(); - - // draw the rendering bins. - sceneView->draw(); + viewer.frame(); // Swap Buffers renderSurface->swapBuffers(); diff --git a/examples/osgsimple/GNUmakefile b/examples/osgsimple/GNUmakefile index 9b3180b6e..35d924512 100644 --- a/examples/osgsimple/GNUmakefile +++ b/examples/osgsimple/GNUmakefile @@ -4,7 +4,7 @@ include $(TOPDIR)/Make/makedefs CXXFILES =\ osgsimple.cpp\ -LIBS += -lProducer -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads +LIBS += -lProducer -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads INSTFILES = \ $(CXXFILES)\ diff --git a/examples/osgsimple/osgsimple.cpp b/examples/osgsimple/osgsimple.cpp index 37ce48715..ad62f8088 100644 --- a/examples/osgsimple/osgsimple.cpp +++ b/examples/osgsimple/osgsimple.cpp @@ -4,9 +4,10 @@ // graphics window, and OSG for rendering. #include -#include + #include #include +#include int main( int argc, char **argv ) @@ -32,46 +33,26 @@ int main( int argc, char **argv ) renderSurface->useBorder(true); renderSurface->realize(); - // create the view of the scene. - osg::ref_ptr sceneView = new osgUtil::SceneView; - sceneView->setDefaults(); - sceneView->setSceneData(loadedModel.get()); + + osgGA::SimpleViewer viewer; + viewer.setSceneData(loadedModel.get()); // initialize the view to look at the center of the scene graph const osg::BoundingSphere& bs = loadedModel->getBound(); osg::Matrix viewMatrix; viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); - // record the timer tick at the start of rendering. - osg::Timer_t start_tick = osg::Timer::instance()->tick(); - - unsigned int frameNum = 0; - // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) while( renderSurface->isRealized() ) - { - // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly - osg::ref_ptr frameStamp = new osg::FrameStamp; - frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); - frameStamp->setFrameNumber(frameNum++); - - // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp - sceneView->setFrameStamp(frameStamp.get()); - - // update the viewport dimensions, incase the window has been resized. - sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); - - // set the view - sceneView->setViewMatrix(viewMatrix); + { + // update the window dimensions, in case the window has been resized. + viewer.getEventQueue()->windowResize(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); - // do the update traversal the scene graph - such as updating animations - sceneView->update(); + // set the view + viewer.getCamera()->setViewMatrix(viewMatrix); - // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins - sceneView->cull(); - - // draw the rendering bins. - sceneView->draw(); + // advance the frame, handle events, update the scene and render it. + viewer.frame(); // Swap Buffers renderSurface->swapBuffers(); diff --git a/include/osgGA/EventQueue b/include/osgGA/EventQueue index 687cb7cd3..454cc29a1 100644 --- a/include/osgGA/EventQueue +++ b/include/osgGA/EventQueue @@ -52,7 +52,7 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced /** Method for adapting window resize event, placing this event on the back of the event queue. */ - void windowResize(float Xmin, float Ymin, float Xmax, float Ymax); + void windowResize(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange = true); /** Method for adapting mouse scroll wheel events, placing this event on the back of the event queue. */ void mouseScroll(GUIEventAdapter::ScrollingMotion sm); diff --git a/include/osgGA/GUIEventAdapter b/include/osgGA/GUIEventAdapter index 79d0b91c6..9536af5b9 100644 --- a/include/osgGA/GUIEventAdapter +++ b/include/osgGA/GUIEventAdapter @@ -271,6 +271,23 @@ public: /** deprecated function for getting time of event. */ double time() const { return _time; } + + /** set window rectangle. */ + void setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange = true); + + /** get window x origin.*/ + int getWindowX() const { return _windowX; } + + /** get window y origin.*/ + int getWindowY() const { return _windowY; } + + /** get window width.*/ + unsigned int getWindowWidth() const { return _windowWidth; } + + /** get window height.*/ + unsigned int getWindowHeight() const { return _windowHeight; } + + /** set key pressed. */ inline void setKey(int key) { _key = key; } @@ -283,31 +300,20 @@ public: /** button pressed/released, return -1 if inappropriate for this GUIEventAdapter.*/ int getButton() const { return _button; } - /** set window size. */ - void setWindowSize(float Xmin, float Ymin, float Xmax, float Ymax); - /** set window minimum x. */ - void setXmin(float x) { _Xmin = x; } + /** set mouse input range. */ + void setInputRange(float Xmin, float Ymin, float Xmax, float Ymax); - /** get window minimum x. */ + /** get mouse minimum x. */ float getXmin() const { return _Xmin; } - /** set window maximum x. */ - void setXmax(float x) { _Xmax = x; } - - /** get window maximum x. */ + /** get mouse maximum x. */ float getXmax() const { return _Xmax; } - /** set window minimum y. */ - void setYmin(float y) { _Ymin = y; } - - /** get window minimum y. */ + /** get mmouse minimum y. */ float getYmin() const { return _Ymin; } - /** set window maYimum y. */ - void setYmax(float y) { _Ymax = y; } - - /** get window maYimum y. */ + /** get mouse maYimum y. */ float getYmax() const { return _Ymax; } /** set current mouse x position.*/ @@ -388,6 +394,10 @@ public: EventType _eventType; double _time; + int _windowX; + int _windowY; + int _windowWidth; + int _windowHeight; int _key; int _button; float _Xmin,_Xmax; diff --git a/include/osgGA/SimpleViewer b/include/osgGA/SimpleViewer new file mode 100644 index 000000000..b8d3253f9 --- /dev/null +++ b/include/osgGA/SimpleViewer @@ -0,0 +1,114 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGGA_SimpleViewer +#define OSGGA_SimpleViewer 1 + +#include +#include +#include + +#include + +#include + +namespace osgGA{ + +/** SimpleViewer provide a simple interface for setting up rendering of an scene graph, using a single camera view within a single window.*/ +class OSGGA_EXPORT SimpleViewer : public osgGA::GUIActionAdapter +{ + public: + + SimpleViewer(); + virtual ~SimpleViewer(); + + void setSceneData(osg::Node* node); + osg::Node* getSceneData(); + const osg::Node* getSceneData() const; + + osg::CameraNode* getCamera(); + const osg::CameraNode* getCamera() const; + + void setCameraManipulator(MatrixManipulator* manipulator); + MatrixManipulator* getCameraManipulator() { return _cameraManipulator.get(); } + const MatrixManipulator* getCameraManipulator() const { return _cameraManipulator.get(); } + + + typedef std::list< osg::ref_ptr > EventHandlers; + + void addEventHandler(GUIEventHandler* eventHandler); + EventHandlers& getEventHandlers() { return _eventHandlers; } + const EventHandlers& getEventHandlers() const { return _eventHandlers; } + + EventQueue* getEventQueue() { return _eventQueue.get(); } + const EventQueue* getEventQueue() const { return _eventQueue.get(); } + + void setDatabasePager(osgDB::DatabasePager* dp); + osgDB::DatabasePager* getDatabasePager() { return _databasePager.get(); } + const osgDB::DatabasePager* getDatabasePager() const { return _databasePager.get(); } + + + /** Render a complete new frame. + * Calls frameAdvance(), frameEventTraversal(), frameUpateTraversal(), frameCullTraversal() and frameDrawTraversal(). + * Note, no internal makeCurrent() is issued before, or swap buffers called after frame(), these operations are the responsibility of the calling code.*/ + virtual void frame(); + + virtual void frameAdvance(); + virtual void frameEventTraversal(); + virtual void frameUpdateTraversal(); + virtual void frameCullTraversal(); + virtual void frameDrawTraversal(); + + /** Clean up all OpenGL objects associated with this viewer scenegraph. Note, must only be called from the graphics context associated with this viewer.*/ + virtual void cleanup(); + + public: + + // Override from GUIActionAdapter + virtual void requestRedraw() {} + + // Override from GUIActionAdapter + virtual void requestContinuousUpdate(bool /*needed*/=true) {} + + // Override from GUIActionAdapter + virtual void requestWarpPointer(float /*x*/,float /*y*/) {} + + osgUtil::SceneView* getSceneView() { return _sceneView.get(); } + const osgUtil::SceneView* getSceneView() const { return _sceneView.get(); } + + void init(); + + protected: + + + bool _firstFrame; + osg::Timer_t _startTick; + osg::ref_ptr _frameStamp; + + osg::ref_ptr _sceneView; + + osg::ref_ptr _eventQueue; + + osg::ref_ptr _cameraManipulator; + EventHandlers _eventHandlers; + + osg::ref_ptr _eventVisitor; + + osg::ref_ptr _databasePager; + +}; + + +} + +#endif diff --git a/src/osgGA/EventQueue.cpp b/src/osgGA/EventQueue.cpp index 586c541c2..6042cde94 100644 --- a/src/osgGA/EventQueue.cpp +++ b/src/osgGA/EventQueue.cpp @@ -77,9 +77,9 @@ bool EventQueue::copyEvents(Events& events) const } -void EventQueue::windowResize(float Xmin, float Ymin, float Xmax, float Ymax) +void EventQueue::windowResize(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange) { - _accumulateEventState->setWindowSize(Xmin, Ymin, Xmax, Ymax); + _accumulateEventState->setWindowRectangle(x, y, width, height, updateMouseRange); GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState); event->setEventType(GUIEventAdapter::RESIZE); diff --git a/src/osgGA/GNUmakefile b/src/osgGA/GNUmakefile index 92890fa6c..24a2cec71 100644 --- a/src/osgGA/GNUmakefile +++ b/src/osgGA/GNUmakefile @@ -16,6 +16,7 @@ CXXFILES = \ KeySwitchMatrixManipulator.cpp\ SetSceneViewVisitor.cpp\ StateSetManipulator.cpp\ + SimpleViewer.cpp\ TerrainManipulator.cpp\ NodeTrackerManipulator.cpp\ TrackballManipulator.cpp\ diff --git a/src/osgGA/GUIEventAdapter.cpp b/src/osgGA/GUIEventAdapter.cpp index e8345a0b9..b2a7ff733 100644 --- a/src/osgGA/GUIEventAdapter.cpp +++ b/src/osgGA/GUIEventAdapter.cpp @@ -18,6 +18,10 @@ using namespace osgGA; GUIEventAdapter::GUIEventAdapter(): _eventType(NONE), _time(0.0), + _windowX(0), + _windowY(0), + _windowWidth(1280), + _windowHeight(1024), _key(0), _button(0), _Xmin(0.0), @@ -40,6 +44,10 @@ GUIEventAdapter::GUIEventAdapter(const GUIEventAdapter& rhs): osg::Referenced(), _eventType(rhs._eventType), _time(rhs._time), + _windowX(rhs._windowX), + _windowY(rhs._windowY), + _windowWidth(rhs._windowWidth), + _windowHeight(rhs._windowHeight), _key(rhs._key), _button(rhs._button), _Xmin(rhs._Xmin), @@ -62,7 +70,21 @@ GUIEventAdapter::~GUIEventAdapter() { } -void GUIEventAdapter::setWindowSize(float Xmin, float Ymin, float Xmax, float Ymax) +void GUIEventAdapter::setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange) +{ + _windowX = x; + _windowY = y; + _windowWidth = width; + _windowHeight = height; + + if (updateMouseRange) + { + setInputRange(x, y, x+width, y+height); + } + +} + +void GUIEventAdapter::setInputRange(float Xmin, float Ymin, float Xmax, float Ymax) { _Xmin = Xmin; _Ymin = Ymin; diff --git a/src/osgGA/SimpleViewer.cpp b/src/osgGA/SimpleViewer.cpp new file mode 100644 index 000000000..f61d1e673 --- /dev/null +++ b/src/osgGA/SimpleViewer.cpp @@ -0,0 +1,235 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include +#include + +using namespace osgGA; + +SimpleViewer::SimpleViewer(): + _firstFrame(true) +{ + _sceneView = new osgUtil::SceneView; + _sceneView->setDefaults(); + _sceneView->getState()->setContextID(osg::GraphicsContext::createNewContextID()); + + _startTick = osg::Timer::instance()->tick(); + _frameStamp = new osg::FrameStamp; + _frameStamp->setFrameNumber(0); + _frameStamp->setReferenceTime(0); + + _eventQueue = new osgGA::EventQueue; + _eventQueue->setStartTick(_startTick); + + _eventVisitor = new osgGA::EventVisitor; +} + +SimpleViewer::~SimpleViewer() +{ + _sceneView->releaseAllGLObjects(); + osg::GraphicsContext::decrementContextIDUsageCount(_sceneView->getState()->getContextID()); +} + +void SimpleViewer::setSceneData(osg::Node* node) +{ + _sceneView->setSceneData(node); + + if (_cameraManipulator.valid()) + { + _cameraManipulator->setNode(node); + + osg::ref_ptr dummyEvent = _eventQueue->createEvent(); + _cameraManipulator->home(*dummyEvent, *this); + } +} + +osg::Node* SimpleViewer::getSceneData() +{ + return _sceneView->getSceneData(); +} + +const osg::Node* SimpleViewer::getSceneData() const +{ + return _sceneView->getSceneData(); +} + +osg::CameraNode* SimpleViewer::getCamera() +{ + return _sceneView->getCamera(); +} + +const osg::CameraNode* SimpleViewer::getCamera() const +{ + return _sceneView->getCamera(); +} + +void SimpleViewer::setCameraManipulator(MatrixManipulator* manipulator) +{ + if (_cameraManipulator == manipulator) return; + + _cameraManipulator = manipulator; + if (_cameraManipulator.valid()) + { + _cameraManipulator->setNode(_sceneView->getSceneData()); + + osg::ref_ptr dummyEvent = _eventQueue->createEvent(); + _cameraManipulator->home(*dummyEvent, *this); + } +} + +void SimpleViewer::addEventHandler(GUIEventHandler* eventHandler) +{ + _eventHandlers.push_back(eventHandler); +} + +void SimpleViewer::init() +{ + osg::ref_ptr initEvent = _eventQueue->createEvent(); + initEvent->setEventType(osgGA::GUIEventAdapter::FRAME); + _cameraManipulator->init(*initEvent, *this); +} + +void SimpleViewer::frame() +{ + if (_firstFrame) + { + init(); + _firstFrame = false; + } + + frameAdvance(); + frameEventTraversal(); + frameUpdateTraversal(); + frameCullTraversal(); + frameDrawTraversal(); +} + +void SimpleViewer::frameAdvance() +{ + osg::Timer_t currentTick = osg::Timer::instance()->tick(); + _frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(_startTick,currentTick)); + _frameStamp->setFrameNumber(_frameStamp->getFrameNumber()+1); + + _sceneView->setFrameStamp(_frameStamp.get()); +} + +void SimpleViewer::frameEventTraversal() +{ + _eventQueue->frame( _frameStamp->getReferenceTime() ); + + osgGA::EventQueue::Events events; + _eventQueue->takeEvents(events); + + if (_eventVisitor.valid()) + { + _eventVisitor->setTraversalNumber(_frameStamp->getFrameNumber()); + } + + for(osgGA::EventQueue::Events::iterator itr = events.begin(); + itr != events.end(); + ++itr) + { + osgGA::GUIEventAdapter* event = itr->get(); + + bool handled = false; + + if (_eventVisitor.valid()) + { + _eventVisitor->reset(); + _eventVisitor->addEvent( event ); + + getSceneData()->accept(*_eventVisitor); + + if (_eventVisitor->getEventHandled()) handled = true; + } + + if (_cameraManipulator.valid()) + { + _cameraManipulator->handle( *event, *this ); + } + + for(EventHandlers::iterator hitr = _eventHandlers.begin(); + hitr != _eventHandlers.end() && !handled; + ++hitr) + { + handled = (*hitr)->handle( *event, *this, 0, 0); + } + } +} + +void SimpleViewer::frameUpdateTraversal() +{ + double previousAspectRatio = ( static_cast(_sceneView->getViewport()->width())/ + static_cast(_sceneView->getViewport()->height()) ); + + // update the viewport + int width = _eventQueue->getCurrentEventState()->getWindowWidth(); + int height = _eventQueue->getCurrentEventState()->getWindowHeight(); + _sceneView->setViewport(0,0,width,height); + + double newAspectRatio = ( static_cast(_sceneView->getViewport()->width())/ + static_cast(_sceneView->getViewport()->height()) ); + + + // if aspect ratio adjusted change the project matrix to suit. + if (previousAspectRatio != newAspectRatio) + { + osg::Matrixd& pm = _sceneView->getProjectionMatrix(); + bool orthographicCamera = (pm(0,3)==0.0) && (pm(0,3)==0.0) && (pm(0,3)==0.0) && (pm(0,3)==1.0); + if (orthographicCamera) + { + double left, right, bottom, top, zNear, zFar; + _sceneView->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); + + double mid = (right+left)*0.5; + double halfWidth = (right-left)*0.5; + left = mid - halfWidth * (newAspectRatio/previousAspectRatio); + right = mid + halfWidth * (newAspectRatio/previousAspectRatio); + _sceneView->setProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); + } + else + { + double left, right, bottom, top, zNear, zFar; + _sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); + + double mid = (right+left)*0.5; + double halfWidth = (right-left)*0.5; + left = mid - halfWidth * (newAspectRatio/previousAspectRatio); + right = mid + halfWidth * (newAspectRatio/previousAspectRatio); + _sceneView->setProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); + } + } + + if (_cameraManipulator.valid()) + { + _sceneView->setViewMatrix(_cameraManipulator->getInverseMatrix()); + } + + _sceneView->update(); +} + +void SimpleViewer::frameCullTraversal() +{ + _sceneView->cull(); +} + +void SimpleViewer::frameDrawTraversal() +{ + _sceneView->draw(); +} + +void SimpleViewer::cleanup() +{ + _sceneView->releaseAllGLObjects(); + _sceneView->flushAllDeletedGLObjects(); +} diff --git a/src/osgProducer/KeyboardMouseCallback.cpp b/src/osgProducer/KeyboardMouseCallback.cpp index 8aad923d4..ed4985cda 100644 --- a/src/osgProducer/KeyboardMouseCallback.cpp +++ b/src/osgProducer/KeyboardMouseCallback.cpp @@ -158,9 +158,7 @@ void KeyboardMouseCallback::updateWindowSize() maxY = osg::maximum(maxY,ir.bottom()+ir.height()); } - // osg::notify(osg::NOTICE)<<"IA ea->setWindowSize("<setWindowSize(minX,minY,maxX,maxY); + ea->setInputRange(minX,minY,maxX,maxY); } else if (rs) { @@ -175,7 +173,12 @@ void KeyboardMouseCallback::updateWindowSize() // osg::notify(osg::NOTICE)<<"RS ea->setWindowSize("<setWindowSize(minX,minY,maxX,maxY); + ea->setInputRange(minX,minY,maxX,maxY); + } + + if (rs) + { + ea->setWindowRectangle(rs->getWindowOriginX(), rs->getWindowOriginY(), rs->getWindowWidth(),rs->getWindowHeight()); } } diff --git a/src/osgWrappers/osgGA/EventQueue.cpp b/src/osgWrappers/osgGA/EventQueue.cpp index 40999168a..1d04fd1d0 100644 --- a/src/osgWrappers/osgGA/EventQueue.cpp +++ b/src/osgWrappers/osgGA/EventQueue.cpp @@ -32,7 +32,7 @@ BEGIN_OBJECT_REFLECTOR(osgGA::EventQueue) I_Method1(bool, copyEvents, IN, osgGA::EventQueue::Events &, events); I_Method1(void, appendEvents, IN, osgGA::EventQueue::Events &, events); I_Method1(void, addEvent, IN, osgGA::GUIEventAdapter *, event); - I_Method4(void, windowResize, IN, float, Xmin, IN, float, Ymin, IN, float, Xmax, IN, float, Ymax); + I_MethodWithDefaults5(void, windowResize, IN, int, x, , IN, int, y, , IN, unsigned int, width, , IN, unsigned int, height, , IN, bool, updateMouseRange, true); I_Method1(void, mouseScroll, IN, osgGA::GUIEventAdapter::ScrollingMotion, sm); I_Method2(void, mouseScroll2D, IN, float, x, IN, float, y); I_Method1(void, penPressure, IN, float, pressure); diff --git a/src/osgWrappers/osgGA/GNUmakefile b/src/osgWrappers/osgGA/GNUmakefile index 8382f86cb..d3a16a6b5 100644 --- a/src/osgWrappers/osgGA/GNUmakefile +++ b/src/osgWrappers/osgGA/GNUmakefile @@ -15,6 +15,7 @@ CXXFILES =\ MatrixManipulator.cpp\ NodeTrackerManipulator.cpp\ SetSceneViewVisitor.cpp\ + SimpleViewer.cpp\ StateSetManipulator.cpp\ TerrainManipulator.cpp\ TrackballManipulator.cpp\ diff --git a/src/osgWrappers/osgGA/GUIEventAdapter.cpp b/src/osgWrappers/osgGA/GUIEventAdapter.cpp index 471fe574b..593ac8af6 100644 --- a/src/osgWrappers/osgGA/GUIEventAdapter.cpp +++ b/src/osgWrappers/osgGA/GUIEventAdapter.cpp @@ -215,18 +215,19 @@ BEGIN_OBJECT_REFLECTOR(osgGA::GUIEventAdapter) I_Method1(void, setTime, IN, double, time); I_Method0(double, getTime); I_Method0(double, time); + I_MethodWithDefaults5(void, setWindowRectangle, IN, int, x, , IN, int, y, , IN, unsigned int, width, , IN, unsigned int, height, , IN, bool, updateMouseRange, true); + I_Method0(int, getWindowX); + I_Method0(int, getWindowY); + I_Method0(unsigned int, getWindowWidth); + I_Method0(unsigned int, getWindowHeight); I_Method1(void, setKey, IN, int, key); I_Method0(int, getKey); I_Method1(void, setButton, IN, int, button); I_Method0(int, getButton); - I_Method4(void, setWindowSize, IN, float, Xmin, IN, float, Ymin, IN, float, Xmax, IN, float, Ymax); - I_Method1(void, setXmin, IN, float, x); + I_Method4(void, setInputRange, IN, float, Xmin, IN, float, Ymin, IN, float, Xmax, IN, float, Ymax); I_Method0(float, getXmin); - I_Method1(void, setXmax, IN, float, x); I_Method0(float, getXmax); - I_Method1(void, setYmin, IN, float, y); I_Method0(float, getYmin); - I_Method1(void, setYmax, IN, float, y); I_Method0(float, getYmax); I_Method1(void, setX, IN, float, x); I_Method0(float, getX); @@ -261,13 +262,17 @@ BEGIN_OBJECT_REFLECTOR(osgGA::GUIEventAdapter) I_Property(osgGA::GUIEventAdapter::ScrollingMotion, ScrollingMotion); I_Property(osgGA::GUIEventAdapter::TabletPointerType, TabletPointerType); I_Property(double, Time); + I_ReadOnlyProperty(unsigned int, WindowHeight); + I_ReadOnlyProperty(unsigned int, WindowWidth); + I_ReadOnlyProperty(int, WindowX); + I_ReadOnlyProperty(int, WindowY); I_Property(float, X); - I_Property(float, Xmax); - I_Property(float, Xmin); + I_ReadOnlyProperty(float, Xmax); + I_ReadOnlyProperty(float, Xmin); I_ReadOnlyProperty(float, Xnormalized); I_Property(float, Y); - I_Property(float, Ymax); - I_Property(float, Ymin); + I_ReadOnlyProperty(float, Ymax); + I_ReadOnlyProperty(float, Ymin); I_ReadOnlyProperty(float, Ynormalized); END_REFLECTOR diff --git a/src/osgWrappers/osgGA/SimpleViewer.cpp b/src/osgWrappers/osgGA/SimpleViewer.cpp new file mode 100644 index 000000000..6b630b793 --- /dev/null +++ b/src/osgWrappers/osgGA/SimpleViewer.cpp @@ -0,0 +1,74 @@ +// *************************************************************************** +// +// Generated automatically by genwrapper. +// Please DO NOT EDIT this file! +// +// *************************************************************************** + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Must undefine IN and OUT macros defined in Windows headers +#ifdef IN +#undef IN +#endif +#ifdef OUT +#undef OUT +#endif + +TYPE_NAME_ALIAS(std::list< osg::ref_ptr< osgGA::GUIEventHandler > >, osgGA::SimpleViewer::EventHandlers); + +BEGIN_OBJECT_REFLECTOR(osgGA::SimpleViewer) + I_BaseType(osgGA::GUIActionAdapter); + I_Constructor0(); + I_Method1(void, setSceneData, IN, osg::Node *, node); + I_Method0(osg::Node *, getSceneData); + I_Method0(const osg::Node *, getSceneData); + I_Method0(osg::CameraNode *, getCamera); + I_Method0(const osg::CameraNode *, getCamera); + I_Method1(void, setCameraManipulator, IN, osgGA::MatrixManipulator *, manipulator); + I_Method0(osgGA::MatrixManipulator *, getCameraManipulator); + I_Method0(const osgGA::MatrixManipulator *, getCameraManipulator); + I_Method1(void, addEventHandler, IN, osgGA::GUIEventHandler *, eventHandler); + I_Method0(osgGA::SimpleViewer::EventHandlers &, getEventHandlers); + I_Method0(const osgGA::SimpleViewer::EventHandlers &, getEventHandlers); + I_Method0(osgGA::EventQueue *, getEventQueue); + I_Method0(const osgGA::EventQueue *, getEventQueue); + I_Method1(void, setDatabasePager, IN, osgDB::DatabasePager *, dp); + I_Method0(osgDB::DatabasePager *, getDatabasePager); + I_Method0(const osgDB::DatabasePager *, getDatabasePager); + I_Method0(void, frame); + I_Method0(void, frameAdvance); + I_Method0(void, frameEventTraversal); + I_Method0(void, frameUpdateTraversal); + I_Method0(void, frameCullTraversal); + I_Method0(void, frameDrawTraversal); + I_Method0(void, cleanup); + I_Method0(void, requestRedraw); + I_MethodWithDefaults1(void, requestContinuousUpdate, IN, bool, x, true); + I_Method2(void, requestWarpPointer, IN, float, x, IN, float, x); + I_Method0(osgUtil::SceneView *, getSceneView); + I_Method0(const osgUtil::SceneView *, getSceneView); + I_Method0(void, init); + I_ReadOnlyProperty(osg::CameraNode *, Camera); + I_Property(osgGA::MatrixManipulator *, CameraManipulator); + I_Property(osgDB::DatabasePager *, DatabasePager); + I_ReadOnlyProperty(osgGA::SimpleViewer::EventHandlers &, EventHandlers); + I_ReadOnlyProperty(osgGA::EventQueue *, EventQueue); + I_Property(osg::Node *, SceneData); + I_ReadOnlyProperty(osgUtil::SceneView *, SceneView); +END_REFLECTOR + +STD_LIST_REFLECTOR(std::list< osg::ref_ptr< osgGA::GUIEventHandler > >); +