flightgear/utils/fgviewer/HLAViewerFederate.cxx
2022-10-20 20:29:11 +08:00

254 lines
6.9 KiB
C++

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