dnl Check for SDL if enabled.
AC_ARG_ENABLE(sdl, [ --enable-sdl Configure to use SDL instead of GLUT], [enable_sdl="$enableval"])
+AC_ARG_ENABLE(osgviewer, [ --enable-osgviewer Configure to use osgViewer], [enable_osgviewer="$enableval"])
AM_CONDITIONAL(USE_SDL, test "x$enable_sdl" = "xyes")
+AM_CONDITIONAL(USE_OSGVIEWER, test "x$enable_osgviewer" = "xyes")
if test "x$enable_sdl" = "xyes"; then
AC_DEFINE([PU_USE_SDL], 1, [Define to use SDL])
else
- AC_DEFINE([PU_USE_GLUT], 1, [Define to use glut])
+ if test "x$enable_osgviewer" = "xyes"; then
+ AC_DEFINE([ENABLE_OSGVIEWER], 1, [Define to use osgViewer in renderer])
+ AC_DEFINE([PU_USE_NATIVE], 1, [Define to use native system])
+ else
+ AC_DEFINE([PU_USE_GLUT], 1, [Define to use glut])
+ fi
fi
dnl check for OpenGL related libraries
--- /dev/null
+#include <osg/Math>
+
+#include <osgViewer/Viewer>
+
+#include <plib/pu.h>
+#include "FGManipulator.hxx"
+
+// The manipulator is responsible for updating a Viewer's camera. It's
+// event handling method is also a convenient place to run the the FG
+// idle and draw handlers.
+
+void FGManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+ // Yuck
+ position = matrix.getTrans();
+ attitude = matrix.getRotate();
+}
+
+osg::Matrixd FGManipulator::getMatrix() const
+{
+ return osg::Matrixd::rotate(attitude) * osg::Matrixd::translate(position);
+}
+
+osg::Matrixd FGManipulator::getInverseMatrix() const
+{
+ return (osg::Matrixd::translate(-position)
+ * osg::Matrixd::rotate(attitude.inverse())) ;
+}
+
+// Not used, but part of the interface.
+void FGManipulator::setNode(osg::Node* node)
+{
+ _node = node;
+}
+
+const osg::Node* FGManipulator::getNode() const
+{
+ return _node.get();
+}
+
+osg::Node* FGManipulator::getNode()
+{
+ return _node.get();
+}
+
+namespace {
+// All the usual translation from window system to FG / plib
+int osgToFGModifiers(int modifiers)
+{
+ int result = 0;
+ if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT |
+ osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT))
+ result |= KEYMOD_SHIFT;
+ if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL |
+ osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL))
+ result |= KEYMOD_CTRL;
+ if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_ALT |
+ osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT))
+ result |= KEYMOD_ALT;
+ return result;
+}
+} // namespace
+
+void FGManipulator::init(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us)
+{
+ currentModifiers = osgToFGModifiers(ea.getModKeyMask());
+ (void)handle(ea, us);
+}
+
+namespace {
+void eventToViewport(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us,
+ int& x, int& y)
+{
+ osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&us);
+ osg::Viewport* viewport = viewer->getCamera()->getViewport();
+ const osg::GraphicsContext::Traits* traits
+ = viewer->getCamera()->getGraphicsContext()->getTraits();
+ x = (int)ea.getX();
+ y = (int)ea.getY();
+ if (ea.getMouseYOrientation()
+ == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
+ y = (int)traits->height - y;
+}
+}
+
+bool FGManipulator::handle(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us)
+{
+ int x, y;
+ switch (ea.getEventType()) {
+ case osgGA::GUIEventAdapter::FRAME:
+ if (idleHandler)
+ (*idleHandler)();
+ if (drawHandler)
+ (*drawHandler)();
+ return true;
+ case osgGA::GUIEventAdapter::KEYDOWN:
+ case osgGA::GUIEventAdapter::KEYUP:
+ {
+ int key, modmask;
+ handleKey(ea, key, modmask);
+ eventToViewport(ea, us, x, y);
+ if (keyHandler)
+ (*keyHandler)(key, modmask, x, y);
+ }
+ return true;
+ case osgGA::GUIEventAdapter::PUSH:
+ case osgGA::GUIEventAdapter::RELEASE:
+ {
+ eventToViewport(ea, us, x, y);
+ int button = 0;
+ switch (ea.getButton()) {
+ case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
+ button = 0;
+ break;
+ case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
+ button = 1;
+ break;
+ case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
+ button = 2;
+ break;
+ }
+ if (mouseClickHandler)
+ (*mouseClickHandler)(button,
+ (ea.getEventType()
+ == osgGA::GUIEventAdapter::RELEASE), x, y);
+ return true;
+ }
+ case osgGA::GUIEventAdapter::MOVE:
+ case osgGA::GUIEventAdapter::DRAG:
+ eventToViewport(ea, us, x, y);
+ if (mouseMotionHandler)
+ (*mouseMotionHandler)(x, y);
+ return true;
+ case osgGA::GUIEventAdapter::RESIZE:
+ if (windowResizeHandler)
+ (*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
+ return true;
+ default:
+ return false;
+ }
+}
+
+void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
+ int& modifiers)
+{
+ key = ea.getKey();
+ // XXX Probably other translations are needed too.
+ switch (key) {
+ case osgGA::GUIEventAdapter::KEY_Escape: key = 0x1b; break;
+ case osgGA::GUIEventAdapter::KEY_Return: key = '\n'; break;
+ case osgGA::GUIEventAdapter::KEY_Left: key = PU_KEY_LEFT; break;
+ case osgGA::GUIEventAdapter::KEY_Up: key = PU_KEY_UP; break;
+ case osgGA::GUIEventAdapter::KEY_Right: key = PU_KEY_RIGHT; break;
+ case osgGA::GUIEventAdapter::KEY_Down: key = PU_KEY_DOWN; break;
+ case osgGA::GUIEventAdapter::KEY_Page_Up: key = PU_KEY_PAGE_UP; break;
+ case osgGA::GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
+ case osgGA::GUIEventAdapter::KEY_Home: key = PU_KEY_HOME; break;
+ case osgGA::GUIEventAdapter::KEY_End: key = PU_KEY_END; break;
+ case osgGA::GUIEventAdapter::KEY_Insert: key = PU_KEY_INSERT; break;
+ case osgGA::GUIEventAdapter::KEY_F1: key = PU_KEY_F1; break;
+ case osgGA::GUIEventAdapter::KEY_F2: key = PU_KEY_F2; break;
+ case osgGA::GUIEventAdapter::KEY_F3: key = PU_KEY_F3; break;
+ case osgGA::GUIEventAdapter::KEY_F4: key = PU_KEY_F4; break;
+ case osgGA::GUIEventAdapter::KEY_F5: key = PU_KEY_F5; break;
+ case osgGA::GUIEventAdapter::KEY_F6: key = PU_KEY_F6; break;
+ case osgGA::GUIEventAdapter::KEY_F7: key = PU_KEY_F7; break;
+ case osgGA::GUIEventAdapter::KEY_F8: key = PU_KEY_F8; break;
+ case osgGA::GUIEventAdapter::KEY_F9: key = PU_KEY_F9; break;
+ case osgGA::GUIEventAdapter::KEY_F10: key = PU_KEY_F10; break;
+ case osgGA::GUIEventAdapter::KEY_F11: key = PU_KEY_F11; break;
+ case osgGA::GUIEventAdapter::KEY_F12: key = PU_KEY_F12; break;
+ }
+ modifiers = osgToFGModifiers(ea.getModKeyMask());
+ currentModifiers = modifiers;
+ if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
+ modifiers |= KEYMOD_RELEASED;
+}
+
--- /dev/null
+#ifndef FGMANIPULATOR_H
+#define FGMANIPULATOR_H 1
+
+#include <osg/Quat>
+#include <osgGA/MatrixManipulator>
+
+#include "fg_os.hxx"
+
+class FGManipulator : public osgGA::MatrixManipulator {
+public:
+ FGManipulator() :
+ idleHandler(0), drawHandler(0), windowResizeHandler(0), keyHandler(0),
+ mouseClickHandler(0), mouseMotionHandler(0), currentModifiers(0)
+ {}
+ virtual ~FGManipulator() {}
+
+ virtual const char* className() const {return "FGManipulator"; }
+
+ /** set the position of the matrix manipulator using a 4x4 Matrix.*/
+ virtual void setByMatrix(const osg::Matrixd& matrix);
+
+ virtual void setByInverseMatrix(const osg::Matrixd& matrix)
+ { setByMatrix(osg::Matrixd::inverse(matrix)); }
+
+ /** get the position of the manipulator as 4x4 Matrix.*/
+ virtual osg::Matrixd getMatrix() const;
+
+ /** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
+ virtual osg::Matrixd getInverseMatrix() const;
+
+ virtual void setNode(osg::Node* node);
+
+ const osg::Node* getNode() const;
+
+ osg::Node* getNode();
+
+ virtual void init(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us);
+
+ virtual bool handle(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us);
+
+ void setIdleHandler(fgIdleHandler idleHandler)
+ {
+ this->idleHandler = idleHandler;
+ }
+
+ fgIdleHandler getIdleHandler() const
+ {
+ return idleHandler;
+ }
+
+ void setDrawHandler(fgDrawHandler drawHandler)
+ {
+ this->drawHandler = drawHandler;
+ }
+
+ fgDrawHandler getDrawHandler() const
+ {
+ return drawHandler;
+ }
+
+ void setWindowResizeHandler(fgWindowResizeHandler windowResizeHandler)
+ {
+ this->windowResizeHandler = windowResizeHandler;
+ }
+
+ fgWindowResizeHandler getWindowResizeHandler() const
+ {
+ return windowResizeHandler;
+ }
+
+ void setKeyHandler(fgKeyHandler keyHandler)
+ {
+ this->keyHandler = keyHandler;
+ }
+
+ fgKeyHandler getKeyHandler() const
+ {
+ return keyHandler;
+ }
+
+ void setMouseClickHandler(fgMouseClickHandler mouseClickHandler)
+ {
+ this->mouseClickHandler = mouseClickHandler;
+ }
+
+ fgMouseClickHandler getMouseClickHandler()
+ {
+ return mouseClickHandler;
+ }
+
+ void setMouseMotionHandler(fgMouseMotionHandler mouseMotionHandler)
+ {
+ this->mouseMotionHandler = mouseMotionHandler;
+ }
+
+ fgMouseMotionHandler getMouseMotionHandler()
+ {
+ return mouseMotionHandler;
+ }
+
+ int getCurrentModifiers() const
+ {
+ return currentModifiers;
+ }
+ void setPosition(const osg::Vec3d position) { this->position = position; }
+ void setAttitude(const osg::Quat attitude) { this->attitude = attitude; }
+
+protected:
+ osg::ref_ptr<osg::Node> _node;
+ fgIdleHandler idleHandler;
+ fgDrawHandler drawHandler;
+ fgWindowResizeHandler windowResizeHandler;
+ fgKeyHandler keyHandler;
+ fgMouseClickHandler mouseClickHandler;
+ fgMouseMotionHandler mouseMotionHandler;
+ int currentModifiers;
+ osg::Vec3d position;
+ osg::Quat attitude;
+ void handleKey(const osgGA::GUIEventAdapter& ea, int& key, int& modifiers);
+
+};
+#endif
EXTRA_DIST = 3dfx.sh runfgfs.in runfgfs.bat.in \
- fg_os_sdl.cxx fg_os.cxx fg_os.hxx
+ fg_os_sdl.cxx fg_os.cxx fg_os_osgviewer.cxx fg_os.hxx
MPLAYER_LIBS = $(top_builddir)/src/MultiPlayer/libMultiPlayer.a
if USE_SDL
GFX_CODE = fg_os_sdl.cxx fg_os.hxx
else
+if USE_OSGVIEWER
+GFX_CODE = fg_os_osgviewer.cxx fg_os.hxx
+else
GFX_CODE = fg_os.cxx fg_os.hxx
endif
+endif
JSBSIM_LIBS = \
$(top_builddir)/src/FDM/JSBSim/libJSBSim.a \
util.cxx util.hxx \
viewer.cxx viewer.hxx \
viewmgr.cxx viewmgr.hxx \
+ FGManipulator.cxx FGManipulator.hxx \
$(GFX_CODE)
fgfs_SOURCES = bootstrap.cxx
-lsgstructure -lsgenvironment \
-lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet \
-lplibsg -lplibul \
- -losgUtil -losgDB -losgSim -losg -lOpenThreads \
+ -losgViewer -losgFX -losgUtil -losgDB -losgSim -losg -lOpenThreads \
$(THREAD_LIBS) \
$(network_LIBS) \
-lz \
glutReshapeFunc(GLUTreshape);
}
+// Noop; the graphics context is always current
+void fgMakeCurrent()
+{
+}
void fgRegisterMouseClickHandler(fgMouseClickHandler func);
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func);
+void fgMakeCurrent();
#endif // _FG_OS_HXX
--- /dev/null
+#include <stdlib.h>
+
+#include <simgear/compiler.h>
+#include <simgear/structure/exception.hxx>
+#include <simgear/debug/logstream.hxx>
+
+#include <osg/GraphicsContext>
+#include <osg/Group>
+#include <osg/Matrixd>
+#include <osg/Viewport>
+#include <osgViewer/StatsHandler>
+#include <osgViewer/Viewer>
+#include <osgGA/MatrixManipulator>
+
+#include "fg_os.hxx"
+#include "util.hxx"
+#include "globals.hxx"
+#include "renderer.hxx"
+
+// fg_os implementation using OpenSceneGraph's osgViewer::Viewer class
+// to create the graphics window and run the event/update/render loop.
+//
+// fg_os callback registration APIs
+//
+
+
+// Event handling and scene graph update is all handled by a
+// manipulator. See FGManipulator.cpp
+void fgRegisterIdleHandler(fgIdleHandler func)
+{
+ globals->get_renderer()->getManipulator()->setIdleHandler(func);
+}
+
+void fgRegisterDrawHandler(fgDrawHandler func)
+{
+ globals->get_renderer()->getManipulator()->setDrawHandler(func);
+}
+
+void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
+{
+ globals->get_renderer()->getManipulator()->setWindowResizeHandler(func);
+}
+
+void fgRegisterKeyHandler(fgKeyHandler func)
+{
+ globals->get_renderer()->getManipulator()->setKeyHandler(func);
+}
+
+void fgRegisterMouseClickHandler(fgMouseClickHandler func)
+{
+ globals->get_renderer()->getManipulator()->setMouseClickHandler(func);
+}
+
+void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
+{
+ globals->get_renderer()->getManipulator()->setMouseMotionHandler(func);
+}
+
+// Redraw "happens" every frame whether you want it or not.
+void fgRequestRedraw()
+{
+}
+
+//
+// fg_os implementation
+//
+
+
+static osg::ref_ptr<osgViewer::Viewer> viewer;
+
+void fgOSOpenWindow(int w, int h, int bpp,
+ bool alpha, bool stencil, bool fullscreen)
+{
+ viewer = new osgViewer::Viewer;
+ // Avoid complications with fg's custom drawables.
+ viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
+ osg::ref_ptr<osg::GraphicsContext::Traits> traits
+ = new osg::GraphicsContext::Traits;
+ int cbits = (bpp <= 16) ? 5 : 8;
+ int zbits = (bpp <= 16) ? 16 : 24;
+ traits->width = w;
+ traits->height = h;
+ traits->red = traits->green = traits->blue = cbits;
+ traits->depth = zbits;
+ if (alpha)
+ traits->alpha = 8;
+ if (stencil)
+ traits->stencil = 8;
+ if (fullscreen)
+ traits->windowDecoration = false;
+ else
+ traits->windowDecoration = true;
+ traits->supportsResize = true;
+ traits->doubleBuffer = true;
+ osg::GraphicsContext* gc
+ = osg::GraphicsContext::createGraphicsContext(traits.get());
+ viewer->getCamera()->setGraphicsContext(gc);
+ // If a viewport isn't set on the camera, then it's hard to dig it
+ // out of the SceneView objects in the viewer, and the coordinates
+ // of mouse events are somewhat bizzare.
+ viewer->getCamera()->setViewport(new osg::Viewport(0, 0,
+ traits->width,
+ traits->height));
+ viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
+ // Let FG handle the escape key with a confirmation
+ viewer->setKeyEventSetsDone(0);
+ osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
+ statsHandler->setKeyEventTogglesOnScreenStats('*');
+ statsHandler->setKeyEventPrintsOutStats(0);
+ viewer->addEventHandler(statsHandler);
+ // The viewer won't start without some root.
+ viewer->setSceneData(new osg::Group);
+ globals->get_renderer()->setViewer(viewer.get());
+}
+
+static int status = 0;
+
+void fgOSExit(int code)
+{
+ viewer->setDone(true);
+ status = code;
+}
+
+void fgOSMainLoop()
+{
+ viewer->run();
+ fgExit(status);
+}
+
+int fgGetKeyModifiers()
+{
+ return globals->get_renderer()->getManipulator()->getCurrentModifiers();
+}
+
+void fgWarpMouse(int x, int y)
+{
+ viewer->requestWarpPointer((float)x, (float)y);
+}
+
+// Noop
+void fgOSInit(int* argc, char** argv)
+{
+}
+
+void fgOSFullScreen()
+{
+ // Noop, but is probably doable
+
+}
+
+// No support in OSG yet
+void fgSetMouseCursor(int cursor)
+{
+}
+
+int fgGetMouseCursor()
+{
+ return 0;
+}
+
+void fgMakeCurrent()
+{
+ osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
+ gc->makeCurrent();
+}
cursors[i].hoty);
}
}
+
+// Noop; the graphics context is always current
+void fgMakeCurrent()
+{
+}
// then on.
static void fgIdleFunction ( void ) {
+ // Some intialization requires a valid graphics context, in
+ // particular that of plib. Boo, hiss!
+ fgMakeCurrent();
if ( idle_state == 0 ) {
idle_state++;
#ifdef FG_JPEG_SERVER
jpgRenderFrame = FGRenderer::update;
#endif
+#ifdef ENABLE_OSGVIEWER
+ manipulator = new FGManipulator;
+#endif
}
FGRenderer::~FGRenderer()
}
// Initialize various GL/view parameters
+// XXX This should be called "preinit" or something, as it initializes
+// critical parts of the scene graph in addition to the splash screen.
void
FGRenderer::splashinit( void ) {
- // Add the splash screen node
- mRealRoot->addChild(fgCreateSplashNode());
- sceneView->setSceneData(mRealRoot.get());
-
- sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
- sceneView->setFrameStamp(mFrameStamp.get());
- sceneView->setUpdateVisitor(mUpdateVisitor.get());
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+ if (viewer) {
+ sceneView = 0;
+ mRealRoot = dynamic_cast<osg::Group*>(viewer->getSceneData());
+ mRealRoot->addChild(fgCreateSplashNode());
+ osgViewer::Scene* scene = viewer->getScene();
+ scene->setFrameStamp(mFrameStamp.get());
+ // Scene doesn't seem to pass the frame stamp to the update
+ // visitor automatically.
+ mUpdateVisitor->setFrameStamp(mFrameStamp.get());
+ scene->setUpdateVisitor(mUpdateVisitor.get());
+ } else {
+ // Add the splash screen node
+ mRealRoot->addChild(fgCreateSplashNode());
+ sceneView->setSceneData(mRealRoot.get());
+ sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
+ sceneView->setFrameStamp(mFrameStamp.get());
+ sceneView->setUpdateVisitor(mUpdateVisitor.get());
+ }
}
void
FGRenderer::init( void ) {
-
+ // The viewer can call this before the graphics context is current
+ // in the main thread; indeed, in a multithreaded setup it might
+ // never be current in the main thread.
+ fgMakeCurrent();
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
osg::initNotifyLevel();
// The number of polygon-offset "units" to place between layers. In
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
-
- sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
- sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+ if (viewer) {
+ viewer->getCamera()
+ ->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+ } else {
+ sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+ sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
+ }
osg::StateSet* stateSet = mRoot->getOrCreateStateSet();
mRealRoot->addChild(sw);
mRealRoot->addChild(FGCreateRedoutNode());
mRealRoot->addChild(guiCamera);
+// sceneView->getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
}
FGRenderer::update( bool refresh_camera_settings ) {
bool scenery_loaded = fgGetBool("sim/sceneryloaded")
|| fgGetBool("sim/sceneryloaded-override");
-
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
if ( idle_state < 1000 || !scenery_loaded ) {
fgSetDouble("/sim/startup/splash-alpha", 1.0);
globals->set_sim_time_sec( 0.0 );
// the splash screen is now in the scenegraph
- sceneView->update();
- sceneView->cull();
- sceneView->draw();
-
+ if (!viewer) {
+ sceneView->update();
+ sceneView->cull();
+ sceneView->draw();
+ }
return;
}
SGVec3d position = current__view->getViewPosition();
SGQuatd attitude = current__view->getViewOrientation();
SGVec3d osgPosition = attitude.transform(-position);
- mCameraView->setPosition(osgPosition.osg());
- mCameraView->setAttitude(inverse(attitude).osg());
+ if (viewer) {
+ FGManipulator *manipulator
+ = globals->get_renderer()->getManipulator();
+ manipulator->setPosition(position.osg());
+ manipulator->setAttitude(attitude.osg());
+ } else {
+ mCameraView->setPosition(osgPosition.osg());
+ mCameraView->setAttitude(inverse(attitude).osg());
+ }
}
-
+ osg::Camera *camera;
+ if (viewer)
+ camera = viewer->getCamera();
+ else
+ camera = sceneView->getCamera();
if ( skyblend ) {
+
if ( fgGetBool("/sim/rendering/textures") ) {
SGVec4f clearColor(l->adj_fog_color());
- sceneView->getCamera()->setClearColor(clearColor.osg());
+ camera->setClearColor(clearColor.osg());
}
} else {
SGVec4f clearColor(l->sky_color());
- sceneView->getCamera()->setClearColor(clearColor.osg());
+ camera->setClearColor(clearColor.osg());
}
// update fog params if visibility has changed
// shadows->endOfFrame();
// need to call the update visitor once
- mFrameStamp->setReferenceTime(globals->get_sim_time_sec());
- mFrameStamp->setFrameNumber(1+mFrameStamp->getFrameNumber());
+ if (!viewer) {
+ mFrameStamp->setReferenceTime(globals->get_sim_time_sec());
+ mFrameStamp->setFrameNumber(1+mFrameStamp->getFrameNumber());
+ }
mFrameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
mUpdateVisitor->setViewData(current__view->getViewPosition(),
current__view->getViewOrientation());
l->adj_fog_color(),
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
mUpdateVisitor->setVisibility(actual_visibility);
-
- if (fgGetBool("/sim/panel-hotspots"))
- sceneView->setCullMask(sceneView->getCullMask()|SG_NODEMASK_PICK_BIT);
- else
- sceneView->setCullMask(sceneView->getCullMask()&(~SG_NODEMASK_PICK_BIT));
-
- sceneView->update();
- sceneView->cull();
- sceneView->draw();
+ bool hotspots = fgGetBool("/sim/panel-hotspots");
+ if (viewer) {
+ if (hotspots)
+ camera->setCullMask(camera->getCullMask()|SG_NODEMASK_PICK_BIT);
+ else
+ camera->setCullMask(camera->getCullMask()
+ & ~SG_NODEMASK_PICK_BIT);
+ } else {
+ if (hotspots)
+ sceneView->setCullMask(sceneView->getCullMask()
+ |SG_NODEMASK_PICK_BIT);
+ else
+ sceneView->setCullMask(sceneView->getCullMask()
+ &(~SG_NODEMASK_PICK_BIT));
+ sceneView->update();
+ sceneView->cull();
+ sceneView->draw();
+ }
}
} else {
view_h = height;
}
-
- sceneView->getViewport()->setViewport(0, height - view_h, width, view_h);
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+ if (viewer)
+ viewer->getCamera()->getViewport()->setViewport(0, height - view_h,
+ width, view_h);
+ else
+ sceneView->getViewport()->setViewport(0, height - view_h,
+ width, view_h);
static int lastwidth = 0;
static int lastheight = 0;
= fgGetNode("/sim/current-view/frustum-bottom-pct");
static SGPropertyNode *top_pct
= fgGetNode("/sim/current-view/frustum-top-pct");
-
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
double left, right;
double bottom, top;
double zNear, zFar;
- sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar);
+ if (viewer)
+ viewer->getCamera()->getProjectionMatrixAsFrustum(left, right,
+ bottom, top,
+ zNear, zFar);
+ else
+ sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top,
+ zNear, zFar);
// cout << " l = " << f->getLeft()
// << " r = " << f->getRight()
// << " b = " << f->getBot()
} else {
t = top;
}
-
- sceneView->setProjectionMatrixAsFrustum(l, r, b, t, zNear, zFar);
+ if (viewer)
+ viewer->getCamera()->setProjectionMatrixAsFrustum(l, r, b, t,
+ zNear, zFar);
+ else
+ sceneView->setProjectionMatrixAsFrustum(l, r, b, t, zNear, zFar);
}
void FGRenderer::setFOV( float w, float h ) {
fov_width = w;
fov_height = h;
-
- sceneView->setProjectionMatrixAsPerspective(fov_height,
- fov_width/fov_height,
- fov_near, fov_far);
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+ if (viewer)
+ viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height,
+ fov_width/fov_height,
+ fov_near, fov_far);
+ else
+ sceneView->setProjectionMatrixAsPerspective(fov_height,
+ fov_width/fov_height,
+ fov_near, fov_far);
// fully specify the view frustum before hacking it (so we don't
// accumulate hacked effects
fgHackFrustum();
n = 0.1;
fov_near = n;
fov_far = f;
-
- sceneView->setProjectionMatrixAsPerspective(fov_height,
- fov_width/fov_height,
- fov_near, fov_far);
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+ if (viewer)
+ viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height,
+ fov_width/fov_height,
+ fov_near, fov_far);
+ else
+ sceneView->setProjectionMatrixAsPerspective(fov_height,
+ fov_width/fov_height,
+ fov_near, fov_far);
// fully specify the view frustum before hacking it (so we don't
// accumulate hacked effects
FGRenderer::pick( unsigned x, unsigned y,
std::vector<SGSceneryPick>& pickList )
{
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
// wipe out the return ...
pickList.resize(0);
- // we can get called early ...
- if (!sceneView.valid())
- return false;
-
osg::Node* sceneData = globals->get_scenery()->get_scene_graph();
if (!sceneData)
return false;
- osg::Viewport* viewport = sceneView->getViewport();
- if (!viewport)
+ osg::Viewport* viewport = 0;
+ osg::Matrix projection;
+ osg::Matrix modelview;
+
+ if (sceneView.valid()) {
+ viewport = sceneView->getViewport();
+ if (!viewport)
+ return false;
+ // don't know why, but the update has partly happened somehow,
+ // so update the scenery part of the viewer
+ FGViewer *current_view = globals->get_current_view();
+ // Force update of center dependent values ...
+ current_view->set_dirty();
+ SGVec3d position = current_view->getViewPosition();
+ SGQuatd attitude = current_view->getViewOrientation();
+ SGVec3d osgPosition = attitude.transform(-position);
+ mCameraView->setPosition(osgPosition.osg());
+ mCameraView->setAttitude(inverse(attitude).osg());
+
+ osg::Matrix projection(sceneView->getProjectionMatrix());
+ osg::Matrix modelview(sceneView->getViewMatrix());
+
+ osg::NodePathList nodePath = sceneData->getParentalNodePaths();
+ // modify the view matrix so that it accounts for this nodePath's
+ // accumulated transform
+ if (!nodePath.empty())
+ modelview.preMult(computeLocalToWorld(nodePath.front()));
+ } else if (viewer) {
+ // I don't think the Viewer case needs to update the camera
+ // matrices before picking. The user has clicked on the old scene
+ // -- that which is displayed in the front buffer -- so we need to
+ // use the camera state in effect for that view of the scene.
+ osg::Camera *camera = viewer->getCamera();
+ viewport = camera->getViewport();
+ projection = camera->getProjectionMatrix();
+ modelview = camera->getViewMatrix();
+ // Accumulated transforms? Don't think that applies for the
+ // Viewer's camera.
+ } else { // we can get called early ...
return false;
-
- // don't know why, but the update has partly happened somehow,
- // so update the scenery part of the viewer
- FGViewer *current_view = globals->get_current_view();
- // Force update of center dependent values ...
- current_view->set_dirty();
- SGVec3d position = current_view->getViewPosition();
- SGQuatd attitude = current_view->getViewOrientation();
- SGVec3d osgPosition = attitude.transform(-position);
- mCameraView->setPosition(osgPosition.osg());
- mCameraView->setAttitude(inverse(attitude).osg());
-
- osg::Matrix projection(sceneView->getProjectionMatrix());
- osg::Matrix modelview(sceneView->getViewMatrix());
-
- osg::NodePathList nodePath = sceneData->getParentalNodePaths();
- // modify the view matrix so that it accounts for this nodePath's
- // accumulated transform
- if (!nodePath.empty())
- modelview.preMult(computeLocalToWorld(nodePath.front()));
-
+ }
// swap the y values ...
y = viewport->height() - y;
// set up the pick visitor
#include <simgear/scene/sky/sky.hxx>
#include <simgear/scene/util/SGPickCallback.hxx>
+#include <osgViewer/Viewer>
+
+#include "FGManipulator.hxx"
+
#define FG_ENABLE_MULTIPASS_CLOUDS 1
class SGSky;
*/
static bool pick( unsigned x, unsigned y,
std::vector<SGSceneryPick>& pickList );
+
+ /** Get and set the OSG Viewer object, if any.
+ */
+ osgViewer::Viewer* getViewer() { return viewer.get(); }
+ const osgViewer::Viewer* getViewer() const { return viewer.get(); }
+ void setViewer(osgViewer::Viewer* viewer) { this->viewer = viewer; }
+ /** Get and set the manipulator object, if any.
+ */
+ FGManipulator* getManipulator() { return manipulator.get(); }
+ const FGManipulator* getManipulator() const { return manipulator.get(); }
+ void setManipulator(FGManipulator* manipulator)
+ {
+ this->manipulator = manipulator;
+ }
+protected:
+ osg::ref_ptr<osgViewer::Viewer> viewer;
+ osg::ref_ptr<FGManipulator> manipulator;
};
#endif
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
+#include <Main/renderer.hxx>
#include "jpg-httpd.hxx"
SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< HTTP Request : " << pRequest );
double left, right, bottom, top, zNear, zFar;
- sceneView->getCamera()->getProjectionMatrixAsFrustum( left, right, bottom, top, zNear, zFar );
+ osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
+ if (viewer)
+ viewer->getCamera()->getProjectionMatrixAsFrustum(left, right,
+ bottom, top,
+ zNear, zFar);
+ else
+ sceneView->getCamera()->getProjectionMatrixAsFrustum(left, right,
+ bottom, top,
+ zNear, zFar);
JpgFactory->setFrustum( left, right, bottom, top, zNear, zFar );
nImageLen = JpgFactory -> render();