From: Mathias Froehlich Date: Sun, 16 Dec 2012 15:43:22 +0000 (+0100) Subject: fgviewer: Import hla based viewer application. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=243929274b2665e812016bd0cdddb8f54d7be286;p=flightgear.git fgviewer: Import hla based viewer application. --- diff --git a/utils/fgviewer/CMakeLists.txt b/utils/fgviewer/CMakeLists.txt index dcfc3ac62..bbbdac3e4 100644 --- a/utils/fgviewer/CMakeLists.txt +++ b/utils/fgviewer/CMakeLists.txt @@ -1,11 +1,52 @@ +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) diff --git a/utils/fgviewer/Drawable.cxx b/utils/fgviewer/Drawable.cxx new file mode 100644 index 000000000..8d2f0a8d8 --- /dev/null +++ b/utils/fgviewer/Drawable.cxx @@ -0,0 +1,128 @@ +// 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 +#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.lock(); + if (!drawable.valid()) + return; + drawable->resize(x, y, width, height); + } + SGWeakPtr _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 traits = _getTraits(viewer); + return viewer.createGraphicsContext(traits.get()); +} + +osg::ref_ptr +Drawable::_getTraits(Viewer& viewer) +{ + osg::GraphicsContext::ScreenIdentifier screenIdentifier; + screenIdentifier.setScreenIdentifier(_screenIdentifier); + + osg::ref_ptr 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 diff --git a/utils/fgviewer/Drawable.hxx b/utils/fgviewer/Drawable.hxx new file mode 100644 index 000000000..fc448a13c --- /dev/null +++ b/utils/fgviewer/Drawable.hxx @@ -0,0 +1,106 @@ +// 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 +#include +#include +#include +#include + +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 _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 _graphicsContext; + std::list > _slaveCameraList; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/Frustum.hxx b/utils/fgviewer/Frustum.hxx new file mode 100644 index 000000000..263c64eb8 --- /dev/null +++ b/utils/fgviewer/Frustum.hxx @@ -0,0 +1,156 @@ +// 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 +#include +#include +#include +#include + +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 diff --git a/utils/fgviewer/HLACamera.cxx b/utils/fgviewer/HLACamera.cxx new file mode 100644 index 000000000..f78083e47 --- /dev/null +++ b/utils/fgviewer/HLACamera.cxx @@ -0,0 +1,55 @@ +// 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 +#endif + +#include "HLACamera.hxx" + +#include +#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(getObjectClass().get())); + HLACameraClass& objectClass = static_cast(*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 diff --git a/utils/fgviewer/HLACamera.hxx b/utils/fgviewer/HLACamera.hxx new file mode 100644 index 000000000..15f4d7561 --- /dev/null +++ b/utils/fgviewer/HLACamera.hxx @@ -0,0 +1,81 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLACameraClass.cxx b/utils/fgviewer/HLACameraClass.cxx new file mode 100644 index 000000000..044cea9ad --- /dev/null +++ b/utils/fgviewer/HLACameraClass.cxx @@ -0,0 +1,62 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLACameraClass.hxx b/utils/fgviewer/HLACameraClass.hxx new file mode 100644 index 000000000..19116f416 --- /dev/null +++ b/utils/fgviewer/HLACameraClass.hxx @@ -0,0 +1,77 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLACameraManipulator.cxx b/utils/fgviewer/HLACameraManipulator.cxx new file mode 100644 index 000000000..2aa470b41 --- /dev/null +++ b/utils/fgviewer/HLACameraManipulator.cxx @@ -0,0 +1,248 @@ +// 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 +#endif + +#include "HLACameraManipulator.hxx" + +#include +#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(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 diff --git a/utils/fgviewer/HLACameraManipulator.hxx b/utils/fgviewer/HLACameraManipulator.hxx new file mode 100644 index 000000000..96161ed0f --- /dev/null +++ b/utils/fgviewer/HLACameraManipulator.hxx @@ -0,0 +1,64 @@ +// 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 +#include +#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 _perspectiveViewer; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLADrawable.cxx b/utils/fgviewer/HLADrawable.cxx new file mode 100644 index 000000000..90cf31a7b --- /dev/null +++ b/utils/fgviewer/HLADrawable.cxx @@ -0,0 +1,52 @@ +// 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 +#endif + +#include "HLADrawable.hxx" + +#include +#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(getObjectClass().get())); + HLADrawableClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement()); + setAttributeDataElement(objectClass.getRendererIndex(), _renderer.getDataElement()); + setAttributeDataElement(objectClass.getDisplayIndex(), _display.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLADrawable.hxx b/utils/fgviewer/HLADrawable.hxx new file mode 100644 index 000000000..430764f0a --- /dev/null +++ b/utils/fgviewer/HLADrawable.hxx @@ -0,0 +1,60 @@ +// 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 +#include + +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 _renderer; + simgear::HLAStringData _renderer; + simgear::HLAStringData _display; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLADrawableClass.cxx b/utils/fgviewer/HLADrawableClass.cxx new file mode 100644 index 000000000..8851bb101 --- /dev/null +++ b/utils/fgviewer/HLADrawableClass.cxx @@ -0,0 +1,56 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLADrawableClass.hxx b/utils/fgviewer/HLADrawableClass.hxx new file mode 100644 index 000000000..8727a1981 --- /dev/null +++ b/utils/fgviewer/HLADrawableClass.hxx @@ -0,0 +1,59 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAEyeTracker.cxx b/utils/fgviewer/HLAEyeTracker.cxx new file mode 100644 index 000000000..5b2bc1d24 --- /dev/null +++ b/utils/fgviewer/HLAEyeTracker.cxx @@ -0,0 +1,51 @@ +// 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 +#endif + +#include "HLAEyeTracker.hxx" + +#include +#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(getObjectClass().get())); + HLAEyeTrackerClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getLeftEyeOffsetIndex(), _leftEyeOffset.getDataElement()); + setAttributeDataElement(objectClass.getRightEyeOffsetIndex(), _rightEyeOffset.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLAEyeTracker.hxx b/utils/fgviewer/HLAEyeTracker.hxx new file mode 100644 index 000000000..9cca5cda0 --- /dev/null +++ b/utils/fgviewer/HLAEyeTracker.hxx @@ -0,0 +1,52 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAEyeTrackerClass.cxx b/utils/fgviewer/HLAEyeTrackerClass.cxx new file mode 100644 index 000000000..23e27a9f7 --- /dev/null +++ b/utils/fgviewer/HLAEyeTrackerClass.cxx @@ -0,0 +1,54 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAEyeTrackerClass.hxx b/utils/fgviewer/HLAEyeTrackerClass.hxx new file mode 100644 index 000000000..5851e17a0 --- /dev/null +++ b/utils/fgviewer/HLAEyeTrackerClass.hxx @@ -0,0 +1,53 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAMPAircraft.cxx b/utils/fgviewer/HLAMPAircraft.cxx new file mode 100644 index 000000000..51602b247 --- /dev/null +++ b/utils/fgviewer/HLAMPAircraft.cxx @@ -0,0 +1,82 @@ +// 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 +#endif + +#include "HLAMPAircraft.hxx" + +#include "HLAMPAircraftClass.hxx" + +namespace fgviewer { + +HLAMPAircraft::HLAMPAircraft(HLASceneObjectClass* objectClass, const SGWeakPtr& 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(getObjectClass().get())); + HLAMPAircraftClass& objectClass = static_cast(*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 diff --git a/utils/fgviewer/HLAMPAircraft.hxx b/utils/fgviewer/HLAMPAircraft.hxx new file mode 100644 index 000000000..480470fa8 --- /dev/null +++ b/utils/fgviewer/HLAMPAircraft.hxx @@ -0,0 +1,45 @@ +// 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& 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 diff --git a/utils/fgviewer/HLAMPAircraftClass.cxx b/utils/fgviewer/HLAMPAircraftClass.cxx new file mode 100644 index 000000000..df528edaa --- /dev/null +++ b/utils/fgviewer/HLAMPAircraftClass.cxx @@ -0,0 +1,55 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAMPAircraftClass.hxx b/utils/fgviewer/HLAMPAircraftClass.hxx new file mode 100644 index 000000000..d6b102cdf --- /dev/null +++ b/utils/fgviewer/HLAMPAircraftClass.hxx @@ -0,0 +1,52 @@ +// 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 diff --git a/utils/fgviewer/HLAObjectReferenceData.hxx b/utils/fgviewer/HLAObjectReferenceData.hxx new file mode 100644 index 000000000..2b8d943c9 --- /dev/null +++ b/utils/fgviewer/HLAObjectReferenceData.hxx @@ -0,0 +1,176 @@ +// 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 +#include +#include + +#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& 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 federate = _federate.lock(); + if (!federate.valid()) + return false; + SGSharedPtr 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 _federate; +}; + + +template +class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement { +public: + // FIXME drop the federate once we have a decode/encode visitor?! + HLAObjectReferenceDataElement(const SGWeakPtr& federate) : + HLAAbstractObjectReferenceDataElement(federate) + { } + + const SGSharedPtr& getObject() const + { return _object; } + void setObject(const SGSharedPtr& 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(objectInstance)) + return false; + _object = static_cast(objectInstance); + return true; + } + } + +private: + SGSharedPtr _object; +}; + +template +class HLAObjectReferenceData { +public: + typedef HLAObjectReferenceDataElement DataElement; + + HLAObjectReferenceData(const SGWeakPtr& federate) : + _dataElement(new DataElement(federate)) + { } + + const HLADataElement* getDataElement() const + { return _dataElement.get(); } + HLADataElement* getDataElement() + { return _dataElement.get(); } + + const SGSharedPtr& getObject() const + { return _dataElement->getObject(); } + void setObject(const SGSharedPtr& 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; +}; + +} + +#endif diff --git a/utils/fgviewer/HLAOrthographicCamera.cxx b/utils/fgviewer/HLAOrthographicCamera.cxx new file mode 100644 index 000000000..efea54701 --- /dev/null +++ b/utils/fgviewer/HLAOrthographicCamera.cxx @@ -0,0 +1,51 @@ +// 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 +#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(getObjectClass().get())); + HLAOrthographicCameraClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getLeftIndex(), _left.getDataElement()); + setAttributeDataElement(objectClass.getRightIndex(), _right.getDataElement()); + setAttributeDataElement(objectClass.getBottomIndex(), _bottom.getDataElement()); + setAttributeDataElement(objectClass.getTopIndex(), _top.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLAOrthographicCamera.hxx b/utils/fgviewer/HLAOrthographicCamera.hxx new file mode 100644 index 000000000..1b403d3a7 --- /dev/null +++ b/utils/fgviewer/HLAOrthographicCamera.hxx @@ -0,0 +1,64 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAOrthographicCameraClass.cxx b/utils/fgviewer/HLAOrthographicCameraClass.cxx new file mode 100644 index 000000000..3f2c8be81 --- /dev/null +++ b/utils/fgviewer/HLAOrthographicCameraClass.cxx @@ -0,0 +1,57 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAOrthographicCameraClass.hxx b/utils/fgviewer/HLAOrthographicCameraClass.hxx new file mode 100644 index 000000000..1d68e44ac --- /dev/null +++ b/utils/fgviewer/HLAOrthographicCameraClass.hxx @@ -0,0 +1,64 @@ +// 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 diff --git a/utils/fgviewer/HLAPerspectiveCamera.cxx b/utils/fgviewer/HLAPerspectiveCamera.cxx new file mode 100644 index 000000000..2d80ba9cf --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveCamera.cxx @@ -0,0 +1,82 @@ +// 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 +#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(getObjectClass().get())); + HLAPerspectiveCameraClass& objectClass = static_cast(*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 diff --git a/utils/fgviewer/HLAPerspectiveCamera.hxx b/utils/fgviewer/HLAPerspectiveCamera.hxx new file mode 100644 index 000000000..2af9c0f0c --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveCamera.hxx @@ -0,0 +1,77 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAPerspectiveCameraClass.cxx b/utils/fgviewer/HLAPerspectiveCameraClass.cxx new file mode 100644 index 000000000..363a0d604 --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveCameraClass.cxx @@ -0,0 +1,59 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAPerspectiveCameraClass.hxx b/utils/fgviewer/HLAPerspectiveCameraClass.hxx new file mode 100644 index 000000000..cc6f9bfe8 --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveCameraClass.hxx @@ -0,0 +1,70 @@ +// 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 diff --git a/utils/fgviewer/HLAPerspectiveViewer.cxx b/utils/fgviewer/HLAPerspectiveViewer.cxx new file mode 100644 index 000000000..37c08786b --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveViewer.cxx @@ -0,0 +1,118 @@ +// 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 +#endif + +#include "HLAPerspectiveViewer.hxx" + +#include "HLAPerspectiveViewerClass.hxx" + +namespace fgviewer { + +HLAPerspectiveViewer::HLAPerspectiveViewer(HLAPerspectiveViewerClass* objectClass, const SGWeakPtr& federate) : + HLAViewer(objectClass), + _view(federate), + _zoomFactor(1), + _eyeTracker(federate) +{ +} + +HLAPerspectiveViewer::~HLAPerspectiveViewer() +{ +} + +void +HLAPerspectiveViewer::createAttributeDataElements() +{ + HLAViewer::createAttributeDataElements(); + + assert(dynamic_cast(getObjectClass().get())); + HLAPerspectiveViewerClass& objectClass = static_cast(*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 diff --git a/utils/fgviewer/HLAPerspectiveViewer.hxx b/utils/fgviewer/HLAPerspectiveViewer.hxx new file mode 100644 index 000000000..0094e4e8c --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveViewer.hxx @@ -0,0 +1,75 @@ +// 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& 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 _view; + simgear::HLAVec3dData _position; + simgear::HLAQuat3dData _orientation; + simgear::HLADoubleData _zoomFactor; + simgear::HLAObjectReferenceData _eyeTracker; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLAPerspectiveViewerClass.cxx b/utils/fgviewer/HLAPerspectiveViewerClass.cxx new file mode 100644 index 000000000..9d52c8ddf --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveViewerClass.cxx @@ -0,0 +1,60 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAPerspectiveViewerClass.hxx b/utils/fgviewer/HLAPerspectiveViewerClass.hxx new file mode 100644 index 000000000..50bfc9547 --- /dev/null +++ b/utils/fgviewer/HLAPerspectiveViewerClass.hxx @@ -0,0 +1,70 @@ +// 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 diff --git a/utils/fgviewer/HLAProxyDataElement.hxx b/utils/fgviewer/HLAProxyDataElement.hxx new file mode 100644 index 000000000..bb339793e --- /dev/null +++ b/utils/fgviewer/HLAProxyDataElement.hxx @@ -0,0 +1,90 @@ +// 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 + +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 diff --git a/utils/fgviewer/HLARenderer.cxx b/utils/fgviewer/HLARenderer.cxx new file mode 100644 index 000000000..e4a84d37d --- /dev/null +++ b/utils/fgviewer/HLARenderer.cxx @@ -0,0 +1,50 @@ +// 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 +#endif + +#include "HLARenderer.hxx" + +#include +#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(getObjectClass().get())); + HLARendererClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLARenderer.hxx b/utils/fgviewer/HLARenderer.hxx new file mode 100644 index 000000000..e25d959fa --- /dev/null +++ b/utils/fgviewer/HLARenderer.hxx @@ -0,0 +1,41 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLARendererClass.cxx b/utils/fgviewer/HLARendererClass.cxx new file mode 100644 index 000000000..f6761c1d5 --- /dev/null +++ b/utils/fgviewer/HLARendererClass.cxx @@ -0,0 +1,52 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLARendererClass.hxx b/utils/fgviewer/HLARendererClass.hxx new file mode 100644 index 000000000..4189a25a9 --- /dev/null +++ b/utils/fgviewer/HLARendererClass.hxx @@ -0,0 +1,47 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLASceneObject.cxx b/utils/fgviewer/HLASceneObject.cxx new file mode 100644 index 000000000..115e17d50 --- /dev/null +++ b/utils/fgviewer/HLASceneObject.cxx @@ -0,0 +1,314 @@ +// 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 +#endif + +#include "HLASceneObject.hxx" + +#include + +#include +#include +#include + +#include "HLASceneObjectClass.hxx" +#include "HLAViewerFederate.hxx" + +namespace fgviewer { + +class HLASceneObject::_ModelDataElement : public simgear::HLAProxyDataElement { +public: + _ModelDataElement(const SGWeakPtr& 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 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 _sceneObject; + simgear::HLAStringData _name; +}; + +class HLASceneObject::_Transform : public osg::Transform { +public: + _Transform(const SGWeakPtr& 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 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 _sceneObject; +}; + +HLASceneObject::HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr& 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(getObjectClass().get())); + HLASceneObjectClass& objectClass = static_cast(*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 federate = getFederate().lock(); + if (federate.valid()) { + assert(dynamic_cast(federate.get())); + HLAViewerFederate* viewerFederate = static_cast(federate.get()); + + osg::ref_ptr localOptions; + localOptions = static_cast(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 federate = getFederate().lock(); + if (!federate.valid()) + return; + assert(dynamic_cast(federate.get())); + HLAViewerFederate* viewerFederate = static_cast(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 diff --git a/utils/fgviewer/HLASceneObject.hxx b/utils/fgviewer/HLASceneObject.hxx new file mode 100644 index 000000000..f470c23e6 --- /dev/null +++ b/utils/fgviewer/HLASceneObject.hxx @@ -0,0 +1,86 @@ +// 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 +#include +#include + +#include +#include + +#include "HLAObjectReferenceData.hxx" + +namespace fgviewer { + +class HLASceneObjectClass; + +class HLASceneObject : public simgear::HLAObjectInstance { +public: + HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr& 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 _location; + // If this object is living relative to an other one, this one is non zero + simgear::HLAObjectReferenceData _sceneObject; + + // The top level transform node for this scene object + osg::ref_ptr<_Transform> _transform; + osg::ref_ptr _pagedLOD; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLASceneObjectClass.cxx b/utils/fgviewer/HLASceneObjectClass.cxx new file mode 100644 index 000000000..ea42902c6 --- /dev/null +++ b/utils/fgviewer/HLASceneObjectClass.cxx @@ -0,0 +1,59 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLASceneObjectClass.hxx b/utils/fgviewer/HLASceneObjectClass.hxx new file mode 100644 index 000000000..9ef21e596 --- /dev/null +++ b/utils/fgviewer/HLASceneObjectClass.hxx @@ -0,0 +1,76 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAView.cxx b/utils/fgviewer/HLAView.cxx new file mode 100644 index 000000000..5854ce4c9 --- /dev/null +++ b/utils/fgviewer/HLAView.cxx @@ -0,0 +1,135 @@ +// 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 +#endif + +#include "HLAView.hxx" + +#include +#include "HLAViewClass.hxx" +#include "HLAViewerFederate.hxx" + +namespace fgviewer { + +HLAView::HLAView(HLAViewClass* objectClass, const SGWeakPtr& 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(getObjectClass().get())); + HLAViewClass& objectClass = static_cast(*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 federate = getFederate().lock(); + if (federate.valid()) { + assert(dynamic_cast(federate.get())); + static_cast(federate.get())->insertView(this); + } +} + +void +HLAView::removeInstance(const simgear::RTIData& tag) +{ + HLAObjectInstance::removeInstance(tag); + + SGSharedPtr federate = getFederate().lock(); + if (federate.valid()) { + assert(dynamic_cast(federate.get())); + static_cast(federate.get())->eraseView(this); + } +} + +void +HLAView::registerInstance(simgear::HLAObjectClass* objectClass) +{ + HLAObjectInstance::registerInstance(objectClass); + + SGSharedPtr federate = getFederate().lock(); + if (federate.valid()) { + assert(dynamic_cast(federate.get())); + static_cast(federate.get())->insertView(this); + } +} + +void +HLAView::deleteInstance(const simgear::RTIData& tag) +{ + SGSharedPtr federate = getFederate().lock(); + if (federate.valid()) { + assert(dynamic_cast(federate.get())); + static_cast(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 diff --git a/utils/fgviewer/HLAView.hxx b/utils/fgviewer/HLAView.hxx new file mode 100644 index 000000000..f8c11d6f5 --- /dev/null +++ b/utils/fgviewer/HLAView.hxx @@ -0,0 +1,76 @@ +// 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 +#include + +#include "HLAObjectReferenceData.hxx" +#include "HLASceneObject.hxx" + +namespace fgviewer { + +class HLAViewClass; + +class HLAView : public simgear::HLAObjectInstance { +public: + HLAView(HLAViewClass* objectClass, const SGWeakPtr& 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 _sceneObject; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLAViewClass.cxx b/utils/fgviewer/HLAViewClass.cxx new file mode 100644 index 000000000..e33caa73e --- /dev/null +++ b/utils/fgviewer/HLAViewClass.cxx @@ -0,0 +1,58 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAViewClass.hxx b/utils/fgviewer/HLAViewClass.hxx new file mode 100644 index 000000000..e57a17c04 --- /dev/null +++ b/utils/fgviewer/HLAViewClass.hxx @@ -0,0 +1,65 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAViewer.cxx b/utils/fgviewer/HLAViewer.cxx new file mode 100644 index 000000000..3cc6566cf --- /dev/null +++ b/utils/fgviewer/HLAViewer.cxx @@ -0,0 +1,49 @@ +// 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 +#endif + +#include "HLAViewer.hxx" + +#include +#include "HLAViewerClass.hxx" + +namespace fgviewer { + +HLAViewer::HLAViewer(HLAViewerClass* objectClass) : + HLAObjectInstance(objectClass) +{ +} + +HLAViewer::~HLAViewer() +{ +} + +void +HLAViewer::createAttributeDataElements() +{ + HLAObjectInstance::createAttributeDataElements(); + + assert(dynamic_cast(getObjectClass().get())); + HLAViewerClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLAViewer.hxx b/utils/fgviewer/HLAViewer.hxx new file mode 100644 index 000000000..432dfed94 --- /dev/null +++ b/utils/fgviewer/HLAViewer.hxx @@ -0,0 +1,41 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAViewerClass.cxx b/utils/fgviewer/HLAViewerClass.cxx new file mode 100644 index 000000000..a27484df2 --- /dev/null +++ b/utils/fgviewer/HLAViewerClass.cxx @@ -0,0 +1,52 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAViewerClass.hxx b/utils/fgviewer/HLAViewerClass.hxx new file mode 100644 index 000000000..110eccd4f --- /dev/null +++ b/utils/fgviewer/HLAViewerClass.hxx @@ -0,0 +1,47 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/HLAViewerFederate.cxx b/utils/fgviewer/HLAViewerFederate.cxx new file mode 100644 index 000000000..b2b769ece --- /dev/null +++ b/utils/fgviewer/HLAViewerFederate.cxx @@ -0,0 +1,253 @@ +// 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 +#endif + +#include "HLAViewerFederate.hxx" + +#include +#include + +#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 +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(); + 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 diff --git a/utils/fgviewer/HLAViewerFederate.hxx b/utils/fgviewer/HLAViewerFederate.hxx new file mode 100644 index 000000000..9f66dfcc8 --- /dev/null +++ b/utils/fgviewer/HLAViewerFederate.hxx @@ -0,0 +1,98 @@ +// 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 +#include +#include +#include +#include + +#include + +#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 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 _perspectiveViewerClass; + SGSharedPtr _viewClass; + + /// The perspective viewer of this viewer federate. FIXME: also allow orthographic viewers for instruments! + SGSharedPtr _perspectiveViewer; + + /// The default absolute view + SGSharedPtr _defaultView; + + /// A list of all available views + typedef std::list > ViewList; + ViewList _viewList; + + /// The openscenegraphs side of this component + osg::ref_ptr _group; + + /// The backward reference to the viewer + osg::observer_ptr _viewer; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/HLAWindowDrawable.cxx b/utils/fgviewer/HLAWindowDrawable.cxx new file mode 100644 index 000000000..409553cff --- /dev/null +++ b/utils/fgviewer/HLAWindowDrawable.cxx @@ -0,0 +1,50 @@ +// 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 +#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(getObjectClass().get())); + HLAWindowDrawableClass& objectClass = static_cast(*getObjectClass()); + + setAttributeDataElement(objectClass.getFullscreenIndex(), _fullscreen.getDataElement()); + setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement()); + setAttributeDataElement(objectClass.getSizeIndex(), _size.getDataElement()); +} + +} // namespace fgviewer diff --git a/utils/fgviewer/HLAWindowDrawable.hxx b/utils/fgviewer/HLAWindowDrawable.hxx new file mode 100644 index 000000000..4ab1f56f4 --- /dev/null +++ b/utils/fgviewer/HLAWindowDrawable.hxx @@ -0,0 +1,58 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAWindowDrawableClass.cxx b/utils/fgviewer/HLAWindowDrawableClass.cxx new file mode 100644 index 000000000..5a13c579c --- /dev/null +++ b/utils/fgviewer/HLAWindowDrawableClass.cxx @@ -0,0 +1,55 @@ +// 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 +#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 diff --git a/utils/fgviewer/HLAWindowDrawableClass.hxx b/utils/fgviewer/HLAWindowDrawableClass.hxx new file mode 100644 index 000000000..84d9c3ea3 --- /dev/null +++ b/utils/fgviewer/HLAWindowDrawableClass.hxx @@ -0,0 +1,58 @@ +// 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 diff --git a/utils/fgviewer/MEncoderCaptureOperation.hxx b/utils/fgviewer/MEncoderCaptureOperation.hxx new file mode 100644 index 000000000..051996584 --- /dev/null +++ b/utils/fgviewer/MEncoderCaptureOperation.hxx @@ -0,0 +1,134 @@ +// 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 +#include +#include + +#include + +/// 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 diff --git a/utils/fgviewer/Renderer.cxx b/utils/fgviewer/Renderer.cxx new file mode 100644 index 000000000..600bd685b --- /dev/null +++ b/utils/fgviewer/Renderer.cxx @@ -0,0 +1,121 @@ +// 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 +#endif + +#include "Renderer.hxx" + +#include +#include + +#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(camera.getRenderer()); + for (int i = 0; i < 2; ++i) { + osgUtil::SceneView* sceneView = renderer->getSceneView(i); + osg::ref_ptr 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 diff --git a/utils/fgviewer/Renderer.hxx b/utils/fgviewer/Renderer.hxx new file mode 100644 index 000000000..40d7e5dd4 --- /dev/null +++ b/utils/fgviewer/Renderer.hxx @@ -0,0 +1,52 @@ +// 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 +#include + +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 diff --git a/utils/fgviewer/SlaveCamera.cxx b/utils/fgviewer/SlaveCamera.cxx new file mode 100644 index 000000000..41fc51669 --- /dev/null +++ b/utils/fgviewer/SlaveCamera.cxx @@ -0,0 +1,349 @@ +// 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 +#endif + +#include "SlaveCamera.hxx" + +#include + +#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::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 diff --git a/utils/fgviewer/SlaveCamera.hxx b/utils/fgviewer/SlaveCamera.hxx new file mode 100644 index 000000000..8ef1e1089 --- /dev/null +++ b/utils/fgviewer/SlaveCamera.hxx @@ -0,0 +1,114 @@ +// 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 +#include +#include +#include + +#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 _viewport; + osg::Matrix _viewOffset; + Frustum _frustum; + /// The camera that is attached to the slave and that has a context attached. + osg::ref_ptr _camera; + + /// For relative views, the named reference points in the projection space + typedef std::map NameReferencePointMap; + NameReferencePointMap _referencePointMap; +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/Viewer.cxx b/utils/fgviewer/Viewer.cxx new file mode 100644 index 000000000..090de9e1e --- /dev/null +++ b/utils/fgviewer/Viewer.cxx @@ -0,0 +1,763 @@ +// 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 +#endif + +#include "Viewer.hxx" + +#include +#include +#include +#include + +#ifdef __linux__ +#include +#include +#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 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(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(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(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(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(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 diff --git a/utils/fgviewer/Viewer.hxx b/utils/fgviewer/Viewer.hxx new file mode 100644 index 000000000..9503c44c5 --- /dev/null +++ b/utils/fgviewer/Viewer.hxx @@ -0,0 +1,158 @@ +// 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 +#include + +#include +#include +#include +#include + +#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; + + /// The drawables managed by this viewer. + typedef std::vector > 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 > SlaveCameraVector; + SlaveCameraVector _slaveCameraVector; + + /// The top level options struct + osg::ref_ptr _readerWriterOptions; + + /// The top level scenegraph structure that is used for drawing + osg::ref_ptr _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 _viewerFederate; +#endif +}; + +} // namespace fgviewer + +#endif diff --git a/utils/fgviewer/fgviewer.cxx b/utils/fgviewer/fgviewer.cxx index a23336dab..1e96dc46b 100644 --- a/utils/fgviewer/fgviewer.cxx +++ b/utils/fgviewer/fgviewer.cxx @@ -20,15 +20,9 @@ #include #endif -#include -#include - #include -#include #include -#include #include -#include #include #include #include @@ -38,7 +32,6 @@ #include #include -#include #include #include #include @@ -46,6 +39,15 @@ #include #include +#include "Renderer.hxx" +#include "Viewer.hxx" + +#ifdef FG_HAVE_HLA +#include "HLACameraManipulator.hxx" +#include "HLAViewerFederate.hxx" +#endif + + int main(int argc, char** argv) { @@ -55,6 +57,9 @@ 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")) { @@ -101,10 +106,39 @@ main(int argc, char** argv) 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; @@ -122,7 +156,7 @@ main(int argc, char** argv) 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); @@ -130,14 +164,6 @@ main(int argc, char** argv) 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(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); @@ -177,11 +203,42 @@ main(int argc, char** argv) 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 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. @@ -203,7 +260,10 @@ main(int argc, char** argv) } // 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(); }