From 128be070bab0b17205fdec4556f86dbc9af94a1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 21 Jan 2003 13:14:29 +0000 Subject: [PATCH] Added new osgProducer::Viewer class for putting together simple producer based viewers very quickly. --- include/osgProducer/ActionAdapter | 15 +- include/osgProducer/CameraGroup | 56 ++++-- include/osgProducer/EventAdapter | 15 +- include/osgProducer/Export | 15 +- include/osgProducer/KeyboardMouseCallback | 15 +- include/osgProducer/ReadCameraConfigFile | 15 +- include/osgProducer/SceneHandler | 16 +- include/osgProducer/Version | 15 +- include/osgProducer/Viewer | 103 +++++++++++ include/osgProducer/WriteCameraConfigFile | 15 +- src/Demos/osgproducer/osgproducer.cpp | 190 ++------------------ src/osgProducer/CameraGroup.cpp | 121 ++++++++----- src/osgProducer/Makefile | 1 + src/osgProducer/Viewer.cpp | 204 ++++++++++++++++++++++ 14 files changed, 538 insertions(+), 258 deletions(-) create mode 100644 include/osgProducer/Viewer create mode 100644 src/osgProducer/Viewer.cpp diff --git a/include/osgProducer/ActionAdapter b/include/osgProducer/ActionAdapter index 61963d246..71d37dd85 100644 --- a/include/osgProducer/ActionAdapter +++ b/include/osgProducer/ActionAdapter @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 PRODUCERACTIONADAPTER #define PRODUCERGUIACTIONADAPTER 1 diff --git a/include/osgProducer/CameraGroup b/include/osgProducer/CameraGroup index 7c6fb9fa9..98b4cd76a 100644 --- a/include/osgProducer/CameraGroup +++ b/include/osgProducer/CameraGroup @@ -1,13 +1,23 @@ -//C++ header - Open Producer - Copyright (C) 2002 Don Burns -//Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSG_CAMERA_GROUP_H #define OSG_CAMERA_GROUP_H #include -#include +#include #include #include #include @@ -31,6 +41,7 @@ class OSGPRODUCER_EXPORT CameraGroup : public Producer::CameraGroup virtual ~CameraGroup() {} + void setSceneData( osg::Node *scene ); osg::Node *getSceneData() { return _scene_data.get(); } @@ -38,6 +49,14 @@ class OSGPRODUCER_EXPORT CameraGroup : public Producer::CameraGroup const osg::Node *getSceneData() const { return _scene_data.get(); } + + void setSceneDecorator( osg::Group* decorator); + + osg::Group* getSceneDecorator() { return _scene_decorator.get(); } + + const osg::Group* getSceneDecorator() const { return _scene_decorator.get(); } + + void setDisplaySettings( osg::DisplaySettings *ds ) { _ds = ds; } @@ -68,7 +87,7 @@ class OSGPRODUCER_EXPORT CameraGroup : public Producer::CameraGroup const osg::Vec4& getBackgroundColor() const { return _background_color; } - void setLODScale( float bias ); + void setLODScale( float scale ); void setFusionDistance( osgUtil::SceneView::FusionDistanceMode mode,float value=1.0f); @@ -76,7 +95,7 @@ class OSGPRODUCER_EXPORT CameraGroup : public Producer::CameraGroup void advance(); - void realize( ThreadingModel thread_model= SingleThreaded ); + virtual void realize( ThreadingModel thread_model= SingleThreaded ); virtual void frame(); @@ -84,16 +103,25 @@ class OSGPRODUCER_EXPORT CameraGroup : public Producer::CameraGroup protected : + void setUpSceneViewsWithData(); - osg::ref_ptr _scene_data; - osg::ref_ptr _global_stateset; - osg::Vec4 _background_color; - SceneHandlerList _shvec; - osg::ref_ptr _ds; - bool _initialized; - osg::ref_ptr _frameStamp; - void _init();; + osg::ref_ptr _scene_data; + osg::ref_ptr _scene_decorator; + + osg::ref_ptr _global_stateset; + osg::Vec4 _background_color; + float _LODScale; + + osgUtil::SceneView::FusionDistanceMode _fusionDistanceMode; + float _fusionDistanceValue; + + SceneHandlerList _shvec; + osg::ref_ptr _ds; + bool _initialized; + osg::ref_ptr _frameStamp; + + void _init(); }; } diff --git a/include/osgProducer/EventAdapter b/include/osgProducer/EventAdapter index 6a401e31f..75eecb14a 100644 --- a/include/osgProducer/EventAdapter +++ b/include/osgProducer/EventAdapter @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGGLUT_ProducerEventAdapter #define OSGGLUT_ProducerEventAdapter 1 diff --git a/include/osgProducer/Export b/include/osgProducer/Export index cacaabfda..52f3c6bb0 100644 --- a/include/osgProducer/Export +++ b/include/osgProducer/Export @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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. +*/ // The following symbol has a underscore suffix for compatibility. #ifndef OSGPRODUCER_EXPORT_ diff --git a/include/osgProducer/KeyboardMouseCallback b/include/osgProducer/KeyboardMouseCallback index f06e5d200..0d2653076 100644 --- a/include/osgProducer/KeyboardMouseCallback +++ b/include/osgProducer/KeyboardMouseCallback @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGPRODUCER_EVENTCALLBACK #define OSGPRODUCER_EVENTCALLBACK 1 diff --git a/include/osgProducer/ReadCameraConfigFile b/include/osgProducer/ReadCameraConfigFile index 16c5db3de..e2751a973 100644 --- a/include/osgProducer/ReadCameraConfigFile +++ b/include/osgProducer/ReadCameraConfigFile @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGDB_READCAMERACONDIGFILE #define OSGDB_READCAMERACONDIGFILE 1 diff --git a/include/osgProducer/SceneHandler b/include/osgProducer/SceneHandler index 1b12a2ba4..cdc9716cd 100644 --- a/include/osgProducer/SceneHandler +++ b/include/osgProducer/SceneHandler @@ -1,6 +1,16 @@ -//C++ header - Open Producer - Copyright (C) 2002 Don Burns -//Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGPRODUCER_SCENEHANDLER #define OSGPRODUCER_SCENEHANDLER 1 diff --git a/include/osgProducer/Version b/include/osgProducer/Version index 740600ff7..5608ec1b6 100644 --- a/include/osgProducer/Version +++ b/include/osgProducer/Version @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGPRODUCER_VERSION #define OSGPRODUCER_VERSION 1 diff --git a/include/osgProducer/Viewer b/include/osgProducer/Viewer new file mode 100644 index 000000000..94f66972c --- /dev/null +++ b/include/osgProducer/Viewer @@ -0,0 +1,103 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSG_VIEWER_H +#define OSG_VIEWER_H + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +namespace osgProducer { + +class OSGPRODUCER_EXPORT Viewer : public CameraGroup, public osgGA::GUIActionAdapter +{ + public : + + Viewer(); + + Viewer(Producer::CameraConfig *cfg); + + Viewer(const std::string& configFile); + + Viewer(int& argc, char** argv); + + virtual ~Viewer() {} + + + bool readCommandLine(int& argc, char** argv); + + + enum ViewerOptions + { + TRACKBALL_MANIPULATOR = 1, + DRIVE_MANIPULATOR = 2, + FLIGHT_MANIPULATOR = 4, + STATE_MANIPULATOR = 8, + HEAD_LIGHT_SOURCE = 16, + SKY_LIGHT_SOURCE = 32, + STANDARD_SETTINGS = TRACKBALL_MANIPULATOR| + DRIVE_MANIPULATOR | + FLIGHT_MANIPULATOR | + STATE_MANIPULATOR | + HEAD_LIGHT_SOURCE + }; + + void setUpViewer(ViewerOptions options=STANDARD_SETTINGS); + + bool done() const { return _done; } + + virtual void sync(); + + virtual void update(); + + typedef std::list< osg::ref_ptr > EventHandlerList; + + EventHandlerList& getEventHandlerList() { return _eventHandlerList; } + + virtual void realize( ThreadingModel thread_model= SingleThreaded ); + + virtual void requestRedraw() {} + virtual void requestContinuousUpdate(bool) {} + virtual void requestWarpPointer(int x,int y); + + protected : + + + bool _done; + + unsigned int _frameNumber; + osg::Timer _timer; + osg::Timer_t _start_tick; + + osgProducer::KeyboardMouseCallback* _kbmcb; + + EventHandlerList _eventHandlerList; + osg::ref_ptr _keyswitchManipulator; + + osg::ref_ptr _old_style_osg_camera; + + osg::ref_ptr _updateVisitor; +}; + +} + +#endif diff --git a/include/osgProducer/WriteCameraConfigFile b/include/osgProducer/WriteCameraConfigFile index e53a1a4bb..36da8af5d 100644 --- a/include/osgProducer/WriteCameraConfigFile +++ b/include/osgProducer/WriteCameraConfigFile @@ -1,6 +1,15 @@ -//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield -//Distributed under the terms of the GNU Library General Public License (LGPL) -//as published by the Free Software Foundation. +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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 OSGDB_WRITECAMERACONDIGFILE #define OSGDB_WRITECAMERACONDIGFILE 1 diff --git a/src/Demos/osgproducer/osgproducer.cpp b/src/Demos/osgproducer/osgproducer.cpp index 88bba2f15..ffd605dd8 100644 --- a/src/Demos/osgproducer/osgproducer.cpp +++ b/src/Demos/osgproducer/osgproducer.cpp @@ -1,48 +1,16 @@ -#include //C++ source file - Open Producer - Copyright (C) 2002 Don Burns //Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL) //as published by the Free Software Foundation. -// Simple example of use of Producer::RenderSurface -// The myGraphics class is a simple sample of how one would implement -// graphics drawing with Producer::RenderSurface - -#include -#include -#include -#include - -#include - #include -#include - #include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - +#include int main( int argc, char **argv ) { - // threading model. - Producer::CameraGroup::ThreadingModel threadingModel = Producer::CameraGroup::SingleThreaded; - threadingModel = Producer::CameraGroup::ThreadPerCamera; - - // configuration file. - std::string configFile; - //configFile = "twoWindows.cfg"; + // create the camera group. + osgProducer::Viewer viewer(argc,argv); // set up the database files to read. std::vector filenameList; @@ -50,169 +18,39 @@ int main( int argc, char **argv ) else filenameList.push_back("cow.osg"); - - // create the camera group. - osgProducer::CameraGroup *cg = configFile.empty() ? - (new osgProducer::CameraGroup()): - (new osgProducer::CameraGroup(configFile)); - - // set up the maximum number of graphics contexts, before loading the scene graph - // to ensure that texture objects and display buffers are configured to the correct size. - osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( cg->getNumberOfCameras() ); - - // read the scene. osg::ref_ptr loadedModel = osgDB::readNodeFiles(filenameList); if (!loadedModel) return 1; + // optimize it, remove rendundent nodes and state etc. osgUtil::Optimizer optimizer; optimizer.optimize(loadedModel.get()); - // set up the keyboard and mouse handling. - Producer::InputArea *ia = cg->getCameraConfig()->getInputArea(); - Producer::KeyboardMouse *kbm = ia ? - (new Producer::KeyboardMouse(ia)) : - (new Producer::KeyboardMouse(cg->getCamera(0)->getRenderSurface())); + // set up the value with sensible defaults. + viewer.setUpViewer(); - // set up the time and frame counter. - unsigned int frameNumber = 0; - osg::Timer timer; - osg::Timer_t start_tick = timer.tick(); - - // set the keyboard mouse callback to catch the events from the windows. - bool done = false; - osgProducer::KeyboardMouseCallback kbmcb(done); - kbmcb.setStartTick(start_tick); - - // register the callback with the keyboard mouse manger. - kbm->setCallback( &kbmcb ); - //kbm->allowContinuousMouseMotionUpdate(true); - kbm->startThread(); - - - - // set the globa state - osg::ref_ptr globalStateSet = new osg::StateSet; - globalStateSet->setGlobalDefaults(); - cg->setGlobalStateSet(globalStateSet.get()); - - - // add either a headlight or sun light to the scene. - osg::LightSource* lightsource = new osg::LightSource; - osg::Light* light = new osg::Light; - lightsource->setLight(light); - lightsource->setReferenceFrame(osg::LightSource::RELATIVE_TO_ABSOLUTE); // headlight. - lightsource->setLocalStateSetModes(osg::StateAttribute::ON); - - lightsource->addChild(loadedModel.get()); - - // set the scene to render -// cg->setSceneData(scene.get()); - cg->setSceneData(lightsource); + viewer.setSceneData(loadedModel.get()); // set up the pthread stack size to large enough to run into problems. - cg->setStackSize( 20*1024*1024); + viewer.setStackSize( 20*1024*1024); // create the windows and run the threads. - cg->realize(threadingModel); + viewer.realize(Producer::CameraGroup::ThreadPerCamera); - osg::ref_ptr frameStamp = cg->getFrameStamp(); - - osgUtil::UpdateVisitor update; - update.setFrameStamp(frameStamp.get()); - - - - // create a camera to use with the manipulators. - osg::ref_ptr old_style_osg_camera = new osg::Camera; - - osg::ref_ptr keyswitchManipulator = new osgGA::KeySwitchCameraManipulator; - keyswitchManipulator->addNumberedCameraManipulator(new osgGA::TrackballManipulator); - keyswitchManipulator->addNumberedCameraManipulator(new osgGA::FlightManipulator); - keyswitchManipulator->addNumberedCameraManipulator(new osgGA::DriveManipulator); - - keyswitchManipulator->setCamera(old_style_osg_camera.get()); - keyswitchManipulator->setNode(loadedModel.get()); - - - osg::ref_ptr statesetManipulator = new osgGA::StateSetManipulator; - statesetManipulator->setStateSet(globalStateSet.get()); - - // create an event handler list, we'll dispatch our event to these.. - typedef std::list< osg::ref_ptr > EventHandlerList; - EventHandlerList eventHandlerList; - eventHandlerList.push_back(keyswitchManipulator.get()); - eventHandlerList.push_back(statesetManipulator.get()); - - // create a dummy action adapter right now. - osgProducer::ActionAdapter actionAdapter; - - osg::ref_ptr init_event = new osgProducer::EventAdapter; - init_event->adaptFrame(0.0); - keyswitchManipulator->getCurrentCameraManipulator()->home(*init_event,actionAdapter); - - double previous_time_since_start = 0.0f; - int number_frames_since_last_print = 0; - int number_of_frame_samples = 10; - bool printOutFrameStats=true; - while( !done ) + while( !viewer.done() ) { - // syncronize to screen refresh. - cg->sync(); - - // set the frame stamp for the new frame. - double time_since_start = timer.delta_s(start_tick,timer.tick()); - frameStamp->setFrameNumber(frameNumber); - frameStamp->setReferenceTime(time_since_start); - - if (printOutFrameStats) - { - if (number_frames_since_last_print==number_of_frame_samples) - { - cout << "frame rate = "<< (double)number_of_frame_samples/(time_since_start-previous_time_since_start)< frame_event = new osgProducer::EventAdapter; - frame_event->adaptFrame(frameStamp->getReferenceTime()); - queue.push_back(frame_event); - - // dispatch the events in order of arrival. - for(osgProducer::KeyboardMouseCallback::EventQueue::iterator event_itr=queue.begin(); - event_itr!=queue.end(); - ++event_itr) - { - bool handled = false; - for(EventHandlerList::iterator handler_itr=eventHandlerList.begin(); - handler_itr!=eventHandlerList.end() && !handled; - ++handler_itr) - { - handled = (*handler_itr)->handle(*(*event_itr),actionAdapter); - } - } + // wait for all cull and draw threads to complete. + viewer.sync(); // update the scene by traversing it with the the update visitor which will // call all node update callbacks and animations. - cg->getSceneData()->accept(update); - - - // update the main producer camera - cg->setView(old_style_osg_camera->getModelViewMatrix().ptr()); + viewer.update(); // fire off the cull and draw traversals of the scene. - cg->frame(); + viewer.frame(); - // increment the frame number ready for the next frame - ++frameNumber; } return 0; } diff --git a/src/osgProducer/CameraGroup.cpp b/src/osgProducer/CameraGroup.cpp index 0aa5d85c6..98d8949fb 100644 --- a/src/osgProducer/CameraGroup.cpp +++ b/src/osgProducer/CameraGroup.cpp @@ -27,81 +27,110 @@ void CameraGroup::_init() _scene_data = NULL; _global_stateset = NULL; _background_color.set( 0.2f, 0.2f, 0.4f, 1.0f ); + _LODScale = 1.0f; + + _fusionDistanceMode = osgUtil::SceneView::USE_CAMERA_FUSION_DISTANCE; + _fusionDistanceValue = 1.0f; + _initialized = false; + if (!_frameStamp) _frameStamp = new osg::FrameStamp; + + // set up the maximum number of graphics contexts, before loading the scene graph + // to ensure that texture objects and display buffers are configured to the correct size. + osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( getNumberOfCameras() ); + } void CameraGroup::setSceneData( osg::Node *scene ) { - _scene_data = scene; - if( _shvec.size() > 0 ) + if (_scene_data==scene) return; + + if (_scene_decorator.valid() && _scene_data.valid()) { - SceneHandlerList::iterator p; - for( p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setSceneData( _scene_data.get() ); - } + _scene_decorator->removeChild(_scene_data.get()); } + + _scene_data = scene; + + if (_scene_decorator.valid() && _scene_data.valid()) + { + _scene_decorator->addChild(scene); + } + + setUpSceneViewsWithData(); } +void CameraGroup::setSceneDecorator( osg::Group* decorator) +{ + if (_scene_decorator==decorator) return; + + _scene_decorator = decorator; + + if (_scene_data.valid() && decorator) + { + decorator->addChild(_scene_data.get()); + } + setUpSceneViewsWithData(); +} + +void CameraGroup::setUpSceneViewsWithData() +{ + for(SceneHandlerList::iterator p = _shvec.begin(); p != _shvec.end(); p++ ) + { + if (_scene_decorator.valid()) + { + (*p)->setSceneData( _scene_decorator.get() ); + } + else if (_scene_data.valid()) + { + (*p)->setSceneData( _scene_data.get() ); + + } + + (*p)->setFrameStamp( _frameStamp.get() ); + (*p)->setGlobalStateSet( _global_stateset.get() ); + (*p)->setBackgroundColor( _background_color ); + (*p)->setLODScale( _LODScale ); + (*p)->setFusionDistance( _fusionDistanceMode, _fusionDistanceValue ); + + } +} + + void CameraGroup::setFrameStamp( osg::FrameStamp* fs ) { _frameStamp = fs; - - for(SceneHandlerList::iterator p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setFrameStamp( fs ); - } + setUpSceneViewsWithData(); } void CameraGroup::setGlobalStateSet( osg::StateSet *sset ) { _global_stateset = sset; - - for(SceneHandlerList::iterator p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setGlobalStateSet( _global_stateset.get() ); - } + setUpSceneViewsWithData(); } void CameraGroup::setBackgroundColor( const osg::Vec4& backgroundColor ) { _background_color = backgroundColor; - - if( _shvec.size() > 0 ) - { - SceneHandlerList::iterator p; - for( p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setBackgroundColor( _background_color ); - } - } + setUpSceneViewsWithData(); } -void CameraGroup::setLODScale( float bias ) +void CameraGroup::setLODScale( float scale ) { - if( _shvec.size() > 0 ) - { - SceneHandlerList::iterator p; - for( p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setLODScale( bias ); - } - } + // need to set a local variable? + _LODScale = scale; + setUpSceneViewsWithData(); } -void CameraGroup::setFusionDistance( osgUtil::SceneView::FusionDistanceMode mode,float value=1.0f) +void CameraGroup::setFusionDistance( osgUtil::SceneView::FusionDistanceMode mode,float value) { - if( _shvec.size() > 0 ) - { - SceneHandlerList::iterator p; - for( p = _shvec.begin(); p != _shvec.end(); p++ ) - { - (*p)->setFusionDistance( mode, value ); - } - } + // need to set a local variable? + _fusionDistanceMode = mode; + _fusionDistanceValue = value; + setUpSceneViewsWithData(); } void CameraGroup::advance() @@ -114,6 +143,7 @@ void CameraGroup::realize( ThreadingModel thread_model= SingleThreaded ) { if( _initialized ) return; + if (!_ds) _ds = osg::DisplaySettings::instance(); _ds->setMaxNumberOfGraphicsContexts( _cfg->getNumberOfCameras() ); @@ -136,6 +166,8 @@ void CameraGroup::realize( ThreadingModel thread_model= SingleThreaded ) } + setUpSceneViewsWithData(); + /// Make all statesets the same as the first. if( _global_stateset == NULL && _shvec.size() > 0 ) { @@ -147,6 +179,7 @@ void CameraGroup::realize( ThreadingModel thread_model= SingleThreaded ) (*p)->setGlobalStateSet( _global_stateset.get() ); } + Producer::CameraGroup::realize( thread_model ); _initialized = true; } diff --git a/src/osgProducer/Makefile b/src/osgProducer/Makefile index 330b99f8a..883f5cca3 100644 --- a/src/osgProducer/Makefile +++ b/src/osgProducer/Makefile @@ -8,6 +8,7 @@ CXXFILES =\ SceneHandler.cpp\ ReadCameraConfigFile.cpp\ WriteCameraConfigFile.cpp\ + Viewer.cpp\ LIBS += -lProducer $(GL_LIBS) -losgGA -losgUtil -losgDB -losg $(OTHER_LIBS) DEF += -DOSGPRODUCER_LIBRARY diff --git a/src/osgProducer/Viewer.cpp b/src/osgProducer/Viewer.cpp new file mode 100644 index 000000000..7ddbc340b --- /dev/null +++ b/src/osgProducer/Viewer.cpp @@ -0,0 +1,204 @@ +#include + +#include + +#include + +#include +#include +#include +#include + +using namespace osgProducer; + +Viewer::Viewer(): + _done(0), + _frameNumber(0), + _kbmcb(0) +{ +} + +Viewer::Viewer(Producer::CameraConfig *cfg): + CameraGroup(cfg), + _done(0), + _frameNumber(0), + _kbmcb(0) +{ + _done = false; +} + +Viewer::Viewer(const std::string& configFile): + CameraGroup(configFile), + _done(0), + _frameNumber(0), + _kbmcb(0) +{ + _done = false; +} + +Viewer::Viewer(int& argc, char** argv): + _done(0), + _frameNumber(0), + _kbmcb(0) +{ + _done = false; + + readCommandLine(argc,argv); + // set up the maximum number of graphics contexts, before loading the scene graph + // to ensure that texture objects and display buffers are configured to the correct size. + osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( getNumberOfCameras() ); +} + + +bool Viewer::readCommandLine(int&, char**) +{ + return false; +} + +void Viewer::setUpViewer(Viewer::ViewerOptions options) +{ + + // set up the keyboard and mouse handling. + Producer::InputArea *ia = getCameraConfig()->getInputArea(); + Producer::KeyboardMouse *kbm = ia ? + (new Producer::KeyboardMouse(ia)) : + (new Producer::KeyboardMouse(getCamera(0)->getRenderSurface())); + + // set up the time and frame counter. + _frameNumber = 0; + _start_tick = _timer.tick(); + + // set the keyboard mouse callback to catch the events from the windows. + _kbmcb = new osgProducer::KeyboardMouseCallback(_done); + _kbmcb->setStartTick(_start_tick); + + // register the callback with the keyboard mouse manger. + kbm->setCallback( _kbmcb ); + //kbm->allowContinuousMouseMotionUpdate(true); + kbm->startThread(); + + + + // set the globa state + + osg::ref_ptr globalStateSet = new osg::StateSet; + setGlobalStateSet(globalStateSet.get()); + { + globalStateSet->setGlobalDefaults(); + // enable depth testing by default. + globalStateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); + + // set up an alphafunc by default to speed up blending operations. + osg::AlphaFunc* alphafunc = new osg::AlphaFunc; + alphafunc->setFunction(osg::AlphaFunc::GREATER,0.0f); + globalStateSet->setAttributeAndModes(alphafunc, osg::StateAttribute::ON); + } + + + // add either a headlight or sun light to the scene. + osg::LightSource* lightsource = new osg::LightSource; + setSceneDecorator(lightsource); + { + osg::Light* light = new osg::Light; + lightsource->setLight(light); + lightsource->setReferenceFrame(osg::LightSource::RELATIVE_TO_ABSOLUTE); // headlight. + lightsource->setLocalStateSetModes(osg::StateAttribute::ON); + } + + + + _updateVisitor = new osgUtil::UpdateVisitor; + _updateVisitor->setFrameStamp(_frameStamp.get()); + + // create a camera to use with the manipulators. + _old_style_osg_camera = new osg::Camera; + + if (options&(TRACKBALL_MANIPULATOR|FLIGHT_MANIPULATOR|DRIVE_MANIPULATOR)) + { + + _keyswitchManipulator = new osgGA::KeySwitchCameraManipulator; + if (options&TRACKBALL_MANIPULATOR) _keyswitchManipulator->addNumberedCameraManipulator(new osgGA::TrackballManipulator); + if (options&FLIGHT_MANIPULATOR) _keyswitchManipulator->addNumberedCameraManipulator(new osgGA::FlightManipulator); + if (options&DRIVE_MANIPULATOR) _keyswitchManipulator->addNumberedCameraManipulator(new osgGA::DriveManipulator); + + _keyswitchManipulator->setCamera(_old_style_osg_camera.get()); + _keyswitchManipulator->setNode(getSceneDecorator()); + + _eventHandlerList.push_back(_keyswitchManipulator.get()); + + osg::ref_ptr init_event = new osgProducer::EventAdapter; + init_event->adaptFrame(0.0); + _keyswitchManipulator->getCurrentCameraManipulator()->home(*init_event,*this); + + } + + if (options&STATE_MANIPULATOR) + { + osg::ref_ptr statesetManipulator = new osgGA::StateSetManipulator; + statesetManipulator->setStateSet(getGlobalStateSet()); + _eventHandlerList.push_back(statesetManipulator.get()); + } + +} + +void Viewer::realize( ThreadingModel thread_model) +{ + if (_keyswitchManipulator.valid()) + { + osg::ref_ptr init_event = new osgProducer::EventAdapter; + init_event->adaptFrame(0.0); + _keyswitchManipulator->getCurrentCameraManipulator()->home(*init_event,*this); + } + + CameraGroup::realize( thread_model ); + + +} + +void Viewer::sync() +{ + CameraGroup::sync(); + + // set the frame stamp for the new frame. + double time_since_start = _timer.delta_s(_start_tick,_timer.tick()); + _frameStamp->setFrameNumber(_frameNumber++); + _frameStamp->setReferenceTime(time_since_start); +} + +void Viewer::update() +{ + // get the event since the last frame. + osgProducer::KeyboardMouseCallback::EventQueue queue; + if (_kbmcb) _kbmcb->getEventQueue(queue); + + // create an event to signal the new frame. + osg::ref_ptr frame_event = new osgProducer::EventAdapter; + frame_event->adaptFrame(_frameStamp->getReferenceTime()); + queue.push_back(frame_event); + + // dispatch the events in order of arrival. + for(osgProducer::KeyboardMouseCallback::EventQueue::iterator event_itr=queue.begin(); + event_itr!=queue.end(); + ++event_itr) + { + bool handled = false; + for(EventHandlerList::iterator handler_itr=_eventHandlerList.begin(); + handler_itr!=_eventHandlerList.end() && !handled; + ++handler_itr) + { + handled = (*handler_itr)->handle(*(*event_itr),*this); + } + } + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + getSceneData()->accept(*_updateVisitor); + + // update the main producer camera + if (_old_style_osg_camera.valid()) setView(_old_style_osg_camera->getModelViewMatrix().ptr()); +} + +void Viewer::requestWarpPointer(int x,int y) +{ + osg::notify(osg::WARN) << "Warning: requestWarpPointer("<