+set(FGVIEWER_SOURCES
+ fgviewer.cxx
+ Drawable.cxx
+ Renderer.cxx
+ SlaveCamera.cxx
+ Viewer.cxx
+)
-add_executable(fgviewer fgviewer.cxx)
+if(RTI_FOUND)
+ set(FGVIEWER_RTI_SOURCES
+ HLACamera.cxx
+ HLACameraClass.cxx
+ HLACameraManipulator.cxx
+ HLADrawable.cxx
+ HLADrawableClass.cxx
+ HLAEyeTracker.cxx
+ HLAEyeTrackerClass.cxx
+ HLAMPAircraft.cxx
+ HLAMPAircraftClass.cxx
+ HLAOrthographicCamera.cxx
+ HLAOrthographicCameraClass.cxx
+ HLAPerspectiveCamera.cxx
+ HLAPerspectiveCameraClass.cxx
+ HLAPerspectiveViewer.cxx
+ HLAPerspectiveViewerClass.cxx
+ HLARenderer.cxx
+ HLARendererClass.cxx
+ HLASceneObject.cxx
+ HLASceneObjectClass.cxx
+ HLAView.cxx
+ HLAViewClass.cxx
+ HLAViewer.cxx
+ HLAViewerClass.cxx
+ HLAViewerFederate.cxx
+ HLAWindowDrawable.cxx
+ HLAWindowDrawableClass.cxx
+ )
+ set(FGVIEWER_RTI_LIBRARIES ${RTI_LIBRARIES})
+else()
+ set(FGVIEWER_RTI_LIBRARIES "")
+ set(FGVIEWER_RTI_SOURCES "")
+endif()
+add_executable(fgviewer ${FGVIEWER_SOURCES} ${FGVIEWER_RTI_SOURCES})
target_link_libraries(fgviewer
+ ${FGVIEWER_RTI_LIBRARIES}
${SIMGEAR_LIBRARIES}
${OPENSCENEGRAPH_LIBRARIES}
${OPENGL_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}
)
-
install(TARGETS fgviewer RUNTIME DESTINATION bin)
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Drawable.hxx"
+
+#include "Viewer.hxx"
+
+namespace fgviewer {
+
+class Drawable::_ResizedCallback : public osg::GraphicsContext::ResizedCallback {
+public:
+ _ResizedCallback(Drawable* drawable) :
+ _drawable(drawable)
+ { }
+ virtual ~_ResizedCallback()
+ { }
+ virtual void resizedImplementation(osg::GraphicsContext*, int x, int y, int width, int height)
+ {
+ SGSharedPtr<Drawable> drawable = _drawable.lock();
+ if (!drawable.valid())
+ return;
+ drawable->resize(x, y, width, height);
+ }
+ SGWeakPtr<Drawable> _drawable;
+};
+
+Drawable::Drawable(const std::string& name) :
+ _name(name),
+ _position(0, 0),
+ _size(600, 800),
+ _offscreen(false),
+ _fullscreen(false)
+{
+}
+
+Drawable::~Drawable()
+{
+}
+
+void
+Drawable::attachSlaveCamera(SlaveCamera* slaveCamera)
+{
+ if (!slaveCamera)
+ return;
+ _slaveCameraList.push_back(slaveCamera);
+}
+
+bool
+Drawable::resize(int x, int y, int width, int height)
+{
+ unsigned numCameras = _slaveCameraList.size();
+ if (1 < numCameras)
+ return false;
+ _graphicsContext->resizedImplementation(x, y, width, height);
+ if (numCameras < 1)
+ return true;
+ _slaveCameraList.front()->setViewport(SGVec4i(0, 0, width, height));
+ return true;
+}
+
+bool
+Drawable::realize(Viewer& viewer)
+{
+ if (_graphicsContext.valid())
+ return false;
+ _graphicsContext = _realizeImplementation(viewer);
+ if (!_graphicsContext.valid())
+ return false;
+ _graphicsContext->setResizedCallback(new _ResizedCallback(this));
+ return true;
+}
+
+osg::GraphicsContext*
+Drawable::_realizeImplementation(Viewer& viewer)
+{
+ osg::ref_ptr<osg::GraphicsContext::Traits> traits = _getTraits(viewer);
+ return viewer.createGraphicsContext(traits.get());
+}
+
+osg::ref_ptr<osg::GraphicsContext::Traits>
+Drawable::_getTraits(Viewer& viewer)
+{
+ osg::GraphicsContext::ScreenIdentifier screenIdentifier;
+ screenIdentifier.setScreenIdentifier(_screenIdentifier);
+
+ osg::ref_ptr<osg::GraphicsContext::Traits> traits;
+ traits = viewer.getTraits(screenIdentifier);
+
+ // The window name as displayed by the window manager
+ traits->windowName = getName();
+
+ traits->x = _position[0];
+ traits->y = _position[1];
+ if (!_fullscreen) {
+ traits->width = _size[0];
+ traits->height = _size[1];
+ }
+
+ traits->windowDecoration = !_fullscreen;
+ if (_slaveCameraList.size() <= 1)
+ traits->supportsResize = true;
+ else
+ traits->supportsResize = false;
+ traits->pbuffer = _offscreen;
+
+ return traits;
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _fgviewer_Drawable_hxx
+#define _fgviewer_Drawable_hxx
+
+#include <string>
+#include <list>
+#include <osg/GraphicsContext>
+#include <simgear/math/SGMath.hxx>
+#include <simgear/structure/SGWeakReferenced.hxx>
+
+namespace fgviewer {
+
+class Viewer;
+class SlaveCamera;
+
+class Drawable : public SGWeakReferenced {
+public:
+ Drawable(const std::string& name);
+ virtual ~Drawable();
+
+ const std::string& getName() const
+ { return _name; }
+
+ virtual bool setScreenIdentifier(const std::string& screenIdentifier)
+ {
+ if (_graphicsContext.valid())
+ return false;
+ _screenIdentifier = screenIdentifier;
+ return true;
+ }
+ const std::string& getScreenIdentifier() const
+ { return _screenIdentifier; }
+
+ virtual bool setPosition(const SGVec2i& position)
+ { _position = position; return true; }
+ const SGVec2i& getPosition() const
+ { return _position; }
+
+ virtual bool setSize(const SGVec2i& size)
+ { _size = size; return true; }
+ const SGVec2i& getSize() const
+ { return _size; }
+
+ virtual bool setOffscreen(bool offscreen)
+ {
+ if (_graphicsContext.valid())
+ return false;
+ _offscreen = offscreen;
+ return true;
+ }
+ bool getOffscreen() const
+ { return _offscreen; }
+
+ virtual bool setFullscreen(bool fullscreen)
+ { _fullscreen = fullscreen; return true; }
+ bool getFullscreen() const
+ { return _fullscreen; }
+
+ osg::GraphicsContext* getGraphicsContext()
+ { return _graphicsContext.get(); }
+
+ void attachSlaveCamera(SlaveCamera* slaveCamera);
+
+ virtual bool resize(int x, int y, int width, int height);
+
+ bool realize(Viewer& viewer);
+
+protected:
+ virtual osg::GraphicsContext* _realizeImplementation(Viewer& viewer);
+ osg::ref_ptr<osg::GraphicsContext::Traits> _getTraits(Viewer& viewer);
+
+private:
+ Drawable(const Drawable&);
+ Drawable& operator=(const Drawable&);
+
+ class _ResizedCallback;
+
+ /// The immutable name that is used to reference this slave camera.
+ const std::string _name;
+ std::string _screenIdentifier;
+ SGVec2i _position;
+ SGVec2i _size;
+ bool _offscreen;
+ bool _fullscreen;
+ osg::ref_ptr<osg::GraphicsContext> _graphicsContext;
+ std::list<SGSharedPtr<SlaveCamera> > _slaveCameraList;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef Frustum_hxx
+#define Frustum_hxx
+
+#include <cmath>
+#include <osg/Matrix>
+#include <osg/Vec2>
+#include <osg/Vec3>
+#include <simgear/math/SGMath.hxx>
+
+namespace fgviewer {
+
+struct Frustum {
+ Frustum(const double& aspectRatio = 1) :
+ _left(-aspectRatio),
+ _right(aspectRatio),
+ _bottom(-1),
+ _top(1),
+ _near(2)
+ { }
+ Frustum(const double& left, const double& right, const double& bottom, const double& top, const double& near) :
+ _left(left),
+ _right(right),
+ _bottom(bottom),
+ _top(top),
+ _near(near)
+ { }
+ Frustum(const Frustum& frustum) :
+ _left(frustum._left),
+ _right(frustum._right),
+ _bottom(frustum._bottom),
+ _top(frustum._top),
+ _near(frustum._near)
+ { }
+
+ bool setMatrix(const osg::Matrix& matrix)
+ {
+ double zFar;
+ return matrix.getFrustum(_left, _right, _bottom, _top, _near, zFar);
+ }
+ osg::Matrix getMatrix() const
+ {
+ return getMatrix(osg::Vec2(_near, 2*_near));
+ }
+ /// Finite projection matrix
+ osg::Matrix getMatrix(const osg::Vec2& depthRange) const
+ {
+ double near = depthRange[0];
+ double far = depthRange[1];
+ /// left, right, bottom and top are rescaled by near/_near and the result is
+ /// inserted into the final equations. This rescaling factor just cancels out mostly.
+ double a00 = 2*_near/(_right - _left);
+ double a11 = 2*_near/(_top - _bottom);
+ double a20 = (_right + _left)/(_right - _left);
+ double a21 = (_top + _bottom)/(_top - _bottom);
+ double a22 = (near + far)/(near - far);
+ double a23 = -1;
+ double a32 = 2*near*far/(near - far);
+
+ return osg::Matrix(a00, 0, 0, 0,
+ 0, a11, 0, 0,
+ a20, a21, a22, a23,
+ 0, 0, a32, 0);
+ }
+ /// Infinite projection matrix with a given near plane
+ osg::Matrix getMatrix(const double& near, const double& eps = 0) const
+ {
+ /// left, right, bottom and top are rescaled by near/_near and the result is
+ /// inserted into the final equations. This rescaling factor just cancels out mostly.
+ double a00 = 2*_near/(_right - _left);
+ double a11 = 2*_near/(_top - _bottom);
+ double a20 = (_right + _left)/(_right - _left);
+ double a21 = (_top + _bottom)/(_top - _bottom);
+ double a22 = eps - 1;
+ double a23 = -1;
+ double a32 = near*(eps - 2);
+
+ return osg::Matrix(a00, 0, 0, 0,
+ 0, a11, 0, 0,
+ a20, a21, a22, a23,
+ 0, 0, a32, 0);
+ }
+
+ /// Return the aspect ratio of the frustum
+ double getAspectRatio() const
+ { return (_right - _left)/(_top - _bottom); }
+ void setAspectRatio(double aspectRatio)
+ {
+ double aspectScale = aspectRatio/getAspectRatio();
+ _left *= aspectScale;
+ _right *= aspectScale;
+ }
+
+ void setFieldOfViewRad(double fieldOfViewRad)
+ {
+ double fieldOfView = tan(fieldOfViewRad);
+ double aspectRatio = getAspectRatio();
+ _left = -fieldOfView*aspectRatio*0.5*_near;
+ _right = fieldOfView*aspectRatio*0.5*_near;
+ _bottom = -fieldOfView*0.5*_near;
+ _top = fieldOfView*0.5*_near;
+ }
+ void setFieldOfViewDeg(double fieldOfViewDeg)
+ { setFieldOfViewRad(SGMiscd::deg2rad(fieldOfViewDeg)); }
+
+
+ /// Translate this frustum by the given eye point offset
+ Frustum translate(const osg::Vec3& eyeOffset) const
+ {
+ double left = _left - eyeOffset[0];
+ double right = _right - eyeOffset[0];
+ double bottom = _bottom - eyeOffset[1];
+ double top = _top - eyeOffset[1];
+ double near = _near + eyeOffset[2];
+ return Frustum(left, right, bottom, top, near);
+ }
+ /// Scale this frustum around the scale center.
+ /// Gives something similar like zooming into the view.
+ Frustum scale(double scaleFactor, const osg::Vec3& scaleCenter) const
+ {
+ Frustum frustum;
+ frustum._left = scaleFactor*(_left - scaleCenter[0]) + scaleCenter[0];
+ frustum._right = scaleFactor*(_right - scaleCenter[0]) + scaleCenter[0];
+ frustum._bottom = scaleFactor*(_bottom - scaleCenter[1]) + scaleCenter[1];
+ frustum._top = scaleFactor*(_top - scaleCenter[1]) + scaleCenter[1];
+ frustum._near = scaleFactor*(_near + scaleCenter[2]) - scaleCenter[2];
+ return frustum;
+ }
+
+ // Parameters for the reference view frustum.
+ double _left;
+ double _right;
+ double _bottom;
+ double _top;
+ // Is not the real near plane. Just used to reference the other frustum parameters.
+ double _near;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLACamera.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLACameraClass.hxx"
+
+namespace fgviewer {
+
+HLACamera::HLACamera(HLACameraClass* objectClass) :
+ HLAObjectInstance(objectClass)
+{
+}
+
+HLACamera::~HLACamera()
+{
+}
+
+void
+HLACamera::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLACameraClass*>(getObjectClass().get()));
+ HLACameraClass& objectClass = static_cast<HLACameraClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
+ setAttributeDataElement(objectClass.getViewerIndex(), _viewer.getDataElement());
+ setAttributeDataElement(objectClass.getDrawableIndex(), _drawable.getDataElement());
+ setAttributeDataElement(objectClass.getViewportIndex(), _viewport.getDataElement());
+ setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
+ setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLACamera_hxx
+#define HLACamera_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLACameraClass;
+
+class HLACamera : public simgear::HLAObjectInstance {
+public:
+ HLACamera(HLACameraClass* objectClass = 0);
+ virtual ~HLACamera();
+
+ virtual void createAttributeDataElements();
+
+ const std::string& getName() const
+ { return _name.getValue(); }
+ void setName(const std::string& name)
+ { _name.setValue(name); }
+
+ const std::string& getViewer() const
+ { return _viewer.getValue(); }
+ void setViewer(const std::string& viewer)
+ { _viewer.setValue(viewer); }
+
+ const std::string& getDrawable() const
+ { return _drawable.getValue(); }
+ void setDrawable(const std::string& drawable)
+ { _drawable.setValue(drawable); }
+
+ const SGVec4i& getViewport() const
+ { return _viewport.getValue(); }
+ void setViewport(const SGVec4i& viewport)
+ { _viewport.setValue(viewport); }
+
+ const SGVec3d& getPosition() const
+ { return _position.getValue(); }
+ void setPosition(const SGVec3d& position)
+ { _position.setValue(position); }
+
+ const SGQuatd& getOrientation() const
+ { return _orientation.getValue(); }
+ void setOrientation(const SGQuatd& orientation)
+ { _orientation.setValue(orientation); }
+
+ SGLocationd getLocation() const
+ { return SGLocationd(getPosition(), getOrientation()); }
+ void setLocation(const SGLocationd& location)
+ { setPosition(location.getPosition()); setOrientation(location.getOrientation()); }
+
+private:
+ simgear::HLAStringData _name;
+ simgear::HLAStringData _viewer;
+ simgear::HLAStringData _drawable;
+ simgear::HLAVec4iData _viewport;
+ simgear::HLAVec3dData _position;
+ simgear::HLAQuat3dData _orientation;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLACameraClass.hxx"
+
+#include "HLACamera.hxx"
+
+namespace fgviewer {
+
+HLACameraClass::HLACameraClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLACameraClass::~HLACameraClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLACameraClass::createObjectInstance(const std::string& name)
+{
+ return new HLACamera(this);
+}
+
+void
+HLACameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_nameIndex.empty())
+ _nameIndex = getDataElementIndex("name");
+ if (_viewerIndex.empty())
+ _viewerIndex = getDataElementIndex("viewer");
+ if (_drawableIndex.empty())
+ _drawableIndex = getDataElementIndex("drawable");
+ if (_viewportIndex.empty())
+ _viewportIndex = getDataElementIndex("viewport");
+ if (_positionIndex.empty())
+ _positionIndex = getDataElementIndex("location.position");
+ if (_orientationIndex.empty())
+ _orientationIndex = getDataElementIndex("location.orientation");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLACameraClass_hxx
+#define HLACameraClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLACameraClass : public simgear::HLAObjectClass {
+public:
+ HLACameraClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLACameraClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setNameIndex(const std::string& path)
+ { return getDataElementIndex(_nameIndex, path); }
+ const simgear::HLADataElementIndex& getNameIndex() const
+ { return _nameIndex; }
+
+ bool setViewerIndex(const std::string& path)
+ { return getDataElementIndex(_viewerIndex, path); }
+ const simgear::HLADataElementIndex& getViewerIndex() const
+ { return _viewerIndex; }
+
+ bool setDrawableIndex(const std::string& path)
+ { return getDataElementIndex(_drawableIndex, path); }
+ const simgear::HLADataElementIndex& getDrawableIndex() const
+ { return _drawableIndex; }
+
+ bool setViewportIndex(const std::string& path)
+ { return getDataElementIndex(_viewportIndex, path); }
+ const simgear::HLADataElementIndex& getViewportIndex() const
+ { return _viewportIndex; }
+
+ bool setPositionIndex(const std::string& path)
+ { return getDataElementIndex(_positionIndex, path); }
+ const simgear::HLADataElementIndex& getPositionIndex() const
+ { return _positionIndex; }
+
+ bool setOrientationIndex(const std::string& path)
+ { return getDataElementIndex(_orientationIndex, path); }
+ const simgear::HLADataElementIndex& getOrientationIndex() const
+ { return _orientationIndex; }
+
+private:
+ simgear::HLADataElementIndex _nameIndex;
+ simgear::HLADataElementIndex _viewerIndex;
+ simgear::HLADataElementIndex _drawableIndex;
+ simgear::HLADataElementIndex _viewportIndex;
+ simgear::HLADataElementIndex _positionIndex;
+ simgear::HLADataElementIndex _orientationIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLACameraManipulator.hxx"
+
+#include <simgear/scene/util/OsgMath.hxx>
+#include "HLAPerspectiveViewer.hxx"
+#include "Viewer.hxx"
+
+namespace fgviewer {
+
+HLACameraManipulator::HLACameraManipulator(HLAPerspectiveViewer* perspectiveViewer) :
+ _viewMatrix(osg::Matrixd::identity()),
+ _inverseViewMatrix(osg::Matrixd::identity()),
+ _lastMousePos(0, 0),
+ _perspectiveViewer(perspectiveViewer)
+{
+}
+
+HLACameraManipulator::HLACameraManipulator(const HLACameraManipulator& cameraManipulator, const osg::CopyOp& copyOp) :
+ osgGA::CameraManipulator(cameraManipulator, copyOp),
+ _viewMatrix(cameraManipulator._viewMatrix),
+ _inverseViewMatrix(cameraManipulator._inverseViewMatrix),
+ _lastMousePos(cameraManipulator._lastMousePos),
+ _perspectiveViewer(cameraManipulator._perspectiveViewer)
+{
+}
+
+HLACameraManipulator::~HLACameraManipulator()
+{
+}
+
+void
+HLACameraManipulator::setByMatrix(const osg::Matrixd& matrix)
+{
+}
+
+void
+HLACameraManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
+{
+}
+
+osg::Matrixd
+HLACameraManipulator::getMatrix() const
+{
+ return _viewMatrix;
+}
+
+osg::Matrixd
+HLACameraManipulator::getInverseMatrix() const
+{
+ return _inverseViewMatrix;
+}
+
+bool
+HLACameraManipulator::handle(const osgGA::GUIEventAdapter& eventAdapter, osgGA::GUIActionAdapter& actionAdapter)
+{
+ if (_handle(eventAdapter, static_cast<Viewer&>(actionAdapter)))
+ return true;
+ return osgGA::CameraManipulator::handle(eventAdapter, actionAdapter);
+}
+
+bool
+HLACameraManipulator::_handle(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
+{
+ switch (eventAdapter.getEventType()) {
+ case osgGA::GUIEventAdapter::PUSH:
+ _lastMousePos = osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized());
+ break;
+ case osgGA::GUIEventAdapter::RELEASE:
+ break;
+ case osgGA::GUIEventAdapter::DOUBLECLICK:
+ break;
+ case osgGA::GUIEventAdapter::DRAG:
+ if (!eventAdapter.getModKeyMask())
+ _rotateView(osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized()) - _lastMousePos);
+ else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL)
+ _rotateSun(osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized()) - _lastMousePos, viewer);
+ _lastMousePos = osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized());
+ break;
+ case osgGA::GUIEventAdapter::MOVE:
+ break;
+ case osgGA::GUIEventAdapter::SCROLL:
+ break;
+
+ case osgGA::GUIEventAdapter::KEYDOWN:
+ _handleKeyDownEvent(eventAdapter, viewer);
+ break;
+ case osgGA::GUIEventAdapter::KEYUP:
+ _handleKeyUpEvent(eventAdapter, viewer);
+ break;
+
+ case osgGA::GUIEventAdapter::FRAME:
+ _handleFrameEvent(viewer);
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+void
+HLACameraManipulator::_handleFrameEvent(osgGA::GUIActionAdapter& actionAdapter)
+{
+ // Note that eventAdapter.getTime() returns the reference time instead of the simulation time
+ osg::View* view = actionAdapter.asView();
+ if (!view)
+ return;
+ osg::FrameStamp* frameStamp = view->getFrameStamp();
+ if (!frameStamp)
+ return;
+ if (!_perspectiveViewer.valid())
+ return;
+
+ SGLocationd location;
+ location = _perspectiveViewer->getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
+
+ // Update the main cameras view matrix
+ _viewMatrix = osg::Matrixd::identity();
+ // transform from the simulation typical x-forward/y-right/z-down
+ // to the opengl camera system x-right/y-up/z-back
+ // _viewMatrix.postMultRotate(toOsg(SGQuatd::fromEulerDeg(90, 0, -90)));
+ _viewMatrix.postMultRotate(toOsg(SGQuatd(-0.5, -0.5, 0.5, 0.5)));
+ // the orientation of the view
+ _viewMatrix.postMultRotate(toOsg(location.getOrientation()));
+ // the position of the view
+ _viewMatrix.postMultTranslate(toOsg(location.getPosition()));
+ _inverseViewMatrix = osg::Matrixd::inverse(_viewMatrix);
+}
+
+bool
+HLACameraManipulator::_handleKeyDownEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
+{
+ if (!_perspectiveViewer.valid())
+ return false;
+
+ switch (eventAdapter.getKey()) {
+ case osgGA::GUIEventAdapter::KEY_Space:
+ case osgGA::GUIEventAdapter::KEY_Home:
+ _resetView();
+ return false;
+
+ case osgGA::GUIEventAdapter::KEY_Left:
+ _incrementEyePosition(SGVec3d(-0.1, 0, 0));
+ return false;
+ case osgGA::GUIEventAdapter::KEY_Right:
+ _incrementEyePosition(SGVec3d(0.1, 0, 0));
+ return false;
+ case osgGA::GUIEventAdapter::KEY_Up:
+ if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) {
+ _perspectiveViewer->setZoomFactor(_perspectiveViewer->getZoomFactor()*1.1);
+ } else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT) {
+ _incrementEyePosition(SGVec3d(0, 0, 0.1));
+ } else {
+ _incrementEyePosition(SGVec3d(0, 0.1, 0));
+ }
+ return false;
+ case osgGA::GUIEventAdapter::KEY_Down:
+ if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) {
+ _perspectiveViewer->setZoomFactor(_perspectiveViewer->getZoomFactor()/1.1);
+ } else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT) {
+ _incrementEyePosition(SGVec3d(0, 0, -0.1));
+ } else {
+ _incrementEyePosition(SGVec3d(0, -0.1, 0));
+ }
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool
+HLACameraManipulator::_handleKeyUpEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
+{
+ return false;
+}
+
+void
+HLACameraManipulator::_incrementEyePosition(const SGVec3d& offset)
+{
+ if (!_perspectiveViewer.valid())
+ return;
+ HLAEyeTracker* eyeTracker = _perspectiveViewer->getEyeTracker();
+ if (!eyeTracker)
+ return;
+ eyeTracker->setLeftEyeOffset(eyeTracker->getLeftEyeOffset() + offset);
+ eyeTracker->setRightEyeOffset(eyeTracker->getRightEyeOffset() + offset);
+}
+
+void
+HLACameraManipulator::_resetView()
+{
+ if (!_perspectiveViewer.valid())
+ return;
+ _perspectiveViewer->setPosition(SGVec3d::zeros());
+ _perspectiveViewer->setOrientation(SGQuatd::unit());
+ _perspectiveViewer->setZoomFactor(1);
+ HLAEyeTracker* eyeTracker = _perspectiveViewer->getEyeTracker();
+ if (!eyeTracker)
+ return;
+ eyeTracker->setLeftEyeOffset(SGVec3d::zeros());
+ eyeTracker->setRightEyeOffset(SGVec3d::zeros());
+}
+
+void
+HLACameraManipulator::_rotateView(const osg::Vec2& inc)
+{
+ if (!_perspectiveViewer.valid())
+ return;
+ double zDeg, yDeg, xDeg;
+ _perspectiveViewer->getOrientation().getEulerRad(zDeg, yDeg, xDeg);
+ zDeg += inc[0];
+ yDeg += inc[1];
+ _perspectiveViewer->setOrientation(SGQuatd::fromEulerRad(zDeg, yDeg, xDeg));
+}
+
+void
+HLACameraManipulator::_rotateSun(const osg::Vec2& inc, Viewer& viewer)
+{
+ osg::Light* light = viewer.getLight();
+ if (!light)
+ return;
+ osg::Matrix m = osg::Matrix::inverse(viewer.getCamera()->getViewMatrix());
+ osg::Vec3 position(light->getPosition()[0], light->getPosition()[1], light->getPosition()[2]) ;
+ position = osg::Quat(-0.2*inc[0], osg::Matrix::transform3x3(osg::Vec3(0, 1, 0), m))*position;
+ position = osg::Quat(0.2*inc[1], osg::Matrix::transform3x3(osg::Vec3(1, 0, 0), m))*position;
+ light->setPosition(osg::Vec4(position, 0));
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _HLACameraManipulator_hxx
+#define _HLACameraManipulator_hxx
+
+#include <osgGA/CameraManipulator>
+#include <simgear/scene/util/OsgMath.hxx>
+#include "HLAPerspectiveViewer.hxx"
+
+namespace fgviewer {
+
+class Viewer;
+
+class HLACameraManipulator : public osgGA::CameraManipulator {
+public:
+ HLACameraManipulator(HLAPerspectiveViewer* perspectiveViewer = 0);
+ HLACameraManipulator(const HLACameraManipulator& cameraManipulator, const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY);
+ virtual ~HLACameraManipulator();
+
+ META_Object(fgviewer, HLACameraManipulator);
+
+ virtual void setByMatrix(const osg::Matrixd& matrix);
+ virtual void setByInverseMatrix(const osg::Matrixd& matrix);
+
+ virtual osg::Matrixd getMatrix() const;
+ virtual osg::Matrixd getInverseMatrix() const;
+
+ /** Handle events, return true if handled, false otherwise. */
+ virtual bool handle(const osgGA::GUIEventAdapter& eventAdapter, osgGA::GUIActionAdapter& actionAdapter);
+
+protected:
+ bool _handle(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
+ void _handleFrameEvent(osgGA::GUIActionAdapter& actionAdapter);
+ bool _handleKeyDownEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
+ bool _handleKeyUpEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
+ void _incrementEyePosition(const SGVec3d& offset);
+ void _resetView();
+ void _rotateView(const osg::Vec2& inc);
+ void _rotateSun(const osg::Vec2& inc, Viewer& viewer);
+
+private:
+ osg::Matrixd _viewMatrix;
+ osg::Matrixd _inverseViewMatrix;
+ osg::Vec2 _lastMousePos;
+ SGSharedPtr<HLAPerspectiveViewer> _perspectiveViewer;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLADrawable.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLADrawableClass.hxx"
+
+namespace fgviewer {
+
+HLADrawable::HLADrawable(HLADrawableClass* objectClass) :
+ HLAObjectInstance(objectClass)
+{
+}
+
+HLADrawable::~HLADrawable()
+{
+}
+
+void
+HLADrawable::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLADrawableClass*>(getObjectClass().get()));
+ HLADrawableClass& objectClass = static_cast<HLADrawableClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
+ setAttributeDataElement(objectClass.getRendererIndex(), _renderer.getDataElement());
+ setAttributeDataElement(objectClass.getDisplayIndex(), _display.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLADrawable_hxx
+#define HLADrawable_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLADrawableClass;
+
+class HLADrawable : public simgear::HLAObjectInstance {
+public:
+ HLADrawable(HLADrawableClass* objectClass = 0);
+ virtual ~HLADrawable();
+
+ virtual void createAttributeDataElements();
+
+ const std::string& getName() const
+ { return _name.getValue(); }
+ void setName(const std::string& name)
+ { _name.setValue(name); }
+
+ const std::string& getRenderer() const
+ { return _renderer.getValue(); }
+ void setRenderer(const std::string& renderer)
+ { _renderer.setValue(renderer); }
+
+ const std::string& getDisplay() const
+ { return _display.getValue(); }
+ void setDisplay(const std::string& display)
+ { _display.setValue(display); }
+
+private:
+ simgear::HLAStringData _name;
+ // This is normally this object reference, but here it should be sufficient to work with the name
+ // simgear::HLAObjectReferenceData<HLARenderer> _renderer;
+ simgear::HLAStringData _renderer;
+ simgear::HLAStringData _display;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLADrawableClass.hxx"
+
+#include "HLADrawable.hxx"
+
+namespace fgviewer {
+
+HLADrawableClass::HLADrawableClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLADrawableClass::~HLADrawableClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLADrawableClass::createObjectInstance(const std::string& name)
+{
+ return new HLADrawable(this);
+}
+
+void
+HLADrawableClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_nameIndex.empty())
+ _nameIndex = getDataElementIndex("name");
+ if (_rendererIndex.empty())
+ _rendererIndex = getDataElementIndex("renderer");
+ if (_displayIndex.empty())
+ _displayIndex = getDataElementIndex("display");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLADrawableClass_hxx
+#define HLADrawableClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLADrawableClass : public simgear::HLAObjectClass {
+public:
+ HLADrawableClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLADrawableClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setNameIndex(const std::string& path)
+ { return getDataElementIndex(_nameIndex, path); }
+ const simgear::HLADataElementIndex& getNameIndex() const
+ { return _nameIndex; }
+
+ bool setRendererIndex(const std::string& path)
+ { return getDataElementIndex(_rendererIndex, path); }
+ const simgear::HLADataElementIndex& getRendererIndex() const
+ { return _rendererIndex; }
+
+ bool setDisplayIndex(const std::string& path)
+ { return getDataElementIndex(_displayIndex, path); }
+ const simgear::HLADataElementIndex& getDisplayIndex() const
+ { return _displayIndex; }
+
+private:
+ simgear::HLADataElementIndex _nameIndex;
+ simgear::HLADataElementIndex _rendererIndex;
+ simgear::HLADataElementIndex _displayIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAEyeTracker.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLAEyeTrackerClass.hxx"
+
+namespace fgviewer {
+
+HLAEyeTracker::HLAEyeTracker(HLAEyeTrackerClass* objectClass) :
+ HLAObjectInstance(objectClass)
+{
+}
+
+HLAEyeTracker::~HLAEyeTracker()
+{
+}
+
+void
+HLAEyeTracker::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAEyeTrackerClass*>(getObjectClass().get()));
+ HLAEyeTrackerClass& objectClass = static_cast<HLAEyeTrackerClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getLeftEyeOffsetIndex(), _leftEyeOffset.getDataElement());
+ setAttributeDataElement(objectClass.getRightEyeOffsetIndex(), _rightEyeOffset.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAEyeTracker_hxx
+#define HLAEyeTracker_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLAEyeTrackerClass;
+
+class HLAEyeTracker : public simgear::HLAObjectInstance {
+public:
+ HLAEyeTracker(HLAEyeTrackerClass* objectClass = 0);
+ virtual ~HLAEyeTracker();
+
+ virtual void createAttributeDataElements();
+
+ const SGVec3d& getLeftEyeOffset() const
+ { return _leftEyeOffset.getValue(); }
+ void setLeftEyeOffset(const SGVec3d& leftEyeOffset)
+ { _leftEyeOffset.setValue(leftEyeOffset); }
+
+ const SGVec3d& getRightEyeOffset() const
+ { return _rightEyeOffset.getValue(); }
+ void setRightEyeOffset(const SGVec3d& rightEyeOffset)
+ { _rightEyeOffset.setValue(rightEyeOffset); }
+
+private:
+ simgear::HLAVec3dData _leftEyeOffset;
+ simgear::HLAVec3dData _rightEyeOffset;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAEyeTrackerClass.hxx"
+
+#include "HLAEyeTracker.hxx"
+
+namespace fgviewer {
+
+HLAEyeTrackerClass::HLAEyeTrackerClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLAEyeTrackerClass::~HLAEyeTrackerClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAEyeTrackerClass::createObjectInstance(const std::string& name)
+{
+ return new HLAEyeTracker(this);
+}
+
+void
+HLAEyeTrackerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_leftEyeOffsetIndex.empty())
+ _leftEyeOffsetIndex = getDataElementIndex("leftEyeOffset");
+ if (_rightEyeOffsetIndex.empty())
+ _rightEyeOffsetIndex = getDataElementIndex("rightEyeOffset");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAEyeTrackerClass_hxx
+#define HLAEyeTrackerClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLAEyeTrackerClass : public simgear::HLAObjectClass {
+public:
+ HLAEyeTrackerClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAEyeTrackerClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setLeftEyeOffsetIndex(const std::string& path)
+ { return getDataElementIndex(_leftEyeOffsetIndex, path); }
+ const simgear::HLADataElementIndex& getLeftEyeOffsetIndex() const
+ { return _leftEyeOffsetIndex; }
+
+ bool setRightEyeOffsetIndex(const std::string& path)
+ { return getDataElementIndex(_rightEyeOffsetIndex, path); }
+ const simgear::HLADataElementIndex& getRightEyeOffsetIndex() const
+ { return _rightEyeOffsetIndex; }
+
+private:
+ simgear::HLADataElementIndex _leftEyeOffsetIndex;
+ simgear::HLADataElementIndex _rightEyeOffsetIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAMPAircraft.hxx"
+
+#include "HLAMPAircraftClass.hxx"
+
+namespace fgviewer {
+
+HLAMPAircraft::HLAMPAircraft(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
+ HLASceneObject(objectClass, federate),
+ _simTimeOffset(SGLimitsd::max())
+{
+}
+
+HLAMPAircraft::~HLAMPAircraft()
+{
+}
+
+void
+HLAMPAircraft::reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag)
+{
+ HLASceneObject::reflectAttributeValues(indexList, tag);
+}
+
+void
+HLAMPAircraft::reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag)
+{
+ HLASceneObject::reflectAttributeValues(indexList, timeStamp, tag);
+}
+
+void
+HLAMPAircraft::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLASceneObject::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAMPAircraftClass*>(getObjectClass().get()));
+ HLAMPAircraftClass& objectClass = static_cast<HLAMPAircraftClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getSimTimeIndex(), _simTime.getDataElement());
+ setAttributeDataElement(objectClass.getModelPathIndex(), getModelDataElement());
+}
+
+SGLocationd
+HLAMPAircraft::getLocation(const SGTimeStamp& timeStamp) const
+{
+ // FIXME: puh, is frame rate dependent. Think about something more robust ...
+ if (_lastTimeStamp != timeStamp) {
+ double simTimeOffset = timeStamp.toSecs() - _simTime.getValue();
+ if (2 < fabs(simTimeOffset - _simTimeOffset))
+ _simTimeOffset = simTimeOffset;
+ else
+ _simTimeOffset = 0.999*_simTimeOffset + 0.001*simTimeOffset;
+ _lastTimeStamp = timeStamp;
+ }
+ double dt = timeStamp.toSecs() - _simTime.getValue() - _simTimeOffset;
+
+ SGLocationd location = HLASceneObject::getLocation(timeStamp);
+ location.eulerStepBodyVelocitiesMidOrientation(dt, _getRelativeLinearVelocity(), _getRelativeAngularVelocity());
+ return location;
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAMPAircraft_hxx
+#define HLAMPAircraft_hxx
+
+#include "HLASceneObject.hxx"
+
+namespace fgviewer {
+
+class HLAMPAircraft : public HLASceneObject {
+public:
+ HLAMPAircraft(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
+ virtual ~HLAMPAircraft();
+
+ virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag);
+ virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag);
+
+ virtual void createAttributeDataElements();
+
+ virtual SGLocationd getLocation(const SGTimeStamp& timeStamp) const;
+
+private:
+ mutable SGTimeStamp _lastTimeStamp;
+ mutable double _simTimeOffset;
+ simgear::HLADoubleData _simTime;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAMPAircraftClass.hxx"
+
+#include "HLAMPAircraft.hxx"
+#include "HLAViewerFederate.hxx"
+
+namespace fgviewer {
+
+HLAMPAircraftClass::HLAMPAircraftClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLASceneObjectClass(name, federate)
+{
+}
+
+HLAMPAircraftClass::~HLAMPAircraftClass()
+{
+}
+
+HLAMPAircraft*
+HLAMPAircraftClass::createObjectInstance(const std::string& name)
+{
+ return new HLAMPAircraft(this, getFederate());
+}
+
+void
+HLAMPAircraftClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_simTimeIndex.empty())
+ _simTimeIndex = getDataElementIndex("simTime");
+ if (_modelPathIndex.empty())
+ _modelPathIndex = getDataElementIndex("model.path");
+ HLASceneObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAMPAircraftClass_hxx
+#define HLAMPAircraftClass_hxx
+
+#include "HLASceneObjectClass.hxx"
+#include "HLAMPAircraft.hxx"
+
+namespace fgviewer {
+
+class HLAMPAircraftClass : public HLASceneObjectClass {
+public:
+ HLAMPAircraftClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAMPAircraftClass();
+
+ virtual HLAMPAircraft* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setSimTimeIndex(const std::string& path)
+ { return getDataElementIndex(_simTimeIndex, path); }
+ const simgear::HLADataElementIndex& getSimTimeIndex() const
+ { return _simTimeIndex; }
+
+ bool setModelPathIndex(const std::string& path)
+ { return getDataElementIndex(_modelPathIndex, path); }
+ const simgear::HLADataElementIndex& getModelPathIndex() const
+ { return _modelPathIndex; }
+
+private:
+ simgear::HLADataElementIndex _simTimeIndex;
+ simgear::HLADataElementIndex _modelPathIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef HLAObjectReferenceData_hxx
+#define HLAObjectReferenceData_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLADataElement.hxx>
+#include <simgear/hla/HLAFederate.hxx>
+
+#include "HLAProxyDataElement.hxx"
+
+namespace simgear {
+
+/// Data element that references an other object instance by its name, or object instance handle?
+/// Abstract variant that is object type independent and could be registered at the federate
+/// if the object is not found immediately and might arrive later.
+class HLAAbstractObjectReferenceDataElement : public HLAProxyDataElement {
+public:
+ // FIXME drop the federate once we have a decode/encode visitor?!
+ HLAAbstractObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
+ _federate(federate)
+ { }
+
+ virtual bool decode(HLADecodeStream& stream)
+ {
+ if (!HLAProxyDataElement::decode(stream))
+ return false;
+
+ // No change?
+ if (!_name.getDataElement()->getDirty())
+ return true;
+ _name.getDataElement()->setDirty(false);
+
+ return recheckObject();
+ }
+
+ /// Returns true if the object is correctly set
+ bool getComplete() const
+ {
+ if (HLAObjectInstance* objectInstance = _getObjectInstance()) {
+ return _name.getValue() == objectInstance->getName();
+ } else {
+ return _name.getValue().empty();
+ }
+ }
+
+ bool recheckObject()
+ {
+ HLAObjectInstance* objectInstance = _getObjectInstance();
+ if (objectInstance && _name.getValue() == objectInstance->getName())
+ return true;
+
+ if (_name.getValue().empty()) {
+ return _setObjectInstance(0);
+ } else {
+ // Get the object by its name from the federate
+ SGSharedPtr<HLAFederate> federate = _federate.lock();
+ if (!federate.valid())
+ return false;
+ SGSharedPtr<HLAObjectInstance> objectInstance;
+ objectInstance = federate->getObjectInstance(_name.getValue());
+ return _setObjectInstance(objectInstance.get());
+ }
+ }
+
+protected:
+ virtual HLAStringDataElement* _getDataElement()
+ { return _name.getDataElement(); }
+ virtual const HLAStringDataElement* _getDataElement() const
+ { return _name.getDataElement(); }
+
+ virtual HLAObjectInstance* _getObjectInstance() const = 0;
+ virtual bool _setObjectInstance(HLAObjectInstance*) = 0;
+
+ void _setName(const HLAObjectInstance* objectInstance)
+ {
+ if (objectInstance)
+ _name.setValue(objectInstance->getName());
+ else
+ _name.setValue(std::string());
+ _name.getDataElement()->setDirty(true);
+ }
+
+private:
+ HLAStringData _name;
+ SGWeakPtr<HLAFederate> _federate;
+};
+
+
+template<typename T>
+class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement {
+public:
+ // FIXME drop the federate once we have a decode/encode visitor?!
+ HLAObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
+ HLAAbstractObjectReferenceDataElement(federate)
+ { }
+
+ const SGSharedPtr<T>& getObject() const
+ { return _object; }
+ void setObject(const SGSharedPtr<T>& object)
+ {
+ if (_object == object)
+ return;
+ _setName(object.get());
+ _object = object;
+ }
+
+protected:
+ virtual HLAObjectInstance* _getObjectInstance() const
+ {
+ return _object.get();
+ }
+ virtual bool _setObjectInstance(HLAObjectInstance* objectInstance)
+ {
+ if (!objectInstance) {
+ _object.clear();
+ return true;
+ } else {
+ if (!dynamic_cast<T*>(objectInstance))
+ return false;
+ _object = static_cast<T*>(objectInstance);
+ return true;
+ }
+ }
+
+private:
+ SGSharedPtr<T> _object;
+};
+
+template<typename T>
+class HLAObjectReferenceData {
+public:
+ typedef HLAObjectReferenceDataElement<T> DataElement;
+
+ HLAObjectReferenceData(const SGWeakPtr<HLAFederate>& federate) :
+ _dataElement(new DataElement(federate))
+ { }
+
+ const HLADataElement* getDataElement() const
+ { return _dataElement.get(); }
+ HLADataElement* getDataElement()
+ { return _dataElement.get(); }
+
+ const SGSharedPtr<T>& getObject() const
+ { return _dataElement->getObject(); }
+ void setObject(const SGSharedPtr<T>& object)
+ { _dataElement->setObject(object); }
+
+ bool getComplete() const
+ { return _dataElement->getComplete(); }
+ /// FIXME this must happen in the federate by registering object references
+ /// that still want to be resolved
+ bool recheckObject() const
+ { return _dataElement->recheckObject(); }
+
+private:
+ SGSharedPtr<DataElement> _dataElement;
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAOrthographicCamera.hxx"
+
+#include "HLAOrthographicCameraClass.hxx"
+
+namespace fgviewer {
+
+HLAOrthographicCamera::HLAOrthographicCamera(HLAOrthographicCameraClass* objectClass) :
+ HLACamera(objectClass)
+{
+}
+
+HLAOrthographicCamera::~HLAOrthographicCamera()
+{
+}
+
+void
+HLAOrthographicCamera::createAttributeDataElements()
+{
+ HLACamera::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAOrthographicCameraClass*>(getObjectClass().get()));
+ HLAOrthographicCameraClass& objectClass = static_cast<HLAOrthographicCameraClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getLeftIndex(), _left.getDataElement());
+ setAttributeDataElement(objectClass.getRightIndex(), _right.getDataElement());
+ setAttributeDataElement(objectClass.getBottomIndex(), _bottom.getDataElement());
+ setAttributeDataElement(objectClass.getTopIndex(), _top.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAOrthographicCamera_hxx
+#define HLAOrthographicCamera_hxx
+
+#include <simgear/hla/HLABasicDataElement.hxx>
+#include "HLACamera.hxx"
+
+namespace fgviewer {
+
+class HLAOrthographicCameraClass;
+
+class HLAOrthographicCamera : public HLACamera {
+public:
+ HLAOrthographicCamera(HLAOrthographicCameraClass* objectClass);
+ virtual ~HLAOrthographicCamera();
+
+ virtual void createAttributeDataElements();
+
+ double getLeft() const
+ { return _left.getValue(); }
+ void setLeft(double left)
+ { _left.setValue(left); }
+
+ double getRight() const
+ { return _right.getValue(); }
+ void setRight(double right)
+ { _right.setValue(right); }
+
+ double getBottom() const
+ { return _bottom.getValue(); }
+ void setBottom(double bottom)
+ { _bottom.setValue(bottom); }
+
+ double getTop() const
+ { return _top.getValue(); }
+ void setTop(double top)
+ { _top.setValue(top); }
+
+private:
+ simgear::HLADoubleData _left;
+ simgear::HLADoubleData _right;
+ simgear::HLADoubleData _bottom;
+ simgear::HLADoubleData _top;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAOrthographicCameraClass.hxx"
+
+#include "HLAOrthographicCamera.hxx"
+
+namespace fgviewer {
+
+HLAOrthographicCameraClass::HLAOrthographicCameraClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLACameraClass(name, federate)
+{
+}
+
+HLAOrthographicCameraClass::~HLAOrthographicCameraClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAOrthographicCameraClass::createObjectInstance(const std::string& name)
+{
+ return new HLAOrthographicCamera(this);
+}
+
+void
+HLAOrthographicCameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ if (_leftIndex.empty())
+ _leftIndex = getDataElementIndex("projection.left");
+ if (_rightIndex.empty())
+ _rightIndex = getDataElementIndex("projection.right");
+ if (_bottomIndex.empty())
+ _bottomIndex = getDataElementIndex("projection.bottom");
+ if (_topIndex.empty())
+ _topIndex = getDataElementIndex("projection.top");
+ HLACameraClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAOrthographicCameraClass_hxx
+#define HLAOrthographicCameraClass_hxx
+
+#include "HLACameraClass.hxx"
+
+namespace fgviewer {
+
+class HLAOrthographicCameraClass : public HLACameraClass {
+public:
+ HLAOrthographicCameraClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAOrthographicCameraClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setLeftIndex(const std::string& path)
+ { return getDataElementIndex(_leftIndex, path); }
+ const simgear::HLADataElementIndex& getLeftIndex() const
+ { return _leftIndex; }
+
+ bool setRightIndex(const std::string& path)
+ { return getDataElementIndex(_rightIndex, path); }
+ const simgear::HLADataElementIndex& getRightIndex() const
+ { return _rightIndex; }
+
+ bool setBottomIndex(const std::string& path)
+ { return getDataElementIndex(_bottomIndex, path); }
+ const simgear::HLADataElementIndex& getBottomIndex() const
+ { return _bottomIndex; }
+
+ bool setTopIndex(const std::string& path)
+ { return getDataElementIndex(_topIndex, path); }
+ const simgear::HLADataElementIndex& getTopIndex() const
+ { return _topIndex; }
+
+private:
+ simgear::HLADataElementIndex _leftIndex;
+ simgear::HLADataElementIndex _rightIndex;
+ simgear::HLADataElementIndex _bottomIndex;
+ simgear::HLADataElementIndex _topIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAPerspectiveCamera.hxx"
+
+#include "HLAPerspectiveCameraClass.hxx"
+
+namespace fgviewer {
+
+HLAPerspectiveCamera::HLAPerspectiveCamera(HLAPerspectiveCameraClass* objectClass) :
+ HLACamera(objectClass)
+{
+}
+
+HLAPerspectiveCamera::~HLAPerspectiveCamera()
+{
+}
+
+void
+HLAPerspectiveCamera::reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag)
+{
+ HLACamera::reflectAttributeValues(indexList, tag);
+ /// Here push data to the osg viewer side
+}
+
+void
+HLAPerspectiveCamera::reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag)
+{
+ HLACamera::reflectAttributeValues(indexList, timeStamp, tag);
+ /// Here push data to the osg viewer side
+}
+
+void
+HLAPerspectiveCamera::createAttributeDataElements()
+{
+ HLACamera::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAPerspectiveCameraClass*>(getObjectClass().get()));
+ HLAPerspectiveCameraClass& objectClass = static_cast<HLAPerspectiveCameraClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getLeftIndex(), _left.getDataElement());
+ setAttributeDataElement(objectClass.getRightIndex(), _right.getDataElement());
+ setAttributeDataElement(objectClass.getBottomIndex(), _bottom.getDataElement());
+ setAttributeDataElement(objectClass.getTopIndex(), _top.getDataElement());
+ setAttributeDataElement(objectClass.getDistanceIndex(), _distance.getDataElement());
+}
+
+Frustum
+HLAPerspectiveCamera::getFrustum() const
+{
+ return Frustum(getLeft(), getRight(), getBottom(), getTop(), getDistance());
+}
+
+void
+HLAPerspectiveCamera::setFrustum(const Frustum& frustum)
+{
+ setLeft(frustum._left);
+ setRight(frustum._right);
+ setBottom(frustum._bottom);
+ setTop(frustum._top);
+ setDistance(frustum._near);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAPerspectiveCamera_hxx
+#define HLAPerspectiveCamera_hxx
+
+#include <simgear/hla/HLABasicDataElement.hxx>
+#include "Frustum.hxx"
+#include "HLACamera.hxx"
+
+namespace fgviewer {
+
+class HLAPerspectiveCameraClass;
+
+class HLAPerspectiveCamera : public HLACamera {
+public:
+ HLAPerspectiveCamera(HLAPerspectiveCameraClass* objectClass);
+ virtual ~HLAPerspectiveCamera();
+
+ virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag);
+ virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag);
+
+ virtual void createAttributeDataElements();
+
+ double getLeft() const
+ { return _left.getValue(); }
+ void setLeft(double left)
+ { _left.setValue(left); }
+
+ double getRight() const
+ { return _right.getValue(); }
+ void setRight(double right)
+ { _right.setValue(right); }
+
+ double getBottom() const
+ { return _bottom.getValue(); }
+ void setBottom(double bottom)
+ { _bottom.setValue(bottom); }
+
+ double getTop() const
+ { return _top.getValue(); }
+ void setTop(double top)
+ { _top.setValue(top); }
+
+ double getDistance() const
+ { return _distance.getValue(); }
+ void setDistance(double distance)
+ { _distance.setValue(distance); }
+
+ Frustum getFrustum() const;
+ void setFrustum(const Frustum& frustum);
+
+private:
+ simgear::HLADoubleData _left;
+ simgear::HLADoubleData _right;
+ simgear::HLADoubleData _bottom;
+ simgear::HLADoubleData _top;
+ simgear::HLADoubleData _distance;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAPerspectiveCameraClass.hxx"
+
+#include "HLAPerspectiveCamera.hxx"
+
+namespace fgviewer {
+
+HLAPerspectiveCameraClass::HLAPerspectiveCameraClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLACameraClass(name, federate)
+{
+}
+
+HLAPerspectiveCameraClass::~HLAPerspectiveCameraClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAPerspectiveCameraClass::createObjectInstance(const std::string& name)
+{
+ return new HLAPerspectiveCamera(this);
+}
+
+void
+HLAPerspectiveCameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ if (_leftIndex.empty())
+ _leftIndex = getDataElementIndex("projection.left");
+ if (_rightIndex.empty())
+ _rightIndex = getDataElementIndex("projection.right");
+ if (_bottomIndex.empty())
+ _bottomIndex = getDataElementIndex("projection.bottom");
+ if (_topIndex.empty())
+ _topIndex = getDataElementIndex("projection.top");
+ if (_distanceIndex.empty())
+ _distanceIndex = getDataElementIndex("projection.distance");
+ HLACameraClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAPerspectiveCameraClass_hxx
+#define HLAPerspectiveCameraClass_hxx
+
+#include "HLACameraClass.hxx"
+
+namespace fgviewer {
+
+class HLAPerspectiveCameraClass : public HLACameraClass {
+public:
+ HLAPerspectiveCameraClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAPerspectiveCameraClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setLeftIndex(const std::string& path)
+ { return getDataElementIndex(_leftIndex, path); }
+ const simgear::HLADataElementIndex& getLeftIndex() const
+ { return _leftIndex; }
+
+ bool setRightIndex(const std::string& path)
+ { return getDataElementIndex(_rightIndex, path); }
+ const simgear::HLADataElementIndex& getRightIndex() const
+ { return _rightIndex; }
+
+ bool setBottomIndex(const std::string& path)
+ { return getDataElementIndex(_bottomIndex, path); }
+ const simgear::HLADataElementIndex& getBottomIndex() const
+ { return _bottomIndex; }
+
+ bool setTopIndex(const std::string& path)
+ { return getDataElementIndex(_topIndex, path); }
+ const simgear::HLADataElementIndex& getTopIndex() const
+ { return _topIndex; }
+
+ bool setDistanceIndex(const std::string& path)
+ { return getDataElementIndex(_distanceIndex, path); }
+ const simgear::HLADataElementIndex& getDistanceIndex() const
+ { return _distanceIndex; }
+
+private:
+ simgear::HLADataElementIndex _leftIndex;
+ simgear::HLADataElementIndex _rightIndex;
+ simgear::HLADataElementIndex _bottomIndex;
+ simgear::HLADataElementIndex _topIndex;
+ simgear::HLADataElementIndex _distanceIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAPerspectiveViewer.hxx"
+
+#include "HLAPerspectiveViewerClass.hxx"
+
+namespace fgviewer {
+
+HLAPerspectiveViewer::HLAPerspectiveViewer(HLAPerspectiveViewerClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
+ HLAViewer(objectClass),
+ _view(federate),
+ _zoomFactor(1),
+ _eyeTracker(federate)
+{
+}
+
+HLAPerspectiveViewer::~HLAPerspectiveViewer()
+{
+}
+
+void
+HLAPerspectiveViewer::createAttributeDataElements()
+{
+ HLAViewer::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAPerspectiveViewerClass*>(getObjectClass().get()));
+ HLAPerspectiveViewerClass& objectClass = static_cast<HLAPerspectiveViewerClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getViewNameIndex(), _view.getDataElement());
+ setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
+ setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
+ setAttributeDataElement(objectClass.getZoomFactorIndex(), _zoomFactor.getDataElement());
+ setAttributeDataElement(objectClass.getEyeTrackerNameIndex(), _eyeTracker.getDataElement());
+}
+
+const HLAView*
+HLAPerspectiveViewer::getView() const
+{
+ return _view.getObject();
+}
+
+HLAView*
+HLAPerspectiveViewer::getView()
+{
+ return _view.getObject();
+}
+
+void
+HLAPerspectiveViewer::setView(HLAView* view)
+{
+ _view.setObject(view);
+}
+
+const HLAEyeTracker*
+HLAPerspectiveViewer::getEyeTracker() const
+{
+ return _eyeTracker.getObject();
+}
+
+HLAEyeTracker*
+HLAPerspectiveViewer::getEyeTracker()
+{
+ return _eyeTracker.getObject();
+}
+
+void
+HLAPerspectiveViewer::setEyeTracker(HLAEyeTracker* eyeTracker)
+{
+ _eyeTracker.setObject(eyeTracker);
+}
+
+SGLocationd
+HLAPerspectiveViewer::getLocation(const SGTimeStamp& simTime) const
+{
+ const HLAView* view = getView();
+ if (!view)
+ return SGLocationd(getPosition(), getOrientation());
+ return view->getLocation(simTime).getAbsoluteLocation(SGLocationd(getPosition(), getOrientation()));
+}
+
+SGVec3d
+HLAPerspectiveViewer::getLeftEyeOffset() const
+{
+ const HLAEyeTracker* eyeTracker = getEyeTracker();
+ if (!eyeTracker)
+ return SGVec3d(0, 0, 0);
+ return eyeTracker->getLeftEyeOffset();
+}
+
+SGVec3d
+HLAPerspectiveViewer::getRightEyeOffset() const
+{
+ const HLAEyeTracker* eyeTracker = getEyeTracker();
+ if (!eyeTracker)
+ return SGVec3d(0, 0, 0);
+ return eyeTracker->getRightEyeOffset();
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAPerspectiveViewer_hxx
+#define HLAPerspectiveViewer_hxx
+
+#include "HLAEyeTracker.hxx"
+#include "HLAObjectReferenceData.hxx"
+#include "HLAView.hxx"
+#include "HLAViewer.hxx"
+
+namespace fgviewer {
+
+class HLAPerspectiveViewerClass;
+
+class HLAPerspectiveViewer : public HLAViewer {
+public:
+ HLAPerspectiveViewer(HLAPerspectiveViewerClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
+ virtual ~HLAPerspectiveViewer();
+
+ virtual void createAttributeDataElements();
+
+ const HLAView* getView() const;
+ HLAView* getView();
+ void setView(HLAView* view);
+
+ const SGVec3d& getPosition() const
+ { return _position.getValue(); }
+ void setPosition(const SGVec3d& position)
+ { _position.setValue(position); }
+
+ const SGQuatd& getOrientation() const
+ { return _orientation.getValue(); }
+ void setOrientation(const SGQuatd& orientation)
+ { _orientation.setValue(orientation); }
+
+ double getZoomFactor() const
+ { return _zoomFactor.getValue(); }
+ void setZoomFactor(double zoomFactor)
+ { _zoomFactor.setValue(zoomFactor); }
+
+ const HLAEyeTracker* getEyeTracker() const;
+ HLAEyeTracker* getEyeTracker();
+ void setEyeTracker(HLAEyeTracker* eyeTracker);
+
+ SGLocationd getLocation(const SGTimeStamp& simTime) const;
+
+ SGVec3d getLeftEyeOffset() const;
+ SGVec3d getRightEyeOffset() const;
+
+private:
+ simgear::HLAObjectReferenceData<HLAView> _view;
+ simgear::HLAVec3dData _position;
+ simgear::HLAQuat3dData _orientation;
+ simgear::HLADoubleData _zoomFactor;
+ simgear::HLAObjectReferenceData<HLAEyeTracker> _eyeTracker;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAPerspectiveViewerClass.hxx"
+
+#include "HLAPerspectiveViewer.hxx"
+
+namespace fgviewer {
+
+HLAPerspectiveViewerClass::HLAPerspectiveViewerClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAViewerClass(name, federate)
+{
+}
+
+HLAPerspectiveViewerClass::~HLAPerspectiveViewerClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAPerspectiveViewerClass::createObjectInstance(const std::string& name)
+{
+ return new HLAPerspectiveViewer(this, getFederate());
+}
+
+void
+HLAPerspectiveViewerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ if (_viewNameIndex.empty())
+ _viewNameIndex = getDataElementIndex("viewName");
+ if (_positionIndex.empty())
+ _positionIndex = getDataElementIndex("location.position");
+ if (_orientationIndex.empty())
+ _orientationIndex = getDataElementIndex("location.orientation");
+ if (_zoomFactorIndex.empty())
+ _zoomFactorIndex = getDataElementIndex("zoomFactor");
+ if (_eyeTrackerNameIndex.empty())
+ _eyeTrackerNameIndex = getDataElementIndex("eyeTrackerName");
+
+ HLAViewerClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAPerspectiveViewerClass_hxx
+#define HLAPerspectiveViewerClass_hxx
+
+#include "HLAViewerClass.hxx"
+
+namespace fgviewer {
+
+class HLAPerspectiveViewerClass : public HLAViewerClass {
+public:
+ HLAPerspectiveViewerClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAPerspectiveViewerClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setViewNameIndex(const std::string& path)
+ { return getDataElementIndex(_viewNameIndex, path); }
+ const simgear::HLADataElementIndex& getViewNameIndex() const
+ { return _viewNameIndex; }
+
+ bool setPositionIndex(const std::string& path)
+ { return getDataElementIndex(_positionIndex, path); }
+ const simgear::HLADataElementIndex& getPositionIndex() const
+ { return _positionIndex; }
+
+ bool setOrientationIndex(const std::string& path)
+ { return getDataElementIndex(_orientationIndex, path); }
+ const simgear::HLADataElementIndex& getOrientationIndex() const
+ { return _orientationIndex; }
+
+ bool setZoomFactorIndex(const std::string& path)
+ { return getDataElementIndex(_zoomFactorIndex, path); }
+ const simgear::HLADataElementIndex& getZoomFactorIndex() const
+ { return _zoomFactorIndex; }
+
+ bool setEyeTrackerNameIndex(const std::string& path)
+ { return getDataElementIndex(_eyeTrackerNameIndex, path); }
+ const simgear::HLADataElementIndex& getEyeTrackerNameIndex() const
+ { return _eyeTrackerNameIndex; }
+
+private:
+ simgear::HLADataElementIndex _viewNameIndex;
+ simgear::HLADataElementIndex _positionIndex;
+ simgear::HLADataElementIndex _orientationIndex;
+ simgear::HLADataElementIndex _zoomFactorIndex;
+ simgear::HLADataElementIndex _eyeTrackerNameIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef HLAProxyDataElement_hxx
+#define HLAProxyDataElement_hxx
+
+#include <simgear/hla/HLADataElement.hxx>
+
+namespace simgear {
+
+class HLAProxyDataElement : public HLADataElement {
+public:
+ virtual ~HLAProxyDataElement()
+ { }
+
+ virtual void accept(HLADataElementVisitor& visitor)
+ {
+ HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return;
+ dataElement->accept(visitor);
+ }
+ virtual void accept(HLAConstDataElementVisitor& visitor) const
+ {
+ const HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return;
+ dataElement->accept(visitor);
+ }
+
+ virtual bool encode(HLAEncodeStream& stream) const
+ {
+ const HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return false;
+ return dataElement->encode(stream);
+ }
+ virtual bool decode(HLADecodeStream& stream)
+ {
+ HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return false;
+ return dataElement->decode(stream);
+ }
+
+ virtual const HLADataType* getDataType() const
+ {
+ const HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return 0;
+ return dataElement->getDataType();
+ }
+ virtual bool setDataType(const HLADataType* dataType)
+ {
+ HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return false;
+ return dataElement->setDataType(dataType);
+ }
+
+protected:
+ virtual HLADataElement* _getDataElement() = 0;
+ virtual const HLADataElement* _getDataElement() const = 0;
+
+ virtual void _setStamp(Stamp* stamp)
+ {
+ HLADataElement::_setStamp(stamp);
+ HLADataElement* dataElement = _getDataElement();
+ if (!dataElement)
+ return;
+ dataElement->attachStamp(*this);
+ }
+};
+
+}
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLARenderer.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLARendererClass.hxx"
+
+namespace fgviewer {
+
+HLARenderer::HLARenderer(HLARendererClass* objectClass) :
+ HLAObjectInstance(objectClass)
+{
+}
+
+HLARenderer::~HLARenderer()
+{
+}
+
+void
+HLARenderer::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLARendererClass*>(getObjectClass().get()));
+ HLARendererClass& objectClass = static_cast<HLARendererClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLARenderer_hxx
+#define HLARenderer_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLARendererClass;
+
+class HLARenderer : public simgear::HLAObjectInstance {
+public:
+ HLARenderer(HLARendererClass* objectClass = 0);
+ virtual ~HLARenderer();
+
+ virtual void createAttributeDataElements();
+
+private:
+ simgear::HLAStringData _name;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLARendererClass.hxx"
+
+#include "HLARenderer.hxx"
+
+namespace fgviewer {
+
+HLARendererClass::HLARendererClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLARendererClass::~HLARendererClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLARendererClass::createObjectInstance(const std::string& name)
+{
+ return new HLARenderer(this);
+}
+
+void
+HLARendererClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_nameIndex.empty())
+ _nameIndex = getDataElementIndex("name");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLARendererClass_hxx
+#define HLARendererClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLARendererClass : public simgear::HLAObjectClass {
+public:
+ HLARendererClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLARendererClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setNameIndex(const std::string& path)
+ { return getDataElementIndex(_nameIndex, path); }
+ const simgear::HLADataElementIndex& getNameIndex() const
+ { return _nameIndex; }
+
+private:
+ simgear::HLADataElementIndex _nameIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLASceneObject.hxx"
+
+#include <osg/Transform>
+
+#include <simgear/scene/util/OsgMath.hxx>
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/scene/util/SGReaderWriterOptions.hxx>
+
+#include "HLASceneObjectClass.hxx"
+#include "HLAViewerFederate.hxx"
+
+namespace fgviewer {
+
+class HLASceneObject::_ModelDataElement : public simgear::HLAProxyDataElement {
+public:
+ _ModelDataElement(const SGWeakPtr<HLASceneObject>& sceneObject) :
+ _sceneObject(sceneObject)
+ { }
+ virtual ~_ModelDataElement()
+ { }
+
+ virtual bool decode(simgear::HLADecodeStream& stream)
+ {
+ if (!HLAProxyDataElement::decode(stream))
+ return false;
+
+ // No change?
+ if (!_name.getDataElement()->getDirty())
+ return true;
+ _name.getDataElement()->setDirty(false);
+ SGSharedPtr<HLASceneObject> sceneObject = _sceneObject.lock();
+ if (sceneObject.valid())
+ sceneObject->_setModelFileName(_name.getValue());
+ return true;
+ }
+
+protected:
+ virtual simgear::HLAStringDataElement* _getDataElement()
+ { return _name.getDataElement(); }
+ virtual const simgear::HLAStringDataElement* _getDataElement() const
+ { return _name.getDataElement(); }
+
+private:
+ const SGWeakPtr<HLASceneObject> _sceneObject;
+ simgear::HLAStringData _name;
+};
+
+class HLASceneObject::_Transform : public osg::Transform {
+public:
+ _Transform(const SGWeakPtr<const HLASceneObject>& sceneObject) :
+ _sceneObject(sceneObject)
+ {
+ setCullingActive(false);
+ }
+ virtual ~_Transform()
+ {
+ }
+
+ virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
+ {
+ if (!nv)
+ return false;
+ const osg::FrameStamp* frameStamp = nv->getFrameStamp();
+ if (!frameStamp)
+ return false;
+
+ SGLocationd location = _getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
+ // the position of the view
+ matrix.preMultTranslate(toOsg(location.getPosition()));
+ // the orientation of the view
+ matrix.preMultRotate(toOsg(location.getOrientation()));
+
+ return true;
+ }
+ virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
+ {
+ if (!nv)
+ return false;
+ const osg::FrameStamp* frameStamp = nv->getFrameStamp();
+ if (!frameStamp)
+ return false;
+
+ SGLocationd location = _getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
+ // the position of the view
+ matrix.postMultTranslate(toOsg(-location.getPosition()));
+ // the orientation of the view
+ matrix.postMultRotate(toOsg(inverse(location.getOrientation())));
+
+ return true;
+ }
+
+ virtual osg::BoundingSphere computeBound() const
+ {
+ return osg::BoundingSphere();
+ }
+
+private:
+ SGLocationd _getLocation(const SGTimeStamp& timeStamp) const
+ {
+ // transform from the simulation typical x-forward/y-right/z-down
+ // to the flightgear model system x-back/y-right/z-up
+ // SGQuatd simToModel = SGQuatd::fromEulerDeg(0, 180, 0);
+ SGQuatd simToModel = SGQuatd::fromRealImag(0, SGVec3d(0, 1, 0));
+
+ SGSharedPtr<const HLASceneObject> sceneObject = _sceneObject.lock();
+ if (!sceneObject.valid())
+ return SGLocationd(SGVec3d(0, 0, 0), simToModel);
+
+ // Get the cartesian location at the given time stamp from the hla object
+ SGLocationd location = sceneObject->getLocation(timeStamp);
+ location.setOrientation(location.getOrientation()*simToModel);
+
+ return location;
+ }
+
+ SGWeakPtr<const HLASceneObject> _sceneObject;
+};
+
+HLASceneObject::HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
+ HLAObjectInstance(objectClass),
+ _sceneObject(federate)
+{
+ _pagedLOD = new osg::PagedLOD;
+ _pagedLOD->setRange(0, 0, 80000);
+
+ _transform = new _Transform(this);
+ _transform->addChild(_pagedLOD.get());
+}
+
+HLASceneObject::~HLASceneObject()
+{
+ _removeFromSceneGraph();
+}
+
+void
+HLASceneObject::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLASceneObjectClass*>(getObjectClass().get()));
+ HLASceneObjectClass& objectClass = static_cast<HLASceneObjectClass&>(*getObjectClass());
+
+ simgear::HLACartesianLocation* location = new simgear::HLACartesianLocation;
+ setAttributeDataElement(objectClass.getPositionIndex(), location->getPositionDataElement());
+ setAttributeDataElement(objectClass.getOrientationIndex(), location->getOrientationDataElement());
+ setAttributeDataElement(objectClass.getAngularVelocityIndex(), location->getAngularVelocityDataElement());
+ setAttributeDataElement(objectClass.getLinearVelocityIndex(), location->getLinearVelocityDataElement());
+ _location = location;
+
+ setAttributeDataElement(objectClass.getSceneObjectNameIndex(), _sceneObject.getDataElement());
+}
+
+void
+HLASceneObject::discoverInstance(const simgear::RTIData& tag)
+{
+ HLAObjectInstance::discoverInstance(tag);
+ _addToSceneGraph();
+}
+
+void
+HLASceneObject::removeInstance(const simgear::RTIData& tag)
+{
+ _removeFromSceneGraph();
+ HLAObjectInstance::removeInstance(tag);
+}
+
+void
+HLASceneObject::registerInstance(simgear::HLAObjectClass* objectClass)
+{
+ HLAObjectInstance::registerInstance(objectClass);
+ _addToSceneGraph();
+}
+
+void
+HLASceneObject::deleteInstance(const simgear::RTIData& tag)
+{
+ _removeFromSceneGraph();
+ HLAObjectInstance::deleteInstance(tag);
+}
+
+const HLASceneObject*
+HLASceneObject::getSceneObject() const
+{
+ return _sceneObject.getObject();
+}
+
+HLASceneObject*
+HLASceneObject::getSceneObject()
+{
+ return _sceneObject.getObject();
+}
+
+void
+HLASceneObject::setSceneObject(HLASceneObject* sceneObject)
+{
+ _sceneObject.setObject(sceneObject);
+}
+
+SGLocationd
+HLASceneObject::getLocation(const SGTimeStamp& timeStamp) const
+{
+ const HLASceneObject* sceneObject = getSceneObject();
+ if (!sceneObject)
+ return _getRelativeLocation(timeStamp);
+ return sceneObject->getLocation(timeStamp).getAbsoluteLocation(_getRelativeLocation(timeStamp));
+}
+
+simgear::HLADataElement*
+HLASceneObject::getModelDataElement()
+{
+ return new _ModelDataElement(this);
+}
+
+osg::Node*
+HLASceneObject::getNode()
+{
+ return _transform.get();
+}
+
+SGLocationd
+HLASceneObject::_getRelativeLocation(const SGTimeStamp& timeStamp) const
+{
+ if (!_location.valid())
+ return SGLocationd(SGVec3d::zeros(), SGQuatd::unit());
+ return _location->getLocation(timeStamp);
+}
+
+SGVec3d
+HLASceneObject::_getRelativeAngularVelocity() const
+{
+ if (!_location.valid())
+ return SGVec3d(0, 0, 0);
+ return _location->getAngularBodyVelocity();
+}
+
+SGVec3d
+HLASceneObject::_getRelativeLinearVelocity() const
+{
+ if (!_location.valid())
+ return SGVec3d(0, 0, 0);
+ return _location->getLinearBodyVelocity();
+}
+
+void
+HLASceneObject::_setModelFileName(const std::string& fileName)
+{
+ if (0 < _pagedLOD->getNumFileNames() && fileName == _pagedLOD->getFileName(0))
+ return;
+
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (federate.valid()) {
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ HLAViewerFederate* viewerFederate = static_cast<HLAViewerFederate*>(federate.get());
+
+ osg::ref_ptr<osgDB::Options> localOptions;
+ localOptions = static_cast<osgDB::Options*>(viewerFederate->getReaderWriterOptions()->clone(osg::CopyOp()));
+ // FIXME: particle systems have some issues. Do not use them currently.
+ localOptions->setPluginStringData("SimGear::PARTICLESYSTEM", "OFF");
+ _pagedLOD->setDatabaseOptions(localOptions.get());
+ }
+
+ // Finally set the file name
+ if (unsigned numChildren = _pagedLOD->getNumChildren())
+ _pagedLOD->removeChildren(0, numChildren);
+ _pagedLOD->setFileName(0, fileName);
+}
+
+void
+HLASceneObject::_addToSceneGraph()
+{
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (!federate.valid())
+ return;
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ HLAViewerFederate* viewerFederate = static_cast<HLAViewerFederate*>(federate.get());
+
+ /// Add ourselves to the dynamic scene graph
+ viewerFederate->addDynamicModel(getNode());
+}
+
+void
+HLASceneObject::_removeFromSceneGraph()
+{
+ /// FIXME O(#SceneObjects), pool them and reuse in create
+ unsigned i = _transform->getNumParents();
+ while (i--) {
+ osg::Group* parent = _transform->getParent(i);
+ parent->removeChild(_transform.get());
+ }
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLASceneObject_hxx
+#define HLASceneObject_hxx
+
+#include <osg/Node>
+#include <osg/PagedLOD>
+#include <osg/ref_ptr>
+
+#include <simgear/hla/HLAObjectClass.hxx>
+#include <simgear/hla/HLALocation.hxx>
+
+#include "HLAObjectReferenceData.hxx"
+
+namespace fgviewer {
+
+class HLASceneObjectClass;
+
+class HLASceneObject : public simgear::HLAObjectInstance {
+public:
+ HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
+ virtual ~HLASceneObject();
+
+ virtual void createAttributeDataElements();
+
+ virtual void discoverInstance(const simgear::RTIData& tag);
+ virtual void removeInstance(const simgear::RTIData& tag);
+
+ virtual void registerInstance(simgear::HLAObjectClass* objectClass);
+ virtual void deleteInstance(const simgear::RTIData& tag);
+
+ const HLASceneObject* getSceneObject() const;
+ HLASceneObject* getSceneObject();
+ void setSceneObject(HLASceneObject* sceneObject);
+
+ virtual SGLocationd getLocation(const SGTimeStamp& timeStamp) const;
+
+ simgear::HLADataElement* getModelDataElement();
+
+ osg::Node* getNode();
+
+protected:
+ SGLocationd _getRelativeLocation(const SGTimeStamp& timeStamp) const;
+ // Return the velocities of this current object without taking the referenced velocities into account
+ SGVec3d _getRelativeAngularVelocity() const;
+ SGVec3d _getRelativeLinearVelocity() const;
+
+ void _setModelFileName(const std::string& fileName);
+
+private:
+ class _ModelDataElement;
+ class _Transform;
+
+ // Add the transform node to the scenegraph
+ void _addToSceneGraph();
+ // Remove the transform node from the scenegraph
+ void _removeFromSceneGraph();
+
+ // The location of this object
+ SGSharedPtr<simgear::HLAAbstractLocation> _location;
+ // If this object is living relative to an other one, this one is non zero
+ simgear::HLAObjectReferenceData<HLASceneObject> _sceneObject;
+
+ // The top level transform node for this scene object
+ osg::ref_ptr<_Transform> _transform;
+ osg::ref_ptr<osg::PagedLOD> _pagedLOD;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLASceneObjectClass.hxx"
+
+#include "HLASceneObject.hxx"
+#include "HLAViewerFederate.hxx"
+
+namespace fgviewer {
+
+HLASceneObjectClass::HLASceneObjectClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLASceneObjectClass::~HLASceneObjectClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLASceneObjectClass::createObjectInstance(const std::string& name)
+{
+ return new HLASceneObject(this, getFederate());
+}
+
+void
+HLASceneObjectClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_positionIndex.empty())
+ _positionIndex = getDataElementIndex("location.position");
+ if (_orientationIndex.empty())
+ _orientationIndex = getDataElementIndex("location.orientation");
+ if (_angularVelocityIndex.empty())
+ _angularVelocityIndex = getDataElementIndex("velocity.angular");
+ if (_linearVelocityIndex.empty())
+ _linearVelocityIndex = getDataElementIndex("velocity.linear");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLASceneObjectClass_hxx
+#define HLASceneObjectClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLASceneObjectClass : public simgear::HLAObjectClass {
+public:
+ HLASceneObjectClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLASceneObjectClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setPositionIndex(const std::string& path)
+ { return getDataElementIndex(_positionIndex, path); }
+ const simgear::HLADataElementIndex& getPositionIndex() const
+ { return _positionIndex; }
+
+ bool setOrientationIndex(const std::string& path)
+ { return getDataElementIndex(_orientationIndex, path); }
+ const simgear::HLADataElementIndex& getOrientationIndex() const
+ { return _orientationIndex; }
+
+ bool setAngularVelocityIndex(const std::string& path)
+ { return getDataElementIndex(_angularVelocityIndex, path); }
+ const simgear::HLADataElementIndex& getAngularVelocityIndex() const
+ { return _angularVelocityIndex; }
+
+ bool setLinearVelocityIndex(const std::string& path)
+ { return getDataElementIndex(_linearVelocityIndex, path); }
+ const simgear::HLADataElementIndex& getLinearVelocityIndex() const
+ { return _linearVelocityIndex; }
+
+ /// FIXME make sure that we do not get closed reference loops at some point!
+ /// Do this in the setter of the object data element so that its not getting a runtime issue
+ bool setSceneObjectNameIndex(const std::string& path)
+ { return getDataElementIndex(_sceneObjectNameIndex, path); }
+ const simgear::HLADataElementIndex& getSceneObjectNameIndex() const
+ { return _sceneObjectNameIndex; }
+
+private:
+ /// FIXME use a location factory for that?!
+ simgear::HLADataElementIndex _positionIndex;
+ simgear::HLADataElementIndex _orientationIndex;
+
+ simgear::HLADataElementIndex _angularVelocityIndex;
+ simgear::HLADataElementIndex _linearVelocityIndex;
+
+ simgear::HLADataElementIndex _sceneObjectNameIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAView.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLAViewClass.hxx"
+#include "HLAViewerFederate.hxx"
+
+namespace fgviewer {
+
+HLAView::HLAView(HLAViewClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
+ HLAObjectInstance(objectClass),
+ _sceneObject(federate)
+{
+}
+
+HLAView::~HLAView()
+{
+}
+
+void
+HLAView::createAttributeDataElements()
+{
+ /// FIXME at some point we should not need that anymore
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAViewClass*>(getObjectClass().get()));
+ HLAViewClass& objectClass = static_cast<HLAViewClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
+ setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
+ setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
+ setAttributeDataElement(objectClass.getSceneObjectNameIndex(), _sceneObject.getDataElement());
+}
+
+void
+HLAView::discoverInstance(const simgear::RTIData& tag)
+{
+ HLAObjectInstance::discoverInstance(tag);
+
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (federate.valid()) {
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ static_cast<HLAViewerFederate*>(federate.get())->insertView(this);
+ }
+}
+
+void
+HLAView::removeInstance(const simgear::RTIData& tag)
+{
+ HLAObjectInstance::removeInstance(tag);
+
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (federate.valid()) {
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ static_cast<HLAViewerFederate*>(federate.get())->eraseView(this);
+ }
+}
+
+void
+HLAView::registerInstance(simgear::HLAObjectClass* objectClass)
+{
+ HLAObjectInstance::registerInstance(objectClass);
+
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (federate.valid()) {
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ static_cast<HLAViewerFederate*>(federate.get())->insertView(this);
+ }
+}
+
+void
+HLAView::deleteInstance(const simgear::RTIData& tag)
+{
+ SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
+ if (federate.valid()) {
+ assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
+ static_cast<HLAViewerFederate*>(federate.get())->eraseView(this);
+ }
+
+ HLAObjectInstance::deleteInstance(tag);
+}
+
+const HLASceneObject*
+HLAView::getSceneObject() const
+{
+ /// FIXME!!! The federate should track unresolved object references
+ _sceneObject.recheckObject();
+ return _sceneObject.getObject();
+}
+
+HLASceneObject*
+HLAView::getSceneObject()
+{
+ /// FIXME!!! The federate should track unresolved object references
+ _sceneObject.recheckObject();
+ return _sceneObject.getObject();
+}
+
+void
+HLAView::setSceneObject(HLASceneObject* sceneObject)
+{
+ _sceneObject.setObject(sceneObject);
+}
+
+SGLocationd
+HLAView::getLocation(const SGTimeStamp& timeStamp) const
+{
+ const HLASceneObject* sceneObject = getSceneObject();
+ SGLocationd location(getPosition(), getOrientation());
+ if (!sceneObject)
+ return location;
+ return sceneObject->getLocation(timeStamp).getAbsoluteLocation(location);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAView_hxx
+#define HLAView_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectInstance.hxx>
+
+#include "HLAObjectReferenceData.hxx"
+#include "HLASceneObject.hxx"
+
+namespace fgviewer {
+
+class HLAViewClass;
+
+class HLAView : public simgear::HLAObjectInstance {
+public:
+ HLAView(HLAViewClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
+ virtual ~HLAView();
+
+ virtual void createAttributeDataElements();
+
+ virtual void discoverInstance(const simgear::RTIData& tag);
+ virtual void removeInstance(const simgear::RTIData& tag);
+
+ virtual void registerInstance(simgear::HLAObjectClass* objectClass);
+ virtual void deleteInstance(const simgear::RTIData& tag);
+
+ const std::string& getNameAttribute() const
+ { return _name.getValue(); }
+ void setNameAttribute(const std::string& name)
+ { _name.setValue(name); }
+
+ const SGVec3d& getPosition() const
+ { return _position.getValue(); }
+ void setPosition(const SGVec3d& position)
+ { _position.setValue(position); }
+
+ const SGQuatd& getOrientation() const
+ { return _orientation.getValue(); }
+ void setOrientation(const SGQuatd& orientation)
+ { _orientation.setValue(orientation); }
+
+ const HLASceneObject* getSceneObject() const;
+ HLASceneObject* getSceneObject();
+ void setSceneObject(HLASceneObject* sceneObject);
+
+ virtual SGLocationd getLocation(const SGTimeStamp& simTime) const;
+
+private:
+ simgear::HLAStringData _name;
+
+ simgear::HLAVec3dData _position;
+ simgear::HLAQuat3dData _orientation;
+
+ simgear::HLAObjectReferenceData<HLASceneObject> _sceneObject;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAViewClass.hxx"
+
+#include "HLAView.hxx"
+
+namespace fgviewer {
+
+HLAViewClass::HLAViewClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLAViewClass::~HLAViewClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAViewClass::createObjectInstance(const std::string& name)
+{
+ return new HLAView(this, getFederate());
+}
+
+void
+HLAViewClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_nameIndex.empty())
+ _nameIndex = getDataElementIndex("name");
+ if (_positionIndex.empty())
+ _positionIndex = getDataElementIndex("location.position");
+ if (_orientationIndex.empty())
+ _orientationIndex = getDataElementIndex("location.orientation");
+ if (_sceneObjectNameIndex.empty())
+ _sceneObjectNameIndex = getDataElementIndex("sceneObjectName");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAViewClass_hxx
+#define HLAViewClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLAViewClass : public simgear::HLAObjectClass {
+public:
+ HLAViewClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAViewClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setNameIndex(const std::string& path)
+ { return getDataElementIndex(_nameIndex, path); }
+ const simgear::HLADataElementIndex& getNameIndex() const
+ { return _nameIndex; }
+
+ bool setPositionIndex(const std::string& path)
+ { return getDataElementIndex(_positionIndex, path); }
+ const simgear::HLADataElementIndex& getPositionIndex() const
+ { return _positionIndex; }
+
+ bool setOrientationIndex(const std::string& path)
+ { return getDataElementIndex(_orientationIndex, path); }
+ const simgear::HLADataElementIndex& getOrientationIndex() const
+ { return _orientationIndex; }
+
+ bool setSceneObjectNameIndex(const std::string& path)
+ { return getDataElementIndex(_sceneObjectNameIndex, path); }
+ const simgear::HLADataElementIndex& getSceneObjectNameIndex() const
+ { return _sceneObjectNameIndex; }
+
+private:
+ simgear::HLADataElementIndex _nameIndex;
+ simgear::HLADataElementIndex _positionIndex;
+ simgear::HLADataElementIndex _orientationIndex;
+ simgear::HLADataElementIndex _sceneObjectNameIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAViewer.hxx"
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include "HLAViewerClass.hxx"
+
+namespace fgviewer {
+
+HLAViewer::HLAViewer(HLAViewerClass* objectClass) :
+ HLAObjectInstance(objectClass)
+{
+}
+
+HLAViewer::~HLAViewer()
+{
+}
+
+void
+HLAViewer::createAttributeDataElements()
+{
+ HLAObjectInstance::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAViewerClass*>(getObjectClass().get()));
+ HLAViewerClass& objectClass = static_cast<HLAViewerClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAViewer_hxx
+#define HLAViewer_hxx
+
+#include <simgear/hla/HLAArrayDataElement.hxx>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLAViewerClass;
+
+class HLAViewer : public simgear::HLAObjectInstance {
+public:
+ HLAViewer(HLAViewerClass* objectClass = 0);
+ virtual ~HLAViewer();
+
+ virtual void createAttributeDataElements();
+
+private:
+ simgear::HLAStringData _name;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAViewerClass.hxx"
+
+#include "HLAViewer.hxx"
+
+namespace fgviewer {
+
+HLAViewerClass::HLAViewerClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLAObjectClass(name, federate)
+{
+}
+
+HLAViewerClass::~HLAViewerClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAViewerClass::createObjectInstance(const std::string& name)
+{
+ return new HLAViewer(this);
+}
+
+void
+HLAViewerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ /// FIXME resolve these indices somewhere else!
+ if (_nameIndex.empty())
+ _nameIndex = getDataElementIndex("name");
+ HLAObjectClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAViewerClass_hxx
+#define HLAViewerClass_hxx
+
+#include <string>
+#include <simgear/hla/HLAObjectClass.hxx>
+
+namespace fgviewer {
+
+class HLAViewerClass : public simgear::HLAObjectClass {
+public:
+ HLAViewerClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAViewerClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setNameIndex(const std::string& path)
+ { return getDataElementIndex(_nameIndex, path); }
+ const simgear::HLADataElementIndex& getNameIndex() const
+ { return _nameIndex; }
+
+private:
+ simgear::HLADataElementIndex _nameIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAViewerFederate.hxx"
+
+#include <osg/Group>
+#include <osgDB/Options>
+
+#include "HLAEyeTrackerClass.hxx"
+#include "HLAMPAircraftClass.hxx"
+#include "HLAPerspectiveViewer.hxx"
+#include "HLAPerspectiveViewerClass.hxx"
+#include "HLASceneObjectClass.hxx"
+#include "HLAView.hxx"
+#include "HLAViewClass.hxx"
+#include "Viewer.hxx"
+
+namespace fgviewer {
+
+HLAViewerFederate::HLAViewerFederate() :
+ _group(new osg::Group)
+{
+}
+
+HLAViewerFederate::~HLAViewerFederate()
+{
+}
+
+const HLAPerspectiveViewer*
+HLAViewerFederate::getViewer() const
+{
+ return _perspectiveViewer.get();
+}
+
+HLAPerspectiveViewer*
+HLAViewerFederate::getViewer()
+{
+ return _perspectiveViewer.get();
+}
+
+void
+HLAViewerFederate::setViewer(HLAPerspectiveViewer* perspectiveViewer)
+{
+ if (_perspectiveViewer.get() == perspectiveViewer)
+ return;
+ _perspectiveViewer = perspectiveViewer;
+}
+
+const HLAView*
+HLAViewerFederate::getView() const
+{
+ if (!_perspectiveViewer.valid())
+ return 0;
+ return _perspectiveViewer->getView();
+}
+
+HLAView*
+HLAViewerFederate::getView()
+{
+ if (!_perspectiveViewer.valid())
+ return 0;
+ return _perspectiveViewer->getView();
+}
+
+void
+HLAViewerFederate::setView(HLAView* view)
+{
+ if (!_perspectiveViewer.valid())
+ return;
+ return _perspectiveViewer->setView(view);
+}
+
+simgear::HLAObjectClass*
+HLAViewerFederate::createObjectClass(const std::string& name)
+{
+ if (name == "FGView") {
+ _viewClass = new HLAViewClass(name, this);
+ return _viewClass.get();
+ } else if (name == "FGPerspectiveViewer") {
+ _perspectiveViewerClass = new HLAPerspectiveViewerClass(name, this);
+ return _perspectiveViewerClass.get();
+ // } else if (name == "FGOrthographicViewer") {
+ // _orthographicViewerClass = new HLAOrthograpicViewerClass(name, this);
+ // return _orthographicViewerClass.get();
+ } else if (name == "FGEyeTracker") {
+ return new HLAEyeTrackerClass(name, this);
+ // } else if (name == "FGPerspectiveCamera") {
+ // _perspectiveCameraClass = new HLAPerspectiveCameraClass(name, this);
+ // return _perspectiveCameraClass.get();
+ // } else if (name == "FGOrthographicCamera") {
+ // _orthographicCameraClass = new HLAOrthographicCameraClass(name, this);
+ // return _orthographicCameraClass.get();
+ // } else if (name == "FGWindowDrawable") {
+ // _windowDrawableClass = new HLAWindowDrawableClass(name, this);
+ // return _windowDrawableClass.get();
+ // } else if (name == "FGRenderer") {
+ // _rendererClass = new HLARendererClass(name, this);
+ // return _rendererClass.get();
+ }
+ /// Classes for model type objects.
+ else if (name == "FGSceneObject") {
+ return new HLASceneObjectClass(name, this);
+ } else if (name == "MPAircraft") {
+ return new HLAMPAircraftClass(name, this);
+ }
+ /// Do not subscribe to anything else
+ else {
+ return 0;
+ }
+}
+
+bool
+HLAViewerFederate::init()
+{
+ if (!HLAFederate::init())
+ return false;
+
+ if (!_perspectiveViewerClass.valid())
+ return false;
+ if (!_viewClass.valid())
+ return false;
+
+ // Create a viewer ...
+ _perspectiveViewer = new HLAPerspectiveViewer(_perspectiveViewerClass.get(), this);
+ _perspectiveViewer->registerInstance(_perspectiveViewerClass.get());
+ // ... with a nice view
+ _defaultView = new HLAView(_viewClass.get(), this);
+ _defaultView->registerInstance(_viewClass.get());
+ _perspectiveViewer->setView(_defaultView.get());
+
+ return true;
+}
+
+bool
+HLAViewerFederate::update()
+{
+ // if (_view.valid())
+ // _view->updateAttributeValues(simgear::RTIData("frame"));
+ if (_perspectiveViewer.valid())
+ _perspectiveViewer->updateAttributeValues(simgear::RTIData("frame"));
+
+ // Just go ahead as far as possible.
+ // This is just fine for a viewer.
+ return HLAFederate::timeAdvanceAvailable();
+}
+
+bool
+HLAViewerFederate::shutdown()
+{
+ if (_defaultView.valid())
+ _defaultView->deleteInstance(simgear::RTIData("shutdown"));
+ _defaultView.clear();
+
+ if (_perspectiveViewer.valid())
+ _perspectiveViewer->deleteInstance(simgear::RTIData("shutdown"));
+ _perspectiveViewer.clear();
+
+ _group->removeChildren(0, _group->getNumChildren());
+
+ return HLAFederate::shutdown();
+}
+
+osg::Node*
+HLAViewerFederate::getDynamicModelNode()
+{
+ return _group.get();
+}
+
+void
+HLAViewerFederate::addDynamicModel(osg::Node* node)
+{
+ /// FIXME can do something more intelligent like a dequeue
+ /// when returning here something to identify the entry, removal is about O(1)
+ _group->addChild(node);
+}
+
+void
+HLAViewerFederate::removeDynamicModel(osg::Node* node)
+{
+ _group->removeChild(node);
+}
+
+osg::ref_ptr<const osgDB::Options>
+HLAViewerFederate::getReaderWriterOptions() const
+{
+ // Cannot use the thread safe variant of the observed_ptr methods here since the
+ // viewer is currently allocated on the stack.
+ if (!_viewer.valid())
+ return osg::ref_ptr<const osgDB::Options>();
+ return _viewer->getReaderWriterOptions();
+}
+
+void
+HLAViewerFederate::attachToViewer(Viewer* viewer)
+{
+ if (!viewer) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAViewerFederate::attachToViewer(): Ignoring zero viewer!");
+ return;
+ }
+ if (_viewer.valid()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "HLAViewerFederate::attachToViewer(): Not attaching a second viewer!");
+ return;
+ }
+ _viewer = viewer;
+ _viewer->insertSceneData(getDynamicModelNode());
+}
+
+void
+HLAViewerFederate::insertView(HLAView* view)
+{
+ _viewList.push_back(view);
+ /// FIXME not always
+ setView(view);
+}
+
+void
+HLAViewerFederate::eraseView(HLAView* view)
+{
+ //// FIXME store the iterator!!!!
+ for (ViewList::iterator i = _viewList.begin(); i != _viewList.end(); ++i) {
+ if (i->get() != view)
+ continue;
+ _viewList.erase(i);
+ break;
+ }
+ if (getView() == view) {
+ if (_viewList.empty()) {
+ setView(_defaultView.get());
+ } else {
+ setView(_viewList.back().get());
+ }
+ }
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAViewerFederate_hxx
+#define HLAViewerFederate_hxx
+
+#include <osg/ref_ptr>
+#include <osg/observer_ptr>
+#include <osg/Group>
+#include <osg/Node>
+#include <osgDB/Options>
+
+#include <simgear/hla/HLAFederate.hxx>
+
+#include "HLASceneObjectClass.hxx"
+#include "HLAView.hxx"
+#include "HLAViewClass.hxx"
+#include "HLAPerspectiveViewer.hxx"
+#include "HLAPerspectiveViewerClass.hxx"
+#include "HLAMPAircraftClass.hxx"
+
+namespace fgviewer {
+
+class Viewer;
+
+class HLAViewerFederate : public simgear::HLAFederate {
+public:
+ HLAViewerFederate();
+ virtual ~HLAViewerFederate();
+
+ const HLAPerspectiveViewer* getViewer() const;
+ HLAPerspectiveViewer* getViewer();
+ void setViewer(HLAPerspectiveViewer* viewer);
+
+ const HLAView* getView() const;
+ HLAView* getView();
+ void setView(HLAView* view);
+
+ virtual simgear::HLAObjectClass* createObjectClass(const std::string& name);
+
+ virtual bool init();
+ virtual bool update();
+ virtual bool shutdown();
+
+ /// The node containing all the dynamic models attached to this viewer
+ osg::Node* getDynamicModelNode();
+ void addDynamicModel(osg::Node* node);
+ void removeDynamicModel(osg::Node* node);
+
+ /// Dynamic models use this options struct for loading/paging
+ osg::ref_ptr<const osgDB::Options> getReaderWriterOptions() const;
+
+ /// Called by the viewer.
+ void attachToViewer(Viewer* viewer);
+
+ /// Temporary application management
+ void insertView(HLAView* view);
+ void eraseView(HLAView* view);
+
+private:
+ /// Explicitly known object classes
+ SGSharedPtr<HLAPerspectiveViewerClass> _perspectiveViewerClass;
+ SGSharedPtr<HLAViewClass> _viewClass;
+
+ /// The perspective viewer of this viewer federate. FIXME: also allow orthographic viewers for instruments!
+ SGSharedPtr<HLAPerspectiveViewer> _perspectiveViewer;
+
+ /// The default absolute view
+ SGSharedPtr<HLAView> _defaultView;
+
+ /// A list of all available views
+ typedef std::list<SGSharedPtr<HLAView> > ViewList;
+ ViewList _viewList;
+
+ /// The openscenegraphs side of this component
+ osg::ref_ptr<osg::Group> _group;
+
+ /// The backward reference to the viewer
+ osg::observer_ptr<Viewer> _viewer;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAWindowDrawable.hxx"
+
+#include "HLAWindowDrawableClass.hxx"
+
+namespace fgviewer {
+
+HLAWindowDrawable::HLAWindowDrawable(HLAWindowDrawableClass* objectClass) :
+ HLADrawable(objectClass)
+{
+}
+
+HLAWindowDrawable::~HLAWindowDrawable()
+{
+}
+
+void
+HLAWindowDrawable::createAttributeDataElements()
+{
+ HLADrawable::createAttributeDataElements();
+
+ assert(dynamic_cast<HLAWindowDrawableClass*>(getObjectClass().get()));
+ HLAWindowDrawableClass& objectClass = static_cast<HLAWindowDrawableClass&>(*getObjectClass());
+
+ setAttributeDataElement(objectClass.getFullscreenIndex(), _fullscreen.getDataElement());
+ setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
+ setAttributeDataElement(objectClass.getSizeIndex(), _size.getDataElement());
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAWindowDrawable_hxx
+#define HLAWindowDrawable_hxx
+
+#include <simgear/hla/HLABasicDataElement.hxx>
+#include "HLADrawable.hxx"
+
+namespace fgviewer {
+
+class HLAWindowDrawableClass;
+
+class HLAWindowDrawable : public HLADrawable {
+public:
+ HLAWindowDrawable(HLAWindowDrawableClass* objectClass = 0);
+ virtual ~HLAWindowDrawable();
+
+ virtual void createAttributeDataElements();
+
+ bool getFullscreen() const
+ { return _fullscreen.getValue(); }
+ void setFullscreen(bool fullscreen)
+ { _fullscreen.setValue(fullscreen); }
+
+ const SGVec2i& getPosition() const
+ { return _position.getValue(); }
+ void setPosition(const SGVec2i& position)
+ { _position.setValue(position); }
+
+ const SGVec2i& getSize() const
+ { return _size.getValue(); }
+ void setSize(const SGVec2i& size)
+ { _size.setValue(size); }
+
+private:
+ simgear::HLABoolData _fullscreen;
+ simgear::HLAVec2iData _position;
+ simgear::HLAVec2iData _size;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "HLAWindowDrawableClass.hxx"
+
+#include "HLAWindowDrawable.hxx"
+
+namespace fgviewer {
+
+HLAWindowDrawableClass::HLAWindowDrawableClass(const std::string& name, simgear::HLAFederate* federate) :
+ HLADrawableClass(name, federate)
+{
+}
+
+HLAWindowDrawableClass::~HLAWindowDrawableClass()
+{
+}
+
+simgear::HLAObjectInstance*
+HLAWindowDrawableClass::createObjectInstance(const std::string& name)
+{
+ return new HLAWindowDrawable(this);
+}
+
+void
+HLAWindowDrawableClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
+{
+ if (_fullscreenIndex.empty())
+ _fullscreenIndex = getDataElementIndex("fullscreen");
+ if (_positionIndex.empty())
+ _positionIndex = getDataElementIndex("position");
+ if (_sizeIndex.empty())
+ _sizeIndex = getDataElementIndex("size");
+ HLADrawableClass::createAttributeDataElements(objectInstance);
+}
+
+} // namespace fgviewer
--- /dev/null
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLAWindowDrawableClass_hxx
+#define HLAWindowDrawableClass_hxx
+
+#include "HLADrawableClass.hxx"
+
+namespace fgviewer {
+
+class HLAWindowDrawableClass : public HLADrawableClass {
+public:
+ HLAWindowDrawableClass(const std::string& name, simgear::HLAFederate* federate);
+ virtual ~HLAWindowDrawableClass();
+
+ /// Create a new instance of this class.
+ virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
+
+ virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
+
+ bool setFullscreenIndex(const std::string& path)
+ { return getDataElementIndex(_fullscreenIndex, path); }
+ const simgear::HLADataElementIndex& getFullscreenIndex() const
+ { return _fullscreenIndex; }
+
+ bool setPositionIndex(const std::string& path)
+ { return getDataElementIndex(_positionIndex, path); }
+ const simgear::HLADataElementIndex& getPositionIndex() const
+ { return _positionIndex; }
+
+ bool setSizeIndex(const std::string& path)
+ { return getDataElementIndex(_sizeIndex, path); }
+ const simgear::HLADataElementIndex& getSizeIndex() const
+ { return _sizeIndex; }
+
+private:
+ simgear::HLADataElementIndex _fullscreenIndex;
+ simgear::HLADataElementIndex _positionIndex;
+ simgear::HLADataElementIndex _sizeIndex;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// MEncoderCaptureOperation.hxx -- capture video stream into mencoder
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef MEncoderCaptureOperation_HXX
+#define MEncoderCaptureOperation_HXX
+
+#include <cstdio>
+#include <sstream>
+#include <string>
+
+#include <osgViewer/ViewerEventHandlers>
+
+/// Class to capture into a pipe driven mencoder.
+/// To integrate this into a viewer:
+/// MEncoderCaptureOperation* mencoderCaptureOperation = new MEncoderCaptureOperation("/tmp/fgviewer.avi", 60);
+/// osgViewer::ScreenCaptureHandler* c = new osgViewer::ScreenCaptureHandler(mencoderCaptureOperation, -1);
+/// viewer.addEventHandler(c);
+/// c->startCapture();
+
+namespace fgviewer {
+
+class MEncoderCaptureOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation {
+public:
+ MEncoderCaptureOperation(const std::string& fileName = "video.avi", unsigned fps = 30) :
+ _fps(fps),
+ _fileName(fileName),
+ _options("-ovc lavc"),
+ _file(0),
+ _width(-1),
+ _height(-1)
+ { }
+ virtual ~MEncoderCaptureOperation()
+ { _close(); }
+
+ const std::string& getFileName() const
+ { return _fileName; }
+ void setFileName(const std::string& fileName)
+ { _fileName = fileName; }
+
+ unsigned getFramesPerSecond() const
+ { return _fps; }
+ void setFramesPerSecond(unsigned fps)
+ { _fps = fps; }
+
+ const std::string& getOptions() const
+ { return _options; }
+ void setOptions(const std::string& options)
+ { _options = options; }
+
+ virtual void operator()(const osg::Image& image, const unsigned int)
+ {
+ // Delay any action until we have a valid image
+ if (!image.valid())
+ return;
+
+ // Ensure an open file
+ if (!_file) {
+ // If the video was already opened and we got any error,
+ // do not reopen with the same name.
+ if (0 < _width)
+ return;
+ _width = image.s();
+ _height = image.t();
+ if (!_open())
+ return;
+ }
+ // Ensure we did not change dimensions
+ if (image.s() != _width)
+ return;
+ if (image.t() != _height)
+ return;
+
+ // Write upside down flipped image
+ for (int row = _height - 1; 0 <= row; --row) {
+ size_t ret = fwrite(image.data(0, row), 1, image.getRowSizeInBytes(), _file);
+ if (ret != image.getRowSizeInBytes())
+ return;
+ }
+ }
+
+private:
+ bool _open()
+ {
+ if (_file)
+ return false;
+ /// FIXME improve: adapt format to the format we get from the image
+ std::stringstream ss;
+ ss << "mencoder - -demuxer rawvideo -rawvideo fps="
+ << _fps << ":w=" << _width << ":h=" << _height
+ << ":format=rgb24 -o " << _fileName << " " << _options;
+#ifdef _WIN32
+ _file = popen(ss.str().c_str(), "wb");
+#else
+ _file = popen(ss.str().c_str(), "w");
+#endif
+ return _file != 0;
+ }
+ void _close()
+ {
+ if (!_file)
+ return;
+ pclose(_file);
+ _file = 0;
+ }
+
+ /// Externally given:
+ unsigned _fps;
+ std::string _fileName;
+ std::string _options;
+
+ /// Internal determined
+ FILE* _file;
+ int _width;
+ int _height;
+};
+
+}
+
+#endif
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Renderer.hxx"
+
+#include <osgViewer/Renderer>
+#include <simgear/scene/material/EffectCullVisitor.hxx>
+
+#include "Drawable.hxx"
+#include "Viewer.hxx"
+#include "SlaveCamera.hxx"
+
+namespace fgviewer {
+
+// FIXME I understand why we currently need this, but this seems like
+// weird to require an own cull visitor.
+static void installCullVisitor(osg::Camera& camera)
+{
+ osgViewer::Renderer* renderer = static_cast<osgViewer::Renderer*>(camera.getRenderer());
+ for (int i = 0; i < 2; ++i) {
+ osgUtil::SceneView* sceneView = renderer->getSceneView(i);
+ osg::ref_ptr<osgUtil::CullVisitor::Identifier> identifier;
+
+ identifier = sceneView->getCullVisitor()->getIdentifier();
+ sceneView->setCullVisitor(new simgear::EffectCullVisitor);
+ sceneView->getCullVisitor()->setIdentifier(identifier.get());
+
+ identifier = sceneView->getCullVisitorLeft()->getIdentifier();
+ sceneView->setCullVisitorLeft(sceneView->getCullVisitor()->clone());
+ sceneView->getCullVisitorLeft()->setIdentifier(identifier.get());
+
+ identifier = sceneView->getCullVisitorRight()->getIdentifier();
+ sceneView->setCullVisitorRight(sceneView->getCullVisitor()->clone());
+ sceneView->getCullVisitorRight()->setIdentifier(identifier.get());
+ }
+}
+
+class Renderer::_SlaveCamera : public SlaveCamera {
+public:
+ _SlaveCamera(const std::string& name) :
+ SlaveCamera(name)
+ {
+ }
+ virtual ~_SlaveCamera()
+ {
+ }
+ virtual osg::Camera* _realizeImplementation(Viewer& viewer)
+ {
+ osg::Camera* camera = SlaveCamera::_realizeImplementation(viewer);
+ if (!camera)
+ return 0;
+
+ camera->addChild(viewer.getSceneDataGroup());
+
+ viewer.addSlave(camera, osg::Matrix::identity(), getViewOffset(), false /*useMastersSceneData*/);
+ installCullVisitor(*camera);
+
+ return camera;
+ }
+ virtual bool _updateImplementation(Viewer& viewer)
+ {
+ getCamera()->setViewMatrix(getEffectiveViewOffset(viewer));
+ getCamera()->setProjectionMatrix(getEffectiveFrustum(viewer).getMatrix(osg::Vec2(10, 8e4)));
+ return SlaveCamera::_updateImplementation(viewer);
+ }
+};
+
+Renderer::Renderer()
+{
+}
+
+Renderer::~Renderer()
+{
+}
+
+Drawable*
+Renderer::createDrawable(Viewer&, const std::string& name)
+{
+ return new Drawable(name);
+}
+
+SlaveCamera*
+Renderer::createSlaveCamera(Viewer&, const std::string& name)
+{
+ return new _SlaveCamera(name);
+}
+
+bool
+Renderer::realize(Viewer& viewer)
+{
+ if (!viewer.realizeDrawables())
+ return false;
+ return viewer.realizeSlaveCameras();
+}
+
+bool
+Renderer::update(Viewer& viewer)
+{
+ return viewer.updateSlaveCameras();
+}
+
+} // namespace fgviewer
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _FGVIEWER_RENDERER_HXX
+#define _FGVIEWER_RENDERER_HXX
+
+#include <string>
+#include <simgear/structure/SGWeakReferenced.hxx>
+
+namespace fgviewer {
+
+class Drawable;
+class Viewer;
+class SlaveCamera;
+
+/// Default renderer, doing fixed function work
+class Renderer : public SGWeakReferenced {
+public:
+ Renderer();
+ virtual ~Renderer();
+
+ virtual Drawable* createDrawable(Viewer& viewer, const std::string& name);
+ virtual SlaveCamera* createSlaveCamera(Viewer& viewer, const std::string& name);
+
+ virtual bool realize(Viewer& viewer);
+ virtual bool update(Viewer& viewer);
+
+private:
+ Renderer(const Renderer&);
+ Renderer& operator=(const Renderer&);
+
+ class _SlaveCamera;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SlaveCamera.hxx"
+
+#include <simgear/scene/util/OsgMath.hxx>
+
+#include "Viewer.hxx"
+
+#ifdef FG_HAVE_HLA
+#include "HLAViewerFederate.hxx"
+#include "HLAPerspectiveViewer.hxx"
+#endif
+
+namespace fgviewer {
+
+class NoUpdateCallback : public osg::NodeCallback {
+public:
+ virtual ~NoUpdateCallback()
+ { }
+ virtual void operator()(osg::Node* node, osg::NodeVisitor* nodeVisitor)
+ { }
+};
+
+SlaveCamera::SlaveCamera(const std::string& name) :
+ _name(name),
+ _viewport(new osg::Viewport())
+{
+ _referencePointMap["lowerLeft"] = osg::Vec2(-1, -1);
+ _referencePointMap["lowerRight"] = osg::Vec2(1, -1);
+ _referencePointMap["upperRight"] = osg::Vec2(1, 1);
+ _referencePointMap["upperLeft"] = osg::Vec2(-1, 1);
+}
+
+SlaveCamera::~SlaveCamera()
+{
+}
+
+bool
+SlaveCamera::setDrawableName(const std::string& drawableName)
+{
+ if (_camera.valid())
+ return false;
+ _drawableName = drawableName;
+ return true;
+}
+
+bool
+SlaveCamera::setViewport(const SGVec4i& viewport)
+{
+ _viewport->setViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
+ _frustum.setAspectRatio(getAspectRatio());
+ return true;
+}
+
+bool
+SlaveCamera::setViewOffset(const osg::Matrix& viewOffset)
+{
+ _viewOffset = viewOffset;
+ return true;
+}
+
+bool
+SlaveCamera::setViewOffsetDeg(double headingDeg, double pitchDeg, double rollDeg)
+{
+ osg::Matrix viewOffset = osg::Matrix::identity();
+ viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(headingDeg), osg::Vec3(0, 1, 0)));
+ viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(pitchDeg), osg::Vec3(-1, 0, 0)));
+ viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(rollDeg), osg::Vec3(0, 0, 1)));
+ return setViewOffset(viewOffset);
+}
+
+bool
+SlaveCamera::setFrustum(const Frustum& frustum)
+{
+ _frustum = frustum;
+ return true;
+}
+
+void
+SlaveCamera::setFustumByFieldOfViewDeg(double fieldOfViewDeg)
+{
+ Frustum frustum(getAspectRatio());
+ frustum.setFieldOfViewDeg(fieldOfViewDeg);
+ setFrustum(frustum);
+}
+
+bool
+SlaveCamera::setRelativeFrustum(const std::string names[2], const SlaveCamera& referenceCameraData,
+ const std::string referenceNames[2])
+{
+ // Track the way from one projection space to the other:
+ // We want
+ // P = T2*S*T*P0
+ // where P0 is the projection template sensible for the given window size,
+ // S a scale matrix and T is a translation matrix.
+ // We need to determine T and S so that the reference points in the parents
+ // projection space match the two reference points in this cameras projection space.
+
+ // Starting from the parents camera projection space, we get into this cameras
+ // projection space by the transform matrix:
+ // P*R*inv(pP*pR) = T2*S*T*P0*R*inv(pP*pR)
+ // So, at first compute that matrix without T2*S*T and determine S and T* from that
+
+ // The initial projeciton matrix to build upon
+ osg::Matrix P = Frustum(getAspectRatio()).getMatrix();
+
+ osg::Matrix R = getViewOffset();
+ osg::Matrix pP = referenceCameraData.getFrustum().getMatrix();
+ osg::Matrix pR = referenceCameraData.getViewOffset();
+
+ // Transform from the reference cameras projection space into this cameras eye space.
+ osg::Matrix pPtoEye = osg::Matrix::inverse(pR*pP)*R;
+
+ osg::Vec2 pRef[2] = {
+ referenceCameraData.getProjectionReferencePoint(referenceNames[0]),
+ referenceCameraData.getProjectionReferencePoint(referenceNames[1])
+ };
+
+ // The first reference point transformed to this cameras projection space
+ osg::Vec3d pRefInThis0 = P.preMult(pPtoEye.preMult(osg::Vec3d(pRef[0], 1)));
+ // Translate this proejction matrix so that the first reference point is at the origin
+ P.postMultTranslate(-pRefInThis0);
+
+ // Transform the second reference point and get the scaling correct.
+ osg::Vec3d pRefInThis1 = P.preMult(pPtoEye.preMult(osg::Vec3d(pRef[1], 1)));
+ double s = osg::Vec2d(pRefInThis1[0], pRefInThis1[1]).length();
+ if (s <= std::numeric_limits<double>::min())
+ return false;
+ osg::Vec2 ref[2] = {
+ getProjectionReferencePoint(names[0]),
+ getProjectionReferencePoint(names[1])
+ };
+ s = (ref[0] - ref[1]).length()/s;
+ P.postMultScale(osg::Vec3d(s, s, 1));
+
+ // The first reference point still maps to the origin in this projection space.
+ // Translate the origin to the desired first reference point.
+ P.postMultTranslate(osg::Vec3d(ref[0], 1));
+
+ // Now osg::Matrix::inverse(pR*pP)*R*P should map pRef[i] exactly onto ref[i] for i = 0, 1.
+ // Note that osg::Matrix::inverse(pR*pP)*R*P should exactly map pRef[0] at the near plane
+ // to ref[0] at the near plane. The far plane is not taken care of.
+
+ Frustum frustum;
+ if (!frustum.setMatrix(P))
+ return false;
+
+ return setFrustum(frustum);
+}
+
+void
+SlaveCamera::setProjectionReferencePoint(const std::string& name, const osg::Vec2& point)
+{
+ _referencePointMap[name] = point;
+}
+
+osg::Vec2
+SlaveCamera::getProjectionReferencePoint(const std::string& name) const
+{
+ NameReferencePointMap::const_iterator i = _referencePointMap.find(name);
+ if (i != _referencePointMap.end())
+ return i->second;
+ return osg::Vec2(0, 0);
+}
+
+void
+SlaveCamera::setMonitorProjectionReferences(double width, double height,
+ double bezelTop, double bezelBottom,
+ double bezelLeft, double bezelRight)
+{
+ double left = 1 + 2*bezelLeft/width;
+ double right = 1 + 2*bezelRight/width;
+
+ double bottom = 1 + 2*bezelBottom/height;
+ double top = 1 + 2*bezelTop/height;
+
+ setProjectionReferencePoint("lowerLeft", osg::Vec2(-left, -bottom));
+ setProjectionReferencePoint("lowerRight", osg::Vec2(right, -bottom));
+ setProjectionReferencePoint("upperRight", osg::Vec2(right, top));
+ setProjectionReferencePoint("upperLeft", osg::Vec2(-left, top));
+}
+
+osg::Vec3
+SlaveCamera::getLeftEyeOffset(const Viewer& viewer) const
+{
+#ifdef FG_HAVE_HLA
+ const HLAViewerFederate* viewerFederate = viewer.getViewerFederate();
+ if (!viewerFederate)
+ return osg::Vec3(0, 0, 0);
+ const HLAPerspectiveViewer* perspectiveViewer = viewerFederate->getViewer();
+ if (!perspectiveViewer)
+ return osg::Vec3(0, 0, 0);
+ return toOsg(perspectiveViewer->getLeftEyeOffset());
+#else
+ return osg::Vec3(0, 0, 0);
+#endif
+}
+
+osg::Vec3
+SlaveCamera::getRightEyeOffset(const Viewer& viewer) const
+{
+#ifdef FG_HAVE_HLA
+ const HLAViewerFederate* viewerFederate = viewer.getViewerFederate();
+ if (!viewerFederate)
+ return osg::Vec3(0, 0, 0);
+ const HLAPerspectiveViewer* perspectiveViewer = viewerFederate->getViewer();
+ if (!perspectiveViewer)
+ return osg::Vec3(0, 0, 0);
+ return toOsg(perspectiveViewer->getRightEyeOffset());
+#else
+ return osg::Vec3(0, 0, 0);
+#endif
+}
+
+double
+SlaveCamera::getZoomFactor(const Viewer& viewer) const
+{
+#ifdef FG_HAVE_HLA
+ const HLAViewerFederate* viewerFederate = viewer.getViewerFederate();
+ if (!viewerFederate)
+ return 1;
+ const HLAPerspectiveViewer* perspectiveViewer = viewerFederate->getViewer();
+ if (!perspectiveViewer)
+ return 1;
+ return perspectiveViewer->getZoomFactor();
+#else
+ return 1;
+#endif
+}
+
+osg::Matrix
+SlaveCamera::getEffectiveViewOffset(const Viewer& viewer) const
+{
+ // The eye offset in the master cameras coordinates.
+ osg::Vec3 eyeOffset = getLeftEyeOffset(viewer);
+
+ // Transform the eye offset into this slaves coordinates
+ eyeOffset = eyeOffset*getViewOffset();
+
+ // The slaves view matrix is composed of the master matrix
+ osg::Matrix viewOffset = viewer.getCamera()->getViewMatrix();
+ // ... its view offset ...
+ viewOffset.postMult(getViewOffset());
+ // ... and the inverse of the eye offset that is required
+ // to keep the world at the same position wrt the projection walls
+ viewOffset.postMultTranslate(-eyeOffset);
+ return viewOffset;
+}
+
+Frustum
+SlaveCamera::getEffectiveFrustum(const Viewer& viewer) const
+{
+ // The eye offset in the master cameras coordinates.
+ osg::Vec3 eyeOffset = getLeftEyeOffset(viewer);
+
+ // Transform the eye offset into this slaves coordinates
+ eyeOffset = eyeOffset*getViewOffset();
+
+ /// FIXME read that from external
+ osg::Vec3 zoomScaleCenter(0, 0, -1);
+ double zoomFactor = getZoomFactor(viewer);
+
+ /// Transform into the local cameras orientation.
+ zoomScaleCenter = getViewOffset().preMult(zoomScaleCenter);
+
+ // The unmodified frustum
+ Frustum frustum = getFrustum();
+
+ // For unresized views this is a noop
+ frustum.setAspectRatio(getAspectRatio());
+
+ // need to correct this for the eye position within the projection system
+ frustum.translate(-eyeOffset);
+
+ // Scale the whole geometric extent of the projection surfaces by the zoom factor
+ frustum.scale(1/zoomFactor, zoomScaleCenter);
+
+ return frustum;
+}
+
+bool
+SlaveCamera::realize(Viewer& viewer)
+{
+ if (_camera.valid())
+ return false;
+ _camera = _realizeImplementation(viewer);
+ return _camera.valid();
+}
+
+bool
+SlaveCamera::update(Viewer& viewer)
+{
+ return _updateImplementation(viewer);
+}
+
+osg::Camera*
+SlaveCamera::_realizeImplementation(Viewer& viewer)
+{
+ Drawable* drawable = viewer.getDrawable(_drawableName);
+ if (!drawable)
+ return 0;
+ osg::GraphicsContext* graphicsContext = drawable->getGraphicsContext();
+ if (!graphicsContext)
+ return 0;
+
+ osg::Camera* camera = new osg::Camera;
+ camera->setName(getName());
+ camera->setGraphicsContext(graphicsContext);
+ camera->setViewport(_viewport.get());
+ camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
+
+ // Not seriously consider someting different
+ camera->setDrawBuffer(GL_BACK);
+ camera->setReadBuffer(GL_BACK);
+
+ camera->setUpdateCallback(new NoUpdateCallback);
+
+ return camera;
+}
+
+bool
+SlaveCamera::_updateImplementation(Viewer& viewer)
+{
+ if (!_camera.valid())
+ return false;
+ return true;
+}
+
+} // namespace fgviewer
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _fgviewer_SlaveCamera_hxx
+#define _fgviewer_SlaveCamera_hxx
+
+#include <string>
+#include <osg/Camera>
+#include <simgear/math/SGMath.hxx>
+#include <simgear/structure/SGWeakReferenced.hxx>
+
+#include "Frustum.hxx"
+
+namespace fgviewer {
+
+class Viewer;
+
+class SlaveCamera : public SGWeakReferenced {
+public:
+ SlaveCamera(const std::string& name);
+ virtual ~SlaveCamera();
+
+ const std::string& getName() const
+ { return _name; }
+
+ /// The drawable this camera renders to
+ bool setDrawableName(const std::string& drawableName);
+ const std::string& getDrawableName() const
+ { return _drawableName; }
+
+ /// The viewport into the above drawable
+ virtual bool setViewport(const SGVec4i& viewport);
+ SGVec4i getViewport() const
+ { return SGVec4i(_viewport->x(), _viewport->y(), _viewport->width(), _viewport->height()); }
+ double getAspectRatio() const
+ { return _viewport->aspectRatio(); }
+
+ /// The view offset, usually an orientation offset
+ virtual bool setViewOffset(const osg::Matrix& viewOffset);
+ const osg::Matrix& getViewOffset() const
+ { return _viewOffset; }
+ bool setViewOffsetDeg(double headingDeg, double pitchDeg, double rollDeg);
+
+ /// The frustum for this camera
+ virtual bool setFrustum(const Frustum& frustum);
+ const Frustum& getFrustum() const
+ { return _frustum; }
+ void setFustumByFieldOfViewDeg(double fieldOfViewDeg);
+ bool setRelativeFrustum(const std::string names[2], const SlaveCamera& referenceCameraData,
+ const std::string referenceNames[2]);
+
+ /// For relative cameras configure the reference points that should match
+ void setProjectionReferencePoint(const std::string& name, const osg::Vec2& point);
+ osg::Vec2 getProjectionReferencePoint(const std::string& name) const;
+ /// Set the reference points for a monitor configuration
+ void setMonitorProjectionReferences(double width, double height,
+ double bezelTop, double bezelBottom,
+ double bezelLeft, double bezelRight);
+
+ /// Access parameters of this view/camera
+ osg::Vec3 getLeftEyeOffset(const Viewer& viewer) const;
+ osg::Vec3 getRightEyeOffset(const Viewer& viewer) const;
+ double getZoomFactor(const Viewer& viewer) const;
+ osg::Matrix getEffectiveViewOffset(const Viewer& viewer) const;
+ Frustum getEffectiveFrustum(const Viewer& viewer) const;
+
+ /// The top level camera holding the context
+ osg::Camera* getCamera()
+ { return _camera.get(); }
+
+ /// Top level entry points
+ bool realize(Viewer& viewer);
+ bool update(Viewer& viewer);
+
+protected:
+ virtual osg::Camera* _realizeImplementation(Viewer& viewer);
+ virtual bool _updateImplementation(Viewer& viewer);
+
+private:
+ SlaveCamera(const SlaveCamera&);
+ SlaveCamera& operator=(const SlaveCamera&);
+
+ /// The immutable name that is used to reference this slave camera.
+ const std::string _name;
+ std::string _drawableName;
+ osg::ref_ptr<osg::Viewport> _viewport;
+ osg::Matrix _viewOffset;
+ Frustum _frustum;
+ /// The camera that is attached to the slave and that has a context attached.
+ osg::ref_ptr<osg::Camera> _camera;
+
+ /// For relative views, the named reference points in the projection space
+ typedef std::map<std::string, osg::Vec2> NameReferencePointMap;
+ NameReferencePointMap _referencePointMap;
+};
+
+} // namespace fgviewer
+
+#endif
--- /dev/null
+// Viewer.cxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "Viewer.hxx"
+
+#include <osg/ArgumentParser>
+#include <osg/ProxyNode>
+#include <osg/PagedLOD>
+#include <osgDB/ReadFile>
+
+#ifdef __linux__
+#include <X11/Xlib.h>
+#include <osgViewer/api/X11/GraphicsWindowX11>
+#endif
+
+#include "MEncoderCaptureOperation.hxx"
+
+namespace fgviewer {
+
+Viewer::Viewer(osg::ArgumentParser& arguments) :
+ osgViewer::Viewer(arguments),
+ _sceneDataGroup(new osg::Group),
+ _timeIncrement(SGTimeStamp::fromSec(0)),
+ _simTime(SGTimeStamp::fromSec(0))
+{
+ /// Careful: this method really assigns the sceneDataGroup to all cameras!
+ /// FIXME the 'useMasterScene' flag at the slave is able to get around that!!!
+ osgViewer::Viewer::setSceneData(_sceneDataGroup.get());
+ /// The only changed default that is renderer independent ...
+ getCamera()->setClearColor(osg::Vec4(0, 0, 0, 0));
+}
+
+Viewer::~Viewer()
+{
+ stopThreading();
+
+#ifdef FG_HAVE_HLA
+ if (_viewerFederate.valid())
+ _viewerFederate->shutdown();
+ _viewerFederate = 0;
+#endif
+}
+
+bool
+Viewer::readCameraConfig(const SGPropertyNode& viewerNode)
+{
+ // Collect and realize all windows
+ for (int i = 0; i < viewerNode.nChildren(); ++i) {
+ // FIXME support window, fullscreen, offscreen
+ const SGPropertyNode* windowNode = viewerNode.getChild(i);
+ if (!windowNode || windowNode->getNameString() != "window")
+ continue;
+
+ std::string name = windowNode->getStringValue("name", "");
+ if (name.empty()) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Ignoring unnamed window!");
+ return false;
+ }
+
+ Drawable* drawable = getOrCreateDrawable(name);
+
+ osg::GraphicsContext::ScreenIdentifier screenIdentifier;
+ screenIdentifier = getScreenIdentifier(windowNode->getStringValue("display", ""));
+ drawable->setScreenIdentifier(screenIdentifier.displayName());
+
+ if (windowNode->getBoolValue("fullscreen", false)) {
+ osg::GraphicsContext::ScreenSettings screenSettings;
+ screenSettings = getScreenSettings(screenIdentifier);
+ drawable->setPosition(SGVec2i(0, 0));
+ drawable->setSize(SGVec2i(screenSettings.width, screenSettings.height));
+ drawable->setFullscreen(true);
+ drawable->setOffscreen(false);
+
+ } else if (windowNode->getBoolValue("video", false)) {
+ drawable->setPosition(SGVec2i(0, 0));
+ SGVec2i size;
+ size[0] = windowNode->getIntValue("geometry/width", 1366);
+ size[1] = windowNode->getIntValue("geometry/height", 768);
+ drawable->setSize(size);
+ drawable->setFullscreen(true);
+ drawable->setOffscreen(true);
+
+ std::string outputFile = windowNode->getStringValue("output-file", "fgviewer.avi");
+ unsigned fps = windowNode->getIntValue("frames-per-second", 30);
+
+ /// This is the case for the video writers, have a fixed time increment
+ _timeIncrement = SGTimeStamp::fromSec(1.0/fps);
+
+ MEncoderCaptureOperation* captureOperation;
+ captureOperation = new MEncoderCaptureOperation(outputFile, fps);
+ osgViewer::ScreenCaptureHandler* captureHandler;
+ captureHandler = new osgViewer::ScreenCaptureHandler(captureOperation, -1);
+ addEventHandler(captureHandler);
+ captureHandler->startCapture();
+
+ } else {
+
+ SGVec2i position;
+ position[0] = windowNode->getIntValue("geometry/x", 0);
+ position[1] = windowNode->getIntValue("geometry/y", 0);
+ drawable->setPosition(position);
+ SGVec2i size;
+ size[0] = windowNode->getIntValue("geometry/width", 1366);
+ size[1] = windowNode->getIntValue("geometry/height", 768);
+ drawable->setSize(size);
+ drawable->setFullscreen(false);
+ drawable->setOffscreen(false);
+ }
+ }
+
+ for (int i = 0; i < viewerNode.nChildren(); ++i) {
+ const SGPropertyNode* cameraNode = viewerNode.getChild(i);
+ if (!cameraNode || cameraNode->getNameString() != "camera")
+ continue;
+
+ std::string name = cameraNode->getStringValue("name", "");
+ if (name.empty()) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Camera configuration needs a name!");
+ return false;
+ }
+
+ SlaveCamera* slaveCamera = getOrCreateSlaveCamera(name);
+
+ std::string drawableName = cameraNode->getStringValue("window", "");
+ if (drawableName.empty()) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Camera configuration needs an assigned window!");
+ return false;
+ }
+ Drawable* drawable = getDrawable(drawableName);
+ if (!drawable) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Camera configuration \"" << name << "\" needs a drawable configured!");
+ return false;
+ }
+ slaveCamera->setDrawableName(drawableName);
+ drawable->attachSlaveCamera(slaveCamera);
+
+ SGVec2i size = drawable->getSize();
+ SGVec4i viewport(0, 0, size[0], size[1]);
+ viewport[0] = cameraNode->getIntValue("viewport/x", viewport[0]);
+ viewport[1] = cameraNode->getIntValue("viewport/y", viewport[1]);
+ viewport[2] = cameraNode->getIntValue("viewport/width", viewport[2]);
+ viewport[3] = cameraNode->getIntValue("viewport/height", viewport[3]);
+ slaveCamera->setViewport(viewport);
+
+ double headingDeg = cameraNode->getDoubleValue("view-offset/heading-deg", 0);
+ double pitchDeg = cameraNode->getDoubleValue("view-offset/pitch-deg", 0);
+ double rollDeg = cameraNode->getDoubleValue("view-offset/roll-deg", 0);
+ slaveCamera->setViewOffsetDeg(headingDeg, pitchDeg, rollDeg);
+
+ // Care for the reference points
+ if (const SGPropertyNode* referencePointsNode = cameraNode->getNode("reference-points")) {
+ for (int j = 0; j < referencePointsNode->nChildren(); ++j) {
+ const SGPropertyNode* referencePointNode = cameraNode->getNode("reference-point");
+ if (!referencePointNode)
+ continue;
+ std::string name = referencePointNode->getStringValue("name", "");
+ if (name.empty())
+ continue;
+ osg::Vec2 point;
+ point[0] = referencePointNode->getDoubleValue("x", 0);
+ point[1] = referencePointNode->getDoubleValue("y", 0);
+ slaveCamera->setProjectionReferencePoint(name, point);
+ }
+ }
+ // Define 4 reference points by monitor dimensions
+ else if (const SGPropertyNode* physicalDimensionsNode = cameraNode->getNode("physical-dimensions")) {
+ double physicalWidth = physicalDimensionsNode->getDoubleValue("width", viewport[2]);
+ double physicalHeight = physicalDimensionsNode->getDoubleValue("height", viewport[3]);
+ if (const SGPropertyNode* bezelNode = physicalDimensionsNode->getNode("bezel")) {
+ double bezelHeightTop = bezelNode->getDoubleValue("top", 0);
+ double bezelHeightBottom = bezelNode->getDoubleValue("bottom", 0);
+ double bezelWidthLeft = bezelNode->getDoubleValue("left", 0);
+ double bezelWidthRight = bezelNode->getDoubleValue("right", 0);
+ slaveCamera->setMonitorProjectionReferences(physicalWidth, physicalHeight,
+ bezelHeightTop, bezelHeightBottom,
+ bezelWidthLeft, bezelWidthRight);
+ }
+ }
+
+ // The frustum node takes precedence, as this is the most explicit one.
+ if (const SGPropertyNode* frustumNode = cameraNode->getNode("frustum")) {
+ Frustum frustum(slaveCamera->getAspectRatio());
+ frustum._near = frustumNode->getDoubleValue("near", frustum._near);
+ frustum._left = frustumNode->getDoubleValue("left", frustum._left);
+ frustum._right = frustumNode->getDoubleValue("right", frustum._right);
+ frustum._bottom = frustumNode->getDoubleValue("bottom", frustum._bottom);
+ frustum._top = frustumNode->getDoubleValue("top", frustum._top);
+ slaveCamera->setFrustum(frustum);
+
+ } else if (const SGPropertyNode* perspectiveNode = cameraNode->getNode("perspective")) {
+ double fieldOfViewDeg = perspectiveNode->getDoubleValue("field-of-view-deg", 55);
+ slaveCamera->setFustumByFieldOfViewDeg(fieldOfViewDeg);
+
+ } else if (const SGPropertyNode* monitorNode = cameraNode->getNode("monitor")) {
+
+ std::string referenceCameraName;
+ std::string names[2];
+ std::string referenceNames[2];
+
+ // FIXME??!!
+ if (const SGPropertyNode* leftOfNode = monitorNode->getNode("left-of")) {
+ referenceCameraName = leftOfNode->getStringValue("");
+ names[0] = "lowerRight";
+ referenceNames[0] = "lowerLeft";
+ names[1] = "upperRight";
+ referenceNames[1] = "upperLeft";
+ } else if (const SGPropertyNode* rightOfNode = monitorNode->getNode("right-of")) {
+ referenceCameraName = rightOfNode->getStringValue("");
+ names[0] = "lowerLeft";
+ referenceNames[0] = "lowerRight";
+ names[1] = "upperLeft";
+ referenceNames[1] = "upperRight";
+ } else if (const SGPropertyNode* aboveNode = monitorNode->getNode("above")) {
+ referenceCameraName = aboveNode->getStringValue("");
+ names[0] = "lowerLeft";
+ referenceNames[0] = "upperLeft";
+ names[1] = "lowerRight";
+ referenceNames[1] = "upperRight";
+ } else if (const SGPropertyNode* belowNode = monitorNode->getNode("below")) {
+ referenceCameraName = belowNode->getStringValue("");
+ names[0] = "upperLeft";
+ referenceNames[0] = "lowerLeft";
+ names[1] = "upperRight";
+ referenceNames[1] = "lowerRight";
+ } else {
+ // names[0] = ;
+ // referenceNames[0] = ;
+ // names[1] = ;
+ // referenceNames[1] = ;
+ }
+
+ // If we finally found a set of reference points that should match,
+ // then create a relative frustum matching these references
+ if (SlaveCamera* referenceSlaveCamera = getSlaveCamera(referenceCameraName)) {
+ slaveCamera->setRelativeFrustum(names, *referenceSlaveCamera, referenceNames);
+ } else {
+ SG_LOG(SG_VIEW, SG_ALERT, "Unable to find reference camera \"" << referenceCameraName
+ << "\" for camera \"" << name << "\"!");
+ }
+ } else {
+ // Set a proper default taking the current aspect ratio into account
+ slaveCamera->setFustumByFieldOfViewDeg(55);
+ }
+ }
+
+ return true;
+}
+
+void
+Viewer::setupDefaultCameraConfigIfUnset()
+{
+ if (getNumDrawables() || getNumSlaveCameras())
+ return;
+
+ osg::GraphicsContext::ScreenIdentifier screenIdentifier;
+ screenIdentifier = getDefaultScreenIdentifier();
+
+ Drawable* drawable = getOrCreateDrawable("fgviewer");
+ drawable->setScreenIdentifier(screenIdentifier.displayName());
+ drawable->setPosition(SGVec2i(0, 0));
+ SGVec2i size(800, 600);
+ drawable->setSize(size);
+ drawable->setFullscreen(false);
+ drawable->setOffscreen(false);
+
+ SlaveCamera* slaveCamera = getOrCreateSlaveCamera(drawable->getName());
+ slaveCamera->setDrawableName(drawable->getName());
+ drawable->attachSlaveCamera(slaveCamera);
+ slaveCamera->setViewport(SGVec4i(0, 0, size[0], size[1]));
+ slaveCamera->setViewOffset(osg::Matrix::identity());
+ slaveCamera->setFustumByFieldOfViewDeg(55);
+}
+
+bool
+Viewer::readConfiguration(const std::string&)
+{
+ return false;
+}
+
+void
+Viewer::setRenderer(Renderer* renderer)
+{
+ if (!renderer) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Viewer::setRenderer(): Setting the renderer to zero is not supported!");
+ return;
+ }
+ if (_renderer.valid()) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Viewer::setRenderer(): Setting the renderer twice is not supported!");
+ return;
+ }
+ _renderer = renderer;
+}
+
+Renderer*
+Viewer::getRenderer()
+{
+ return _renderer.get();
+}
+
+Drawable*
+Viewer::getOrCreateDrawable(const std::string& name)
+{
+ Drawable* drawable = getDrawable(name);
+ if (drawable)
+ return drawable;
+ if (!_renderer.valid())
+ return 0;
+ drawable = _renderer->createDrawable(*this, name);
+ if (!drawable)
+ return 0;
+ _drawableVector.push_back(drawable);
+ return drawable;
+}
+
+Drawable*
+Viewer::getDrawable(const std::string& name)
+{
+ return getDrawable(getDrawableIndex(name));
+}
+
+unsigned
+Viewer::getDrawableIndex(const std::string& name)
+{
+ for (DrawableVector::size_type i = 0; i < _drawableVector.size(); ++i) {
+ if (_drawableVector[i]->getName() == name)
+ return i;
+ }
+ return ~0u;
+}
+
+Drawable*
+Viewer::getDrawable(unsigned index)
+{
+ if (_drawableVector.size() <= index)
+ return 0;
+ return _drawableVector[index].get();
+}
+
+unsigned
+Viewer::getNumDrawables() const
+{
+ return _drawableVector.size();
+}
+
+SlaveCamera*
+Viewer::getOrCreateSlaveCamera(const std::string& name)
+{
+ SlaveCamera* slaveCamera = getSlaveCamera(name);
+ if (slaveCamera)
+ return slaveCamera;
+ if (!_renderer.valid())
+ return 0;
+ slaveCamera = _renderer->createSlaveCamera(*this, name);
+ if (!slaveCamera)
+ return 0;
+ _slaveCameraVector.push_back(slaveCamera);
+ return slaveCamera;
+}
+
+SlaveCamera*
+Viewer::getSlaveCamera(const std::string& name)
+{
+ return getSlaveCamera(getSlaveCameraIndex(name));
+}
+
+unsigned
+Viewer::getSlaveCameraIndex(const std::string& name)
+{
+ for (SlaveCameraVector::size_type i = 0; i < _slaveCameraVector.size(); ++i) {
+ if (_slaveCameraVector[i]->getName() == name)
+ return i;
+ }
+ return ~0u;
+}
+
+SlaveCamera*
+Viewer::getSlaveCamera(unsigned index)
+{
+ if (_slaveCameraVector.size() <= index)
+ return 0;
+ return _slaveCameraVector[index].get();
+}
+
+unsigned
+Viewer::getNumSlaveCameras() const
+{
+ return _slaveCameraVector.size();
+}
+
+void
+Viewer::realize()
+{
+ if (isRealized())
+ return;
+
+ if (!_renderer.valid())
+ return;
+
+ // Setup a default config if there is none
+ setupDefaultCameraConfigIfUnset();
+
+ // Realize
+ if (!_renderer->realize(*this)) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Renderer::realize() failed!");
+ return;
+ }
+
+ osgViewer::Viewer::realize();
+}
+
+bool
+Viewer::realizeDrawables()
+{
+ for (DrawableVector::iterator i = _drawableVector.begin(); i != _drawableVector.end(); ++i) {
+ if (!(*i)->realize(*this)) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Unable to realize drawable \"" << (*i)->getName() << "\"!");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+Viewer::realizeSlaveCameras()
+{
+ for (SlaveCameraVector::iterator i = _slaveCameraVector.begin(); i != _slaveCameraVector.end(); ++i) {
+ if (!(*i)->realize(*this)) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Unable to realize camera \"" << (*i)->getName() << "\"!");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void
+Viewer::advance(double)
+{
+ if (_timeIncrement == SGTimeStamp::fromSec(0)) {
+ // Flightgears current scheme - could be improoved
+ _simTime = SGTimeStamp::now();
+ } else {
+ // Giving an explicit time increment makes sense in presence
+ // of the video capture where we need deterministic
+ // frame times and object positions for each picture.
+ _simTime += _timeIncrement;
+ }
+
+ // This sets the frame stamps simulation time to simTime
+ // and schedules a frame event
+ osgViewer::Viewer::advance(_simTime.toSecs());
+}
+
+void
+Viewer::updateTraversal()
+{
+#ifdef FG_HAVE_HLA
+ if (_viewerFederate.valid()) {
+ if (_timeIncrement == SGTimeStamp::fromSec(0)) {
+ if (!_viewerFederate->timeAdvanceAvailable()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate update!");
+ _viewerFederate->shutdown();
+ _viewerFederate = 0;
+ }
+ } else {
+ osg::FrameStamp* frameStamp = getViewerFrameStamp();
+ SGTimeStamp timeStamp = SGTimeStamp::fromSec(frameStamp->getSimulationTime());
+ if (!_viewerFederate->timeAdvance(timeStamp)) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate update!");
+ _viewerFederate->shutdown();
+ _viewerFederate = 0;
+ }
+ }
+ }
+#endif
+
+ osgViewer::Viewer::updateTraversal();
+
+ if (!_renderer->update(*this)) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Renderer::update() failed!");
+ }
+}
+
+bool
+Viewer::updateSlaveCameras()
+{
+ for (SlaveCameraVector::iterator i = _slaveCameraVector.begin(); i != _slaveCameraVector.end(); ++i) {
+ if (!(*i)->update(*this)) {
+ SG_LOG(SG_VIEW, SG_ALERT, "SlaveCamera::update() failed!");
+ return false;
+ }
+ }
+ return true;
+}
+
+void
+Viewer::setReaderWriterOptions(simgear::SGReaderWriterOptions* readerWriterOptions)
+{
+ _readerWriterOptions = readerWriterOptions;
+}
+
+simgear::SGReaderWriterOptions*
+Viewer::getReaderWriterOptions()
+{
+ return _readerWriterOptions.get();
+}
+
+void
+Viewer::setSceneData(osg::Node* node)
+{
+ _sceneDataGroup->removeChildren(0, _sceneDataGroup->getNumChildren());
+ insertSceneData(node);
+}
+
+void
+Viewer::insertSceneData(osg::Node* node)
+{
+ _sceneDataGroup->addChild(node);
+}
+
+bool
+Viewer::insertSceneData(const std::string& fileName, const osgDB::Options* options)
+{
+#if 0
+ osg::ProxyNode* proxyNode = new osg::ProxyNode;
+ if (options)
+ proxyNode->setDatabaseOptions(options->clone(osg::CopyOp()));
+ else
+ proxyNode->setDatabaseOptions(_readerWriterOptions->clone(osg::CopyOp()));
+ proxyNode->setFileName(0, fileName);
+ insertSceneData(proxyNode);
+ return true;
+#else
+ osg::ref_ptr<osg::Node> node = osgDB::readRefNodeFile(fileName, options);
+ if (!node.valid())
+ return false;
+ insertSceneData(node.get());
+ return true;
+#endif
+}
+
+osg::Group*
+Viewer::getSceneDataGroup()
+{
+ return _sceneDataGroup.get();
+}
+
+class Viewer::_PurgeLevelOfDetailNodesVisitor : public osg::NodeVisitor {
+public:
+ _PurgeLevelOfDetailNodesVisitor() :
+ osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
+ { }
+ virtual ~_PurgeLevelOfDetailNodesVisitor()
+ { }
+
+ virtual void apply(osg::ProxyNode& node)
+ {
+ for (unsigned i = 0; i < node.getNumChildren(); ++i) {
+ if (node.getFileName(i).empty())
+ continue;
+ node.removeChildren(i, node.getNumChildren() - i);
+ break;
+ }
+
+ osg::NodeVisitor::apply(static_cast<osg::Group&>(node));
+ }
+ virtual void apply(osg::PagedLOD& node)
+ {
+ for (unsigned i = 0; i < node.getNumChildren(); ++i) {
+ if (node.getFileName(i).empty())
+ continue;
+ node.removeChildren(i, node.getNumChildren() - i);
+ break;
+ }
+
+ osg::NodeVisitor::apply(static_cast<osg::Group&>(node));
+ }
+};
+
+void
+Viewer::purgeLevelOfDetailNodes()
+{
+ _PurgeLevelOfDetailNodesVisitor purgeLevelOfDetailNodesVisitor;
+ _sceneDataGroup->accept(purgeLevelOfDetailNodesVisitor);
+}
+
+osg::GraphicsContext::ScreenIdentifier
+Viewer::getDefaultScreenIdentifier()
+{
+ osg::GraphicsContext::ScreenIdentifier screenIdentifier;
+ screenIdentifier.readDISPLAY();
+ if (screenIdentifier.displayNum < 0)
+ screenIdentifier.displayNum = 0;
+ if (screenIdentifier.screenNum < 0)
+ screenIdentifier.screenNum = 0;
+ return screenIdentifier;
+}
+
+osg::GraphicsContext::ScreenIdentifier
+Viewer::getScreenIdentifier(const std::string& display)
+{
+ osg::GraphicsContext::ScreenIdentifier screenIdentifier;
+ screenIdentifier.setScreenIdentifier(display);
+
+ osg::GraphicsContext::ScreenIdentifier defaultScreenIdentifier;
+ defaultScreenIdentifier = getDefaultScreenIdentifier();
+ if (screenIdentifier.hostName.empty())
+ screenIdentifier.hostName = defaultScreenIdentifier.hostName;
+ if (screenIdentifier.displayNum < 0)
+ screenIdentifier.displayNum = defaultScreenIdentifier.displayNum;
+ if (screenIdentifier.screenNum < 0)
+ screenIdentifier.screenNum = defaultScreenIdentifier.screenNum;
+
+ return screenIdentifier;
+}
+
+osg::GraphicsContext::ScreenSettings
+Viewer::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier)
+{
+ osg::GraphicsContext::ScreenSettings screenSettings;
+
+ osg::GraphicsContext::WindowingSystemInterface* wsi;
+ wsi = osg::GraphicsContext::getWindowingSystemInterface();
+ if (!wsi) {
+ SG_LOG(SG_VIEW, SG_ALERT, "No windowing system interface defined!");
+ return screenSettings;
+ }
+
+ wsi->getScreenSettings(screenIdentifier, screenSettings);
+ return screenSettings;
+}
+
+osg::GraphicsContext::Traits*
+Viewer::getTraits(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier)
+{
+ osg::DisplaySettings* ds = _displaySettings.get();
+ if (!ds)
+ ds = osg::DisplaySettings::instance().get();
+
+ osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits(ds);
+
+ traits->hostName = screenIdentifier.hostName;
+ traits->displayNum = screenIdentifier.displayNum;
+ traits->screenNum = screenIdentifier.screenNum;
+
+ // not seriously consider something different
+ traits->doubleBuffer = true;
+
+ osg::GraphicsContext::ScreenSettings screenSettings;
+ screenSettings = getScreenSettings(screenIdentifier);
+
+ traits->x = 0;
+ traits->y = 0;
+ traits->width = screenSettings.width;
+ traits->height = screenSettings.height;
+
+ return traits;
+}
+
+#ifdef __linux__
+class Viewer::_ResetScreenSaverSwapCallback : public osg::GraphicsContext::SwapCallback {
+public:
+ _ResetScreenSaverSwapCallback() :
+ _timeStamp(SGTimeStamp::fromSec(0))
+ {
+ }
+ virtual ~_ResetScreenSaverSwapCallback()
+ {
+ }
+ virtual void swapBuffersImplementation(osg::GraphicsContext* graphicsContext)
+ {
+ graphicsContext->swapBuffersImplementation();
+
+ // This callback must be attached to this type of graphics context
+ assert(dynamic_cast<osgViewer::GraphicsWindowX11*>(graphicsContext));
+
+ // Reset the screen saver every 10 seconds
+ SGTimeStamp timeStamp = SGTimeStamp::now();
+ if (timeStamp < _timeStamp)
+ return;
+ _timeStamp = timeStamp + SGTimeStamp::fromSec(10);
+ // Obviously runs in the draw thread. Thus, use the draw display.
+ XResetScreenSaver(static_cast<osgViewer::GraphicsWindowX11*>(graphicsContext)->getDisplay());
+ }
+private:
+ SGTimeStamp _timeStamp;
+};
+#endif
+
+osg::GraphicsContext*
+Viewer::createGraphicsContext(osg::GraphicsContext::Traits* traits)
+{
+ osg::GraphicsContext::WindowingSystemInterface* wsi;
+ wsi = osg::GraphicsContext::getWindowingSystemInterface();
+ if (!wsi) {
+ SG_LOG(SG_VIEW, SG_ALERT, "No windowing system interface defined!");
+ return 0;
+ }
+
+ osg::GraphicsContext* graphicsContext = wsi->createGraphicsContext(traits);
+ if (!graphicsContext) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Unable to create window \"" << traits->windowName << "\"!");
+ return 0;
+ }
+
+#ifdef __linux__
+ if (dynamic_cast<osgViewer::GraphicsWindowX11*>(graphicsContext))
+ graphicsContext->setSwapCallback(new _ResetScreenSaverSwapCallback);
+#endif
+
+ return graphicsContext;
+}
+
+#ifdef FG_HAVE_HLA
+const HLAViewerFederate*
+Viewer::getViewerFederate() const
+{
+ return _viewerFederate.get();
+}
+
+HLAViewerFederate*
+Viewer::getViewerFederate()
+{
+ return _viewerFederate.get();
+}
+
+void
+Viewer::setViewerFederate(HLAViewerFederate* viewerFederate)
+{
+ if (!viewerFederate) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Viewer::setViewerFederate(): Setting the viewer federate to zero is not supported!");
+ return;
+ }
+ if (_viewerFederate.valid()) {
+ SG_LOG(SG_VIEW, SG_ALERT, "Viewer::setViewerFederate(): Setting the viewer federate twice is not supported!");
+ return;
+ }
+ _viewerFederate = viewerFederate;
+ _viewerFederate->attachToViewer(this);
+}
+#endif
+
+} // namespace fgviewer
--- /dev/null
+// Viewer.hxx -- alternative flightgear viewer application
+//
+// Copyright (C) 2009 - 2012 Mathias Froehlich
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+#ifndef _FGVIEWER_VIEWER_HXX
+#define _FGVIEWER_VIEWER_HXX
+
+#include <osg/ArgumentParser>
+#include <osgViewer/Viewer>
+
+#include <simgear/math/SGMath.hxx>
+#include <simgear/scene/util/SGReaderWriterOptions.hxx>
+#include <simgear/timing/timestamp.hxx>
+#include <simgear/props/props.hxx>
+
+#include "Drawable.hxx"
+#include "Frustum.hxx"
+#include "Renderer.hxx"
+#include "SlaveCamera.hxx"
+
+#ifdef FG_HAVE_HLA
+#include "HLAViewerFederate.hxx"
+#endif
+
+namespace fgviewer {
+
+class Viewer : public osgViewer::Viewer {
+public:
+ Viewer(osg::ArgumentParser& arguments);
+ virtual ~Viewer();
+
+ bool readCameraConfig(const SGPropertyNode& viewerNode);
+ void setupDefaultCameraConfigIfUnset();
+ /// Short circuit osg config files.
+ virtual bool readConfiguration(const std::string& filename);
+
+ /// Callback class that cares for the camera and drawable setup
+ void setRenderer(Renderer* renderer);
+ Renderer* getRenderer();
+
+ /// Access and create drawables
+ Drawable* getOrCreateDrawable(const std::string& name);
+ Drawable* getDrawable(const std::string& name);
+ unsigned getDrawableIndex(const std::string& name);
+ Drawable* getDrawable(unsigned index);
+ unsigned getNumDrawables() const;
+
+ /// Access and create slave cameras
+ SlaveCamera* getOrCreateSlaveCamera(const std::string& name);
+ SlaveCamera* getSlaveCamera(const std::string& name);
+ unsigned getSlaveCameraIndex(const std::string& name);
+ SlaveCamera* getSlaveCamera(unsigned index);
+ unsigned getNumSlaveCameras() const;
+
+ /// Realize the contexts and attach the cameras there
+ virtual void realize();
+ bool realizeDrawables();
+ bool realizeSlaveCameras();
+
+ /// exec methods
+ virtual void advance(double simTime);
+ virtual void updateTraversal();
+ bool updateSlaveCameras();
+
+ /// Store this per viewer instead of global.
+ void setReaderWriterOptions(simgear::SGReaderWriterOptions* readerWriterOptions);
+ simgear::SGReaderWriterOptions* getReaderWriterOptions();
+
+ /// Puts the scene data under the renderer.
+ /// Replaces the whole renderer independent scene.
+ virtual void setSceneData(osg::Node* node);
+
+ /// Adds the scene node to the global scene
+ /// Use this to add something to the displayed scene.
+ void insertSceneData(osg::Node* node);
+ bool insertSceneData(const std::string& fileName, const osgDB::Options* options = 0);
+ /// Return the scene data group.
+ osg::Group* getSceneDataGroup();
+
+ /// Traverse the scenegraph and throw out all child nodes that can be loaded again.
+ void purgeLevelOfDetailNodes();
+
+ /// Return a default screen identifier. Under UNIX the default DISPLAY environment variable.
+ static osg::GraphicsContext::ScreenIdentifier getDefaultScreenIdentifier();
+ /// Interpret the given display. Is mergend with the default screen identifier.
+ static osg::GraphicsContext::ScreenIdentifier getScreenIdentifier(const std::string& display);
+ /// Return screen settings, mostly the resolution of the given screen.
+ osg::GraphicsContext::ScreenSettings getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier);
+ /// Return traits struct for the given screen identifier. The size and position is already set up for a fullscreen window.
+ osg::GraphicsContext::Traits* getTraits(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier);
+ /// Helper to create an new graphics context from traits.
+ osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits);
+
+#ifdef FG_HAVE_HLA
+ /// The federate if configured, can only be set once
+ const HLAViewerFederate* getViewerFederate() const;
+ HLAViewerFederate* getViewerFederate();
+ void setViewerFederate(HLAViewerFederate* viewerFederate);
+#endif
+
+private:
+ Viewer(const Viewer&);
+ Viewer& operator=(const Viewer&);
+
+ /// Unload all lod's
+ class _PurgeLevelOfDetailNodesVisitor;
+#ifdef __linux__
+ /// Under linux make sure that the screen saver does not jump in
+ class _ResetScreenSaverSwapCallback;
+#endif
+
+ /// The renderer used to setup the higher level camera/scenegraph structure
+ SGSharedPtr<Renderer> _renderer;
+
+ /// The drawables managed by this viewer.
+ typedef std::vector<SGSharedPtr<Drawable> > DrawableVector;
+ DrawableVector _drawableVector;
+
+ /// The slave cameras for this viewer.
+ /// Since we support more complex renderers, we can not only use osg::View::Slave.
+ typedef std::vector<SGSharedPtr<SlaveCamera> > SlaveCameraVector;
+ SlaveCameraVector _slaveCameraVector;
+
+ /// The top level options struct
+ osg::ref_ptr<simgear::SGReaderWriterOptions> _readerWriterOptions;
+
+ /// The top level scenegraph structure that is used for drawing
+ osg::ref_ptr<osg::Group> _sceneDataGroup;
+
+ /// Stores the time increment for each frame.
+ /// If zero, the time advance is done to the current real time.
+ SGTimeStamp _timeIncrement;
+ /// The current simulation time of the viewer
+ SGTimeStamp _simTime;
+
+#ifdef FG_HAVE_HLA
+ /// The federate if configured
+ SGSharedPtr<HLAViewerFederate> _viewerFederate;
+#endif
+};
+
+} // namespace fgviewer
+
+#endif
#include <config.h>
#endif
-#include <iostream>
-#include <cstdlib>
-
#include <osg/ArgumentParser>
-#include <osg/Fog>
#include <osgDB/ReadFile>
-#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
-#include <osgViewer/Renderer>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
-#include <simgear/scene/material/EffectCullVisitor.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/model/ModelRegistry.hxx>
#include <simgear/misc/ResourceManager.hxx>
+#include "Renderer.hxx"
+#include "Viewer.hxx"
+
+#ifdef FG_HAVE_HLA
+#include "HLACameraManipulator.hxx"
+#include "HLAViewerFederate.hxx"
+#endif
+
+
int
main(int argc, char** argv)
{
// FIXME implement a flightgear similar argument parser into simgear and use this one
osg::ArgumentParser arguments(&argc, argv);
+ logbuf::set_log_classes(SG_ALL);
+ logbuf::set_log_priority(SG_ALERT);
+
std::string fg_root;
if (arguments.read("--fg-root", fg_root)) {
} else if (const char *fg_root_env = std::getenv("FG_ROOT")) {
props->setStringValue(prop, value);
}
+ std::string renderer;
+ while (arguments.read("--renderer", renderer));
+
+ if (arguments.read("--hla")) {
+ props->setStringValue("hla/federate/federation", "rti:///FlightGear");
+ }
+ std::string federation;
+ if (arguments.read("--federation", federation)) {
+ props->setStringValue("hla/federate/federation", federation);
+ }
+
/// Start setting up the viewer windows and start feeding them.
// construct the viewer.
- osgViewer::Viewer viewer(arguments);
+ fgviewer::Viewer viewer(arguments);
+
+ if (renderer.empty()) {
+ // Currently just the defautl renderer. More to come.
+ viewer.setRenderer(new fgviewer::Renderer);
+
+ } else {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Unknown renderer configuration \"" << renderer
+ << "\" given on the command line.");
+ return EXIT_FAILURE;
+ }
+
+ // A viewer configuration
+ if (const SGPropertyNode* viewerNode = props->getChild("viewer")) {
+ if (!viewer.readCameraConfig(*viewerNode)) {
+ SG_LOG(SG_GENERAL, SG_ALERT, "Reading camera configuration failed.");
+ return EXIT_FAILURE;
+ }
+ }
// set up the camera manipulators.
osgGA::KeySwitchMatrixManipulator* keyswitchManipulator;
viewer.setCameraManipulator(keyswitchManipulator);
// Usefull stats
- viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
+ viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getSceneDataGroup()->getOrCreateStateSet()));
viewer.addEventHandler(new osgViewer::HelpHandler);
viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.addEventHandler(new osgViewer::ThreadingHandler);
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
- // Sigh, we need our own cull visitor ...
- osg::Camera* camera = viewer.getCamera();
- osgViewer::Renderer* renderer = static_cast<osgViewer::Renderer*>(camera->getRenderer());
- for (int j = 0; j < 2; ++j) {
- osgUtil::SceneView* sceneView = renderer->getSceneView(j);
- sceneView->setCullVisitor(new simgear::EffectCullVisitor);
- }
-
// We want on demand database paging
viewer.setDatabasePager(new osgDB::DatabasePager);
viewer.getDatabasePager()->setUpThreads(1, 1);
options->setPluginStringData("SimGear::FG_ROOT", fg_root);
// Omit building bounding volume trees, as the viewer will not run a simulation
options->setPluginStringData("SimGear::BOUNDINGVOLUMES", "OFF");
+ viewer.setReaderWriterOptions(options.get());
// Here, all arguments are processed
arguments.reportRemainingOptionsAsUnrecognized();
arguments.writeErrorMessages(std::cerr);
+ if (props->getNode("hla/federate/federation")) {
+#if !defined FG_HAVE_HLA
+ SG_LOG(SG_GENERAL, SG_ALERT, "Unable to enter HLA/RTI viewer mode: HLA/RTI disabled at compile time.");
+#else
+ const SGPropertyNode* federateNode = props->getNode("hla/federate");
+
+ SGSharedPtr<fgviewer::HLAViewerFederate> viewerFederate;
+ viewerFederate = new fgviewer::HLAViewerFederate;
+ viewerFederate->setVersion(federateNode->getStringValue("version", "RTI13"));
+ // viewerFederate->setConnectArguments(federateNode->getStringValue("connect-arguments", ""));
+ viewerFederate->setFederateType(federateNode->getStringValue("type", "ViewerFederate"));
+ viewerFederate->setFederateName(federateNode->getStringValue("name", ""));
+ viewerFederate->setFederationExecutionName(federateNode->getStringValue("federation", ""));
+ std::string objectModel;
+ objectModel = federateNode->getStringValue("federation-object-model", "HLA/fg-local-fom.xml");
+ if (SGPath(objectModel).isRelative()) {
+ SGPath path = fg_root;
+ path.append(objectModel);
+ objectModel = path.str();
+ }
+ viewerFederate->setFederationObjectModel(objectModel);
+
+ if (!viewerFederate->init()) {
+ SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate init!");
+ } else {
+ viewer.setViewerFederate(viewerFederate.get());
+ viewer.setCameraManipulator(new fgviewer::HLACameraManipulator(viewerFederate->getViewer()));
+ }
+#endif
+ }
/// Read the model files that are configured.
}
// pass the loaded scene graph to the viewer.
- viewer.setSceneData(loadedModel.get());
+ viewer.insertSceneData(loadedModel.get());
+
+ // Note that this does not affect the hla camera manipulator
+ viewer.home();
return viewer.run();
}