EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
fi
+# specify Boost location
+AC_ARG_WITH(osg, [ --with-boost=PREFIX Specify the prefix path to Boost])
+
+if test "x$with_boost" != "x" ; then
+ echo "Boost prefix is $with_boost"
+ EXTRA_DIRS="${EXTRA_DIRS} $with_boost"
+fi
+
dnl Determine an extra directories to add to include/lib search paths
case "${host}" in
*-apple-darwin* | *-*-mingw32*)
exit
fi
+AC_CHECK_HEADER(boost/foreach.hpp)
+if test "x$ac_cv_header_boost_foreach_hpp" != "xyes"; then
+ echo
+ echo "You *must* have the Boost libraries installed."
+ echo
+ echo "configure aborted."
+ exit
+fi
+
# Find the OSG libraries. Note special handling for OS X frameworks
case "${host}" in
*-apple-darwin*)
#include "globals.hxx"
#include "renderer.hxx"
-#include "FGManipulator.hxx"
+#include "FGEventHandler.hxx"
#include "WindowBuilder.hxx"
#include "WindowSystemAdapter.hxx"
#include <simgear/props/props.hxx>
+#include <simgear/scene/util/RenderConstants.hxx>
#include <algorithm>
#include <cstring>
{
}
+}
+
+namespace
+{
+using namespace osg;
+
+// Given a projection matrix, return a new one with the same frustum
+// sides and new near / far values.
+
+void makeNewProjMat(Matrixd& oldProj, double znear,
+ double zfar, Matrixd& projection)
+{
+ projection = oldProj;
+ // Slightly inflate the near & far planes to avoid objects at the
+ // extremes being clipped out.
+ znear *= 0.999;
+ zfar *= 1.001;
+
+ // Clamp the projection matrix z values to the range (near, far)
+ double epsilon = 1.0e-6;
+ if (fabs(projection(0,3)) < epsilon &&
+ fabs(projection(1,3)) < epsilon &&
+ fabs(projection(2,3)) < epsilon) {
+ // Projection is Orthographic
+ epsilon = -1.0/(zfar - znear); // Used as a temp variable
+ projection(2,2) = 2.0*epsilon;
+ projection(3,2) = (zfar + znear)*epsilon;
+ } else {
+ // Projection is Perspective
+ double trans_near = (-znear*projection(2,2) + projection(3,2)) /
+ (-znear*projection(2,3) + projection(3,3));
+ double trans_far = (-zfar*projection(2,2) + projection(3,2)) /
+ (-zfar*projection(2,3) + projection(3,3));
+ double ratio = fabs(2.0/(trans_near - trans_far));
+ double center = -0.5*(trans_near + trans_far);
+
+ projection.postMult(osg::Matrixd(1.0, 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0, 0.0,
+ 0.0, 0.0, ratio, 0.0,
+ 0.0, 0.0, center*ratio, 1.0));
+ }
+}
+
+void installCullVisitor(Camera* camera)
+{
+#if 0 // Not yet
+ osgViewer::Renderer* renderer
+ = static_cast<osgViewer::Renderer*>(camera->getRenderer());
+ for (int i = 0; i < 2; ++i) {
+ osgUtil::SceneView* sceneView = renderer->getSceneView(i);
+ sceneView->setCullVisitor(new simgear::EffectCullVisitor);
+ }
+#endif
+}
+}
+
+namespace flightgear
+{
CameraInfo* CameraGroup::addCamera(unsigned flags, Camera* camera,
const Matrix& view,
const Matrix& projection,
bool useMasterSceneData)
{
- if ((flags & (VIEW_ABSOLUTE | PROJECTION_ABSOLUTE)) != 0)
- camera->setReferenceFrame(Transform::ABSOLUTE_RF);
- else
- camera->setReferenceFrame(Transform::RELATIVE_RF);
- CameraInfo* info = new CameraInfo(flags, camera);
- _cameras.push_back(info);
+ CameraInfo* info = new CameraInfo(flags);
+ // The camera group will always update the camera
+ camera->setReferenceFrame(Transform::ABSOLUTE_RF);
+
+ Camera* farCamera = 0;
+ if ((flags & (GUI | ORTHO)) == 0) {
+ farCamera = osg::clone(camera);
+ farCamera->setGraphicsContext(camera->getGraphicsContext());
+ // Each camera's viewport is written when the window is
+ // resized; if the the viewport isn't copied here, it gets updated
+ // twice and ends up with the wrong value.
+ farCamera->setViewport(osg::clone(camera->getViewport()));
+ _viewer->addSlave(farCamera, view, projection, useMasterSceneData);
+ installCullVisitor(farCamera);
+ info->farCamera = farCamera;
+ info->farSlaveIndex = _viewer->getNumSlaves() - 1;
+ farCamera->setRenderOrder(Camera::NESTED_RENDER, info->farSlaveIndex);
+ camera->setCullMask(camera->getCullMask() & ~simgear::BACKGROUND_BIT);
+ }
+ camera->setClearMask(GL_DEPTH_BUFFER_BIT);
_viewer->addSlave(camera, view, projection, useMasterSceneData);
+ installCullVisitor(camera);
+ info->camera = camera;
info->slaveIndex = _viewer->getNumSlaves() - 1;
+ camera->setRenderOrder(Camera::NESTED_RENDER, info->slaveIndex);
+ _cameras.push_back(info);
return info;
}
void CameraGroup::update(const osg::Vec3d& position,
const osg::Quat& orientation)
{
- FGManipulator *manipulator
- = dynamic_cast<FGManipulator*>(_viewer->getCameraManipulator());
- if (!manipulator)
- return;
- manipulator->setPosition(position);
- manipulator->setAttitude(orientation);
- const Matrix masterView(manipulator->getInverseMatrix());
+ const Matrix masterView(osg::Matrix::translate(-position)
+ * osg::Matrix::rotate(orientation.inverse()));
+ _viewer->getCamera()->setViewMatrix(masterView);
const Matrix& masterProj = _viewer->getCamera()->getProjectionMatrix();
for (CameraList::iterator i = _cameras.begin(); i != _cameras.end(); ++i) {
const CameraInfo* info = i->get();
- if ((info->flags & (VIEW_ABSOLUTE | PROJECTION_ABSOLUTE)) == 0) {
- // Camera has relative reference frame and is updated by
- // osg::View.
- continue;
- }
const View::Slave& slave = _viewer->getSlave(info->slaveIndex);
Camera* camera = info->camera.get();
+ camera->getViewport()->setViewport(info->x, info->y, info->width,
+ info->height);
+ Matrix viewMatrix;
if ((info->flags & VIEW_ABSOLUTE) != 0)
- camera->setViewMatrix(slave._viewOffset);
+ viewMatrix = slave._viewOffset;
else
- camera->setViewMatrix(masterView * slave._viewOffset);
+ viewMatrix = masterView * slave._viewOffset;
+ camera->setViewMatrix(viewMatrix);
+ Matrix projectionMatrix;
if ((info->flags & PROJECTION_ABSOLUTE) != 0)
- camera->setProjectionMatrix(slave._projectionOffset);
+ projectionMatrix = slave._projectionOffset;
else
- camera->setViewMatrix(masterProj * slave._projectionOffset);
+ projectionMatrix = masterProj * slave._projectionOffset;
+
+ if (!info->farCamera.valid()) {
+ camera->setProjectionMatrix(projectionMatrix);
+ } else {
+ Camera* farCamera = info->farCamera.get();
+ farCamera->getViewport()->setViewport(info->x, info->y, info->width,
+ info->height);
+ farCamera->setViewMatrix(viewMatrix);
+ double left, right, bottom, top, parentNear, parentFar;
+ projectionMatrix.getFrustum(left, right, bottom, top,
+ parentNear, parentFar);
+ if (parentFar < 100.0) {
+ camera->setProjectionMatrix(projectionMatrix);
+ camera->setCullMask(camera->getCullMask()
+ | simgear::BACKGROUND_BIT);
+ farCamera->setNodeMask(0);
+ } else {
+ Matrix nearProj, farProj;
+ makeNewProjMat(projectionMatrix, parentNear, 100.0, nearProj);
+ makeNewProjMat(projectionMatrix, 100.0, parentFar, farProj);
+ camera->setProjectionMatrix(nearProj);
+ camera->setCullMask(camera->getCullMask()
+ & ~simgear::BACKGROUND_BIT);
+ farCamera->setProjectionMatrix(farProj);
+ farCamera->setNodeMask(camera->getNodeMask());
+ }
+ }
}
}
namespace
{
-osg::Viewport* buildViewport(const SGPropertyNode* viewportNode)
+// A raw value for property nodes that references a class member via
+// an osg::ref_ptr.
+template<class C, class T>
+class RefMember : public SGRawValue<T>
{
- double x = viewportNode->getDoubleValue("x", 0.0);
- double y = viewportNode->getDoubleValue("y", 0.0);
- double width = viewportNode->getDoubleValue("width", 0.0);
- double height = viewportNode->getDoubleValue("height", 0.0);
- return new osg::Viewport(x, y, width, height);
+public:
+ RefMember (C *obj, T C::*ptr)
+ : _obj(obj), _ptr(ptr) {}
+ virtual ~RefMember () {}
+ virtual T getValue () const
+ {
+ return _obj.get()->*_ptr;
+ }
+ virtual bool setValue (T value)
+ {
+ _obj.get()->*_ptr = value;
+ return true;
+ }
+ virtual SGRawValue<T> * clone () const
+ {
+ return new RefMember(_obj.get(), _ptr);
+ }
+private:
+ ref_ptr<C> _obj;
+ T C::* const _ptr;
+};
+
+template<typename C, typename T>
+RefMember<C, T> makeRefMember(C *obj, T C::*ptr)
+{
+ return RefMember<C, T>(obj, ptr);
+}
+
+template<typename C, typename T>
+void bindMemberToNode(SGPropertyNode* parent, const char* childName,
+ C* obj, T C::*ptr, T value)
+{
+ SGPropertyNode* valNode = parent->getNode(childName);
+ RefMember<C, T> refMember = makeRefMember(obj, ptr);
+ if (!valNode) {
+ valNode = parent->getNode(childName, true);
+ valNode->tie(refMember, false);
+ setValue(valNode, value);
+ } else {
+ valNode->tie(refMember, true);
+ }
+}
+
+void buildViewport(flightgear::CameraInfo* info, SGPropertyNode* viewportNode,
+ const osg::GraphicsContext::Traits *traits)
+{
+ using namespace flightgear;
+ bindMemberToNode(viewportNode, "x", info, &CameraInfo::x, 0.0);
+ bindMemberToNode(viewportNode, "y", info, &CameraInfo::y, 0.0);
+ bindMemberToNode(viewportNode, "width", info, &CameraInfo::width,
+ static_cast<double>(traits->width));
+ bindMemberToNode(viewportNode, "height", info, &CameraInfo::height,
+ static_cast<double>(traits->height));
}
}
namespace flightgear
{
-CameraInfo* CameraGroup::buildCamera(const SGPropertyNode* cameraNode)
+
+CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode)
{
WindowBuilder *wBuild = WindowBuilder::getWindowBuilder();
const SGPropertyNode* windowNode = cameraNode->getNode("window");
Camera* camera = new Camera;
camera->setAllowEventFocus(false);
camera->setGraphicsContext(window->gc.get());
- // 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.
- const SGPropertyNode* viewportNode = cameraNode->getNode("viewport");
- Viewport* viewport = 0;
- if (viewportNode) {
- viewport = buildViewport(viewportNode);
- } else {
- const GraphicsContext::Traits *traits = window->gc->getTraits();
- viewport = new Viewport(0, 0, traits->width, traits->height);
- }
- camera->setViewport(viewport);
+ camera->setViewport(new Viewport);
+ camera->setCullingMode(CullSettings::SMALL_FEATURE_CULLING
+ | CullSettings::VIEW_FRUSTUM_CULLING);
+ camera->setInheritanceMask(CullSettings::ALL_VARIABLES
+ & ~(CullSettings::CULL_MASK
+ | CullSettings::CULLING_MODE));
+
osg::Matrix pOff;
osg::Matrix vOff;
const SGPropertyNode* viewNode = cameraNode->getNode("view");
double sheary = cameraNode->getDoubleValue("shear-y", 0);
pOff.makeTranslate(-shearx, -sheary, 0);
}
- return addCamera(cameraFlags, camera, pOff, vOff);
+ CameraInfo* info = addCamera(cameraFlags, camera, pOff, vOff);
+ // 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.
+ SGPropertyNode* viewportNode = cameraNode->getNode("viewport", true);
+ buildViewport(info, viewportNode, window->gc->getTraits());
+ return info;
}
-CameraInfo* CameraGroup::buildGUICamera(const SGPropertyNode* cameraNode,
+CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode,
GraphicsWindow* window)
{
WindowBuilder *wBuild = WindowBuilder::getWindowBuilder();
Camera* camera = new Camera;
camera->setAllowEventFocus(false);
camera->setGraphicsContext(window->gc.get());
- const SGPropertyNode* viewportNode = (cameraNode
- ? cameraNode->getNode("viewport")
- : 0);
- Viewport* viewport = 0;
- if (viewportNode) {
- viewport = buildViewport(viewportNode);
- } else {
- const GraphicsContext::Traits *traits = window->gc->getTraits();
- viewport = new Viewport(0, 0, traits->width, traits->height);
- }
- camera->setViewport(viewport);
+ camera->setViewport(new Viewport);
// XXX Camera needs to be drawn last; eventually the render order
// should be assigned by a camera manager.
camera->setRenderOrder(osg::Camera::POST_RENDER, 100);
const int cameraFlags = GUI;
CameraInfo* result = addCamera(cameraFlags, camera, Matrixd::identity(),
Matrixd::identity(), false);
+ SGPropertyNode* viewportNode = cameraNode->getNode("viewport", true);
+ buildViewport(result, viewportNode, window->gc->getTraits());
+
// Disable statistics for the GUI camera.
result->camera->setStats(0);
return result;
}
CameraGroup* CameraGroup::buildCameraGroup(osgViewer::Viewer* viewer,
- const SGPropertyNode* gnode)
+ SGPropertyNode* gnode)
{
CameraGroup* cgroup = new CameraGroup(viewer);
for (int i = 0; i < gnode->nChildren(); ++i) {
- const SGPropertyNode* pNode = gnode->getChild(i);
+ SGPropertyNode* pNode = gnode->getChild(i);
const char* name = pNode->getName();
if (!strcmp(name, "camera")) {
cgroup->buildCamera(pNode);
return cgroup;
}
+void CameraGroup::setCameraCullMasks(Node::NodeMask nm)
+{
+ for (CameraIterator i = camerasBegin(), e = camerasEnd(); i != e; ++i) {
+ if ((*i)->flags & GUI)
+ continue;
+ (*i)->camera->setCullMask(nm & ~simgear::BACKGROUND_BIT);
+ (*i)->farCamera->setCullMask(nm);
+ }
+}
+
Camera* getGUICamera(CameraGroup* cgroup)
{
CameraGroup::CameraIterator end = cgroup->camerasEnd();
= dynamic_cast<GraphicsWindow*>(guiCamera->getGraphicsContext());
if (!gw)
return;
- globals->get_renderer()->getManipulator()->setMouseWarped();
+ globals->get_renderer()->getEventHandler()->setMouseWarped();
// Translate the warp request into the viewport of the GUI camera,
// send the request to the window, then transform the coordinates
// for the Viewer's event queue.
#include <osg/Matrix>
#include <osg/ref_ptr>
#include <osg/Referenced>
+#include <osg/Node>
// For osgUtil::LineSegmentIntersector::Intersections, which is a typedef.
#include <osgUtil/LineSegmentIntersector>
*/
struct CameraInfo : public osg::Referenced
{
- CameraInfo(unsigned flags_, osg::Camera* camera_)
- : flags(flags_), camera(camera_), slaveIndex(-1)
+ CameraInfo(unsigned flags_, osg::Camera* camera_ = 0)
+ : flags(flags_), camera(camera_), slaveIndex(-1), farSlaveIndex(-1),
+ x(0.0), y(0.0), width(0.0), height(0.0)
{
}
/** Properties of the camera. @see CameraGroup::Flags.
/** the camera object
*/
osg::ref_ptr<osg::Camera> camera;
+ /** camera for rendering far field, if needed
+ */
+ osg::ref_ptr<osg::Camera> farCamera;
/** Index of this camera in the osgViewer::Viewer slave list.
*/
int slaveIndex;
+ /** index of far camera in slave list
+ */
+ int farSlaveIndex;
+ /** Viewport parameters.
+ */
+ double x;
+ double y;
+ double width;
+ double height;
};
class CameraGroup : public osg::Referenced
* @param cameraNode the property node.
* @return a CameraInfo object for the camera.
*/
- CameraInfo* buildCamera(const SGPropertyNode* cameraNode);
+ CameraInfo* buildCamera(SGPropertyNode* cameraNode);
/** Create a camera from properties that will draw the GUI and add
* it to the camera group.
* @param cameraNode the property node. This can be 0, in which
* this is 0, the window is determined from the property node.
* @return a CameraInfo object for the GUI camera.
*/
- CameraInfo* buildGUICamera(const SGPropertyNode* cameraNode,
+ CameraInfo* buildGUICamera(SGPropertyNode* cameraNode,
GraphicsWindow* window = 0);
/** Update the view for the camera group.
* @param position the world position of the view
* @param the camera group property node.
*/
static CameraGroup* buildCameraGroup(osgViewer::Viewer* viewer,
- const SGPropertyNode* node);
+ SGPropertyNode* node);
+ /** Set the cull mask on all non-GUI cameras
+ */
+ void setCameraCullMasks(osg::Node::NodeMask nm);
+
protected:
CameraList _cameras;
osg::ref_ptr<osgViewer::Viewer> _viewer;
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <osg/Camera>
+#include <osg/GraphicsContext>
+#include <osg/Math>
+#include <osg/Viewport>
+#include <osgViewer/Viewer>
+
+#include <plib/pu.h>
+#include <Main/fg_props.hxx>
+#include "CameraGroup.hxx"
+#include "FGEventHandler.hxx"
+#include "WindowSystemAdapter.hxx"
+
+#if !defined(X_DISPLAY_MISSING)
+#define X_DOUBLE_SCROLL_BUG 1
+#endif
+
+namespace flightgear
+{
+const int displayStatsKey = 1;
+const int printStatsKey = 2;
+
+
+// The manipulator is responsible for updating a Viewer's camera. Its
+// event handling method is also a convenient place to run the FG idle
+// and draw handlers.
+
+FGEventHandler::FGEventHandler() :
+ idleHandler(0),
+ drawHandler(0),
+ windowResizeHandler(0),
+ keyHandler(0),
+ mouseClickHandler(0),
+ mouseMotionHandler(0),
+ statsHandler(new osgViewer::StatsHandler),
+ statsEvent(new osgGA::GUIEventAdapter),
+ statsType(osgViewer::StatsHandler::NO_STATS),
+ currentModifiers(0),
+ resizable(true),
+ mouseWarped(false),
+ scrollButtonPressed(false)
+{
+ using namespace osgGA;
+ statsHandler->setKeyEventTogglesOnScreenStats(displayStatsKey);
+ statsHandler->setKeyEventPrintsOutStats(printStatsKey);
+ statsEvent->setEventType(GUIEventAdapter::KEYDOWN);
+
+ // OSG reports NumPad keycodes independent of the NumLock modifier.
+ // Both KP-4 and KP-Left are reported as KEY_KP_Left (0xff96), so we
+ // have to generate the locked keys ourselves.
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Insert] = '0';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_End] = '1';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Down] = '2';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Page_Down] = '3';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Left] = '4';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Begin] = '5';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Right] = '6';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Home] = '7';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Up] = '8';
+ numlockKeyMap[GUIEventAdapter::KEY_KP_Page_Up] = '9';
+
+ for (int i = 0; i < 128; i++)
+ release_keys[i] = i;
+}
+
+namespace
+{
+// Translate OSG modifier mask to FG modifier mask.
+int osgToFGModifiers(int modifiers)
+{
+ int result = 0;
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_SHIFT)
+ result |= KEYMOD_SHIFT;
+
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_CTRL)
+ result |= KEYMOD_CTRL;
+
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_ALT)
+ result |= KEYMOD_ALT;
+
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_META)
+ result |= KEYMOD_META;
+
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_SUPER)
+ result |= KEYMOD_SUPER;
+
+ if (modifiers & osgGA::GUIEventAdapter::MODKEY_HYPER)
+ result |= KEYMOD_HYPER;
+ return result;
+}
+}
+
+#if 0
+void FGEventHandler::init(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us)
+{
+ currentModifiers = osgToFGModifiers(ea.getModKeyMask());
+ (void)handle(ea, us);
+}
+#endif
+
+// Calculate event coordinates in the viewport of the GUI camera, if
+// possible. Otherwise return false and (-1, -1).
+namespace
+{
+bool
+eventToViewport(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us,
+ int& x, int& y)
+{
+ x = -1;
+ y = -1;
+
+ const osg::GraphicsContext* eventGC = ea.getGraphicsContext();
+ const osg::GraphicsContext::Traits* traits = eventGC->getTraits();
+ osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
+ if (!guiCamera)
+ return false;
+ osg::Viewport* vport = guiCamera->getViewport();
+ if (!vport)
+ return false;
+
+ // Scale x, y to the dimensions of the window
+ double wx = (((ea.getX() - ea.getXmin()) / (ea.getXmax() - ea.getXmin()))
+ * (float)traits->width);
+ double wy = (((ea.getY() - ea.getYmin()) / (ea.getYmax() - ea.getYmin()))
+ * (float)traits->height);
+ if (vport->x() <= wx && wx <= vport->x() + vport->width()
+ && vport->y() <= wy && wy <= vport->y() + vport->height()) {
+ // Finally, into viewport coordinates. Change y to "increasing
+ // downwards".
+ x = wx - vport->x();
+ y = vport->height() - (wy - vport->y());
+ return true;
+ } else {
+ return false;
+ }
+}
+}
+
+bool FGEventHandler::handle(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us)
+{
+ int x = 0;
+ int y = 0;
+
+ switch (ea.getEventType()) {
+ case osgGA::GUIEventAdapter::FRAME:
+ if (idleHandler)
+ (*idleHandler)();
+ if (drawHandler)
+ (*drawHandler)();
+ mouseWarped = false;
+ handleStats(us);
+ 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:
+ {
+ bool mainWindow = 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, mainWindow, &ea);
+ return true;
+ }
+ case osgGA::GUIEventAdapter::SCROLL:
+ {
+ bool mainWindow = eventToViewport(ea, us, x, y);
+#ifdef X_DOUBLE_SCROLL_BUG
+ scrollButtonPressed = !scrollButtonPressed;
+ if (!scrollButtonPressed) // Drop the button release event
+ return true;
+#endif
+ int button;
+ if (ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_UP)
+ button = 3;
+ else
+ button = 4;
+ if (mouseClickHandler) {
+ (*mouseClickHandler)(button, 0, x, y, mainWindow, &ea);
+ (*mouseClickHandler)(button, 1, x, y, mainWindow, &ea);
+ }
+ return true;
+ }
+ case osgGA::GUIEventAdapter::MOVE:
+ case osgGA::GUIEventAdapter::DRAG:
+ // If we warped the mouse, then disregard all pointer motion
+ // events for this frame. We really want to flush the event
+ // queue of mouse events, but don't have the ability to do
+ // that with osgViewer.
+ if (mouseWarped)
+ return true;
+ if (eventToViewport(ea, us, x, y) && mouseMotionHandler)
+ (*mouseMotionHandler)(x, y);
+ return true;
+ case osgGA::GUIEventAdapter::RESIZE:
+ if (resizable && windowResizeHandler)
+ (*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
+ return true;
+ case osgGA::GUIEventAdapter::CLOSE_WINDOW:
+ case osgGA::GUIEventAdapter::QUIT_APPLICATION:
+ fgOSExit(0);
+ return true;
+ default:
+ return false;
+ }
+}
+
+void FGEventHandler::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
+ int& modifiers)
+{
+ using namespace osgGA;
+ key = ea.getKey();
+ // XXX Probably other translations are needed too.
+ switch (key) {
+ case GUIEventAdapter::KEY_Escape: key = 0x1b; break;
+ case GUIEventAdapter::KEY_Return: key = '\n'; break;
+ case GUIEventAdapter::KEY_BackSpace: key = '\b'; break;
+ case GUIEventAdapter::KEY_Delete: key = 0x7f; break;
+ case GUIEventAdapter::KEY_Tab: key = '\t'; break;
+ case GUIEventAdapter::KEY_Left: key = PU_KEY_LEFT; break;
+ case GUIEventAdapter::KEY_Up: key = PU_KEY_UP; break;
+ case GUIEventAdapter::KEY_Right: key = PU_KEY_RIGHT; break;
+ case GUIEventAdapter::KEY_Down: key = PU_KEY_DOWN; break;
+ case GUIEventAdapter::KEY_Page_Up: key = PU_KEY_PAGE_UP; break;
+ case GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
+ case GUIEventAdapter::KEY_Home: key = PU_KEY_HOME; break;
+ case GUIEventAdapter::KEY_End: key = PU_KEY_END; break;
+ case GUIEventAdapter::KEY_Insert: key = PU_KEY_INSERT; break;
+ case GUIEventAdapter::KEY_F1: key = PU_KEY_F1; break;
+ case GUIEventAdapter::KEY_F2: key = PU_KEY_F2; break;
+ case GUIEventAdapter::KEY_F3: key = PU_KEY_F3; break;
+ case GUIEventAdapter::KEY_F4: key = PU_KEY_F4; break;
+ case GUIEventAdapter::KEY_F5: key = PU_KEY_F5; break;
+ case GUIEventAdapter::KEY_F6: key = PU_KEY_F6; break;
+ case GUIEventAdapter::KEY_F7: key = PU_KEY_F7; break;
+ case GUIEventAdapter::KEY_F8: key = PU_KEY_F8; break;
+ case GUIEventAdapter::KEY_F9: key = PU_KEY_F9; break;
+ case GUIEventAdapter::KEY_F10: key = PU_KEY_F10; break;
+ case GUIEventAdapter::KEY_F11: key = PU_KEY_F11; break;
+ case GUIEventAdapter::KEY_F12: key = PU_KEY_F12; break;
+ case GUIEventAdapter::KEY_KP_Delete: key = '.'; break;
+ case GUIEventAdapter::KEY_KP_Enter: key = '\r'; break;
+ case GUIEventAdapter::KEY_KP_Add: key = '+'; break;
+ case GUIEventAdapter::KEY_KP_Divide: key = '/'; break;
+ case GUIEventAdapter::KEY_KP_Multiply: key = '*'; break;
+ case GUIEventAdapter::KEY_KP_Subtract: key = '-'; break;
+ }
+ osgGA::GUIEventAdapter::EventType eventType = ea.getEventType();
+
+ std::map<int, int>::iterator numPadIter = numlockKeyMap.find(key);
+
+ if (numPadIter != numlockKeyMap.end()) {
+ if (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_NUM_LOCK) {
+ key = numPadIter->second;
+ }
+ }
+
+ modifiers = osgToFGModifiers(ea.getModKeyMask());
+ currentModifiers = modifiers;
+ if (eventType == osgGA::GUIEventAdapter::KEYUP)
+ modifiers |= KEYMOD_RELEASED;
+
+ // Release the letter key, for which the key press was reported. This
+ // is to deal with Ctrl-press -> a-press -> Ctrl-release -> a-release
+ // correctly.
+ if (key >= 0 && key < 128) {
+ if (modifiers & KEYMOD_RELEASED) {
+ key = release_keys[key];
+ } else {
+ release_keys[key] = key;
+ if (key >= 1 && key <= 26) {
+ release_keys[key + '@'] = key;
+ release_keys[key + '`'] = key;
+ } else if (key >= 'A' && key <= 'Z') {
+ release_keys[key - '@'] = key;
+ release_keys[tolower(key)] = key;
+ } else if (key >= 'a' && key <= 'z') {
+ release_keys[key - '`'] = key;
+ release_keys[toupper(key)] = key;
+ }
+ }
+ }
+}
+
+void FGEventHandler::handleStats(osgGA::GUIActionAdapter& us)
+{
+ static SGPropertyNode_ptr display = fgGetNode("/sim/rendering/on-screen-statistics", true);
+ static SGPropertyNode_ptr print = fgGetNode("/sim/rendering/print-statistics", true);
+
+ int type = display->getIntValue() % osgViewer::StatsHandler::LAST;
+ if (type != statsType) {
+ statsEvent->setKey(displayStatsKey);
+ do {
+ statsType = (statsType + 1) % osgViewer::StatsHandler::LAST;
+ statsHandler->handle(*statsEvent, us);
+ } while (statsType != type);
+
+ display->setIntValue(statsType);
+ }
+
+ if (print->getBoolValue()) {
+ statsEvent->setKey(printStatsKey);
+ statsHandler->handle(*statsEvent, us);
+ print->setBoolValue(false);
+ }
+}
+
+void eventToWindowCoords(const osgGA::GUIEventAdapter* ea,
+ double& x, double& y)
+{
+ using namespace osg;
+ const GraphicsContext* gc = ea->getGraphicsContext();
+ const GraphicsContext::Traits* traits = gc->getTraits() ;
+ // Scale x, y to the dimensions of the window
+ x = (((ea->getX() - ea->getXmin()) / (ea->getXmax() - ea->getXmin()))
+ * (double)traits->width);
+ y = (((ea->getY() - ea->getYmin()) / (ea->getYmax() - ea->getYmin()))
+ * (double)traits->height);
+ if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS)
+ y = (double)traits->height - y;
+}
+
+void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
+ double& x, double& y)
+{
+ using namespace osg;
+ const GraphicsContext* gc = ea->getGraphicsContext();
+ const GraphicsContext::Traits* traits = gc->getTraits() ;
+ // Scale x, y to the dimensions of the window
+ x = (((ea->getX() - ea->getXmin()) / (ea->getXmax() - ea->getXmin()))
+ * (double)traits->width);
+ y = (((ea->getY() - ea->getYmin()) / (ea->getYmax() - ea->getYmin()))
+ * (double)traits->height);
+ if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
+ y = (double)traits->height - y;
+}
+}
--- /dev/null
+#ifndef FGEVENTHANDLER_H
+#define FGEVENTHANDLER_H 1
+
+#include <map>
+#include <osg/Quat>
+#include <osgGA/GUIEventHandler>
+#include <osgViewer/ViewerEventHandlers>
+
+#include "fg_os.hxx"
+
+namespace flightgear
+{
+class FGEventHandler : public osgGA::GUIEventHandler {
+public:
+ FGEventHandler();
+
+ virtual ~FGEventHandler() {}
+
+ virtual const char* className() const {return "FGEventHandler"; }
+#if 0
+ virtual void init(const osgGA::GUIEventAdapter& ea,
+ osgGA::GUIActionAdapter& us);
+#endif
+ 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 setMouseWarped()
+ {
+ mouseWarped = true;
+ }
+
+ /** Whether or not resizing is supported. It might not be when
+ * using multiple displays.
+ */
+ bool getResizable() { return resizable; }
+ void setResizable(bool _resizable) { resizable = _resizable; }
+
+protected:
+ osg::ref_ptr<osg::Node> _node;
+ fgIdleHandler idleHandler;
+ fgDrawHandler drawHandler;
+ fgWindowResizeHandler windowResizeHandler;
+ fgKeyHandler keyHandler;
+ fgMouseClickHandler mouseClickHandler;
+ fgMouseMotionHandler mouseMotionHandler;
+ osg::ref_ptr<osgViewer::StatsHandler> statsHandler;
+ osg::ref_ptr<osgGA::GUIEventAdapter> statsEvent;
+ int statsType;
+ int currentModifiers;
+ std::map<int, int> numlockKeyMap;
+ void handleKey(const osgGA::GUIEventAdapter& ea, int& key, int& modifiers);
+ bool resizable;
+ bool mouseWarped;
+ // workaround for osgViewer double scroll events
+ bool scrollButtonPressed;
+ int release_keys[128];
+ void handleStats(osgGA::GUIActionAdapter& us);
+};
+
+void eventToWindowCoords(const osgGA::GUIEventAdapter* ea, double& x, double& y);
+void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
+ double& x, double& y);
+}
+#endif
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <osg/Camera>
-#include <osg/GraphicsContext>
-#include <osg/Math>
-#include <osg/Viewport>
-#include <osgViewer/Viewer>
-
-#include <plib/pu.h>
-#include <Main/fg_props.hxx>
-#include "CameraGroup.hxx"
-#include "FGManipulator.hxx"
-#include "WindowSystemAdapter.hxx"
-
-#if !defined(X_DISPLAY_MISSING)
-#define X_DOUBLE_SCROLL_BUG 1
-#endif
-
-namespace flightgear
-{
-const int displayStatsKey = 1;
-const int printStatsKey = 2;
-
-
-// The manipulator is responsible for updating a Viewer's camera. Its
-// event handling method is also a convenient place to run the FG idle
-// and draw handlers.
-
-FGManipulator::FGManipulator() :
- idleHandler(0),
- drawHandler(0),
- windowResizeHandler(0),
- keyHandler(0),
- mouseClickHandler(0),
- mouseMotionHandler(0),
- statsHandler(new osgViewer::StatsHandler),
- statsEvent(new osgGA::GUIEventAdapter),
- statsType(osgViewer::StatsHandler::NO_STATS),
- currentModifiers(0),
- resizable(true),
- mouseWarped(false),
- scrollButtonPressed(false)
-{
- using namespace osgGA;
- statsHandler->setKeyEventTogglesOnScreenStats(displayStatsKey);
- statsHandler->setKeyEventPrintsOutStats(printStatsKey);
- statsEvent->setEventType(GUIEventAdapter::KEYDOWN);
-
- // OSG reports NumPad keycodes independent of the NumLock modifier.
- // Both KP-4 and KP-Left are reported as KEY_KP_Left (0xff96), so we
- // have to generate the locked keys ourselves.
- numlockKeyMap[GUIEventAdapter::KEY_KP_Insert] = '0';
- numlockKeyMap[GUIEventAdapter::KEY_KP_End] = '1';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Down] = '2';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Page_Down] = '3';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Left] = '4';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Begin] = '5';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Right] = '6';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Home] = '7';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Up] = '8';
- numlockKeyMap[GUIEventAdapter::KEY_KP_Page_Up] = '9';
-
- for (int i = 0; i < 128; i++)
- release_keys[i] = i;
-}
-
-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
-{
-// Translate OSG modifier mask to FG modifier mask.
-int osgToFGModifiers(int modifiers)
-{
- int result = 0;
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_SHIFT)
- result |= KEYMOD_SHIFT;
-
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_CTRL)
- result |= KEYMOD_CTRL;
-
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_ALT)
- result |= KEYMOD_ALT;
-
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_META)
- result |= KEYMOD_META;
-
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_SUPER)
- result |= KEYMOD_SUPER;
-
- if (modifiers & osgGA::GUIEventAdapter::MODKEY_HYPER)
- result |= KEYMOD_HYPER;
- return result;
-}
-}
-
-void FGManipulator::init(const osgGA::GUIEventAdapter& ea,
- osgGA::GUIActionAdapter& us)
-{
- currentModifiers = osgToFGModifiers(ea.getModKeyMask());
- (void)handle(ea, us);
-}
-
-// Calculate event coordinates in the viewport of the GUI camera, if
-// possible. Otherwise return false and (-1, -1).
-namespace
-{
-bool
-eventToViewport(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us,
- int& x, int& y)
-{
- x = -1;
- y = -1;
-
- const osg::GraphicsContext* eventGC = ea.getGraphicsContext();
- const osg::GraphicsContext::Traits* traits = eventGC->getTraits();
- osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
- if (!guiCamera)
- return false;
- osg::Viewport* vport = guiCamera->getViewport();
- if (!vport)
- return false;
-
- // Scale x, y to the dimensions of the window
- double wx = (((ea.getX() - ea.getXmin()) / (ea.getXmax() - ea.getXmin()))
- * (float)traits->width);
- double wy = (((ea.getY() - ea.getYmin()) / (ea.getYmax() - ea.getYmin()))
- * (float)traits->height);
- if (vport->x() <= wx && wx <= vport->x() + vport->width()
- && vport->y() <= wy && wy <= vport->y() + vport->height()) {
- // Finally, into viewport coordinates. Change y to "increasing
- // downwards".
- x = wx - vport->x();
- y = vport->height() - (wy - vport->y());
- return true;
- } else {
- return false;
- }
-}
-}
-
-bool FGManipulator::handle(const osgGA::GUIEventAdapter& ea,
- osgGA::GUIActionAdapter& us)
-{
- int x = 0;
- int y = 0;
-
- switch (ea.getEventType()) {
- case osgGA::GUIEventAdapter::FRAME:
- if (idleHandler)
- (*idleHandler)();
- if (drawHandler)
- (*drawHandler)();
- mouseWarped = false;
- handleStats(us);
- 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:
- {
- bool mainWindow = 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, mainWindow, &ea);
- return true;
- }
- case osgGA::GUIEventAdapter::SCROLL:
- {
- bool mainWindow = eventToViewport(ea, us, x, y);
-#ifdef X_DOUBLE_SCROLL_BUG
- scrollButtonPressed = !scrollButtonPressed;
- if (!scrollButtonPressed) // Drop the button release event
- return true;
-#endif
- int button;
- if (ea.getScrollingMotion() == osgGA::GUIEventAdapter::SCROLL_UP)
- button = 3;
- else
- button = 4;
- if (mouseClickHandler) {
- (*mouseClickHandler)(button, 0, x, y, mainWindow, &ea);
- (*mouseClickHandler)(button, 1, x, y, mainWindow, &ea);
- }
- return true;
- }
- case osgGA::GUIEventAdapter::MOVE:
- case osgGA::GUIEventAdapter::DRAG:
- // If we warped the mouse, then disregard all pointer motion
- // events for this frame. We really want to flush the event
- // queue of mouse events, but don't have the ability to do
- // that with osgViewer.
- if (mouseWarped)
- return true;
- if (eventToViewport(ea, us, x, y) && mouseMotionHandler)
- (*mouseMotionHandler)(x, y);
- return true;
- case osgGA::GUIEventAdapter::RESIZE:
- if (resizable && windowResizeHandler)
- (*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
- return true;
- case osgGA::GUIEventAdapter::CLOSE_WINDOW:
- case osgGA::GUIEventAdapter::QUIT_APPLICATION:
- fgOSExit(0);
- return true;
- default:
- return false;
- }
-}
-
-void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
- int& modifiers)
-{
- using namespace osgGA;
- key = ea.getKey();
- // XXX Probably other translations are needed too.
- switch (key) {
- case GUIEventAdapter::KEY_Escape: key = 0x1b; break;
- case GUIEventAdapter::KEY_Return: key = '\n'; break;
- case GUIEventAdapter::KEY_BackSpace: key = '\b'; break;
- case GUIEventAdapter::KEY_Delete: key = 0x7f; break;
- case GUIEventAdapter::KEY_Tab: key = '\t'; break;
- case GUIEventAdapter::KEY_Left: key = PU_KEY_LEFT; break;
- case GUIEventAdapter::KEY_Up: key = PU_KEY_UP; break;
- case GUIEventAdapter::KEY_Right: key = PU_KEY_RIGHT; break;
- case GUIEventAdapter::KEY_Down: key = PU_KEY_DOWN; break;
- case GUIEventAdapter::KEY_Page_Up: key = PU_KEY_PAGE_UP; break;
- case GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
- case GUIEventAdapter::KEY_Home: key = PU_KEY_HOME; break;
- case GUIEventAdapter::KEY_End: key = PU_KEY_END; break;
- case GUIEventAdapter::KEY_Insert: key = PU_KEY_INSERT; break;
- case GUIEventAdapter::KEY_F1: key = PU_KEY_F1; break;
- case GUIEventAdapter::KEY_F2: key = PU_KEY_F2; break;
- case GUIEventAdapter::KEY_F3: key = PU_KEY_F3; break;
- case GUIEventAdapter::KEY_F4: key = PU_KEY_F4; break;
- case GUIEventAdapter::KEY_F5: key = PU_KEY_F5; break;
- case GUIEventAdapter::KEY_F6: key = PU_KEY_F6; break;
- case GUIEventAdapter::KEY_F7: key = PU_KEY_F7; break;
- case GUIEventAdapter::KEY_F8: key = PU_KEY_F8; break;
- case GUIEventAdapter::KEY_F9: key = PU_KEY_F9; break;
- case GUIEventAdapter::KEY_F10: key = PU_KEY_F10; break;
- case GUIEventAdapter::KEY_F11: key = PU_KEY_F11; break;
- case GUIEventAdapter::KEY_F12: key = PU_KEY_F12; break;
- case GUIEventAdapter::KEY_KP_Delete: key = '.'; break;
- case GUIEventAdapter::KEY_KP_Enter: key = '\r'; break;
- case GUIEventAdapter::KEY_KP_Add: key = '+'; break;
- case GUIEventAdapter::KEY_KP_Divide: key = '/'; break;
- case GUIEventAdapter::KEY_KP_Multiply: key = '*'; break;
- case GUIEventAdapter::KEY_KP_Subtract: key = '-'; break;
- }
- osgGA::GUIEventAdapter::EventType eventType = ea.getEventType();
-
- std::map<int, int>::iterator numPadIter = numlockKeyMap.find(key);
-
- if (numPadIter != numlockKeyMap.end()) {
- if (ea.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_NUM_LOCK) {
- key = numPadIter->second;
- }
- }
-
- modifiers = osgToFGModifiers(ea.getModKeyMask());
- currentModifiers = modifiers;
- if (eventType == osgGA::GUIEventAdapter::KEYUP)
- modifiers |= KEYMOD_RELEASED;
-
- // Release the letter key, for which the key press was reported. This
- // is to deal with Ctrl-press -> a-press -> Ctrl-release -> a-release
- // correctly.
- if (key >= 0 && key < 128) {
- if (modifiers & KEYMOD_RELEASED) {
- key = release_keys[key];
- } else {
- release_keys[key] = key;
- if (key >= 1 && key <= 26) {
- release_keys[key + '@'] = key;
- release_keys[key + '`'] = key;
- } else if (key >= 'A' && key <= 'Z') {
- release_keys[key - '@'] = key;
- release_keys[tolower(key)] = key;
- } else if (key >= 'a' && key <= 'z') {
- release_keys[key - '`'] = key;
- release_keys[toupper(key)] = key;
- }
- }
- }
-}
-
-void FGManipulator::handleStats(osgGA::GUIActionAdapter& us)
-{
- static SGPropertyNode_ptr display = fgGetNode("/sim/rendering/on-screen-statistics", true);
- static SGPropertyNode_ptr print = fgGetNode("/sim/rendering/print-statistics", true);
-
- int type = display->getIntValue() % osgViewer::StatsHandler::LAST;
- if (type != statsType) {
- statsEvent->setKey(displayStatsKey);
- do {
- statsType = (statsType + 1) % osgViewer::StatsHandler::LAST;
- statsHandler->handle(*statsEvent, us);
- } while (statsType != type);
-
- display->setIntValue(statsType);
- }
-
- if (print->getBoolValue()) {
- statsEvent->setKey(printStatsKey);
- statsHandler->handle(*statsEvent, us);
- print->setBoolValue(false);
- }
-}
-
-void eventToWindowCoords(const osgGA::GUIEventAdapter* ea,
- double& x, double& y)
-{
- using namespace osg;
- const GraphicsContext* gc = ea->getGraphicsContext();
- const GraphicsContext::Traits* traits = gc->getTraits() ;
- // Scale x, y to the dimensions of the window
- x = (((ea->getX() - ea->getXmin()) / (ea->getXmax() - ea->getXmin()))
- * (double)traits->width);
- y = (((ea->getY() - ea->getYmin()) / (ea->getYmax() - ea->getYmin()))
- * (double)traits->height);
- if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS)
- y = (double)traits->height - y;
-}
-
-void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
- double& x, double& y)
-{
- using namespace osg;
- const GraphicsContext* gc = ea->getGraphicsContext();
- const GraphicsContext::Traits* traits = gc->getTraits() ;
- // Scale x, y to the dimensions of the window
- x = (((ea->getX() - ea->getXmin()) / (ea->getXmax() - ea->getXmin()))
- * (double)traits->width);
- y = (((ea->getY() - ea->getYmin()) / (ea->getYmax() - ea->getYmin()))
- * (double)traits->height);
- if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
- y = (double)traits->height - y;
-}
-}
+++ /dev/null
-#ifndef FGMANIPULATOR_H
-#define FGMANIPULATOR_H 1
-
-#include <map>
-#include <osg/Quat>
-#include <osgGA/MatrixManipulator>
-#include <osgViewer/ViewerEventHandlers>
-
-#include "fg_os.hxx"
-
-namespace flightgear
-{
-class FGManipulator : public osgGA::MatrixManipulator {
-public:
- FGManipulator();
-
- 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 setMouseWarped()
- {
- mouseWarped = true;
- }
-
- void setPosition(const osg::Vec3d position) { this->position = position; }
- void setAttitude(const osg::Quat attitude) { this->attitude = attitude; }
-
- /** Whether or not resizing is supported. It might not be when
- * using multiple displays.
- */
- bool getResizable() { return resizable; }
- void setResizable(bool _resizable) { resizable = _resizable; }
-
-protected:
- osg::ref_ptr<osg::Node> _node;
- fgIdleHandler idleHandler;
- fgDrawHandler drawHandler;
- fgWindowResizeHandler windowResizeHandler;
- fgKeyHandler keyHandler;
- fgMouseClickHandler mouseClickHandler;
- fgMouseMotionHandler mouseMotionHandler;
- osg::ref_ptr<osgViewer::StatsHandler> statsHandler;
- osg::ref_ptr<osgGA::GUIEventAdapter> statsEvent;
- int statsType;
- int currentModifiers;
- std::map<int, int> numlockKeyMap;
- osg::Vec3d position;
- osg::Quat attitude;
- void handleKey(const osgGA::GUIEventAdapter& ea, int& key, int& modifiers);
- bool resizable;
- bool mouseWarped;
- // workaround for osgViewer double scroll events
- bool scrollButtonPressed;
- int release_keys[128];
- void handleStats(osgGA::GUIActionAdapter& us);
-};
-
-void eventToWindowCoords(const osgGA::GUIEventAdapter* ea, double& x, double& y);
-void eventToWindowCoordsYDown(const osgGA::GUIEventAdapter* ea,
- double& x, double& y);
-}
-#endif
EXTRA_DIST = 3dfx.sh runfgfs.in runfgfs.bat.in \
- fg_os_sdl.cxx fg_os.cxx fg_os_osgviewer.cxx fg_os.hxx
+ fg_os_osgviewer.cxx fg_os.hxx
MPLAYER_LIBS = $(top_builddir)/src/MultiPlayer/libMultiPlayer.a
THREAD_LIBS =
endif
-GFX_COMMON = fg_os_common.cxx fg_os.hxx
-if USE_SDL
-GFX_CODE = fg_os_sdl.cxx $(GFX_COMMON)
-else
-if USE_GLUT
-GFX_CODE = fg_os.cxx $(GFX_COMMON)
-else
-GFX_CODE = fg_os_osgviewer.cxx $(GFX_COMMON)
-endif
-endif
+GFX_CODE = fg_os_osgviewer.cxx fg_os_common.cxx fg_os.hxx
JSBSIM_LIBS = \
$(top_builddir)/src/FDM/JSBSim/libJSBSim.a \
viewer.cxx viewer.hxx \
viewmgr.cxx viewmgr.hxx \
CameraGroup.cxx CameraGroup.hxx \
- FGManipulator.cxx FGManipulator.hxx \
+ FGEventHandler.cxx FGEventHandler.hxx \
ViewPartitionNode.cxx ViewPartitionNode.hxx \
WindowSystemAdapter.hxx WindowSystemAdapter.cxx \
WindowBuilder.hxx WindowBuilder.cxx \
ref_ptr<WindowBuilder> WindowBuilder::windowBuilder;
+const string WindowBuilder::defaultWindowName("FlightGear");
+
void WindowBuilder::initWindowBuilder(bool stencil)
{
windowBuilder = new WindowBuilder(stencil);
return 0;
}
} else {
+ // XXX What if the window has no traits, but does have a name?
+ // We should create a "default window" registered with that name.
return getDefaultWindow();
}
}
GraphicsWindow* WindowBuilder::getDefaultWindow()
{
- if (defaultWindow.valid())
- return defaultWindow.get();
+ GraphicsWindow* defaultWindow
+ = WindowSystemAdapter::getWSA()->findWindow(defaultWindowName);
+ if (defaultWindow)
+ return defaultWindow;
GraphicsContext::Traits* traits
= new GraphicsContext::Traits(*defaultTraits);
traits->windowName = "FlightGear";
if (gc) {
gc->realize();
defaultWindow = WindowSystemAdapter::getWSA()
- ->registerWindow(gc, traits->windowName);
- return defaultWindow.get();
+ ->registerWindow(gc, defaultWindowName);
+ return defaultWindow;
} else {
return 0;
}
* @return the default graphics window
*/
GraphicsWindow* getDefaultWindow();
+ /** Get the name used to look up the default window.
+ */
+ const std::string& getDefaultWindowName() { return defaultWindowName; }
protected:
WindowBuilder(bool stencil);
static osg::GraphicsContext::Traits* makeDefaultTraits(bool stencil);
osg::ref_ptr<osg::GraphicsContext::Traits> defaultTraits;
int defaultCounter;
static osg::ref_ptr<WindowBuilder> windowBuilder;
- osg::ref_ptr<GraphicsWindow> defaultWindow;
+ static const std::string defaultWindowName;
};
/** Silly function for making the default window and camera
+++ /dev/null
-#ifndef _MSC_VER // MSVC really needs a definition for wchar_t
-#define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
- // redefine it
-#endif
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <osg/Matrix>
-#include <osgViewer/Viewer>
-#include <osgViewer/ViewerEventHandlers>
-
-#include <simgear/compiler.h>
-
-#if defined( __APPLE__)
-# include <GLUT/glut.h>
-#else
-# include <GL/glut.h>
-#endif
-#include <plib/pu.h>
-
-#include <Scenery/scenery.hxx>
-#include "fg_os.hxx"
-#include "globals.hxx"
-#include "renderer.hxx"
-#include "fg_props.hxx"
-#include "WindowSystemAdapter.hxx"
-#include "CameraGroup.hxx"
-
-using namespace flightgear;
-
-//
-// Native glut callbacks.
-// These translate the glut event model into osgGA events
-//
-
-static osg::ref_ptr<osgViewer::Viewer> viewer;
-static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
-
-static int GlutModifiers = 0;
-static unsigned int getOSGModifiers(int modifiers);
-
-static void callKeyHandler(int k, int mods, int x, int y)
-{
-
- int key = 0;
- switch (k) {
- case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
- case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
- case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
- case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
- case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
- case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
- case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
- case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
- case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
- case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
- case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
- case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
- case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
- case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
- case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
- case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
- case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
- case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
- case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
- case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
- case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
- case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
- case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
- case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
- case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
- case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
- default: key = k; break;
- }
- unsigned int osgModifiers = getOSGModifiers(mods);
- osgGA::EventQueue& queue = *gw->getEventQueue();
- queue.getCurrentEventState()->setModKeyMask(osgModifiers);
- if (mods & KEYMOD_RELEASED)
- queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
- else
- queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
-}
-
-static void GLUTmotion (int x, int y)
-{
- if (!gw.valid())
- return;
- gw->getEventQueue()->mouseMotion(x, y);
-}
-
-static void GLUTmouse (int button, int updown, int x, int y)
-{
- GlutModifiers = glutGetModifiers();
- if (gw.valid()) {
- if (updown == 0)
- gw->getEventQueue()->mouseButtonPress(x, y, button+1);
- else
- gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
- }
-}
-
-static void GLUTspecialkeyup(int k, int x, int y)
-{
- GlutModifiers = glutGetModifiers();
- callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
-}
-
-static void GLUTspecialkey(int k, int x, int y)
-{
- GlutModifiers = glutGetModifiers();
- callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
-}
-
-static unsigned char release_keys[256];
-
-static void GLUTkeyup(unsigned char k, int x, int y)
-{
- GlutModifiers = glutGetModifiers();
- callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
-}
-
-static void GLUTkey(unsigned char k, int x, int y)
-{
- GlutModifiers = glutGetModifiers();
- release_keys[k] = k;
- if (k >= 1 && k <= 26) {
- release_keys[k + '@'] = k;
- release_keys[k + '`'] = k;
- } else if (k >= 'A' && k <= 'Z') {
- release_keys[k - '@'] = k;
- release_keys[tolower(k)] = k;
- } else if (k >= 'a' && k <= 'z') {
- release_keys[k - '`'] = k;
- release_keys[toupper(k)] = k;
- }
- callKeyHandler(k, fgGetKeyModifiers(), x, y);
-}
-
-static void GLUTdraw()
-{
- viewer->frame();
- glutSwapBuffers();
- glutPostRedisplay();
-}
-
-static void GLUTreshape(int w, int h)
-{
- // update the window dimensions, in case the window has been resized.
- gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
- gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
- w, h);
-}
-
-//
-// fg_os API definition
-//
-
-void fgOSInit(int* argc, char** argv)
-{
- glutInit(argc, argv);
- WindowSystemAdapter::setWSA(new WindowSystemAdapter);
-}
-
-void fgOSFullScreen()
-{
- glutFullScreen();
-}
-
-void fgOSMainLoop()
-{
- glutMainLoop();
-}
-
-void fgOSExit(int code)
-{
- exit(code);
-}
-
-static int CurrentCursor = MOUSE_CURSOR_POINTER;
-
-int fgGetMouseCursor()
-{
- return CurrentCursor;
-}
-
-void fgSetMouseCursor(int cursor)
-{
- CurrentCursor = cursor;
- if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
- else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
- else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
- else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
- else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
- // Otherwise, pass it through unchanged...
- glutSetCursor(cursor);
-}
-
-void fgWarpMouse(int x, int y)
-{
- globals->get_renderer()->getManipulator()->setMouseWarped();
- glutWarpPointer(x, y);
-}
-
-int fgGetKeyModifiers()
-{
- int result = 0;
- if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
- if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
- if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
- return result;
-}
-
-static unsigned int getOSGModifiers(int glutModifiers)
-{
- unsigned int result = 0;
- if (glutModifiers & GLUT_ACTIVE_SHIFT)
- result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
- if (glutModifiers & GLUT_ACTIVE_CTRL)
- result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
- if(glutModifiers & GLUT_ACTIVE_ALT)
- result |= osgGA::GUIEventAdapter::MODKEY_ALT;
- return result;
-}
-
-void fgOSOpenWindow(bool stencil)
-{
- int w = fgGetInt("/sim/startup/xsize");
- int h = fgGetInt("/sim/startup/ysize");
- int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
- bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
- bool fullscreen = fgGetBool("/sim/startup/fullscreen");
- WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
- int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
-
- if(alpha) mode |= GLUT_ALPHA;
- if(stencil && bpp > 16) mode |= GLUT_STENCIL;
-
- glutInitDisplayMode(mode);
- glutInitWindowSize(w, h);
- if(!fgGetBool("/sim/startup/game-mode")) {
- glutCreateWindow("FlightGear");
- } else {
- char game_mode_str[20];
- SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
- if (p) {
- int hz = p->getIntValue();
- snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
- } else {
- snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
- }
- glutGameModeString( game_mode_str );
- glutEnterGameMode();
- }
-
- // Register these here. Calling them before the window is open
- // crashes.
- glutMotionFunc(GLUTmotion);
- glutPassiveMotionFunc(GLUTmotion);
- glutMouseFunc(GLUTmouse);
- glutSpecialUpFunc(GLUTspecialkeyup);
- glutSpecialFunc(GLUTspecialkey);
- glutKeyboardUpFunc(GLUTkeyup);
- glutKeyboardFunc(GLUTkey);
- glutDisplayFunc(GLUTdraw);
- glutReshapeFunc(GLUTreshape);
- // XXX
- int realw = w;
- int realh = h;
- viewer = new osgViewer::Viewer;
- gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
- GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
- window->flags |= GraphicsWindow::GUI;
- viewer->setDatabasePager(FGScenery::getPagerSingleton());
- // now the main camera ...
- osg::Camera* camera = new osg::Camera;
- // 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.
- camera->setViewport(new osg::Viewport(0, 0, realw, realh));
- camera->setProjectionResizePolicy(osg::Camera::FIXED);
- CameraGroup* cgroup = new CameraGroup(viewer.get());
- cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, camera,
- osg::Matrixd::identity(), osg::Matrixd::identity(),
- true);
- cgroup->buildGUICamera(0, window);
- CameraGroup::setDefault(cgroup);
- 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());
-}
#include "fg_os.hxx"
#include "globals.hxx"
#include "renderer.hxx"
+#include "FGEventHandler.hxx"
// fg_os callback registration APIs
//
// Event handling and scene graph update is all handled by a
-// manipulator. See FGManipulator.cpp
+// manipulator. See FGEventHandler.cpp
void fgRegisterIdleHandler(fgIdleHandler func)
{
- globals->get_renderer()->getManipulator()->setIdleHandler(func);
+ globals->get_renderer()->getEventHandler()->setIdleHandler(func);
}
void fgRegisterDrawHandler(fgDrawHandler func)
{
- globals->get_renderer()->getManipulator()->setDrawHandler(func);
+ globals->get_renderer()->getEventHandler()->setDrawHandler(func);
}
void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
{
- globals->get_renderer()->getManipulator()->setWindowResizeHandler(func);
+ globals->get_renderer()->getEventHandler()->setWindowResizeHandler(func);
}
void fgRegisterKeyHandler(fgKeyHandler func)
{
- globals->get_renderer()->getManipulator()->setKeyHandler(func);
+ globals->get_renderer()->getEventHandler()->setKeyHandler(func);
}
void fgRegisterMouseClickHandler(fgMouseClickHandler func)
{
- globals->get_renderer()->getManipulator()->setMouseClickHandler(func);
+ globals->get_renderer()->getEventHandler()->setMouseClickHandler(func);
}
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
{
- globals->get_renderer()->getManipulator()->setMouseMotionHandler(func);
+ globals->get_renderer()->getEventHandler()->setMouseMotionHandler(func);
}
// Redraw "happens" every frame whether you want it or not.
#include <stdlib.h>
+#include <boost/foreach.hpp>
+
#include <simgear/compiler.h>
#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
+#include <simgear/props/props_io.hxx>
#include <osg/Camera>
#include <osg/GraphicsContext>
#include "globals.hxx"
#include "renderer.hxx"
#include "CameraGroup.hxx"
+#include "FGEventHandler.hxx"
#include "WindowBuilder.hxx"
#include "WindowSystemAdapter.hxx"
static osg::ref_ptr<osgViewer::Viewer> viewer;
static osg::ref_ptr<osg::Camera> mainCamera;
-namespace
-{
-// If a camera group isn't specified, build one from the top-level
-// camera specs and then add a camera aligned with the master camera
-// if it doesn't seem to exist.
-CameraGroup* buildDefaultCameraGroup(osgViewer::Viewer* viewer,
- const SGPropertyNode* gnode)
-{
- WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
- CameraGroup* cgroup = CameraGroup::buildCameraGroup(viewer, gnode);
- // Look for a camera with no shear
- Camera* masterCamera = 0;
- for (CameraGroup::CameraIterator citer = cgroup->camerasBegin(),
- e = cgroup->camerasEnd();
- citer != e;
- ++citer) {
- const View::Slave& slave = viewer->getSlave((*citer)->slaveIndex);
- if (slave._projectionOffset.isIdentity()) {
- masterCamera = (*citer)->camera.get();
- break;
- }
- }
- if (!masterCamera) {
- // No master camera found; better add one.
- GraphicsWindow* window
- = WindowBuilder::getWindowBuilder()->getDefaultWindow();
- masterCamera = new Camera();
- masterCamera->setGraphicsContext(window->gc.get());
- const GraphicsContext::Traits *traits = window->gc->getTraits();
- masterCamera->setViewport(new Viewport(0, 0,
- traits->width, traits->height));
- cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, masterCamera,
- Matrix(), Matrix());
- }
- // Find window on which the GUI is drawn.
- WindowVector::iterator iter = wsa->windows.begin();
- WindowVector::iterator end = wsa->windows.end();
- for (; iter != end; ++iter) {
- if ((*iter)->gc.get() == masterCamera->getGraphicsContext())
- break;
- }
- if (iter != end) { // Better not happen
- (*iter)->flags |= GraphicsWindow::GUI;
- cgroup->buildGUICamera(0, iter->get());
- }
- return cgroup;
-}
-}
-
void fgOSOpenWindow(bool stencil)
{
osg::GraphicsContext::WindowingSystemInterface* wsi
// Look for windows, camera groups, and the old syntax of
// top-level cameras
- const SGPropertyNode* renderingNode = fgGetNode("/sim/rendering");
- for (int i = 0; i < renderingNode->nChildren(); ++i) {
- const SGPropertyNode* propNode = renderingNode->getChild(i);
- const char* propName = propNode->getName();
- if (!strcmp(propName, "window")) {
- windowBuilder->buildWindow(propNode);
- } else if (!strcmp(propName, "camera-group")) {
- cameraGroup = CameraGroup::buildCameraGroup(viewer.get(), propNode);
+ SGPropertyNode* renderingNode = fgGetNode("/sim/rendering");
+ SGPropertyNode* cgroupNode = renderingNode->getChild("camera-group");
+ if (!cgroupNode) {
+ cgroupNode = renderingNode->getNode("camera-group", true);
+ for (int i = 0; i < renderingNode->nChildren(); ++i) {
+ SGPropertyNode* propNode = renderingNode->getChild(i);
+ const char* propName = propNode->getName();
+ if (!strcmp(propName, "window") || !strcmp(propName, "camera")) {
+ SGPropertyNode* copiedNode
+ = cgroupNode->getNode(propName, propNode->getIndex(), true);
+ copyProperties(propNode, copiedNode);
+ }
}
+ vector<SGPropertyNode_ptr> cameras = cgroupNode->getChildren("camera");
+ SGPropertyNode* masterCamera = 0;
+ BOOST_FOREACH(SGPropertyNode_ptr& camera, cameras) {
+ if (camera->getDoubleValue("shear-x", 0.0) == 0.0
+ && camera->getDoubleValue("shear-y", 0.0) == 0.0) {
+ masterCamera = camera.ptr();
+ break;
+ }
+ }
+ if (!masterCamera) {
+ masterCamera = cgroupNode->getChild("camera", cameras.size(), true);
+ setValue(masterCamera->getNode("window/name", true),
+ windowBuilder->getDefaultWindowName());
+ }
+ SGPropertyNode* nameNode = masterCamera->getNode("window/name");
+ if (nameNode)
+ setValue(cgroupNode->getNode("gui/window/name", true),
+ nameNode->getStringValue());
}
- if (!cameraGroup)
- cameraGroup = buildDefaultCameraGroup(viewer.get(), renderingNode);
+ cameraGroup = CameraGroup::buildCameraGroup(viewer.get(), cgroupNode);
Camera* guiCamera = getGUICamera(cameraGroup);
if (guiCamera) {
Viewport* guiViewport = guiCamera->getViewport();
fgSetInt("/sim/startup/xsize", guiViewport->width());
fgSetInt("/sim/startup/ysize", guiViewport->height());
}
- FGManipulator* manipulator = globals->get_renderer()->getManipulator();
+ FGEventHandler* manipulator = globals->get_renderer()->getEventHandler();
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
if (wsa->windows.size() != 1) {
manipulator->setResizable(false);
}
viewer->getCamera()->setProjectionResizePolicy(osg::Camera::FIXED);
- viewer->setCameraManipulator(manipulator);
+ viewer->addEventHandler(manipulator);
// Let FG handle the escape key with a confirmation
viewer->setKeyEventSetsDone(0);
// The viewer won't start without some root.
void fgOSMainLoop()
{
- viewer->run();
+ ref_ptr<FGEventHandler> manipulator
+ = globals->get_renderer()->getEventHandler();
+ viewer->setReleaseContextAtEndOfFrameHint(false);
+ while (!viewer->done()) {
+ fgIdleHandler idleFunc = manipulator->getIdleHandler();
+ fgDrawHandler drawFunc = manipulator->getDrawHandler();
+ if (idleFunc)
+ (*idleFunc)();
+ if (drawFunc)
+ (*drawFunc)();
+ viewer->frame();
+ }
fgExit(status);
}
int fgGetKeyModifiers()
{
- return globals->get_renderer()->getManipulator()->getCurrentModifiers();
+ return globals->get_renderer()->getEventHandler()->getCurrentModifiers();
}
void fgWarpMouse(int x, int y)
+++ /dev/null
-#include <stdlib.h>
-
-#include <osgViewer/ViewerEventHandlers>
-#include <osgViewer/Viewer>
-
-#include <simgear/compiler.h>
-#include <simgear/structure/exception.hxx>
-#include <simgear/debug/logstream.hxx>
-
-#include <SDL/SDL.h>
-
-#include <Scenery/scenery.hxx>
-#include "fg_os.hxx"
-#include "globals.hxx"
-#include "renderer.hxx"
-#include "fg_props.hxx"
-#include "CameraGroup.hxx"
-#include "WindowSystemAdapter.hxx"
-
-using namespace flightgear;
-
-//
-// fg_os callback registration APIs
-//
-
-static int CurrentModifiers = 0;
-static int CurrentMouseX = 0;
-static int CurrentMouseY = 0;
-static int CurrentMouseCursor = MOUSE_CURSOR_POINTER;
-static int VidMask = SDL_OPENGL|SDL_RESIZABLE;
-
-//
-// fg_os implementation
-//
-static void initCursors();
-
-static osg::ref_ptr<osgViewer::Viewer> viewer;
-static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
-
-void fgOSOpenWindow(bool stencil)
-{
- int w = fgGetInt("/sim/startup/xsize");
- int h = fgGetInt("/sim/startup/ysize");
- int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
- bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
- bool fullscreen = fgGetBool("/sim/startup/fullscreen");
- int cbits = (bpp <= 16) ? 5 : 8;
- int zbits = (bpp <= 16) ? 16 : 24;
- WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
-
- if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) == -1)
- throw sg_throwable(string("Failed to initialize SDL: ")
- + SDL_GetError());
- atexit(SDL_Quit);
-
- SDL_WM_SetCaption("FlightGear", "FlightGear");
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, cbits);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, cbits);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, cbits);
- if(alpha)
- SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
- if(bpp > 16 && stencil)
- SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, zbits);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- if(fullscreen) {
- VidMask |= SDL_FULLSCREEN;
- }
- SDL_Surface* screen = SDL_SetVideoMode(w, h, 16, VidMask);
- if ( screen == 0)
- throw sg_throwable(string("Failed to set SDL video mode: ")
- + SDL_GetError());
-
- // This enables keycode translation (e.g. capital letters when
- // shift is pressed, as well as i18n input methods). Eventually,
- // we may want to port the input maps to specify <mod-shift>
- // explicitly, and will turn this off.
- SDL_EnableUNICODE(1);
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-
- initCursors();
- fgSetMouseCursor(MOUSE_CURSOR_POINTER);
-
- // FIXME: we may not get what we asked for (especially in full
- // screen modes), so these need to be propagated back to the
- // property tree for the rest of the code to inspect...
- //
- int realw = screen->w;
- int realh = screen->h;
- viewer = new osgViewer::Viewer;
- viewer->setDatabasePager(FGScenery::getPagerSingleton());
- gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
- GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
- window->flags |= GraphicsWindow::GUI;
- // now the main camera ...
- osg::Camera* camera = new osg::Camera;
- // 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.
- camera->setViewport(new osg::Viewport(0, 0, realw, realh));
- camera->setProjectionResizePolicy(osg::Camera::FIXED);
- CameraGroup* cgroup = new CameraGroup(viewer.get());
- cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, camera,
- osg::Matrixd::identity(), osg::Matrixd::identity(),
- true);
- cgroup->buildGUICamera(0, window);
- CameraGroup::setDefault(cgroup);
- 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());
-}
-
-// Cheap trick to avoid typing GUIEventAdapter over and over...
-class SDLKeyTranslator : osgGA::GUIEventAdapter
-{
-public:
- static int handleKey(int key, int raw, int keyup);
-};
-
-int SDLKeyTranslator::handleKey(int key, int raw, int keyup)
-{
- using namespace osgGA;
-
- int modmask = 0;
- int osgKey = 0;
- if (key == 0)
- key = raw;
- // Don't pass capslock or numlock to the FGManipulator; SDL
- // already transforms the key properly, so FGManipulator will get
- // confused.
- if (key == SDLK_CAPSLOCK || key == SDLK_NUMLOCK)
- return -1;
- switch(key) {
- case SDLK_RSHIFT: modmask = KEYMOD_SHIFT; osgKey = KEY_Shift_R; break;
- case SDLK_LSHIFT: modmask = KEYMOD_SHIFT; osgKey = KEY_Shift_L; break;
- case SDLK_RCTRL: modmask = KEYMOD_CTRL; osgKey = KEY_Control_R; break;
- case SDLK_LCTRL: modmask = KEYMOD_CTRL; osgKey = KEY_Control_L; break;
- case SDLK_RALT: modmask = KEYMOD_ALT; osgKey = KEY_Alt_R; break;
- case SDLK_LALT: modmask = KEYMOD_ALT; osgKey = KEY_Alt_L; break;
- case SDLK_RMETA: modmask = KEYMOD_META; osgKey = KEY_Meta_R; break;
- case SDLK_LMETA: modmask = KEYMOD_META; osgKey = KEY_Meta_L; break;
- case SDLK_RSUPER: modmask = KEYMOD_SUPER; osgKey = KEY_Super_R; break;
- case SDLK_LSUPER: modmask = KEYMOD_SUPER; osgKey = KEY_Super_L; break;
-
- case SDLK_LEFT: osgKey = KEY_Left; break;
- case SDLK_UP: osgKey = KEY_Up; break;
- case SDLK_RIGHT: osgKey = KEY_Right; break;
- case SDLK_DOWN: osgKey = KEY_Down; break;
- case SDLK_PAGEUP: osgKey = KEY_Page_Up; break;
- case SDLK_PAGEDOWN: osgKey = KEY_Page_Down; break;
- case SDLK_HOME: osgKey = KEY_Home; break;
- case SDLK_END: osgKey = KEY_End; break;
- case SDLK_INSERT: osgKey = KEY_Insert; break;
- case SDLK_F1: osgKey = KEY_F1; break;
- case SDLK_F2: osgKey = KEY_F2; break;
- case SDLK_F3: osgKey = KEY_F3; break;
- case SDLK_F4: osgKey = KEY_F4; break;
- case SDLK_F5: osgKey = KEY_F5; break;
- case SDLK_F6: osgKey = KEY_F6; break;
- case SDLK_F7: osgKey = KEY_F7; break;
- case SDLK_F8: osgKey = KEY_F8; break;
- case SDLK_F9: osgKey = KEY_F9; break;
- case SDLK_F10: osgKey = KEY_F10; break;
- case SDLK_F11: osgKey = KEY_F11; break;
- case SDLK_F12: osgKey = KEY_F12; break;
- default:
- osgKey = key;
- }
- int keymod = 0;
- if(keyup) {
- CurrentModifiers &= ~modmask;
- keymod = CurrentModifiers | KEYMOD_RELEASED;
- } else {
- CurrentModifiers |= modmask;
- keymod = CurrentModifiers & ~KEYMOD_RELEASED;
- }
- return osgKey;
-}
-
-// FIXME: Integrate with existing fgExit() in util.cxx.
-void fgOSExit(int code)
-{
- viewer->setDone(true);
- exit(code);
-}
-
-// originally from osgexamples/osgviewerSDL.cpp
-bool convertEvent(SDL_Event& event, osgGA::EventQueue& eventQueue)
-{
- using namespace osgGA;
- switch (event.type) {
-
- case SDL_MOUSEMOTION:
- eventQueue.mouseMotion(event.motion.x, event.motion.y);
- return true;
-
- case SDL_MOUSEBUTTONDOWN:
- eventQueue.mouseButtonPress(event.button.x, event.button.y, event.button.button);
- return true;
-
- case SDL_MOUSEBUTTONUP:
- eventQueue.mouseButtonRelease(event.button.x, event.button.y, event.button.button);
- return true;
-
- case SDL_KEYUP:
- case SDL_KEYDOWN:
- {
- int realKey = SDLKeyTranslator::handleKey(event.key.keysym.unicode,
- event.key.keysym.sym,
- event.type == SDL_KEYUP);
- if (realKey < -1)
- return true;
- if (event.type == SDL_KEYUP)
- eventQueue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)realKey);
- else
- eventQueue.keyPress((osgGA::GUIEventAdapter::KeySymbol)realKey);
- return true;
- }
- case SDL_VIDEORESIZE:
- if (SDL_SetVideoMode(event.resize.w, event.resize.h, 16, VidMask) == 0)
- throw sg_throwable(string("Failed to set SDL video mode: ")
- + SDL_GetError());
- eventQueue.windowResize(0, 0, event.resize.w, event.resize.h );
- return true;
-
- default:
- break;
- }
- return false;
-}
-
-void fgOSMainLoop()
-{
- while(1) {
- SDL_Event e;
- int key;
- while(SDL_PollEvent(&e)) {
- // pass the SDL event into the viewers event queue
- convertEvent(e, *(gw->getEventQueue()));
-
- switch(e.type) {
- case SDL_QUIT:
- fgOSExit(0);
- break;
- case SDL_VIDEORESIZE:
- gw->resized(0, 0, e.resize.w, e.resize.h );
- break;
- }
- }
- // draw the new frame
- viewer->frame();
-
- // Swap Buffers
- SDL_GL_SwapBuffers();
- }
-}
-
-int fgGetKeyModifiers()
-{
- return CurrentModifiers;
-}
-
-void fgWarpMouse(int x, int y)
-{
- globals->get_renderer()->getManipulator()->setMouseWarped();
- SDL_WarpMouse(x, y);
-}
-
-void fgOSInit(int* argc, char** argv)
-{
- WindowSystemAdapter::setWSA(new WindowSystemAdapter);
-}
-
-void fgOSFullScreen()
-{
- // Noop. SDL must set fullscreen at window open time and cannot
- // change modes.
-}
-
-static struct cursor_rec {
- int name;
- SDL_Cursor* sdlCursor;
- int w;
- int h;
- int hotx;
- int hoty;
- const char *img[32]; // '.' == white, '#' == black, ' ' == transparent
-} cursors[] = {
- { MOUSE_CURSOR_POINTER, 0, // must be first!
- 10, 16, 1, 1,
- { ".. ",
- ".#. ",
- ".##. ",
- ".###. ",
- ".####. ",
- ".#####. ",
- ".######. ",
- ".#######. ",
- ".########.",
- ".#####....",
- ".##.##. ",
- ".#. .##. ",
- ".. .##. ",
- " .##. ",
- " .##. ",
- " .. " } },
- { MOUSE_CURSOR_CROSSHAIR, 0,
- 17, 17, 8, 8,
- { " ... ",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- "........#........",
- ".#######.#######.",
- "........#........",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- " .#. ",
- " ... " } },
- { MOUSE_CURSOR_WAIT, 0,
- 16, 16, 7, 7,
- { " .########. ",
- " .########. ",
- " .########. ",
- " .##########. ",
- ".##....#...##. ",
- "##.....#....##..",
- "#......#.....###",
- "#.....###....###",
- "#.....###....###",
- "#....#.......###",
- "##..#.......##..",
- ".##........##. ",
- " .##########. ",
- " .########. ",
- " .########. ",
- " .########. " } },
- { MOUSE_CURSOR_LEFTRIGHT, 0,
- 17, 9, 8, 4,
- { " .. .. ",
- " .#. .#. ",
- " .##.......##. ",
- " .#############. ",
- ".####.......####.",
- " .#############. ",
- " .##.......##. ",
- " .#. .#. ",
- " .. .. " } },
- { MOUSE_CURSOR_NONE, 0, // must come last!
- 1, 1, 0, 0, { " " } },
-};
-
-#define NCURSORS (sizeof(cursors)/sizeof(struct cursor_rec))
-
-void fgSetMouseCursor(int cursor)
-{
- if(cursor == MOUSE_CURSOR_NONE) {
- SDL_ShowCursor(SDL_DISABLE);
- return;
- }
- SDL_ShowCursor(SDL_ENABLE);
- for(unsigned int i=0; i<NCURSORS; i++) {
- if(cursor == cursors[i].name) {
- CurrentMouseCursor = cursor;
- SDL_SetCursor(cursors[i].sdlCursor);
- return;
- }
- }
- // Default to pointer
- CurrentMouseCursor = MOUSE_CURSOR_POINTER;
- SDL_SetCursor(cursors[0].sdlCursor);
-}
-
-int fgGetMouseCursor()
-{
- return CurrentMouseCursor;
-}
-
-static void initCursors()
-{
- unsigned char mask[128], img[128];
- for(unsigned int i=0; i<NCURSORS; i++) {
- if(cursors[i].name == MOUSE_CURSOR_NONE) break;
- for(int j=0; j<128; j++) mask[j] = img[j] = 0;
- for(int y=0; y<cursors[i].h; y++) {
- for(int x=0; x<cursors[i].w; x++) {
- int byte = (4 * y) + (x >> 3);
- int bit = 1 << (7 - (x & 7));
- int pix = cursors[i].img[y][x];
- if(pix != ' ') { mask[byte] |= bit; }
- if(pix == '#') { img[byte] |= bit; }
- }
- }
- cursors[i].sdlCursor = SDL_CreateCursor(img, mask, 32, 32,
- cursors[i].hotx,
- cursors[i].hoty);
- }
-}
#include "renderer.hxx"
#include "main.hxx"
#include "CameraGroup.hxx"
-#include "ViewPartitionNode.hxx"
+#include "FGEventHandler.hxx"
// XXX Make this go away when OSG 2.2 is released.
#if (FG_OSG_VERSION >= 21004)
static osg::ref_ptr<osg::Group> mRoot = new osg::Group;
-static osg::ref_ptr<ViewPartitionNode> viewPartition = new ViewPartitionNode;
-
FGRenderer::FGRenderer()
{
#ifdef FG_JPEG_SERVER
jpgRenderFrame = FGRenderer::update;
#endif
- manipulator = new FGManipulator;
+ eventHandler = new FGEventHandler;
}
FGRenderer::~FGRenderer()
osg::Switch* sw = new osg::Switch;
sw->setUpdateCallback(new FGScenerySwitchCallback);
sw->addChild(mRoot.get());
- viewPartition->addChild(sw);
- viewPartition->addChild(thesky->getCloudRoot());
-
- mRealRoot->addChild(viewPartition.get());
+ mRealRoot->addChild(sw);
+ mRealRoot->addChild(thesky->getCloudRoot());
mRealRoot->addChild(FGCreateRedoutNode());
}
l->adj_fog_color(),
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
mUpdateVisitor->setVisibility(actual_visibility);
- viewPartition->setVisibility(actual_visibility);
simgear::GroundLightManager::instance()->update(mUpdateVisitor.get());
bool hotspots = fgGetBool("/sim/panel-hotspots");
osg::Node::NodeMask cullMask = ~simgear::LIGHTS_BITS & ~simgear::PICK_BIT;
->getLightNodeMask(mUpdateVisitor.get());
if (hotspots)
cullMask |= simgear::PICK_BIT;
- camera->setCullMask(cullMask);
- // XXX
- for (int i = 0; i < viewer->getNumSlaves(); ++i)
- viewer->getSlave(i)._camera->setCullMask(cullMask);
+ CameraGroup::getDefault()->setCameraCullMasks(cullMask);
}
return !pickList.empty();
}
+void
+FGRenderer::setViewer(osgViewer::Viewer* viewer_)
+{
+ viewer = viewer_;
+}
+
+void
+FGRenderer::setEventHandler(FGEventHandler* eventHandler_)
+{
+ eventHandler = eventHandler_;
+}
+
void
FGRenderer::addCamera(osg::Camera* camera, bool useSceneData)
{
#include <simgear/screen/extensions.hxx>
#include <simgear/scene/util/SGPickCallback.hxx>
-#include <osg/Camera>
-#include <osgViewer/Viewer>
-
-#include "FGManipulator.hxx"
+#include <osg/ref_ptr>
+
+namespace osg
+{
+class Camera;
+class Group;
+}
+
+namespace osgGA
+{
+class GUIEventAdapter;
+}
+
+namespace osgShadow
+{
+class ShadowedScene;
+}
+
+namespace osgViewer
+{
+class Viewer;
+}
+
+namespace flightgear
+{
+class FGEventHandler;
+}
#define FG_ENABLE_MULTIPASS_CLOUDS 1
*/
osgViewer::Viewer* getViewer() { return viewer.get(); }
const osgViewer::Viewer* getViewer() const { return viewer.get(); }
- void setViewer(osgViewer::Viewer* viewer) { this->viewer = viewer; }
+ void setViewer(osgViewer::Viewer* viewer);
/** Get and set the manipulator object, if any.
*/
- flightgear::FGManipulator* getManipulator() { return manipulator.get(); }
- const flightgear::FGManipulator* getManipulator() const { return manipulator.get(); }
- void setManipulator(flightgear::FGManipulator* manipulator) {
- this->manipulator = manipulator;
- }
+ flightgear::FGEventHandler* getEventHandler() { return eventHandler.get(); }
+ const flightgear::FGEventHandler* getEventHandler() const { return eventHandler.get(); }
+ void setEventHandler(flightgear::FGEventHandler* manipulator);
/** Add a top level camera.
*/
protected:
osg::ref_ptr<osgViewer::Viewer> viewer;
- osg::ref_ptr<flightgear::FGManipulator> manipulator;
+ osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
};
bool fgDumpSceneGraphToFile(const char* filename);
#include <algorithm>
#include <functional>
+#include <osgViewer/Viewer>
+
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/point3d.hxx>