first commit

This commit is contained in:
Your Name
2022-10-20 20:29:11 +08:00
commit 4d531f8044
3238 changed files with 1387862 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
// ArgumentParser.cxx -- flightgear viewer argument parser
//
// Copyright (C) 2021 by Erik Hofman
//
// 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.
#include <cstring>
#include <iostream>
#include <string>
#include <map>
#include "ArgumentParser.hxx"
ArgumentParser::ArgumentParser(int argc, char **argv) :
arg_num(argc),
arg_values(argv),
appName(argv[0]),
arguments( osg::ArgumentParser(&arg_num, arg_values) )
{
for (int i=1; i<argc; i++)
{
std::string arg = argv[i];
std::string val;
if (arg[0] == '-')
{
std::size_t pos = arg.find('=');
if (pos != std::string::npos)
{
val = arg.substr(pos+1);
arg = arg.substr(0, pos);
}
else if ((i+1)<argc && argv[i+1][0] != '-') {
val = argv[++i];
} else {
val = "";
}
args[arg] = val;
}
else {
files.push_back(arg);
}
}
}
bool
ArgumentParser::read(const char *arg)
{
auto it = args.find(arg);
if (it != args.end())
{
args.erase(it);
return true;
}
return false;
}
bool
ArgumentParser::read(const char *arg, std::string& value)
{
auto it = args.find(arg);
if (it != args.end())
{
value = it->second;
args.erase(it);
return true;
}
return false;
}
bool
ArgumentParser::read(const char *arg, std::string& name, std::string& value)
{
auto it = args.find(arg);
// old fgviewer behavior: --prop name=value
if (it != args.end()) {
std::string str = it->second;
std::size_t pos = str.find("=");
if (pos != std::string::npos && pos != str.size())
{
value = str.substr(pos);
name = str.substr(0, pos);
args.erase(it);
return true;
}
}
// FlightGear behavior: --prop:name=value
std::string str = name;
str += ':';
str += name;
it = args.find(str);
if (it != args.end())
{
value = it->second;
args.erase(it);
return true;
}
return false;
}
void
ArgumentParser::reportRemainingOptionsAsUnrecognized()
{
for (auto it : args) {
std::cerr << "Unsupported argument: " << it.first << std::endl;
}
}
void
ArgumentParser::writeErrorMessages(std::ostream& output)
{
}

View File

@@ -0,0 +1,57 @@
// ArgumentParser.hxx -- flightgear viewer argument parser
//
// Copyright (C) 2021 by Erik Hofman
//
// 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.
#pragma once
#include <vector>
#include <map>
#include <osg/ArgumentParser>
class ArgumentParser
{
public:
ArgumentParser(int argc, char **argv);
~ArgumentParser() = default;
bool read(const char *arg);
bool read(const char *arg, std::string& value);
bool read(const char *arg, std::string& name, std::string& value);
int argc() { return files.size(); }
std::string& getApplicationName() { return appName; }
void reportRemainingOptionsAsUnrecognized();
void writeErrorMessages(std::ostream& output);
osg::ArgumentParser& osg() { return arguments; }
operator std::vector<std::string>&() { return files; }
private:
int arg_num;
char **arg_values;
std::string appName;
std::vector<std::string> errors;
std::map<std::string, std::string> args;
std::vector<std::string> files;
osg::ArgumentParser arguments;
};

View File

@@ -0,0 +1,54 @@
set(FGVIEWER_SOURCES
ArgumentParser.cxx
fgviewer.cxx
Drawable.cxx
Renderer.cxx
SlaveCamera.cxx
Viewer.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_LDFLAGS})
else()
set(FGVIEWER_RTI_LIBRARIES "")
set(FGVIEWER_RTI_SOURCES "")
endif()
add_executable(fgviewer ${FGVIEWER_SOURCES} ${FGVIEWER_RTI_SOURCES})
if(X11_FOUND)
target_link_libraries(fgviewer ${X11_LIBRARIES})
endif()
target_link_libraries(fgviewer
SimGearScene SimGearCore OpenGL::GL
${FGVIEWER_RTI_LIBRARIES}
)
install(TARGETS fgviewer RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

130
utils/fgviewer/Drawable.cxx Normal file
View File

@@ -0,0 +1,130 @@
// Viewer.hxx -- alternative flightgear viewer application
//
// Copyright (C) 2009 - 2012 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Drawable.hxx"
#include "Viewer.hxx"
#include <simgear/structure/SGWeakPtr.hxx>
namespace fgviewer {
class Drawable::_ResizedCallback : public osg::GraphicsContext::ResizedCallback {
public:
_ResizedCallback(Drawable* drawable) :
_drawable(drawable)
{ }
virtual ~_ResizedCallback()
{ }
virtual void resizedImplementation(osg::GraphicsContext*, int x, int y, int width, int height)
{
SGSharedPtr<Drawable> drawable = _drawable.lock();
if (!drawable.valid())
return;
drawable->resize(x, y, width, height);
}
SGWeakPtr<Drawable> _drawable;
};
Drawable::Drawable(const std::string& name) :
_name(name),
_position(0, 0),
_size(600, 800),
_offscreen(false),
_fullscreen(false)
{
}
Drawable::~Drawable()
{
}
void
Drawable::attachSlaveCamera(SlaveCamera* slaveCamera)
{
if (!slaveCamera)
return;
_slaveCameraList.push_back(slaveCamera);
}
bool
Drawable::resize(int x, int y, int width, int height)
{
unsigned numCameras = _slaveCameraList.size();
if (1 < numCameras)
return false;
_graphicsContext->resizedImplementation(x, y, width, height);
if (numCameras < 1)
return true;
_slaveCameraList.front()->setViewport(SGVec4i(0, 0, width, height));
return true;
}
bool
Drawable::realize(Viewer& viewer)
{
if (_graphicsContext.valid())
return false;
_graphicsContext = _realizeImplementation(viewer);
if (!_graphicsContext.valid())
return false;
_graphicsContext->setResizedCallback(new _ResizedCallback(this));
return true;
}
osg::GraphicsContext*
Drawable::_realizeImplementation(Viewer& viewer)
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = _getTraits(viewer);
return viewer.createGraphicsContext(traits.get());
}
osg::ref_ptr<osg::GraphicsContext::Traits>
Drawable::_getTraits(Viewer& viewer)
{
osg::GraphicsContext::ScreenIdentifier screenIdentifier;
screenIdentifier.setScreenIdentifier(_screenIdentifier);
osg::ref_ptr<osg::GraphicsContext::Traits> traits;
traits = viewer.getTraits(screenIdentifier);
// The window name as displayed by the window manager
traits->windowName = getName();
traits->x = _position[0];
traits->y = _position[1];
if (!_fullscreen) {
traits->width = _size[0];
traits->height = _size[1];
}
traits->windowDecoration = !_fullscreen;
if (_slaveCameraList.size() <= 1)
traits->supportsResize = true;
else
traits->supportsResize = false;
traits->pbuffer = _offscreen;
return traits;
}
} // namespace fgviewer

106
utils/fgviewer/Drawable.hxx Normal file
View File

@@ -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 <string>
#include <list>
#include <osg/GraphicsContext>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGWeakReferenced.hxx>
namespace fgviewer {
class Viewer;
class SlaveCamera;
class Drawable : public SGWeakReferenced {
public:
Drawable(const std::string& name);
virtual ~Drawable();
const std::string& getName() const
{ return _name; }
virtual bool setScreenIdentifier(const std::string& screenIdentifier)
{
if (_graphicsContext.valid())
return false;
_screenIdentifier = screenIdentifier;
return true;
}
const std::string& getScreenIdentifier() const
{ return _screenIdentifier; }
virtual bool setPosition(const SGVec2i& position)
{ _position = position; return true; }
const SGVec2i& getPosition() const
{ return _position; }
virtual bool setSize(const SGVec2i& size)
{ _size = size; return true; }
const SGVec2i& getSize() const
{ return _size; }
virtual bool setOffscreen(bool offscreen)
{
if (_graphicsContext.valid())
return false;
_offscreen = offscreen;
return true;
}
bool getOffscreen() const
{ return _offscreen; }
virtual bool setFullscreen(bool fullscreen)
{ _fullscreen = fullscreen; return true; }
bool getFullscreen() const
{ return _fullscreen; }
osg::GraphicsContext* getGraphicsContext()
{ return _graphicsContext.get(); }
void attachSlaveCamera(SlaveCamera* slaveCamera);
virtual bool resize(int x, int y, int width, int height);
bool realize(Viewer& viewer);
protected:
virtual osg::GraphicsContext* _realizeImplementation(Viewer& viewer);
osg::ref_ptr<osg::GraphicsContext::Traits> _getTraits(Viewer& viewer);
private:
Drawable(const Drawable&);
Drawable& operator=(const Drawable&);
class _ResizedCallback;
/// The immutable name that is used to reference this slave camera.
const std::string _name;
std::string _screenIdentifier;
SGVec2i _position;
SGVec2i _size;
bool _offscreen;
bool _fullscreen;
osg::ref_ptr<osg::GraphicsContext> _graphicsContext;
std::list<SGSharedPtr<SlaveCamera> > _slaveCameraList;
};
} // namespace fgviewer
#endif

156
utils/fgviewer/Frustum.hxx Normal file
View File

@@ -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 <cmath>
#include <osg/Matrix>
#include <osg/Vec2>
#include <osg/Vec3>
#include <simgear/math/SGMath.hxx>
namespace fgviewer {
struct Frustum {
Frustum(const double& aspectRatio = 1) :
_left(-aspectRatio),
_right(aspectRatio),
_bottom(-1),
_top(1),
_near(2)
{ }
Frustum(const double& left, const double& right, const double& bottom, const double& top, const double& zNear) :
_left(left),
_right(right),
_bottom(bottom),
_top(top),
_near(zNear)
{ }
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 zNear = depthRange[0];
double zFar = depthRange[1];
/// left, right, bottom and top are rescaled by zNear/_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 = (zNear + zFar)/(zNear - zFar);
double a23 = -1;
double a32 = 2*zNear*zFar/(zNear - zFar);
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 zNear plane
osg::Matrix getMatrix(const double& zNear, const double& eps = 0) const
{
/// left, right, bottom and top are rescaled by zNear/_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 = zNear*(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 zNear = _near + eyeOffset[2];
return Frustum(left, right, bottom, top, zNear);
}
/// 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 zNear plane. Just used to reference the other frustum parameters.
double _near;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLACamera.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLACameraClass.hxx"
namespace fgviewer {
HLACamera::HLACamera(HLACameraClass* objectClass) :
HLAObjectInstance(objectClass)
{
}
HLACamera::~HLACamera()
{
}
void
HLACamera::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLACameraClass*>(getObjectClass().get()));
HLACameraClass& objectClass = static_cast<HLACameraClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
setAttributeDataElement(objectClass.getViewerIndex(), _viewer.getDataElement());
setAttributeDataElement(objectClass.getDrawableIndex(), _drawable.getDataElement());
setAttributeDataElement(objectClass.getViewportIndex(), _viewport.getDataElement());
setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLACameraClass;
class HLACamera : public simgear::HLAObjectInstance {
public:
HLACamera(HLACameraClass* objectClass = 0);
virtual ~HLACamera();
virtual void createAttributeDataElements();
const std::string& getName() const
{ return _name.getValue(); }
void setName(const std::string& name)
{ _name.setValue(name); }
const std::string& getViewer() const
{ return _viewer.getValue(); }
void setViewer(const std::string& viewer)
{ _viewer.setValue(viewer); }
const std::string& getDrawable() const
{ return _drawable.getValue(); }
void setDrawable(const std::string& drawable)
{ _drawable.setValue(drawable); }
const SGVec4i& getViewport() const
{ return _viewport.getValue(); }
void setViewport(const SGVec4i& viewport)
{ _viewport.setValue(viewport); }
const SGVec3d& getPosition() const
{ return _position.getValue(); }
void setPosition(const SGVec3d& position)
{ _position.setValue(position); }
const SGQuatd& getOrientation() const
{ return _orientation.getValue(); }
void setOrientation(const SGQuatd& orientation)
{ _orientation.setValue(orientation); }
SGLocationd getLocation() const
{ return SGLocationd(getPosition(), getOrientation()); }
void setLocation(const SGLocationd& location)
{ setPosition(location.getPosition()); setOrientation(location.getOrientation()); }
private:
simgear::HLAStringData _name;
simgear::HLAStringData _viewer;
simgear::HLAStringData _drawable;
simgear::HLAVec4iData _viewport;
simgear::HLAVec3dData _position;
simgear::HLAQuat3dData _orientation;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLACameraClass.hxx"
#include "HLACamera.hxx"
namespace fgviewer {
HLACameraClass::HLACameraClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLACameraClass::~HLACameraClass()
{
}
simgear::HLAObjectInstance*
HLACameraClass::createObjectInstance(const std::string& name)
{
return new HLACamera(this);
}
void
HLACameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_nameIndex.empty())
_nameIndex = getDataElementIndex("name");
if (_viewerIndex.empty())
_viewerIndex = getDataElementIndex("viewer");
if (_drawableIndex.empty())
_drawableIndex = getDataElementIndex("drawable");
if (_viewportIndex.empty())
_viewportIndex = getDataElementIndex("viewport");
if (_positionIndex.empty())
_positionIndex = getDataElementIndex("location.position");
if (_orientationIndex.empty())
_orientationIndex = getDataElementIndex("location.orientation");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLACameraClass : public simgear::HLAObjectClass {
public:
HLACameraClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLACameraClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setNameIndex(const std::string& path)
{ return getDataElementIndex(_nameIndex, path); }
const simgear::HLADataElementIndex& getNameIndex() const
{ return _nameIndex; }
bool setViewerIndex(const std::string& path)
{ return getDataElementIndex(_viewerIndex, path); }
const simgear::HLADataElementIndex& getViewerIndex() const
{ return _viewerIndex; }
bool setDrawableIndex(const std::string& path)
{ return getDataElementIndex(_drawableIndex, path); }
const simgear::HLADataElementIndex& getDrawableIndex() const
{ return _drawableIndex; }
bool setViewportIndex(const std::string& path)
{ return getDataElementIndex(_viewportIndex, path); }
const simgear::HLADataElementIndex& getViewportIndex() const
{ return _viewportIndex; }
bool setPositionIndex(const std::string& path)
{ return getDataElementIndex(_positionIndex, path); }
const simgear::HLADataElementIndex& getPositionIndex() const
{ return _positionIndex; }
bool setOrientationIndex(const std::string& path)
{ return getDataElementIndex(_orientationIndex, path); }
const simgear::HLADataElementIndex& getOrientationIndex() const
{ return _orientationIndex; }
private:
simgear::HLADataElementIndex _nameIndex;
simgear::HLADataElementIndex _viewerIndex;
simgear::HLADataElementIndex _drawableIndex;
simgear::HLADataElementIndex _viewportIndex;
simgear::HLADataElementIndex _positionIndex;
simgear::HLADataElementIndex _orientationIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLACameraManipulator.hxx"
#include <simgear/scene/util/OsgMath.hxx>
#include "HLAPerspectiveViewer.hxx"
#include "Viewer.hxx"
namespace fgviewer {
HLACameraManipulator::HLACameraManipulator(HLAPerspectiveViewer* perspectiveViewer) :
_viewMatrix(osg::Matrixd::identity()),
_inverseViewMatrix(osg::Matrixd::identity()),
_lastMousePos(0, 0),
_perspectiveViewer(perspectiveViewer)
{
}
HLACameraManipulator::HLACameraManipulator(const HLACameraManipulator& cameraManipulator, const osg::CopyOp& copyOp) :
osgGA::CameraManipulator(cameraManipulator, copyOp),
_viewMatrix(cameraManipulator._viewMatrix),
_inverseViewMatrix(cameraManipulator._inverseViewMatrix),
_lastMousePos(cameraManipulator._lastMousePos),
_perspectiveViewer(cameraManipulator._perspectiveViewer)
{
}
HLACameraManipulator::~HLACameraManipulator()
{
}
void
HLACameraManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}
void
HLACameraManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
{
}
osg::Matrixd
HLACameraManipulator::getMatrix() const
{
return _viewMatrix;
}
osg::Matrixd
HLACameraManipulator::getInverseMatrix() const
{
return _inverseViewMatrix;
}
bool
HLACameraManipulator::handle(const osgGA::GUIEventAdapter& eventAdapter, osgGA::GUIActionAdapter& actionAdapter)
{
if (_handle(eventAdapter, static_cast<Viewer&>(actionAdapter)))
return true;
return osgGA::CameraManipulator::handle(eventAdapter, actionAdapter);
}
bool
HLACameraManipulator::_handle(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
{
switch (eventAdapter.getEventType()) {
case osgGA::GUIEventAdapter::PUSH:
_lastMousePos = osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized());
break;
case osgGA::GUIEventAdapter::RELEASE:
break;
case osgGA::GUIEventAdapter::DOUBLECLICK:
break;
case osgGA::GUIEventAdapter::DRAG:
if (!eventAdapter.getModKeyMask())
_rotateView(osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized()) - _lastMousePos);
else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL)
_rotateSun(osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized()) - _lastMousePos, viewer);
_lastMousePos = osg::Vec2(eventAdapter.getXnormalized(), eventAdapter.getYnormalized());
break;
case osgGA::GUIEventAdapter::MOVE:
break;
case osgGA::GUIEventAdapter::SCROLL:
break;
case osgGA::GUIEventAdapter::KEYDOWN:
_handleKeyDownEvent(eventAdapter, viewer);
break;
case osgGA::GUIEventAdapter::KEYUP:
_handleKeyUpEvent(eventAdapter, viewer);
break;
case osgGA::GUIEventAdapter::FRAME:
_handleFrameEvent(viewer);
break;
default:
break;
}
return false;
}
void
HLACameraManipulator::_handleFrameEvent(osgGA::GUIActionAdapter& actionAdapter)
{
// Note that eventAdapter.getTime() returns the reference time instead of the simulation time
osg::View* view = actionAdapter.asView();
if (!view)
return;
osg::FrameStamp* frameStamp = view->getFrameStamp();
if (!frameStamp)
return;
if (!_perspectiveViewer.valid())
return;
SGLocationd location;
location = _perspectiveViewer->getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
// Update the main cameras view matrix
_viewMatrix = osg::Matrixd::identity();
// transform from the simulation typical x-forward/y-right/z-down
// to the opengl camera system x-right/y-up/z-back
// _viewMatrix.postMultRotate(toOsg(SGQuatd::fromEulerDeg(90, 0, -90)));
_viewMatrix.postMultRotate(toOsg(SGQuatd(-0.5, -0.5, 0.5, 0.5)));
// the orientation of the view
_viewMatrix.postMultRotate(toOsg(location.getOrientation()));
// the position of the view
_viewMatrix.postMultTranslate(toOsg(location.getPosition()));
_inverseViewMatrix = osg::Matrixd::inverse(_viewMatrix);
}
bool
HLACameraManipulator::_handleKeyDownEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
{
if (!_perspectiveViewer.valid())
return false;
switch (eventAdapter.getKey()) {
case osgGA::GUIEventAdapter::KEY_Space:
case osgGA::GUIEventAdapter::KEY_Home:
_resetView();
return false;
case osgGA::GUIEventAdapter::KEY_Left:
_incrementEyePosition(SGVec3d(-0.1, 0, 0));
return false;
case osgGA::GUIEventAdapter::KEY_Right:
_incrementEyePosition(SGVec3d(0.1, 0, 0));
return false;
case osgGA::GUIEventAdapter::KEY_Up:
if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) {
_perspectiveViewer->setZoomFactor(_perspectiveViewer->getZoomFactor()*1.1);
} else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT) {
_incrementEyePosition(SGVec3d(0, 0, 0.1));
} else {
_incrementEyePosition(SGVec3d(0, 0.1, 0));
}
return false;
case osgGA::GUIEventAdapter::KEY_Down:
if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_CTRL) {
_perspectiveViewer->setZoomFactor(_perspectiveViewer->getZoomFactor()/1.1);
} else if (eventAdapter.getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT) {
_incrementEyePosition(SGVec3d(0, 0, -0.1));
} else {
_incrementEyePosition(SGVec3d(0, -0.1, 0));
}
return false;
default:
return false;
}
}
bool
HLACameraManipulator::_handleKeyUpEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer)
{
return false;
}
void
HLACameraManipulator::_incrementEyePosition(const SGVec3d& offset)
{
if (!_perspectiveViewer.valid())
return;
HLAEyeTracker* eyeTracker = _perspectiveViewer->getEyeTracker();
if (!eyeTracker)
return;
eyeTracker->setLeftEyeOffset(eyeTracker->getLeftEyeOffset() + offset);
eyeTracker->setRightEyeOffset(eyeTracker->getRightEyeOffset() + offset);
}
void
HLACameraManipulator::_resetView()
{
if (!_perspectiveViewer.valid())
return;
_perspectiveViewer->setPosition(SGVec3d::zeros());
_perspectiveViewer->setOrientation(SGQuatd::unit());
_perspectiveViewer->setZoomFactor(1);
HLAEyeTracker* eyeTracker = _perspectiveViewer->getEyeTracker();
if (!eyeTracker)
return;
eyeTracker->setLeftEyeOffset(SGVec3d::zeros());
eyeTracker->setRightEyeOffset(SGVec3d::zeros());
}
void
HLACameraManipulator::_rotateView(const osg::Vec2& inc)
{
if (!_perspectiveViewer.valid())
return;
double zDeg, yDeg, xDeg;
_perspectiveViewer->getOrientation().getEulerRad(zDeg, yDeg, xDeg);
zDeg += inc[0];
yDeg += inc[1];
_perspectiveViewer->setOrientation(SGQuatd::fromEulerRad(zDeg, yDeg, xDeg));
}
void
HLACameraManipulator::_rotateSun(const osg::Vec2& inc, Viewer& viewer)
{
osg::Light* light = viewer.getLight();
if (!light)
return;
osg::Matrix m = osg::Matrix::inverse(viewer.getCamera()->getViewMatrix());
osg::Vec3 position(light->getPosition()[0], light->getPosition()[1], light->getPosition()[2]) ;
position = osg::Quat(-0.2*inc[0], osg::Matrix::transform3x3(osg::Vec3(0, 1, 0), m))*position;
position = osg::Quat(0.2*inc[1], osg::Matrix::transform3x3(osg::Vec3(1, 0, 0), m))*position;
light->setPosition(osg::Vec4(position, 0));
}
} // namespace fgviewer

View File

@@ -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 <osgGA/CameraManipulator>
#include <simgear/scene/util/OsgMath.hxx>
#include "HLAPerspectiveViewer.hxx"
namespace fgviewer {
class Viewer;
class HLACameraManipulator : public osgGA::CameraManipulator {
public:
HLACameraManipulator(HLAPerspectiveViewer* perspectiveViewer = 0);
HLACameraManipulator(const HLACameraManipulator& cameraManipulator, const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY);
virtual ~HLACameraManipulator();
META_Object(fgviewer, HLACameraManipulator);
virtual void setByMatrix(const osg::Matrixd& matrix);
virtual void setByInverseMatrix(const osg::Matrixd& matrix);
virtual osg::Matrixd getMatrix() const;
virtual osg::Matrixd getInverseMatrix() const;
/** Handle events, return true if handled, false otherwise. */
virtual bool handle(const osgGA::GUIEventAdapter& eventAdapter, osgGA::GUIActionAdapter& actionAdapter);
protected:
bool _handle(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
void _handleFrameEvent(osgGA::GUIActionAdapter& actionAdapter);
bool _handleKeyDownEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
bool _handleKeyUpEvent(const osgGA::GUIEventAdapter& eventAdapter, Viewer& viewer);
void _incrementEyePosition(const SGVec3d& offset);
void _resetView();
void _rotateView(const osg::Vec2& inc);
void _rotateSun(const osg::Vec2& inc, Viewer& viewer);
private:
osg::Matrixd _viewMatrix;
osg::Matrixd _inverseViewMatrix;
osg::Vec2 _lastMousePos;
SGSharedPtr<HLAPerspectiveViewer> _perspectiveViewer;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLADrawable.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLADrawableClass.hxx"
namespace fgviewer {
HLADrawable::HLADrawable(HLADrawableClass* objectClass) :
HLAObjectInstance(objectClass)
{
}
HLADrawable::~HLADrawable()
{
}
void
HLADrawable::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLADrawableClass*>(getObjectClass().get()));
HLADrawableClass& objectClass = static_cast<HLADrawableClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
setAttributeDataElement(objectClass.getRendererIndex(), _renderer.getDataElement());
setAttributeDataElement(objectClass.getDisplayIndex(), _display.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLADrawableClass;
class HLADrawable : public simgear::HLAObjectInstance {
public:
HLADrawable(HLADrawableClass* objectClass = 0);
virtual ~HLADrawable();
virtual void createAttributeDataElements();
const std::string& getName() const
{ return _name.getValue(); }
void setName(const std::string& name)
{ _name.setValue(name); }
const std::string& getRenderer() const
{ return _renderer.getValue(); }
void setRenderer(const std::string& renderer)
{ _renderer.setValue(renderer); }
const std::string& getDisplay() const
{ return _display.getValue(); }
void setDisplay(const std::string& display)
{ _display.setValue(display); }
private:
simgear::HLAStringData _name;
// This is normally this object reference, but here it should be sufficient to work with the name
// simgear::HLAObjectReferenceData<HLARenderer> _renderer;
simgear::HLAStringData _renderer;
simgear::HLAStringData _display;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLADrawableClass.hxx"
#include "HLADrawable.hxx"
namespace fgviewer {
HLADrawableClass::HLADrawableClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLADrawableClass::~HLADrawableClass()
{
}
simgear::HLAObjectInstance*
HLADrawableClass::createObjectInstance(const std::string& name)
{
return new HLADrawable(this);
}
void
HLADrawableClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_nameIndex.empty())
_nameIndex = getDataElementIndex("name");
if (_rendererIndex.empty())
_rendererIndex = getDataElementIndex("renderer");
if (_displayIndex.empty())
_displayIndex = getDataElementIndex("display");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLADrawableClass : public simgear::HLAObjectClass {
public:
HLADrawableClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLADrawableClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setNameIndex(const std::string& path)
{ return getDataElementIndex(_nameIndex, path); }
const simgear::HLADataElementIndex& getNameIndex() const
{ return _nameIndex; }
bool setRendererIndex(const std::string& path)
{ return getDataElementIndex(_rendererIndex, path); }
const simgear::HLADataElementIndex& getRendererIndex() const
{ return _rendererIndex; }
bool setDisplayIndex(const std::string& path)
{ return getDataElementIndex(_displayIndex, path); }
const simgear::HLADataElementIndex& getDisplayIndex() const
{ return _displayIndex; }
private:
simgear::HLADataElementIndex _nameIndex;
simgear::HLADataElementIndex _rendererIndex;
simgear::HLADataElementIndex _displayIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAEyeTracker.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLAEyeTrackerClass.hxx"
namespace fgviewer {
HLAEyeTracker::HLAEyeTracker(HLAEyeTrackerClass* objectClass) :
HLAObjectInstance(objectClass)
{
}
HLAEyeTracker::~HLAEyeTracker()
{
}
void
HLAEyeTracker::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLAEyeTrackerClass*>(getObjectClass().get()));
HLAEyeTrackerClass& objectClass = static_cast<HLAEyeTrackerClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getLeftEyeOffsetIndex(), _leftEyeOffset.getDataElement());
setAttributeDataElement(objectClass.getRightEyeOffsetIndex(), _rightEyeOffset.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLAEyeTrackerClass;
class HLAEyeTracker : public simgear::HLAObjectInstance {
public:
HLAEyeTracker(HLAEyeTrackerClass* objectClass = 0);
virtual ~HLAEyeTracker();
virtual void createAttributeDataElements();
const SGVec3d& getLeftEyeOffset() const
{ return _leftEyeOffset.getValue(); }
void setLeftEyeOffset(const SGVec3d& leftEyeOffset)
{ _leftEyeOffset.setValue(leftEyeOffset); }
const SGVec3d& getRightEyeOffset() const
{ return _rightEyeOffset.getValue(); }
void setRightEyeOffset(const SGVec3d& rightEyeOffset)
{ _rightEyeOffset.setValue(rightEyeOffset); }
private:
simgear::HLAVec3dData _leftEyeOffset;
simgear::HLAVec3dData _rightEyeOffset;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAEyeTrackerClass.hxx"
#include "HLAEyeTracker.hxx"
namespace fgviewer {
HLAEyeTrackerClass::HLAEyeTrackerClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLAEyeTrackerClass::~HLAEyeTrackerClass()
{
}
simgear::HLAObjectInstance*
HLAEyeTrackerClass::createObjectInstance(const std::string& name)
{
return new HLAEyeTracker(this);
}
void
HLAEyeTrackerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_leftEyeOffsetIndex.empty())
_leftEyeOffsetIndex = getDataElementIndex("leftEyeOffset");
if (_rightEyeOffsetIndex.empty())
_rightEyeOffsetIndex = getDataElementIndex("rightEyeOffset");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLAEyeTrackerClass : public simgear::HLAObjectClass {
public:
HLAEyeTrackerClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLAEyeTrackerClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setLeftEyeOffsetIndex(const std::string& path)
{ return getDataElementIndex(_leftEyeOffsetIndex, path); }
const simgear::HLADataElementIndex& getLeftEyeOffsetIndex() const
{ return _leftEyeOffsetIndex; }
bool setRightEyeOffsetIndex(const std::string& path)
{ return getDataElementIndex(_rightEyeOffsetIndex, path); }
const simgear::HLADataElementIndex& getRightEyeOffsetIndex() const
{ return _rightEyeOffsetIndex; }
private:
simgear::HLADataElementIndex _leftEyeOffsetIndex;
simgear::HLADataElementIndex _rightEyeOffsetIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAMPAircraft.hxx"
#include "HLAMPAircraftClass.hxx"
namespace fgviewer {
HLAMPAircraft::HLAMPAircraft(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
HLASceneObject(objectClass, federate),
_simTimeOffset(SGLimitsd::max())
{
}
HLAMPAircraft::~HLAMPAircraft()
{
}
void
HLAMPAircraft::reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag)
{
HLASceneObject::reflectAttributeValues(indexList, tag);
}
void
HLAMPAircraft::reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag)
{
HLASceneObject::reflectAttributeValues(indexList, timeStamp, tag);
}
void
HLAMPAircraft::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLASceneObject::createAttributeDataElements();
assert(dynamic_cast<HLAMPAircraftClass*>(getObjectClass().get()));
HLAMPAircraftClass& objectClass = static_cast<HLAMPAircraftClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getSimTimeIndex(), _simTime.getDataElement());
setAttributeDataElement(objectClass.getModelPathIndex(), getModelDataElement());
}
SGLocationd
HLAMPAircraft::getLocation(const SGTimeStamp& timeStamp) const
{
// FIXME: puh, is frame rate dependent. Think about something more robust ...
if (_lastTimeStamp != timeStamp) {
double simTimeOffset = timeStamp.toSecs() - _simTime.getValue();
if (2 < fabs(simTimeOffset - _simTimeOffset))
_simTimeOffset = simTimeOffset;
else
_simTimeOffset = 0.999*_simTimeOffset + 0.001*simTimeOffset;
_lastTimeStamp = timeStamp;
}
double dt = timeStamp.toSecs() - _simTime.getValue() - _simTimeOffset;
SGLocationd location = HLASceneObject::getLocation(timeStamp);
location.eulerStepBodyVelocitiesMidOrientation(dt, _getRelativeLinearVelocity(), _getRelativeAngularVelocity());
return location;
}
} // namespace fgviewer

View File

@@ -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<simgear::HLAFederate>& federate);
virtual ~HLAMPAircraft();
virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag);
virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag);
virtual void createAttributeDataElements();
virtual SGLocationd getLocation(const SGTimeStamp& timeStamp) const;
private:
mutable SGTimeStamp _lastTimeStamp;
mutable double _simTimeOffset;
simgear::HLADoubleData _simTime;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAMPAircraftClass.hxx"
#include "HLAMPAircraft.hxx"
#include "HLAViewerFederate.hxx"
namespace fgviewer {
HLAMPAircraftClass::HLAMPAircraftClass(const std::string& name, simgear::HLAFederate* federate) :
HLASceneObjectClass(name, federate)
{
}
HLAMPAircraftClass::~HLAMPAircraftClass()
{
}
HLAMPAircraft*
HLAMPAircraftClass::createObjectInstance(const std::string& name)
{
return new HLAMPAircraft(this, getFederate());
}
void
HLAMPAircraftClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_simTimeIndex.empty())
_simTimeIndex = getDataElementIndex("simTime");
if (_modelPathIndex.empty())
_modelPathIndex = getDataElementIndex("model.path");
HLASceneObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLADataElement.hxx>
#include <simgear/hla/HLAFederate.hxx>
#include "HLAProxyDataElement.hxx"
namespace simgear {
/// Data element that references an other object instance by its name, or object instance handle?
/// Abstract variant that is object type independent and could be registered at the federate
/// if the object is not found immediately and might arrive later.
class HLAAbstractObjectReferenceDataElement : public HLAProxyDataElement {
public:
// FIXME drop the federate once we have a decode/encode visitor?!
HLAAbstractObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
_federate(federate)
{ }
virtual bool decode(HLADecodeStream& stream)
{
if (!HLAProxyDataElement::decode(stream))
return false;
// No change?
if (!_name.getDataElement()->getDirty())
return true;
_name.getDataElement()->setDirty(false);
return recheckObject();
}
/// Returns true if the object is correctly set
bool getComplete() const
{
if (HLAObjectInstance* objectInstance = _getObjectInstance()) {
return _name.getValue() == objectInstance->getName();
} else {
return _name.getValue().empty();
}
}
bool recheckObject()
{
HLAObjectInstance* objectInstance = _getObjectInstance();
if (objectInstance && _name.getValue() == objectInstance->getName())
return true;
if (_name.getValue().empty()) {
return _setObjectInstance(0);
} else {
// Get the object by its name from the federate
SGSharedPtr<HLAFederate> federate = _federate.lock();
if (!federate.valid())
return false;
SGSharedPtr<HLAObjectInstance> objectInstance;
objectInstance = federate->getObjectInstance(_name.getValue());
return _setObjectInstance(objectInstance.get());
}
}
protected:
virtual HLAStringDataElement* _getDataElement()
{ return _name.getDataElement(); }
virtual const HLAStringDataElement* _getDataElement() const
{ return _name.getDataElement(); }
virtual HLAObjectInstance* _getObjectInstance() const = 0;
virtual bool _setObjectInstance(HLAObjectInstance*) = 0;
void _setName(const HLAObjectInstance* objectInstance)
{
if (objectInstance)
_name.setValue(objectInstance->getName());
else
_name.setValue(std::string());
_name.getDataElement()->setDirty(true);
}
private:
HLAStringData _name;
SGWeakPtr<HLAFederate> _federate;
};
template<typename T>
class HLAObjectReferenceDataElement : public HLAAbstractObjectReferenceDataElement {
public:
// FIXME drop the federate once we have a decode/encode visitor?!
HLAObjectReferenceDataElement(const SGWeakPtr<HLAFederate>& federate) :
HLAAbstractObjectReferenceDataElement(federate)
{ }
const SGSharedPtr<T>& getObject() const
{ return _object; }
void setObject(const SGSharedPtr<T>& object)
{
if (_object == object)
return;
_setName(object.get());
_object = object;
}
protected:
virtual HLAObjectInstance* _getObjectInstance() const
{
return _object.get();
}
virtual bool _setObjectInstance(HLAObjectInstance* objectInstance)
{
if (!objectInstance) {
_object.clear();
return true;
} else {
if (!dynamic_cast<T*>(objectInstance))
return false;
_object = static_cast<T*>(objectInstance);
return true;
}
}
private:
SGSharedPtr<T> _object;
};
template<typename T>
class HLAObjectReferenceData {
public:
typedef HLAObjectReferenceDataElement<T> DataElement;
HLAObjectReferenceData(const SGWeakPtr<HLAFederate>& federate) :
_dataElement(new DataElement(federate))
{ }
const HLADataElement* getDataElement() const
{ return _dataElement.get(); }
HLADataElement* getDataElement()
{ return _dataElement.get(); }
const SGSharedPtr<T>& getObject() const
{ return _dataElement->getObject(); }
void setObject(const SGSharedPtr<T>& object)
{ _dataElement->setObject(object); }
bool getComplete() const
{ return _dataElement->getComplete(); }
/// FIXME this must happen in the federate by registering object references
/// that still want to be resolved
bool recheckObject() const
{ return _dataElement->recheckObject(); }
private:
SGSharedPtr<DataElement> _dataElement;
};
}
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAOrthographicCamera.hxx"
#include "HLAOrthographicCameraClass.hxx"
namespace fgviewer {
HLAOrthographicCamera::HLAOrthographicCamera(HLAOrthographicCameraClass* objectClass) :
HLACamera(objectClass)
{
}
HLAOrthographicCamera::~HLAOrthographicCamera()
{
}
void
HLAOrthographicCamera::createAttributeDataElements()
{
HLACamera::createAttributeDataElements();
assert(dynamic_cast<HLAOrthographicCameraClass*>(getObjectClass().get()));
HLAOrthographicCameraClass& objectClass = static_cast<HLAOrthographicCameraClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getLeftIndex(), _left.getDataElement());
setAttributeDataElement(objectClass.getRightIndex(), _right.getDataElement());
setAttributeDataElement(objectClass.getBottomIndex(), _bottom.getDataElement());
setAttributeDataElement(objectClass.getTopIndex(), _top.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLABasicDataElement.hxx>
#include "HLACamera.hxx"
namespace fgviewer {
class HLAOrthographicCameraClass;
class HLAOrthographicCamera : public HLACamera {
public:
HLAOrthographicCamera(HLAOrthographicCameraClass* objectClass);
virtual ~HLAOrthographicCamera();
virtual void createAttributeDataElements();
double getLeft() const
{ return _left.getValue(); }
void setLeft(double left)
{ _left.setValue(left); }
double getRight() const
{ return _right.getValue(); }
void setRight(double right)
{ _right.setValue(right); }
double getBottom() const
{ return _bottom.getValue(); }
void setBottom(double bottom)
{ _bottom.setValue(bottom); }
double getTop() const
{ return _top.getValue(); }
void setTop(double top)
{ _top.setValue(top); }
private:
simgear::HLADoubleData _left;
simgear::HLADoubleData _right;
simgear::HLADoubleData _bottom;
simgear::HLADoubleData _top;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAOrthographicCameraClass.hxx"
#include "HLAOrthographicCamera.hxx"
namespace fgviewer {
HLAOrthographicCameraClass::HLAOrthographicCameraClass(const std::string& name, simgear::HLAFederate* federate) :
HLACameraClass(name, federate)
{
}
HLAOrthographicCameraClass::~HLAOrthographicCameraClass()
{
}
simgear::HLAObjectInstance*
HLAOrthographicCameraClass::createObjectInstance(const std::string& name)
{
return new HLAOrthographicCamera(this);
}
void
HLAOrthographicCameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
if (_leftIndex.empty())
_leftIndex = getDataElementIndex("projection.left");
if (_rightIndex.empty())
_rightIndex = getDataElementIndex("projection.right");
if (_bottomIndex.empty())
_bottomIndex = getDataElementIndex("projection.bottom");
if (_topIndex.empty())
_topIndex = getDataElementIndex("projection.top");
HLACameraClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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

View File

@@ -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 <config.h>
#endif
#include "HLAPerspectiveCamera.hxx"
#include "HLAPerspectiveCameraClass.hxx"
namespace fgviewer {
HLAPerspectiveCamera::HLAPerspectiveCamera(HLAPerspectiveCameraClass* objectClass) :
HLACamera(objectClass)
{
}
HLAPerspectiveCamera::~HLAPerspectiveCamera()
{
}
void
HLAPerspectiveCamera::reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag)
{
HLACamera::reflectAttributeValues(indexList, tag);
/// Here push data to the osg viewer side
}
void
HLAPerspectiveCamera::reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag)
{
HLACamera::reflectAttributeValues(indexList, timeStamp, tag);
/// Here push data to the osg viewer side
}
void
HLAPerspectiveCamera::createAttributeDataElements()
{
HLACamera::createAttributeDataElements();
assert(dynamic_cast<HLAPerspectiveCameraClass*>(getObjectClass().get()));
HLAPerspectiveCameraClass& objectClass = static_cast<HLAPerspectiveCameraClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getLeftIndex(), _left.getDataElement());
setAttributeDataElement(objectClass.getRightIndex(), _right.getDataElement());
setAttributeDataElement(objectClass.getBottomIndex(), _bottom.getDataElement());
setAttributeDataElement(objectClass.getTopIndex(), _top.getDataElement());
setAttributeDataElement(objectClass.getDistanceIndex(), _distance.getDataElement());
}
Frustum
HLAPerspectiveCamera::getFrustum() const
{
return Frustum(getLeft(), getRight(), getBottom(), getTop(), getDistance());
}
void
HLAPerspectiveCamera::setFrustum(const Frustum& frustum)
{
setLeft(frustum._left);
setRight(frustum._right);
setBottom(frustum._bottom);
setTop(frustum._top);
setDistance(frustum._near);
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLABasicDataElement.hxx>
#include "Frustum.hxx"
#include "HLACamera.hxx"
namespace fgviewer {
class HLAPerspectiveCameraClass;
class HLAPerspectiveCamera : public HLACamera {
public:
HLAPerspectiveCamera(HLAPerspectiveCameraClass* objectClass);
virtual ~HLAPerspectiveCamera();
virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const simgear::RTIData& tag);
virtual void reflectAttributeValues(const simgear::HLAIndexList& indexList, const SGTimeStamp& timeStamp, const simgear::RTIData& tag);
virtual void createAttributeDataElements();
double getLeft() const
{ return _left.getValue(); }
void setLeft(double left)
{ _left.setValue(left); }
double getRight() const
{ return _right.getValue(); }
void setRight(double right)
{ _right.setValue(right); }
double getBottom() const
{ return _bottom.getValue(); }
void setBottom(double bottom)
{ _bottom.setValue(bottom); }
double getTop() const
{ return _top.getValue(); }
void setTop(double top)
{ _top.setValue(top); }
double getDistance() const
{ return _distance.getValue(); }
void setDistance(double distance)
{ _distance.setValue(distance); }
Frustum getFrustum() const;
void setFrustum(const Frustum& frustum);
private:
simgear::HLADoubleData _left;
simgear::HLADoubleData _right;
simgear::HLADoubleData _bottom;
simgear::HLADoubleData _top;
simgear::HLADoubleData _distance;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAPerspectiveCameraClass.hxx"
#include "HLAPerspectiveCamera.hxx"
namespace fgviewer {
HLAPerspectiveCameraClass::HLAPerspectiveCameraClass(const std::string& name, simgear::HLAFederate* federate) :
HLACameraClass(name, federate)
{
}
HLAPerspectiveCameraClass::~HLAPerspectiveCameraClass()
{
}
simgear::HLAObjectInstance*
HLAPerspectiveCameraClass::createObjectInstance(const std::string& name)
{
return new HLAPerspectiveCamera(this);
}
void
HLAPerspectiveCameraClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
if (_leftIndex.empty())
_leftIndex = getDataElementIndex("projection.left");
if (_rightIndex.empty())
_rightIndex = getDataElementIndex("projection.right");
if (_bottomIndex.empty())
_bottomIndex = getDataElementIndex("projection.bottom");
if (_topIndex.empty())
_topIndex = getDataElementIndex("projection.top");
if (_distanceIndex.empty())
_distanceIndex = getDataElementIndex("projection.distance");
HLACameraClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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

View File

@@ -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 <config.h>
#endif
#include "HLAPerspectiveViewer.hxx"
#include "HLAPerspectiveViewerClass.hxx"
namespace fgviewer {
HLAPerspectiveViewer::HLAPerspectiveViewer(HLAPerspectiveViewerClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
HLAViewer(objectClass),
_view(federate),
_zoomFactor(1),
_eyeTracker(federate)
{
}
HLAPerspectiveViewer::~HLAPerspectiveViewer()
{
}
void
HLAPerspectiveViewer::createAttributeDataElements()
{
HLAViewer::createAttributeDataElements();
assert(dynamic_cast<HLAPerspectiveViewerClass*>(getObjectClass().get()));
HLAPerspectiveViewerClass& objectClass = static_cast<HLAPerspectiveViewerClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getViewNameIndex(), _view.getDataElement());
setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
setAttributeDataElement(objectClass.getZoomFactorIndex(), _zoomFactor.getDataElement());
setAttributeDataElement(objectClass.getEyeTrackerNameIndex(), _eyeTracker.getDataElement());
}
const HLAView*
HLAPerspectiveViewer::getView() const
{
return _view.getObject();
}
HLAView*
HLAPerspectiveViewer::getView()
{
return _view.getObject();
}
void
HLAPerspectiveViewer::setView(HLAView* view)
{
_view.setObject(view);
}
const HLAEyeTracker*
HLAPerspectiveViewer::getEyeTracker() const
{
return _eyeTracker.getObject();
}
HLAEyeTracker*
HLAPerspectiveViewer::getEyeTracker()
{
return _eyeTracker.getObject();
}
void
HLAPerspectiveViewer::setEyeTracker(HLAEyeTracker* eyeTracker)
{
_eyeTracker.setObject(eyeTracker);
}
SGLocationd
HLAPerspectiveViewer::getLocation(const SGTimeStamp& simTime) const
{
const HLAView* view = getView();
if (!view)
return SGLocationd(getPosition(), getOrientation());
return view->getLocation(simTime).getAbsoluteLocation(SGLocationd(getPosition(), getOrientation()));
}
SGVec3d
HLAPerspectiveViewer::getLeftEyeOffset() const
{
const HLAEyeTracker* eyeTracker = getEyeTracker();
if (!eyeTracker)
return SGVec3d(0, 0, 0);
return eyeTracker->getLeftEyeOffset();
}
SGVec3d
HLAPerspectiveViewer::getRightEyeOffset() const
{
const HLAEyeTracker* eyeTracker = getEyeTracker();
if (!eyeTracker)
return SGVec3d(0, 0, 0);
return eyeTracker->getRightEyeOffset();
}
} // namespace fgviewer

View File

@@ -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<simgear::HLAFederate>& federate);
virtual ~HLAPerspectiveViewer();
virtual void createAttributeDataElements();
const HLAView* getView() const;
HLAView* getView();
void setView(HLAView* view);
const SGVec3d& getPosition() const
{ return _position.getValue(); }
void setPosition(const SGVec3d& position)
{ _position.setValue(position); }
const SGQuatd& getOrientation() const
{ return _orientation.getValue(); }
void setOrientation(const SGQuatd& orientation)
{ _orientation.setValue(orientation); }
double getZoomFactor() const
{ return _zoomFactor.getValue(); }
void setZoomFactor(double zoomFactor)
{ _zoomFactor.setValue(zoomFactor); }
const HLAEyeTracker* getEyeTracker() const;
HLAEyeTracker* getEyeTracker();
void setEyeTracker(HLAEyeTracker* eyeTracker);
SGLocationd getLocation(const SGTimeStamp& simTime) const;
SGVec3d getLeftEyeOffset() const;
SGVec3d getRightEyeOffset() const;
private:
simgear::HLAObjectReferenceData<HLAView> _view;
simgear::HLAVec3dData _position;
simgear::HLAQuat3dData _orientation;
simgear::HLADoubleData _zoomFactor;
simgear::HLAObjectReferenceData<HLAEyeTracker> _eyeTracker;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAPerspectiveViewerClass.hxx"
#include "HLAPerspectiveViewer.hxx"
namespace fgviewer {
HLAPerspectiveViewerClass::HLAPerspectiveViewerClass(const std::string& name, simgear::HLAFederate* federate) :
HLAViewerClass(name, federate)
{
}
HLAPerspectiveViewerClass::~HLAPerspectiveViewerClass()
{
}
simgear::HLAObjectInstance*
HLAPerspectiveViewerClass::createObjectInstance(const std::string& name)
{
return new HLAPerspectiveViewer(this, getFederate());
}
void
HLAPerspectiveViewerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
if (_viewNameIndex.empty())
_viewNameIndex = getDataElementIndex("viewName");
if (_positionIndex.empty())
_positionIndex = getDataElementIndex("location.position");
if (_orientationIndex.empty())
_orientationIndex = getDataElementIndex("location.orientation");
if (_zoomFactorIndex.empty())
_zoomFactorIndex = getDataElementIndex("zoomFactor");
if (_eyeTrackerNameIndex.empty())
_eyeTrackerNameIndex = getDataElementIndex("eyeTrackerName");
HLAViewerClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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

View File

@@ -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 <simgear/hla/HLADataElement.hxx>
namespace simgear {
class HLAProxyDataElement : public HLADataElement {
public:
virtual ~HLAProxyDataElement()
{ }
virtual void accept(HLADataElementVisitor& visitor)
{
HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return;
dataElement->accept(visitor);
}
virtual void accept(HLAConstDataElementVisitor& visitor) const
{
const HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return;
dataElement->accept(visitor);
}
virtual bool encode(HLAEncodeStream& stream) const
{
const HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return false;
return dataElement->encode(stream);
}
virtual bool decode(HLADecodeStream& stream)
{
HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return false;
return dataElement->decode(stream);
}
virtual const HLADataType* getDataType() const
{
const HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return 0;
return dataElement->getDataType();
}
virtual bool setDataType(const HLADataType* dataType)
{
HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return false;
return dataElement->setDataType(dataType);
}
protected:
virtual HLADataElement* _getDataElement() = 0;
virtual const HLADataElement* _getDataElement() const = 0;
virtual void _setStamp(Stamp* stamp)
{
HLADataElement::_setStamp(stamp);
HLADataElement* dataElement = _getDataElement();
if (!dataElement)
return;
dataElement->attachStamp(*this);
}
};
}
#endif

View File

@@ -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 <config.h>
#endif
#include "HLARenderer.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLARendererClass.hxx"
namespace fgviewer {
HLARenderer::HLARenderer(HLARendererClass* objectClass) :
HLAObjectInstance(objectClass)
{
}
HLARenderer::~HLARenderer()
{
}
void
HLARenderer::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLARendererClass*>(getObjectClass().get()));
HLARendererClass& objectClass = static_cast<HLARendererClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLARendererClass;
class HLARenderer : public simgear::HLAObjectInstance {
public:
HLARenderer(HLARendererClass* objectClass = 0);
virtual ~HLARenderer();
virtual void createAttributeDataElements();
private:
simgear::HLAStringData _name;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLARendererClass.hxx"
#include "HLARenderer.hxx"
namespace fgviewer {
HLARendererClass::HLARendererClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLARendererClass::~HLARendererClass()
{
}
simgear::HLAObjectInstance*
HLARendererClass::createObjectInstance(const std::string& name)
{
return new HLARenderer(this);
}
void
HLARendererClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_nameIndex.empty())
_nameIndex = getDataElementIndex("name");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLARendererClass : public simgear::HLAObjectClass {
public:
HLARendererClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLARendererClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setNameIndex(const std::string& path)
{ return getDataElementIndex(_nameIndex, path); }
const simgear::HLADataElementIndex& getNameIndex() const
{ return _nameIndex; }
private:
simgear::HLADataElementIndex _nameIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLASceneObject.hxx"
#include <osg/Transform>
#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include "HLASceneObjectClass.hxx"
#include "HLAViewerFederate.hxx"
namespace fgviewer {
class HLASceneObject::_ModelDataElement : public simgear::HLAProxyDataElement {
public:
_ModelDataElement(const SGWeakPtr<HLASceneObject>& sceneObject) :
_sceneObject(sceneObject)
{ }
virtual ~_ModelDataElement()
{ }
virtual bool decode(simgear::HLADecodeStream& stream)
{
if (!HLAProxyDataElement::decode(stream))
return false;
// No change?
if (!_name.getDataElement()->getDirty())
return true;
_name.getDataElement()->setDirty(false);
SGSharedPtr<HLASceneObject> sceneObject = _sceneObject.lock();
if (sceneObject.valid())
sceneObject->_setModelFileName(_name.getValue());
return true;
}
protected:
virtual simgear::HLAStringDataElement* _getDataElement()
{ return _name.getDataElement(); }
virtual const simgear::HLAStringDataElement* _getDataElement() const
{ return _name.getDataElement(); }
private:
const SGWeakPtr<HLASceneObject> _sceneObject;
simgear::HLAStringData _name;
};
class HLASceneObject::_Transform : public osg::Transform {
public:
_Transform(const SGWeakPtr<const HLASceneObject>& sceneObject) :
_sceneObject(sceneObject)
{
setCullingActive(false);
}
virtual ~_Transform()
{
}
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
if (!nv)
return false;
const osg::FrameStamp* frameStamp = nv->getFrameStamp();
if (!frameStamp)
return false;
SGLocationd location = _getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
// the position of the view
matrix.preMultTranslate(toOsg(location.getPosition()));
// the orientation of the view
matrix.preMultRotate(toOsg(location.getOrientation()));
return true;
}
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
if (!nv)
return false;
const osg::FrameStamp* frameStamp = nv->getFrameStamp();
if (!frameStamp)
return false;
SGLocationd location = _getLocation(SGTimeStamp::fromSec(frameStamp->getSimulationTime()));
// the position of the view
matrix.postMultTranslate(toOsg(-location.getPosition()));
// the orientation of the view
matrix.postMultRotate(toOsg(inverse(location.getOrientation())));
return true;
}
virtual osg::BoundingSphere computeBound() const
{
return osg::BoundingSphere();
}
private:
SGLocationd _getLocation(const SGTimeStamp& timeStamp) const
{
// transform from the simulation typical x-forward/y-right/z-down
// to the flightgear model system x-back/y-right/z-up
// SGQuatd simToModel = SGQuatd::fromEulerDeg(0, 180, 0);
SGQuatd simToModel = SGQuatd::fromRealImag(0, SGVec3d(0, 1, 0));
SGSharedPtr<const HLASceneObject> sceneObject = _sceneObject.lock();
if (!sceneObject.valid())
return SGLocationd(SGVec3d(0, 0, 0), simToModel);
// Get the cartesian location at the given time stamp from the hla object
SGLocationd location = sceneObject->getLocation(timeStamp);
location.setOrientation(location.getOrientation()*simToModel);
return location;
}
SGWeakPtr<const HLASceneObject> _sceneObject;
};
HLASceneObject::HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
HLAObjectInstance(objectClass),
_sceneObject(federate)
{
_pagedLOD = new osg::PagedLOD;
_pagedLOD->setRange(0, 0, 80000);
_transform = new _Transform(this);
_transform->addChild(_pagedLOD.get());
}
HLASceneObject::~HLASceneObject()
{
_removeFromSceneGraph();
}
void
HLASceneObject::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLASceneObjectClass*>(getObjectClass().get()));
HLASceneObjectClass& objectClass = static_cast<HLASceneObjectClass&>(*getObjectClass());
simgear::HLACartesianLocation* location = new simgear::HLACartesianLocation;
setAttributeDataElement(objectClass.getPositionIndex(), location->getPositionDataElement());
setAttributeDataElement(objectClass.getOrientationIndex(), location->getOrientationDataElement());
setAttributeDataElement(objectClass.getAngularVelocityIndex(), location->getAngularVelocityDataElement());
setAttributeDataElement(objectClass.getLinearVelocityIndex(), location->getLinearVelocityDataElement());
_location = location;
setAttributeDataElement(objectClass.getSceneObjectNameIndex(), _sceneObject.getDataElement());
}
void
HLASceneObject::discoverInstance(const simgear::RTIData& tag)
{
HLAObjectInstance::discoverInstance(tag);
_addToSceneGraph();
}
void
HLASceneObject::removeInstance(const simgear::RTIData& tag)
{
_removeFromSceneGraph();
HLAObjectInstance::removeInstance(tag);
}
void
HLASceneObject::registerInstance(simgear::HLAObjectClass* objectClass)
{
HLAObjectInstance::registerInstance(objectClass);
_addToSceneGraph();
}
void
HLASceneObject::deleteInstance(const simgear::RTIData& tag)
{
_removeFromSceneGraph();
HLAObjectInstance::deleteInstance(tag);
}
const HLASceneObject*
HLASceneObject::getSceneObject() const
{
return _sceneObject.getObject();
}
HLASceneObject*
HLASceneObject::getSceneObject()
{
return _sceneObject.getObject();
}
void
HLASceneObject::setSceneObject(HLASceneObject* sceneObject)
{
_sceneObject.setObject(sceneObject);
}
SGLocationd
HLASceneObject::getLocation(const SGTimeStamp& timeStamp) const
{
const HLASceneObject* sceneObject = getSceneObject();
if (!sceneObject)
return _getRelativeLocation(timeStamp);
return sceneObject->getLocation(timeStamp).getAbsoluteLocation(_getRelativeLocation(timeStamp));
}
simgear::HLADataElement*
HLASceneObject::getModelDataElement()
{
return new _ModelDataElement(this);
}
osg::Node*
HLASceneObject::getNode()
{
return _transform.get();
}
SGLocationd
HLASceneObject::_getRelativeLocation(const SGTimeStamp& timeStamp) const
{
if (!_location.valid())
return SGLocationd(SGVec3d::zeros(), SGQuatd::unit());
return _location->getLocation(timeStamp);
}
SGVec3d
HLASceneObject::_getRelativeAngularVelocity() const
{
if (!_location.valid())
return SGVec3d(0, 0, 0);
return _location->getAngularBodyVelocity();
}
SGVec3d
HLASceneObject::_getRelativeLinearVelocity() const
{
if (!_location.valid())
return SGVec3d(0, 0, 0);
return _location->getLinearBodyVelocity();
}
void
HLASceneObject::_setModelFileName(const std::string& fileName)
{
if (0 < _pagedLOD->getNumFileNames() && fileName == _pagedLOD->getFileName(0))
return;
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (federate.valid()) {
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
HLAViewerFederate* viewerFederate = static_cast<HLAViewerFederate*>(federate.get());
osg::ref_ptr<osgDB::Options> localOptions;
localOptions = static_cast<osgDB::Options*>(viewerFederate->getReaderWriterOptions()->clone(osg::CopyOp()));
// FIXME: particle systems have some issues. Do not use them currently.
localOptions->setPluginStringData("SimGear::PARTICLESYSTEM", "OFF");
_pagedLOD->setDatabaseOptions(localOptions.get());
}
// Finally set the file name
if (unsigned numChildren = _pagedLOD->getNumChildren())
_pagedLOD->removeChildren(0, numChildren);
_pagedLOD->setFileName(0, fileName);
}
void
HLASceneObject::_addToSceneGraph()
{
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (!federate.valid())
return;
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
HLAViewerFederate* viewerFederate = static_cast<HLAViewerFederate*>(federate.get());
/// Add ourselves to the dynamic scene graph
viewerFederate->addDynamicModel(getNode());
}
void
HLASceneObject::_removeFromSceneGraph()
{
/// FIXME O(#SceneObjects), pool them and reuse in create
unsigned i = _transform->getNumParents();
while (i--) {
osg::Group* parent = _transform->getParent(i);
parent->removeChild(_transform.get());
}
}
} // namespace fgviewer

View File

@@ -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 <osg/Node>
#include <osg/PagedLOD>
#include <osg/ref_ptr>
#include <simgear/hla/HLAObjectClass.hxx>
#include <simgear/hla/HLALocation.hxx>
#include "HLAObjectReferenceData.hxx"
namespace fgviewer {
class HLASceneObjectClass;
class HLASceneObject : public simgear::HLAObjectInstance {
public:
HLASceneObject(HLASceneObjectClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
virtual ~HLASceneObject();
virtual void createAttributeDataElements();
virtual void discoverInstance(const simgear::RTIData& tag);
virtual void removeInstance(const simgear::RTIData& tag);
virtual void registerInstance(simgear::HLAObjectClass* objectClass);
virtual void deleteInstance(const simgear::RTIData& tag);
const HLASceneObject* getSceneObject() const;
HLASceneObject* getSceneObject();
void setSceneObject(HLASceneObject* sceneObject);
virtual SGLocationd getLocation(const SGTimeStamp& timeStamp) const;
simgear::HLADataElement* getModelDataElement();
osg::Node* getNode();
protected:
SGLocationd _getRelativeLocation(const SGTimeStamp& timeStamp) const;
// Return the velocities of this current object without taking the referenced velocities into account
SGVec3d _getRelativeAngularVelocity() const;
SGVec3d _getRelativeLinearVelocity() const;
void _setModelFileName(const std::string& fileName);
private:
class _ModelDataElement;
class _Transform;
// Add the transform node to the scenegraph
void _addToSceneGraph();
// Remove the transform node from the scenegraph
void _removeFromSceneGraph();
// The location of this object
SGSharedPtr<simgear::HLAAbstractLocation> _location;
// If this object is living relative to an other one, this one is non zero
simgear::HLAObjectReferenceData<HLASceneObject> _sceneObject;
// The top level transform node for this scene object
osg::ref_ptr<_Transform> _transform;
osg::ref_ptr<osg::PagedLOD> _pagedLOD;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLASceneObjectClass.hxx"
#include "HLASceneObject.hxx"
#include "HLAViewerFederate.hxx"
namespace fgviewer {
HLASceneObjectClass::HLASceneObjectClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLASceneObjectClass::~HLASceneObjectClass()
{
}
simgear::HLAObjectInstance*
HLASceneObjectClass::createObjectInstance(const std::string& name)
{
return new HLASceneObject(this, getFederate());
}
void
HLASceneObjectClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_positionIndex.empty())
_positionIndex = getDataElementIndex("location.position");
if (_orientationIndex.empty())
_orientationIndex = getDataElementIndex("location.orientation");
if (_angularVelocityIndex.empty())
_angularVelocityIndex = getDataElementIndex("velocity.angular");
if (_linearVelocityIndex.empty())
_linearVelocityIndex = getDataElementIndex("velocity.linear");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLASceneObjectClass : public simgear::HLAObjectClass {
public:
HLASceneObjectClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLASceneObjectClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setPositionIndex(const std::string& path)
{ return getDataElementIndex(_positionIndex, path); }
const simgear::HLADataElementIndex& getPositionIndex() const
{ return _positionIndex; }
bool setOrientationIndex(const std::string& path)
{ return getDataElementIndex(_orientationIndex, path); }
const simgear::HLADataElementIndex& getOrientationIndex() const
{ return _orientationIndex; }
bool setAngularVelocityIndex(const std::string& path)
{ return getDataElementIndex(_angularVelocityIndex, path); }
const simgear::HLADataElementIndex& getAngularVelocityIndex() const
{ return _angularVelocityIndex; }
bool setLinearVelocityIndex(const std::string& path)
{ return getDataElementIndex(_linearVelocityIndex, path); }
const simgear::HLADataElementIndex& getLinearVelocityIndex() const
{ return _linearVelocityIndex; }
/// FIXME make sure that we do not get closed reference loops at some point!
/// Do this in the setter of the object data element so that its not getting a runtime issue
bool setSceneObjectNameIndex(const std::string& path)
{ return getDataElementIndex(_sceneObjectNameIndex, path); }
const simgear::HLADataElementIndex& getSceneObjectNameIndex() const
{ return _sceneObjectNameIndex; }
private:
/// FIXME use a location factory for that?!
simgear::HLADataElementIndex _positionIndex;
simgear::HLADataElementIndex _orientationIndex;
simgear::HLADataElementIndex _angularVelocityIndex;
simgear::HLADataElementIndex _linearVelocityIndex;
simgear::HLADataElementIndex _sceneObjectNameIndex;
};
} // namespace fgviewer
#endif

135
utils/fgviewer/HLAView.cxx Normal file
View File

@@ -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 <config.h>
#endif
#include "HLAView.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLAViewClass.hxx"
#include "HLAViewerFederate.hxx"
namespace fgviewer {
HLAView::HLAView(HLAViewClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate) :
HLAObjectInstance(objectClass),
_sceneObject(federate)
{
}
HLAView::~HLAView()
{
}
void
HLAView::createAttributeDataElements()
{
/// FIXME at some point we should not need that anymore
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLAViewClass*>(getObjectClass().get()));
HLAViewClass& objectClass = static_cast<HLAViewClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
setAttributeDataElement(objectClass.getOrientationIndex(), _orientation.getDataElement());
setAttributeDataElement(objectClass.getSceneObjectNameIndex(), _sceneObject.getDataElement());
}
void
HLAView::discoverInstance(const simgear::RTIData& tag)
{
HLAObjectInstance::discoverInstance(tag);
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (federate.valid()) {
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
static_cast<HLAViewerFederate*>(federate.get())->insertView(this);
}
}
void
HLAView::removeInstance(const simgear::RTIData& tag)
{
HLAObjectInstance::removeInstance(tag);
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (federate.valid()) {
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
static_cast<HLAViewerFederate*>(federate.get())->eraseView(this);
}
}
void
HLAView::registerInstance(simgear::HLAObjectClass* objectClass)
{
HLAObjectInstance::registerInstance(objectClass);
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (federate.valid()) {
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
static_cast<HLAViewerFederate*>(federate.get())->insertView(this);
}
}
void
HLAView::deleteInstance(const simgear::RTIData& tag)
{
SGSharedPtr<simgear::HLAFederate> federate = getFederate().lock();
if (federate.valid()) {
assert(dynamic_cast<HLAViewerFederate*>(federate.get()));
static_cast<HLAViewerFederate*>(federate.get())->eraseView(this);
}
HLAObjectInstance::deleteInstance(tag);
}
const HLASceneObject*
HLAView::getSceneObject() const
{
/// FIXME!!! The federate should track unresolved object references
_sceneObject.recheckObject();
return _sceneObject.getObject();
}
HLASceneObject*
HLAView::getSceneObject()
{
/// FIXME!!! The federate should track unresolved object references
_sceneObject.recheckObject();
return _sceneObject.getObject();
}
void
HLAView::setSceneObject(HLASceneObject* sceneObject)
{
_sceneObject.setObject(sceneObject);
}
SGLocationd
HLAView::getLocation(const SGTimeStamp& timeStamp) const
{
const HLASceneObject* sceneObject = getSceneObject();
SGLocationd location(getPosition(), getOrientation());
if (!sceneObject)
return location;
return sceneObject->getLocation(timeStamp).getAbsoluteLocation(location);
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectInstance.hxx>
#include "HLAObjectReferenceData.hxx"
#include "HLASceneObject.hxx"
namespace fgviewer {
class HLAViewClass;
class HLAView : public simgear::HLAObjectInstance {
public:
HLAView(HLAViewClass* objectClass, const SGWeakPtr<simgear::HLAFederate>& federate);
virtual ~HLAView();
virtual void createAttributeDataElements();
virtual void discoverInstance(const simgear::RTIData& tag);
virtual void removeInstance(const simgear::RTIData& tag);
virtual void registerInstance(simgear::HLAObjectClass* objectClass);
virtual void deleteInstance(const simgear::RTIData& tag);
const std::string& getNameAttribute() const
{ return _name.getValue(); }
void setNameAttribute(const std::string& name)
{ _name.setValue(name); }
const SGVec3d& getPosition() const
{ return _position.getValue(); }
void setPosition(const SGVec3d& position)
{ _position.setValue(position); }
const SGQuatd& getOrientation() const
{ return _orientation.getValue(); }
void setOrientation(const SGQuatd& orientation)
{ _orientation.setValue(orientation); }
const HLASceneObject* getSceneObject() const;
HLASceneObject* getSceneObject();
void setSceneObject(HLASceneObject* sceneObject);
virtual SGLocationd getLocation(const SGTimeStamp& simTime) const;
private:
simgear::HLAStringData _name;
simgear::HLAVec3dData _position;
simgear::HLAQuat3dData _orientation;
simgear::HLAObjectReferenceData<HLASceneObject> _sceneObject;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAViewClass.hxx"
#include "HLAView.hxx"
namespace fgviewer {
HLAViewClass::HLAViewClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLAViewClass::~HLAViewClass()
{
}
simgear::HLAObjectInstance*
HLAViewClass::createObjectInstance(const std::string& name)
{
return new HLAView(this, getFederate());
}
void
HLAViewClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_nameIndex.empty())
_nameIndex = getDataElementIndex("name");
if (_positionIndex.empty())
_positionIndex = getDataElementIndex("location.position");
if (_orientationIndex.empty())
_orientationIndex = getDataElementIndex("location.orientation");
if (_sceneObjectNameIndex.empty())
_sceneObjectNameIndex = getDataElementIndex("sceneObjectName");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLAViewClass : public simgear::HLAObjectClass {
public:
HLAViewClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLAViewClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setNameIndex(const std::string& path)
{ return getDataElementIndex(_nameIndex, path); }
const simgear::HLADataElementIndex& getNameIndex() const
{ return _nameIndex; }
bool setPositionIndex(const std::string& path)
{ return getDataElementIndex(_positionIndex, path); }
const simgear::HLADataElementIndex& getPositionIndex() const
{ return _positionIndex; }
bool setOrientationIndex(const std::string& path)
{ return getDataElementIndex(_orientationIndex, path); }
const simgear::HLADataElementIndex& getOrientationIndex() const
{ return _orientationIndex; }
bool setSceneObjectNameIndex(const std::string& path)
{ return getDataElementIndex(_sceneObjectNameIndex, path); }
const simgear::HLADataElementIndex& getSceneObjectNameIndex() const
{ return _sceneObjectNameIndex; }
private:
simgear::HLADataElementIndex _nameIndex;
simgear::HLADataElementIndex _positionIndex;
simgear::HLADataElementIndex _orientationIndex;
simgear::HLADataElementIndex _sceneObjectNameIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAViewer.hxx"
#include <simgear/hla/HLAArrayDataElement.hxx>
#include "HLAViewerClass.hxx"
namespace fgviewer {
HLAViewer::HLAViewer(HLAViewerClass* objectClass) :
HLAObjectInstance(objectClass)
{
}
HLAViewer::~HLAViewer()
{
}
void
HLAViewer::createAttributeDataElements()
{
HLAObjectInstance::createAttributeDataElements();
assert(dynamic_cast<HLAViewerClass*>(getObjectClass().get()));
HLAViewerClass& objectClass = static_cast<HLAViewerClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getNameIndex(), _name.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLAArrayDataElement.hxx>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLAViewerClass;
class HLAViewer : public simgear::HLAObjectInstance {
public:
HLAViewer(HLAViewerClass* objectClass = 0);
virtual ~HLAViewer();
virtual void createAttributeDataElements();
private:
simgear::HLAStringData _name;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAViewerClass.hxx"
#include "HLAViewer.hxx"
namespace fgviewer {
HLAViewerClass::HLAViewerClass(const std::string& name, simgear::HLAFederate* federate) :
HLAObjectClass(name, federate)
{
}
HLAViewerClass::~HLAViewerClass()
{
}
simgear::HLAObjectInstance*
HLAViewerClass::createObjectInstance(const std::string& name)
{
return new HLAViewer(this);
}
void
HLAViewerClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
/// FIXME resolve these indices somewhere else!
if (_nameIndex.empty())
_nameIndex = getDataElementIndex("name");
HLAObjectClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/hla/HLAObjectClass.hxx>
namespace fgviewer {
class HLAViewerClass : public simgear::HLAObjectClass {
public:
HLAViewerClass(const std::string& name, simgear::HLAFederate* federate);
virtual ~HLAViewerClass();
/// Create a new instance of this class.
virtual simgear::HLAObjectInstance* createObjectInstance(const std::string& name);
virtual void createAttributeDataElements(simgear::HLAObjectInstance& objectInstance);
bool setNameIndex(const std::string& path)
{ return getDataElementIndex(_nameIndex, path); }
const simgear::HLADataElementIndex& getNameIndex() const
{ return _nameIndex; }
private:
simgear::HLADataElementIndex _nameIndex;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAViewerFederate.hxx"
#include <osg/Group>
#include <osgDB/Options>
#include "HLAEyeTrackerClass.hxx"
#include "HLAMPAircraftClass.hxx"
#include "HLAPerspectiveViewer.hxx"
#include "HLAPerspectiveViewerClass.hxx"
#include "HLASceneObjectClass.hxx"
#include "HLAView.hxx"
#include "HLAViewClass.hxx"
#include "Viewer.hxx"
namespace fgviewer {
HLAViewerFederate::HLAViewerFederate() :
_group(new osg::Group)
{
}
HLAViewerFederate::~HLAViewerFederate()
{
}
const HLAPerspectiveViewer*
HLAViewerFederate::getViewer() const
{
return _perspectiveViewer.get();
}
HLAPerspectiveViewer*
HLAViewerFederate::getViewer()
{
return _perspectiveViewer.get();
}
void
HLAViewerFederate::setViewer(HLAPerspectiveViewer* perspectiveViewer)
{
if (_perspectiveViewer.get() == perspectiveViewer)
return;
_perspectiveViewer = perspectiveViewer;
}
const HLAView*
HLAViewerFederate::getView() const
{
if (!_perspectiveViewer.valid())
return 0;
return _perspectiveViewer->getView();
}
HLAView*
HLAViewerFederate::getView()
{
if (!_perspectiveViewer.valid())
return 0;
return _perspectiveViewer->getView();
}
void
HLAViewerFederate::setView(HLAView* view)
{
if (!_perspectiveViewer.valid())
return;
return _perspectiveViewer->setView(view);
}
simgear::HLAObjectClass*
HLAViewerFederate::createObjectClass(const std::string& name)
{
if (name == "FGView") {
_viewClass = new HLAViewClass(name, this);
return _viewClass.get();
} else if (name == "FGPerspectiveViewer") {
_perspectiveViewerClass = new HLAPerspectiveViewerClass(name, this);
return _perspectiveViewerClass.get();
// } else if (name == "FGOrthographicViewer") {
// _orthographicViewerClass = new HLAOrthograpicViewerClass(name, this);
// return _orthographicViewerClass.get();
} else if (name == "FGEyeTracker") {
return new HLAEyeTrackerClass(name, this);
// } else if (name == "FGPerspectiveCamera") {
// _perspectiveCameraClass = new HLAPerspectiveCameraClass(name, this);
// return _perspectiveCameraClass.get();
// } else if (name == "FGOrthographicCamera") {
// _orthographicCameraClass = new HLAOrthographicCameraClass(name, this);
// return _orthographicCameraClass.get();
// } else if (name == "FGWindowDrawable") {
// _windowDrawableClass = new HLAWindowDrawableClass(name, this);
// return _windowDrawableClass.get();
// } else if (name == "FGRenderer") {
// _rendererClass = new HLARendererClass(name, this);
// return _rendererClass.get();
}
/// Classes for model type objects.
else if (name == "FGSceneObject") {
return new HLASceneObjectClass(name, this);
} else if (name == "MPAircraft") {
return new HLAMPAircraftClass(name, this);
}
/// Do not subscribe to anything else
else {
return 0;
}
}
bool
HLAViewerFederate::init()
{
if (!HLAFederate::init())
return false;
if (!_perspectiveViewerClass.valid())
return false;
if (!_viewClass.valid())
return false;
// Create a viewer ...
_perspectiveViewer = new HLAPerspectiveViewer(_perspectiveViewerClass.get(), this);
_perspectiveViewer->registerInstance(_perspectiveViewerClass.get());
// ... with a nice view
_defaultView = new HLAView(_viewClass.get(), this);
_defaultView->registerInstance(_viewClass.get());
_perspectiveViewer->setView(_defaultView.get());
return true;
}
bool
HLAViewerFederate::update()
{
// if (_view.valid())
// _view->updateAttributeValues(simgear::RTIData("frame"));
if (_perspectiveViewer.valid())
_perspectiveViewer->updateAttributeValues(simgear::RTIData("frame"));
// Just go ahead as far as possible.
// This is just fine for a viewer.
return HLAFederate::timeAdvanceAvailable();
}
bool
HLAViewerFederate::shutdown()
{
if (_defaultView.valid())
_defaultView->deleteInstance(simgear::RTIData("shutdown"));
_defaultView.clear();
if (_perspectiveViewer.valid())
_perspectiveViewer->deleteInstance(simgear::RTIData("shutdown"));
_perspectiveViewer.clear();
_group->removeChildren(0, _group->getNumChildren());
return HLAFederate::shutdown();
}
osg::Node*
HLAViewerFederate::getDynamicModelNode()
{
return _group.get();
}
void
HLAViewerFederate::addDynamicModel(osg::Node* node)
{
/// FIXME can do something more intelligent like a dequeue
/// when returning here something to identify the entry, removal is about O(1)
_group->addChild(node);
}
void
HLAViewerFederate::removeDynamicModel(osg::Node* node)
{
_group->removeChild(node);
}
osg::ref_ptr<const osgDB::Options>
HLAViewerFederate::getReaderWriterOptions() const
{
// Cannot use the thread safe variant of the observed_ptr methods here since the
// viewer is currently allocated on the stack.
if (!_viewer.valid())
return osg::ref_ptr<const osgDB::Options>();
return _viewer->getReaderWriterOptions();
}
void
HLAViewerFederate::attachToViewer(Viewer* viewer)
{
if (!viewer) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLAViewerFederate::attachToViewer(): Ignoring zero viewer!");
return;
}
if (_viewer.valid()) {
SG_LOG(SG_NETWORK, SG_ALERT, "HLAViewerFederate::attachToViewer(): Not attaching a second viewer!");
return;
}
_viewer = viewer;
_viewer->insertSceneData(getDynamicModelNode());
}
void
HLAViewerFederate::insertView(HLAView* view)
{
_viewList.push_back(view);
/// FIXME not always
setView(view);
}
void
HLAViewerFederate::eraseView(HLAView* view)
{
//// FIXME store the iterator!!!!
for (ViewList::iterator i = _viewList.begin(); i != _viewList.end(); ++i) {
if (i->get() != view)
continue;
_viewList.erase(i);
break;
}
if (getView() == view) {
if (_viewList.empty()) {
setView(_defaultView.get());
} else {
setView(_viewList.back().get());
}
}
}
} // namespace fgviewer

View File

@@ -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 <osg/ref_ptr>
#include <osg/observer_ptr>
#include <osg/Group>
#include <osg/Node>
#include <osgDB/Options>
#include <simgear/hla/HLAFederate.hxx>
#include "HLASceneObjectClass.hxx"
#include "HLAView.hxx"
#include "HLAViewClass.hxx"
#include "HLAPerspectiveViewer.hxx"
#include "HLAPerspectiveViewerClass.hxx"
#include "HLAMPAircraftClass.hxx"
namespace fgviewer {
class Viewer;
class HLAViewerFederate : public simgear::HLAFederate {
public:
HLAViewerFederate();
virtual ~HLAViewerFederate();
const HLAPerspectiveViewer* getViewer() const;
HLAPerspectiveViewer* getViewer();
void setViewer(HLAPerspectiveViewer* viewer);
const HLAView* getView() const;
HLAView* getView();
void setView(HLAView* view);
virtual simgear::HLAObjectClass* createObjectClass(const std::string& name);
virtual bool init();
virtual bool update();
virtual bool shutdown();
/// The node containing all the dynamic models attached to this viewer
osg::Node* getDynamicModelNode();
void addDynamicModel(osg::Node* node);
void removeDynamicModel(osg::Node* node);
/// Dynamic models use this options struct for loading/paging
osg::ref_ptr<const osgDB::Options> getReaderWriterOptions() const;
/// Called by the viewer.
void attachToViewer(Viewer* viewer);
/// Temporary application management
void insertView(HLAView* view);
void eraseView(HLAView* view);
private:
/// Explicitly known object classes
SGSharedPtr<HLAPerspectiveViewerClass> _perspectiveViewerClass;
SGSharedPtr<HLAViewClass> _viewClass;
/// The perspective viewer of this viewer federate. FIXME: also allow orthographic viewers for instruments!
SGSharedPtr<HLAPerspectiveViewer> _perspectiveViewer;
/// The default absolute view
SGSharedPtr<HLAView> _defaultView;
/// A list of all available views
typedef std::list<SGSharedPtr<HLAView> > ViewList;
ViewList _viewList;
/// The openscenegraphs side of this component
osg::ref_ptr<osg::Group> _group;
/// The backward reference to the viewer
osg::observer_ptr<Viewer> _viewer;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAWindowDrawable.hxx"
#include "HLAWindowDrawableClass.hxx"
namespace fgviewer {
HLAWindowDrawable::HLAWindowDrawable(HLAWindowDrawableClass* objectClass) :
HLADrawable(objectClass)
{
}
HLAWindowDrawable::~HLAWindowDrawable()
{
}
void
HLAWindowDrawable::createAttributeDataElements()
{
HLADrawable::createAttributeDataElements();
assert(dynamic_cast<HLAWindowDrawableClass*>(getObjectClass().get()));
HLAWindowDrawableClass& objectClass = static_cast<HLAWindowDrawableClass&>(*getObjectClass());
setAttributeDataElement(objectClass.getFullscreenIndex(), _fullscreen.getDataElement());
setAttributeDataElement(objectClass.getPositionIndex(), _position.getDataElement());
setAttributeDataElement(objectClass.getSizeIndex(), _size.getDataElement());
}
} // namespace fgviewer

View File

@@ -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 <simgear/hla/HLABasicDataElement.hxx>
#include "HLADrawable.hxx"
namespace fgviewer {
class HLAWindowDrawableClass;
class HLAWindowDrawable : public HLADrawable {
public:
HLAWindowDrawable(HLAWindowDrawableClass* objectClass = 0);
virtual ~HLAWindowDrawable();
virtual void createAttributeDataElements();
bool getFullscreen() const
{ return _fullscreen.getValue(); }
void setFullscreen(bool fullscreen)
{ _fullscreen.setValue(fullscreen); }
const SGVec2i& getPosition() const
{ return _position.getValue(); }
void setPosition(const SGVec2i& position)
{ _position.setValue(position); }
const SGVec2i& getSize() const
{ return _size.getValue(); }
void setSize(const SGVec2i& size)
{ _size.setValue(size); }
private:
simgear::HLABoolData _fullscreen;
simgear::HLAVec2iData _position;
simgear::HLAVec2iData _size;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "HLAWindowDrawableClass.hxx"
#include "HLAWindowDrawable.hxx"
namespace fgviewer {
HLAWindowDrawableClass::HLAWindowDrawableClass(const std::string& name, simgear::HLAFederate* federate) :
HLADrawableClass(name, federate)
{
}
HLAWindowDrawableClass::~HLAWindowDrawableClass()
{
}
simgear::HLAObjectInstance*
HLAWindowDrawableClass::createObjectInstance(const std::string& name)
{
return new HLAWindowDrawable(this);
}
void
HLAWindowDrawableClass::createAttributeDataElements(simgear::HLAObjectInstance& objectInstance)
{
if (_fullscreenIndex.empty())
_fullscreenIndex = getDataElementIndex("fullscreen");
if (_positionIndex.empty())
_positionIndex = getDataElementIndex("position");
if (_sizeIndex.empty())
_sizeIndex = getDataElementIndex("size");
HLADrawableClass::createAttributeDataElements(objectInstance);
}
} // namespace fgviewer

View File

@@ -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

View File

@@ -0,0 +1,138 @@
// MEncoderCaptureOperation.hxx -- capture video stream into mencoder
//
// Copyright (C) 2009 - 2012 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifndef MEncoderCaptureOperation_HXX
#define MEncoderCaptureOperation_HXX
#include <cstdio>
#include <sstream>
#include <string>
#include <osgViewer/ViewerEventHandlers>
/// Class to capture into a pipe driven mencoder.
/// To integrate this into a viewer:
/// MEncoderCaptureOperation* mencoderCaptureOperation = new MEncoderCaptureOperation("/tmp/fgviewer.avi", 60);
/// osgViewer::ScreenCaptureHandler* c = new osgViewer::ScreenCaptureHandler(mencoderCaptureOperation, -1);
/// viewer.addEventHandler(c);
/// c->startCapture();
namespace fgviewer {
class MEncoderCaptureOperation : public osgViewer::ScreenCaptureHandler::CaptureOperation {
public:
MEncoderCaptureOperation(const std::string& fileName = "video.avi", unsigned fps = 30) :
_fps(fps),
_fileName(fileName),
_options("-ovc lavc"),
_file(0),
_width(-1),
_height(-1)
{ }
virtual ~MEncoderCaptureOperation()
{ _close(); }
const std::string& getFileName() const
{ return _fileName; }
void setFileName(const std::string& fileName)
{ _fileName = fileName; }
unsigned getFramesPerSecond() const
{ return _fps; }
void setFramesPerSecond(unsigned fps)
{ _fps = fps; }
const std::string& getOptions() const
{ return _options; }
void setOptions(const std::string& options)
{ _options = options; }
virtual void operator()(const osg::Image& image, const unsigned int)
{
// Delay any action until we have a valid image
if (!image.valid())
return;
// Ensure an open file
if (!_file) {
// If the video was already opened and we got any error,
// do not reopen with the same name.
if (0 < _width)
return;
_width = image.s();
_height = image.t();
if (!_open())
return;
}
// Ensure we did not change dimensions
if (image.s() != _width)
return;
if (image.t() != _height)
return;
// Write upside down flipped image
for (int row = _height - 1; 0 <= row; --row) {
size_t ret = fwrite(image.data(0, row), 1, image.getRowSizeInBytes(), _file);
if (ret != image.getRowSizeInBytes())
return;
}
}
private:
bool _open()
{
if (_file)
return false;
/// FIXME improve: adapt format to the format we get from the image
std::stringstream ss;
ss << "mencoder - -demuxer rawvideo -rawvideo fps="
<< _fps << ":w=" << _width << ":h=" << _height
<< ":format=rgb24 -o " << _fileName << " " << _options;
#ifdef _WIN32
_file = _popen(ss.str().c_str(), "wb");
#else
_file = popen(ss.str().c_str(), "w");
#endif
return _file != 0;
}
void _close()
{
if (!_file)
return;
#ifdef _WIN32
_pclose(_file);
#else
pclose(_file);
#endif
_file = 0;
}
/// Externally given:
unsigned _fps;
std::string _fileName;
std::string _options;
/// Internal determined
FILE* _file;
int _width;
int _height;
};
}
#endif

121
utils/fgviewer/Renderer.cxx Normal file
View File

@@ -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 <config.h>
#endif
#include "Renderer.hxx"
#include <osgViewer/Renderer>
#include <simgear/scene/material/EffectCullVisitor.hxx>
#include "Drawable.hxx"
#include "Viewer.hxx"
#include "SlaveCamera.hxx"
namespace fgviewer {
// FIXME I understand why we currently need this, but this seems like
// weird to require an own cull visitor.
static void installCullVisitor(osg::Camera& camera)
{
osgViewer::Renderer* renderer = static_cast<osgViewer::Renderer*>(camera.getRenderer());
for (int i = 0; i < 2; ++i) {
osgUtil::SceneView* sceneView = renderer->getSceneView(i);
osg::ref_ptr<osgUtil::CullVisitor::Identifier> identifier;
identifier = sceneView->getCullVisitor()->getIdentifier();
sceneView->setCullVisitor(new simgear::EffectCullVisitor);
sceneView->getCullVisitor()->setIdentifier(identifier.get());
identifier = sceneView->getCullVisitorLeft()->getIdentifier();
sceneView->setCullVisitorLeft(sceneView->getCullVisitor()->clone());
sceneView->getCullVisitorLeft()->setIdentifier(identifier.get());
identifier = sceneView->getCullVisitorRight()->getIdentifier();
sceneView->setCullVisitorRight(sceneView->getCullVisitor()->clone());
sceneView->getCullVisitorRight()->setIdentifier(identifier.get());
}
}
class Renderer::_SlaveCamera : public SlaveCamera {
public:
_SlaveCamera(const std::string& name) :
SlaveCamera(name)
{
}
virtual ~_SlaveCamera()
{
}
virtual osg::Camera* _realizeImplementation(Viewer& viewer)
{
osg::Camera* camera = SlaveCamera::_realizeImplementation(viewer);
if (!camera)
return 0;
camera->addChild(viewer.getSceneDataGroup());
viewer.addSlave(camera, osg::Matrix::identity(), getViewOffset(), false /*useMastersSceneData*/);
installCullVisitor(*camera);
return camera;
}
virtual bool _updateImplementation(Viewer& viewer)
{
getCamera()->setViewMatrix(getEffectiveViewOffset(viewer));
getCamera()->setProjectionMatrix(getEffectiveFrustum(viewer).getMatrix(osg::Vec2(10, 8e4)));
return SlaveCamera::_updateImplementation(viewer);
}
};
Renderer::Renderer()
{
}
Renderer::~Renderer()
{
}
Drawable*
Renderer::createDrawable(Viewer&, const std::string& name)
{
return new Drawable(name);
}
SlaveCamera*
Renderer::createSlaveCamera(Viewer&, const std::string& name)
{
return new _SlaveCamera(name);
}
bool
Renderer::realize(Viewer& viewer)
{
if (!viewer.realizeDrawables())
return false;
return viewer.realizeSlaveCameras();
}
bool
Renderer::update(Viewer& viewer)
{
return viewer.updateSlaveCameras();
}
} // namespace fgviewer

View File

@@ -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 <string>
#include <simgear/structure/SGWeakReferenced.hxx>
namespace fgviewer {
class Drawable;
class Viewer;
class SlaveCamera;
/// Default renderer, doing fixed function work
class Renderer : public SGWeakReferenced {
public:
Renderer();
virtual ~Renderer();
virtual Drawable* createDrawable(Viewer& viewer, const std::string& name);
virtual SlaveCamera* createSlaveCamera(Viewer& viewer, const std::string& name);
virtual bool realize(Viewer& viewer);
virtual bool update(Viewer& viewer);
private:
Renderer(const Renderer&);
Renderer& operator=(const Renderer&);
class _SlaveCamera;
};
} // namespace fgviewer
#endif

View File

@@ -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 <config.h>
#endif
#include "SlaveCamera.hxx"
#include <simgear/scene/util/OsgMath.hxx>
#include "Viewer.hxx"
#if FG_HAVE_HLA
#include "HLAViewerFederate.hxx"
#include "HLAPerspectiveViewer.hxx"
#endif
namespace fgviewer {
class NoUpdateCallback : public osg::NodeCallback {
public:
virtual ~NoUpdateCallback()
{ }
virtual void operator()(osg::Node* node, osg::NodeVisitor* nodeVisitor)
{ }
};
SlaveCamera::SlaveCamera(const std::string& name) :
_name(name),
_viewport(new osg::Viewport())
{
_referencePointMap["lowerLeft"] = osg::Vec2(-1, -1);
_referencePointMap["lowerRight"] = osg::Vec2(1, -1);
_referencePointMap["upperRight"] = osg::Vec2(1, 1);
_referencePointMap["upperLeft"] = osg::Vec2(-1, 1);
}
SlaveCamera::~SlaveCamera()
{
}
bool
SlaveCamera::setDrawableName(const std::string& drawableName)
{
if (_camera.valid())
return false;
_drawableName = drawableName;
return true;
}
bool
SlaveCamera::setViewport(const SGVec4i& viewport)
{
_viewport->setViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
_frustum.setAspectRatio(getAspectRatio());
return true;
}
bool
SlaveCamera::setViewOffset(const osg::Matrix& viewOffset)
{
_viewOffset = viewOffset;
return true;
}
bool
SlaveCamera::setViewOffsetDeg(double headingDeg, double pitchDeg, double rollDeg)
{
osg::Matrix viewOffset = osg::Matrix::identity();
viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(headingDeg), osg::Vec3(0, 1, 0)));
viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(pitchDeg), osg::Vec3(-1, 0, 0)));
viewOffset.postMultRotate(osg::Quat(SGMiscd::deg2rad(rollDeg), osg::Vec3(0, 0, 1)));
return setViewOffset(viewOffset);
}
bool
SlaveCamera::setFrustum(const Frustum& frustum)
{
_frustum = frustum;
return true;
}
void
SlaveCamera::setFustumByFieldOfViewDeg(double fieldOfViewDeg)
{
Frustum frustum(getAspectRatio());
frustum.setFieldOfViewDeg(fieldOfViewDeg);
setFrustum(frustum);
}
bool
SlaveCamera::setRelativeFrustum(const std::string names[2], const SlaveCamera& referenceCameraData,
const std::string referenceNames[2])
{
// Track the way from one projection space to the other:
// We want
// P = T2*S*T*P0
// where P0 is the projection template sensible for the given window size,
// S a scale matrix and T is a translation matrix.
// We need to determine T and S so that the reference points in the parents
// projection space match the two reference points in this cameras projection space.
// Starting from the parents camera projection space, we get into this cameras
// projection space by the transform matrix:
// P*R*inv(pP*pR) = T2*S*T*P0*R*inv(pP*pR)
// So, at first compute that matrix without T2*S*T and determine S and T* from that
// The initial projeciton matrix to build upon
osg::Matrix P = Frustum(getAspectRatio()).getMatrix();
osg::Matrix R = getViewOffset();
osg::Matrix pP = referenceCameraData.getFrustum().getMatrix();
osg::Matrix pR = referenceCameraData.getViewOffset();
// Transform from the reference cameras projection space into this cameras eye space.
osg::Matrix pPtoEye = osg::Matrix::inverse(pR*pP)*R;
osg::Vec2 pRef[2] = {
referenceCameraData.getProjectionReferencePoint(referenceNames[0]),
referenceCameraData.getProjectionReferencePoint(referenceNames[1])
};
// The first reference point transformed to this cameras projection space
osg::Vec3d pRefInThis0 = P.preMult(pPtoEye.preMult(osg::Vec3d(pRef[0], 1)));
// Translate this proejction matrix so that the first reference point is at the origin
P.postMultTranslate(-pRefInThis0);
// Transform the second reference point and get the scaling correct.
osg::Vec3d pRefInThis1 = P.preMult(pPtoEye.preMult(osg::Vec3d(pRef[1], 1)));
double s = osg::Vec2d(pRefInThis1[0], pRefInThis1[1]).length();
if (s <= std::numeric_limits<double>::min())
return false;
osg::Vec2 ref[2] = {
getProjectionReferencePoint(names[0]),
getProjectionReferencePoint(names[1])
};
s = (ref[0] - ref[1]).length()/s;
P.postMultScale(osg::Vec3d(s, s, 1));
// The first reference point still maps to the origin in this projection space.
// Translate the origin to the desired first reference point.
P.postMultTranslate(osg::Vec3d(ref[0], 1));
// Now osg::Matrix::inverse(pR*pP)*R*P should map pRef[i] exactly onto ref[i] for i = 0, 1.
// Note that osg::Matrix::inverse(pR*pP)*R*P should exactly map pRef[0] at the near plane
// to ref[0] at the near plane. The far plane is not taken care of.
Frustum frustum;
if (!frustum.setMatrix(P))
return false;
return setFrustum(frustum);
}
void
SlaveCamera::setProjectionReferencePoint(const std::string& name, const osg::Vec2& point)
{
_referencePointMap[name] = point;
}
osg::Vec2
SlaveCamera::getProjectionReferencePoint(const std::string& name) const
{
NameReferencePointMap::const_iterator i = _referencePointMap.find(name);
if (i != _referencePointMap.end())
return i->second;
return osg::Vec2(0, 0);
}
void
SlaveCamera::setMonitorProjectionReferences(double width, double height,
double bezelTop, double bezelBottom,
double bezelLeft, double bezelRight)
{
double left = 1 + 2*bezelLeft/width;
double right = 1 + 2*bezelRight/width;
double bottom = 1 + 2*bezelBottom/height;
double top = 1 + 2*bezelTop/height;
setProjectionReferencePoint("lowerLeft", osg::Vec2(-left, -bottom));
setProjectionReferencePoint("lowerRight", osg::Vec2(right, -bottom));
setProjectionReferencePoint("upperRight", osg::Vec2(right, top));
setProjectionReferencePoint("upperLeft", osg::Vec2(-left, top));
}
osg::Vec3
SlaveCamera::getLeftEyeOffset(const Viewer& viewer) const
{
#if 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
{
#if 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
{
#if 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

View File

@@ -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 <string>
#include <osg/Camera>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGWeakReferenced.hxx>
#include "Frustum.hxx"
namespace fgviewer {
class Viewer;
class SlaveCamera : public SGWeakReferenced {
public:
SlaveCamera(const std::string& name);
virtual ~SlaveCamera();
const std::string& getName() const
{ return _name; }
/// The drawable this camera renders to
bool setDrawableName(const std::string& drawableName);
const std::string& getDrawableName() const
{ return _drawableName; }
/// The viewport into the above drawable
virtual bool setViewport(const SGVec4i& viewport);
SGVec4i getViewport() const
{ return SGVec4i(_viewport->x(), _viewport->y(), _viewport->width(), _viewport->height()); }
double getAspectRatio() const
{ return _viewport->aspectRatio(); }
/// The view offset, usually an orientation offset
virtual bool setViewOffset(const osg::Matrix& viewOffset);
const osg::Matrix& getViewOffset() const
{ return _viewOffset; }
bool setViewOffsetDeg(double headingDeg, double pitchDeg, double rollDeg);
/// The frustum for this camera
virtual bool setFrustum(const Frustum& frustum);
const Frustum& getFrustum() const
{ return _frustum; }
void setFustumByFieldOfViewDeg(double fieldOfViewDeg);
bool setRelativeFrustum(const std::string names[2], const SlaveCamera& referenceCameraData,
const std::string referenceNames[2]);
/// For relative cameras configure the reference points that should match
void setProjectionReferencePoint(const std::string& name, const osg::Vec2& point);
osg::Vec2 getProjectionReferencePoint(const std::string& name) const;
/// Set the reference points for a monitor configuration
void setMonitorProjectionReferences(double width, double height,
double bezelTop, double bezelBottom,
double bezelLeft, double bezelRight);
/// Access parameters of this view/camera
osg::Vec3 getLeftEyeOffset(const Viewer& viewer) const;
osg::Vec3 getRightEyeOffset(const Viewer& viewer) const;
double getZoomFactor(const Viewer& viewer) const;
osg::Matrix getEffectiveViewOffset(const Viewer& viewer) const;
Frustum getEffectiveFrustum(const Viewer& viewer) const;
/// The top level camera holding the context
osg::Camera* getCamera()
{ return _camera.get(); }
/// Top level entry points
bool realize(Viewer& viewer);
bool update(Viewer& viewer);
protected:
virtual osg::Camera* _realizeImplementation(Viewer& viewer);
virtual bool _updateImplementation(Viewer& viewer);
private:
SlaveCamera(const SlaveCamera&);
SlaveCamera& operator=(const SlaveCamera&);
/// The immutable name that is used to reference this slave camera.
const std::string _name;
std::string _drawableName;
osg::ref_ptr<osg::Viewport> _viewport;
osg::Matrix _viewOffset;
Frustum _frustum;
/// The camera that is attached to the slave and that has a context attached.
osg::ref_ptr<osg::Camera> _camera;
/// For relative views, the named reference points in the projection space
typedef std::map<std::string, osg::Vec2> NameReferencePointMap;
NameReferencePointMap _referencePointMap;
};
} // namespace fgviewer
#endif

766
utils/fgviewer/Viewer.cxx Normal file
View File

@@ -0,0 +1,766 @@
// Viewer.cxx -- alternative flightgear viewer application
//
// Copyright (C) 2009 - 2012 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "Viewer.hxx"
#include <osg/Version>
#include <osg/ProxyNode>
#include <osg/PagedLOD>
#include <osgDB/ReadFile>
#ifdef __linux__
#include <X11/Xlib.h>
#include <osgViewer/api/X11/GraphicsWindowX11>
#endif
#include "MEncoderCaptureOperation.hxx"
#include "ArgumentParser.hxx"
#include <cassert>
namespace fgviewer {
Viewer::Viewer(ArgumentParser& arguments) :
osgViewer::Viewer(arguments.osg()),
_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();
#if 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()
{
#if FG_HAVE_HLA
if (_viewerFederate.valid()) {
if (_timeIncrement == SGTimeStamp::fromSec(0)) {
if (!_viewerFederate->timeAdvanceAvailable()) {
SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate update!");
_viewerFederate->shutdown();
_viewerFederate = 0;
}
} else {
osg::FrameStamp* frameStamp = getViewerFrameStamp();
SGTimeStamp timeStamp = SGTimeStamp::fromSec(frameStamp->getSimulationTime());
if (!_viewerFederate->timeAdvance(timeStamp)) {
SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate update!");
_viewerFederate->shutdown();
_viewerFederate = 0;
}
}
}
#endif
osgViewer::Viewer::updateTraversal();
if (!_renderer->update(*this)) {
SG_LOG(SG_VIEW, SG_ALERT, "Renderer::update() failed!");
}
}
bool
Viewer::updateSlaveCameras()
{
for (SlaveCameraVector::iterator i = _slaveCameraVector.begin(); i != _slaveCameraVector.end(); ++i) {
if (!(*i)->update(*this)) {
SG_LOG(SG_VIEW, SG_ALERT, "SlaveCamera::update() failed!");
return false;
}
}
return true;
}
void
Viewer::setReaderWriterOptions(simgear::SGReaderWriterOptions* readerWriterOptions)
{
_readerWriterOptions = readerWriterOptions;
}
simgear::SGReaderWriterOptions*
Viewer::getReaderWriterOptions()
{
return _readerWriterOptions.get();
}
void
Viewer::setSceneData(osg::Node* node)
{
_sceneDataGroup->removeChildren(0, _sceneDataGroup->getNumChildren());
insertSceneData(node);
}
void
Viewer::insertSceneData(osg::Node* node)
{
_sceneDataGroup->addChild(node);
}
bool
Viewer::insertSceneData(const std::string& fileName, const osgDB::Options* options)
{
#if 0
osg::ProxyNode* proxyNode = new osg::ProxyNode;
if (options)
proxyNode->setDatabaseOptions(options->clone(osg::CopyOp()));
else
proxyNode->setDatabaseOptions(_readerWriterOptions->clone(osg::CopyOp()));
proxyNode->setFileName(0, fileName);
insertSceneData(proxyNode);
return true;
#else
osg::ref_ptr<osg::Node> node = osgDB::readRefNodeFile(fileName, options);
if (!node.valid())
return false;
insertSceneData(node.get());
return true;
#endif
}
osg::Group*
Viewer::getSceneDataGroup()
{
return _sceneDataGroup.get();
}
class Viewer::_PurgeLevelOfDetailNodesVisitor : public osg::NodeVisitor {
public:
_PurgeLevelOfDetailNodesVisitor() :
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{ }
virtual ~_PurgeLevelOfDetailNodesVisitor()
{ }
virtual void apply(osg::ProxyNode& node)
{
for (unsigned i = 0; i < node.getNumChildren(); ++i) {
if (node.getFileName(i).empty())
continue;
node.removeChildren(i, node.getNumChildren() - i);
break;
}
osg::NodeVisitor::apply(static_cast<osg::Group&>(node));
}
virtual void apply(osg::PagedLOD& node)
{
for (unsigned i = 0; i < node.getNumChildren(); ++i) {
if (node.getFileName(i).empty())
continue;
node.removeChildren(i, node.getNumChildren() - i);
break;
}
osg::NodeVisitor::apply(static_cast<osg::Group&>(node));
}
};
void
Viewer::purgeLevelOfDetailNodes()
{
_PurgeLevelOfDetailNodesVisitor purgeLevelOfDetailNodesVisitor;
_sceneDataGroup->accept(purgeLevelOfDetailNodesVisitor);
}
osg::GraphicsContext::ScreenIdentifier
Viewer::getDefaultScreenIdentifier()
{
osg::GraphicsContext::ScreenIdentifier screenIdentifier;
screenIdentifier.readDISPLAY();
if (screenIdentifier.displayNum < 0)
screenIdentifier.displayNum = 0;
if (screenIdentifier.screenNum < 0)
screenIdentifier.screenNum = 0;
return screenIdentifier;
}
osg::GraphicsContext::ScreenIdentifier
Viewer::getScreenIdentifier(const std::string& display)
{
osg::GraphicsContext::ScreenIdentifier screenIdentifier;
screenIdentifier.setScreenIdentifier(display);
osg::GraphicsContext::ScreenIdentifier defaultScreenIdentifier;
defaultScreenIdentifier = getDefaultScreenIdentifier();
if (screenIdentifier.hostName.empty())
screenIdentifier.hostName = defaultScreenIdentifier.hostName;
if (screenIdentifier.displayNum < 0)
screenIdentifier.displayNum = defaultScreenIdentifier.displayNum;
if (screenIdentifier.screenNum < 0)
screenIdentifier.screenNum = defaultScreenIdentifier.screenNum;
return screenIdentifier;
}
osg::GraphicsContext::ScreenSettings
Viewer::getScreenSettings(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier)
{
osg::GraphicsContext::ScreenSettings screenSettings;
osg::GraphicsContext::WindowingSystemInterface* wsi;
wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi) {
SG_LOG(SG_VIEW, SG_ALERT, "No windowing system interface defined!");
return screenSettings;
}
wsi->getScreenSettings(screenIdentifier, screenSettings);
return screenSettings;
}
osg::GraphicsContext::Traits*
Viewer::getTraits(const osg::GraphicsContext::ScreenIdentifier& screenIdentifier)
{
osg::DisplaySettings* ds = _displaySettings.get();
if (!ds)
ds = osg::DisplaySettings::instance().get();
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits(ds);
traits->hostName = screenIdentifier.hostName;
traits->displayNum = screenIdentifier.displayNum;
traits->screenNum = screenIdentifier.screenNum;
// not seriously consider something different
traits->doubleBuffer = true;
osg::GraphicsContext::ScreenSettings screenSettings;
screenSettings = getScreenSettings(screenIdentifier);
traits->x = 0;
traits->y = 0;
traits->width = screenSettings.width;
traits->height = screenSettings.height;
return traits;
}
#ifdef __linux__
class Viewer::_ResetScreenSaverSwapCallback : public osg::GraphicsContext::SwapCallback {
public:
_ResetScreenSaverSwapCallback() :
_timeStamp(SGTimeStamp::fromSec(0))
{
}
virtual ~_ResetScreenSaverSwapCallback()
{
}
virtual void swapBuffersImplementation(osg::GraphicsContext* graphicsContext)
{
graphicsContext->swapBuffersImplementation();
// This callback must be attached to this type of graphics context
assert(dynamic_cast<osgViewer::GraphicsWindowX11*>(graphicsContext));
// Reset the screen saver every 10 seconds
SGTimeStamp timeStamp = SGTimeStamp::now();
if (timeStamp < _timeStamp)
return;
_timeStamp = timeStamp + SGTimeStamp::fromSec(10);
// Obviously runs in the draw thread. Thus, use the draw display.
XResetScreenSaver(static_cast<osgViewer::GraphicsWindowX11*>(graphicsContext)->getDisplay());
}
private:
SGTimeStamp _timeStamp;
};
#endif
osg::GraphicsContext*
Viewer::createGraphicsContext(osg::GraphicsContext::Traits* traits)
{
osg::GraphicsContext::WindowingSystemInterface* wsi;
wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi) {
SG_LOG(SG_VIEW, SG_ALERT, "No windowing system interface defined!");
return 0;
}
osg::GraphicsContext* graphicsContext = wsi->createGraphicsContext(traits);
if (!graphicsContext) {
SG_LOG(SG_VIEW, SG_ALERT, "Unable to create window \"" << traits->windowName << "\"!");
return 0;
}
#ifdef __linux__
if (dynamic_cast<osgViewer::GraphicsWindowX11*>(graphicsContext))
graphicsContext->setSwapCallback(new _ResetScreenSaverSwapCallback);
#endif
return graphicsContext;
}
#if 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

158
utils/fgviewer/Viewer.hxx Normal file
View File

@@ -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 <osgViewer/Viewer>
#include <simgear/math/SGMath.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/timing/timestamp.hxx>
#include <simgear/props/props.hxx>
#include "Drawable.hxx"
#include "Frustum.hxx"
#include "Renderer.hxx"
#include "SlaveCamera.hxx"
#include "ArgumentParser.hxx"
#if FG_HAVE_HLA
#include "HLAViewerFederate.hxx"
#endif
namespace fgviewer {
class Viewer : public osgViewer::Viewer {
public:
Viewer(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);
#if FG_HAVE_HLA
/// The federate if configured, can only be set once
const HLAViewerFederate* getViewerFederate() const;
HLAViewerFederate* getViewerFederate();
void setViewerFederate(HLAViewerFederate* viewerFederate);
#endif
private:
Viewer(const Viewer&);
Viewer& operator=(const Viewer&);
/// Unload all lod's
class _PurgeLevelOfDetailNodesVisitor;
#ifdef __linux__
/// Under linux make sure that the screen saver does not jump in
class _ResetScreenSaverSwapCallback;
#endif
/// The renderer used to setup the higher level camera/scenegraph structure
SGSharedPtr<Renderer> _renderer;
/// The drawables managed by this viewer.
typedef std::vector<SGSharedPtr<Drawable> > DrawableVector;
DrawableVector _drawableVector;
/// The slave cameras for this viewer.
/// Since we support more complex renderers, we can not only use osg::View::Slave.
typedef std::vector<SGSharedPtr<SlaveCamera> > SlaveCameraVector;
SlaveCameraVector _slaveCameraVector;
/// The top level options struct
osg::ref_ptr<simgear::SGReaderWriterOptions> _readerWriterOptions;
/// The top level scenegraph structure that is used for drawing
osg::ref_ptr<osg::Group> _sceneDataGroup;
/// Stores the time increment for each frame.
/// If zero, the time advance is done to the current real time.
SGTimeStamp _timeIncrement;
/// The current simulation time of the viewer
SGTimeStamp _simTime;
#if FG_HAVE_HLA
/// The federate if configured
SGSharedPtr<HLAViewerFederate> _viewerFederate;
#endif
};
} // namespace fgviewer
#endif

275
utils/fgviewer/fgviewer.cxx Normal file
View File

@@ -0,0 +1,275 @@
// fgviewer.cxx -- alternative flightgear viewer application
//
// Copyright (C) 2009 - 2012 Mathias Froehlich
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <osg/Version>
#include <osgDB/ReadFile>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/TerrainManipulator>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/model/ModelRegistry.hxx>
#include <simgear/misc/ResourceManager.hxx>
#include "ArgumentParser.hxx"
#include "Renderer.hxx"
#include "Viewer.hxx"
#if FG_HAVE_HLA
#include "HLACameraManipulator.hxx"
#include "HLAViewerFederate.hxx"
#endif
int
main(int argc, char** argv)
{
/// Read arguments and environment variables.
ArgumentParser arguments(argc, argv);
sglog().set_log_classes(SG_ALL);
sglog().set_log_priority(SG_ALERT);
SGPath fg_root;
std::string r;
if (arguments.read("--fg-root", r)) {
fg_root = SGPath::fromLocal8Bit(r.c_str());
} else if (std::getenv("FG_ROOT")) {
fg_root = SGPath::fromEnv("FG_ROOT");
} else {
fg_root = SGPath(PKGLIBDIR);
}
SGPath fg_scenery;
std::string s;
if (arguments.read("--fg-scenery", s)) {
fg_scenery = SGPath::fromLocal8Bit(s.c_str());
} else if (std::getenv("FG_SCENERY")) {
fg_scenery = SGPath::fromEnv("FG_SCENERY");
} else {
SGPath path(fg_root);
path.append("Scenery");
fg_scenery = path;
}
SGSharedPtr<SGPropertyNode> props = new SGPropertyNode;
try {
SGPath preferencesFile = fg_root;
preferencesFile.append("defaults.xml");
readProperties(preferencesFile, props);
} catch (...) {
// In case of an error, at least make summer :)
props->getNode("sim/startup/season", true)->setStringValue("summer");
SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear preferences.\n"
<< "Probably FG_ROOT is not properly set.");
}
std::string config;
while (arguments.read("--config", config)) {
try {
readProperties(config, props);
} catch (...) {
SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading config file \"" << config
<< "\" given on the command line.");
}
}
std::string prop, value;
while (arguments.read("--prop", prop, value)) {
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.
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;
keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
keyswitchManipulator->addMatrixManipulator('1', "Trackball",
new osgGA::TrackballManipulator);
keyswitchManipulator->addMatrixManipulator('2', "Flight",
new osgGA::FlightManipulator);
keyswitchManipulator->addMatrixManipulator('3', "Drive",
new osgGA::DriveManipulator);
keyswitchManipulator->addMatrixManipulator('4', "Terrain",
new osgGA::TerrainManipulator);
viewer.setCameraManipulator(keyswitchManipulator);
// Usefull stats
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getSceneDataGroup()->getOrCreateStateSet()));
viewer.addEventHandler(new osgViewer::HelpHandler);
viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.addEventHandler(new osgViewer::ThreadingHandler);
viewer.addEventHandler(new osgViewer::LODScaleHandler);
viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer.addEventHandler(new osgViewer::WindowSizeHandler);
// We want on demand database paging
viewer.setDatabasePager(new osgDB::DatabasePager);
viewer.getDatabasePager()->setUpThreads(1, 1);
/// now set up the simgears required model stuff
simgear::ResourceManager::instance()->addBasePath(fg_root, simgear::ResourceManager::PRIORITY_DEFAULT);
// Just reference simgears reader writer stuff so that the globals get
// pulled in by the linker ...
// FIXME: make that more explicit clear and call an initialization function
simgear::ModelRegistry::instance();
// FIXME Ok, replace this by querying the root of the property tree
sgUserDataInit(props.get());
SGSceneFeatures::instance()->setTextureCompression(SGSceneFeatures::DoNotUseCompression);
SGMaterialLibPtr ml = new SGMaterialLib;
SGPath mpath(fg_root);
mpath.append("Materials/default/materials.xml");
try {
ml->load(fg_root.local8BitStr(), mpath.local8BitStr(), props);
} catch (...) {
SG_LOG(SG_GENERAL, SG_ALERT, "Problems loading FlightGear materials.\n"
<< "Probably FG_ROOT is not properly set.");
}
simgear::SGModelLib::init(fg_root.local8BitStr(), props);
// Set up the reader/writer options
osg::ref_ptr<simgear::SGReaderWriterOptions> options;
if (osgDB::Options* ropt = osgDB::Registry::instance()->getOptions())
options = new simgear::SGReaderWriterOptions(*ropt);
else
options = new simgear::SGReaderWriterOptions;
osgDB::convertStringPathIntoFilePathList(fg_scenery.local8BitStr(),
options->getDatabasePathList());
options->setMaterialLib(ml);
options->setPropertyNode(props);
options->setPluginStringData("SimGear::FG_ROOT", fg_root.local8BitStr());
// Omit building bounding volume trees, as the viewer will not run a simulation
options->setPluginStringData("SimGear::BOUNDINGVOLUMES", "OFF");
GLint max_texture_size;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
options->setPluginStringData("SimGear::MAXTEXTURESIZE", std::to_string(max_texture_size? max_texture_size:8192));
viewer.setReaderWriterOptions(options.get());
// Here, all arguments are processed
arguments.reportRemainingOptionsAsUnrecognized();
arguments.writeErrorMessages(std::cerr);
if (props->getNode("hla/federate/federation")) {
#if FG_HAVE_HLA
const SGPropertyNode* federateNode = props->getNode("hla/federate");
SGSharedPtr<fgviewer::HLAViewerFederate> viewerFederate;
viewerFederate = new fgviewer::HLAViewerFederate;
viewerFederate->setVersion(federateNode->getStringValue("version", "RTI13"));
// viewerFederate->setConnectArguments(federateNode->getStringValue("connect-arguments", ""));
viewerFederate->setFederateType(federateNode->getStringValue("type", "ViewerFederate"));
viewerFederate->setFederateName(federateNode->getStringValue("name", ""));
viewerFederate->setFederationExecutionName(federateNode->getStringValue("federation", ""));
std::string objectModel;
objectModel = federateNode->getStringValue("federation-object-model", "HLA/fg-local-fom.xml");
if (SGPath(objectModel).isRelative()) {
SGPath path = fg_root;
path.append(objectModel);
objectModel = path.str();
}
viewerFederate->setFederationObjectModel(objectModel);
if (!viewerFederate->init()) {
SG_LOG(SG_NETWORK, SG_ALERT, "Got error from federate init!");
} else {
viewer.setViewerFederate(viewerFederate.get());
viewer.setCameraManipulator(new fgviewer::HLACameraManipulator(viewerFederate->getViewer()));
}
#else
SG_LOG(SG_GENERAL, SG_ALERT, "Unable to enter HLA/RTI viewer mode: HLA/RTI disabled at compile time.");
#endif
}
/// Read the model files that are configured.
osg::ref_ptr<osg::Node> loadedModel;
if (1 < arguments.argc()) {
// read the scene from the list of file specified command line args.
loadedModel = osgDB::readRefNodeFiles(arguments, options.get());
} else {
// if no arguments given resort to the whole world scenery
options->setPluginStringData("SimGear::FG_EARTH", "ON");
loadedModel = osgDB::readRefNodeFile("w180s90-360x180.spt", options.get());
}
// if no model has been successfully loaded report failure.
if (!loadedModel.valid()) {
SG_LOG(SG_GENERAL, SG_ALERT, arguments.getApplicationName()
<< ": No data loaded");
return EXIT_FAILURE;
}
// pass the loaded scene graph to the viewer.
viewer.insertSceneData(loadedModel.get());
// Note that this does not affect the hla camera manipulator
viewer.home();
return viewer.run();
}