1
0
Fork 0

Modified Files:

configure.ac src/Main/Makefile.am src/Main/fg_os.cxx
	src/Main/fg_os.hxx src/Main/fg_os_sdl.cxx src/Main/main.cxx
	src/Main/renderer.cxx src/Main/renderer.hxx
	src/Network/jpg-httpd.cxx
Added Files:
	src/Main/FGManipulator.cxx src/Main/FGManipulator.hxx
	src/Main/fg_os_osgviewer.cxx:
	Tim Moore: Make use of osgViewer.
This commit is contained in:
frohlich 2007-05-21 17:50:02 +00:00
parent d694d0a205
commit 7443b8b5e8
12 changed files with 690 additions and 77 deletions

View file

@ -199,11 +199,18 @@ base_LIBS="$LIBS"
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

181
src/Main/FGManipulator.cxx Normal file
View file

@ -0,0 +1,181 @@
#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;
}

124
src/Main/FGManipulator.hxx Normal file
View file

@ -0,0 +1,124 @@
#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

View file

@ -1,5 +1,5 @@
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
@ -18,8 +18,12 @@ endif
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 \
@ -55,6 +59,7 @@ libMain_a_SOURCES = \
util.cxx util.hxx \
viewer.cxx viewer.hxx \
viewmgr.cxx viewmgr.hxx \
FGManipulator.cxx FGManipulator.hxx \
$(GFX_CODE)
fgfs_SOURCES = bootstrap.cxx
@ -99,7 +104,7 @@ fgfs_LDADD = \
-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 \

View file

@ -236,3 +236,7 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
glutReshapeFunc(GLUTreshape);
}
// Noop; the graphics context is always current
void fgMakeCurrent()
{
}

View file

@ -76,4 +76,5 @@ void fgRegisterKeyHandler(fgKeyHandler func);
void fgRegisterMouseClickHandler(fgMouseClickHandler func);
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func);
void fgMakeCurrent();
#endif // _FG_OS_HXX

View file

@ -0,0 +1,165 @@
#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();
}

View file

@ -407,3 +407,8 @@ static void initCursors()
cursors[i].hoty);
}
}
// Noop; the graphics context is always current
void fgMakeCurrent()
{
}

View file

@ -603,6 +603,9 @@ static void fgMainLoop( void ) {
// 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++;

View file

@ -358,6 +358,9 @@ FGRenderer::FGRenderer()
#ifdef FG_JPEG_SERVER
jpgRenderFrame = FGRenderer::update;
#endif
#ifdef ENABLE_OSGVIEWER
manipulator = new FGManipulator;
#endif
}
FGRenderer::~FGRenderer()
@ -368,20 +371,38 @@ 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
@ -406,9 +427,13 @@ FGRenderer::init( void ) {
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();
@ -521,6 +546,7 @@ FGRenderer::init( void ) {
mRealRoot->addChild(sw);
mRealRoot->addChild(FGCreateRedoutNode());
mRealRoot->addChild(guiCamera);
// sceneView->getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
}
@ -529,7 +555,7 @@ void
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);
@ -537,10 +563,11 @@ FGRenderer::update( bool refresh_camera_settings ) {
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;
}
@ -586,18 +613,30 @@ FGRenderer::update( bool refresh_camera_settings ) {
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
@ -756,8 +795,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
// 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());
@ -767,15 +808,24 @@ FGRenderer::update( bool refresh_camera_settings ) {
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();
}
}
@ -793,8 +843,13 @@ FGRenderer::resize( int width, int height ) {
} 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;
@ -842,11 +897,17 @@ static void fgHackFrustum() {
= 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()
@ -883,8 +944,11 @@ static void fgHackFrustum() {
} 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);
}
@ -906,10 +970,15 @@ static float fov_far = 1000.0;
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();
@ -925,10 +994,15 @@ void FGRenderer::setNearFar( float n, float f ) {
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
@ -939,40 +1013,54 @@ bool
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

View file

@ -6,6 +6,10 @@
#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;
@ -51,6 +55,23 @@ public:
*/
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

View file

@ -42,6 +42,7 @@
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Main/renderer.hxx>
#include "jpg-httpd.hxx"
@ -106,7 +107,15 @@ void HttpdImageChannel :: foundTerminator( void ) {
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();