Use a new SGPropertyNode flag, LISTENER_SAFE, to white-list properties where we do correctly fire listeners, and test this flag when listening from Nasal, to avoid the warning.
263 lines
5.7 KiB
C++
263 lines
5.7 KiB
C++
// viewmgr.cxx -- class for managing all the views in the flightgear world.
|
|
//
|
|
// Written by Curtis Olson, started October 2000.
|
|
// partially rewritten by Jim Wilson March 2002
|
|
//
|
|
// Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
|
|
//
|
|
// 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.
|
|
//
|
|
// $Id$
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include "viewmgr.hxx"
|
|
#include "ViewPropertyEvaluator.hxx"
|
|
|
|
#include <simgear/compiler.h>
|
|
#include <simgear/scene/util/OsgMath.hxx>
|
|
|
|
#include <Main/fg_props.hxx>
|
|
#include "view.hxx"
|
|
|
|
#include "CameraGroup.hxx"
|
|
|
|
// Constructor
|
|
FGViewMgr::FGViewMgr( void ) :
|
|
inited(false),
|
|
config_list(fgGetNode("/sim", true)->getChildren("view"))
|
|
{
|
|
current = fgGetInt("/sim/current-view/view-number");
|
|
}
|
|
|
|
// Destructor
|
|
FGViewMgr::~FGViewMgr( void )
|
|
{
|
|
}
|
|
|
|
void
|
|
FGViewMgr::init ()
|
|
{
|
|
if (inited) {
|
|
SG_LOG(SG_VIEW, SG_WARN, "duplicate init of view manager");
|
|
return;
|
|
}
|
|
|
|
inited = true;
|
|
|
|
for (unsigned int i = 0; i < config_list.size(); i++) {
|
|
SGPropertyNode *n = config_list[i];
|
|
SGPropertyNode *config = n->getChild("config", 0, true);
|
|
|
|
flightgear::View* v = flightgear::View::createFromProperties(config, n->getIndex());
|
|
if (v) {
|
|
add_view(v);
|
|
}
|
|
}
|
|
|
|
get_current_view()->bind();
|
|
}
|
|
|
|
void
|
|
FGViewMgr::postinit()
|
|
{
|
|
// force update now so many properties of the current view are valid,
|
|
// eg view position and orientation (as exposed via globals)
|
|
update(0.0);
|
|
}
|
|
|
|
void
|
|
FGViewMgr::shutdown()
|
|
{
|
|
if (!inited) {
|
|
return;
|
|
}
|
|
|
|
inited = false;
|
|
views.clear();
|
|
}
|
|
|
|
void
|
|
FGViewMgr::reinit ()
|
|
{
|
|
viewer_list::iterator it;
|
|
for (it = views.begin(); it != views.end(); ++it) {
|
|
(*it)->resetOffsetsAndFOV();
|
|
}
|
|
}
|
|
|
|
void
|
|
FGViewMgr::bind()
|
|
{
|
|
// these are bound to the current view properties
|
|
_tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
|
|
|
|
|
|
_tiedProperties.Tie("view-number", this,
|
|
&FGViewMgr::getView, &FGViewMgr::setView, false);
|
|
_viewNumberProp = _tiedProperties.getRoot()->getNode("view-number");
|
|
_viewNumberProp->setAttribute(SGPropertyNode::ARCHIVE, false);
|
|
_viewNumberProp->setAttribute(SGPropertyNode::PRESERVE, true);
|
|
_viewNumberProp->setAttribute(SGPropertyNode::LISTENER_SAFE, true);
|
|
}
|
|
|
|
|
|
void
|
|
FGViewMgr::unbind ()
|
|
{
|
|
flightgear::View* v = get_current_view();
|
|
if (v) {
|
|
v->unbind();
|
|
}
|
|
|
|
_tiedProperties.Untie();
|
|
_viewNumberProp.clear();
|
|
|
|
ViewPropertyEvaluator::clear();
|
|
}
|
|
|
|
void
|
|
FGViewMgr::update (double dt)
|
|
{
|
|
flightgear::View* currentView = get_current_view();
|
|
if (!currentView) {
|
|
return;
|
|
}
|
|
|
|
// Update the current view
|
|
currentView->update(dt);
|
|
|
|
// update the camera now
|
|
osg::ref_ptr<flightgear::CameraGroup> cameraGroup = flightgear::CameraGroup::getDefault();
|
|
cameraGroup->setCameraParameters(currentView->get_v_fov(),
|
|
cameraGroup->getMasterAspectRatio());
|
|
cameraGroup->update(toOsg(currentView->getViewPosition()),
|
|
toOsg(currentView->getViewOrientation()));
|
|
}
|
|
|
|
void FGViewMgr::clear()
|
|
{
|
|
views.clear();
|
|
}
|
|
|
|
flightgear::View*
|
|
FGViewMgr::get_current_view()
|
|
{
|
|
if ( current < (int)views.size() ) {
|
|
return views[current];
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
const flightgear::View*
|
|
FGViewMgr::get_current_view() const
|
|
{
|
|
if ( current < (int)views.size() ) {
|
|
return views[current];
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
flightgear::View*
|
|
FGViewMgr::get_view( int i )
|
|
{
|
|
if ( i < 0 ) { i = 0; }
|
|
if ( i >= (int)views.size() ) { i = views.size() - 1; }
|
|
return views[i];
|
|
}
|
|
|
|
const flightgear::View*
|
|
FGViewMgr::get_view( int i ) const
|
|
{
|
|
if ( i < 0 ) { i = 0; }
|
|
if ( i >= (int)views.size() ) { i = views.size() - 1; }
|
|
return views[i];
|
|
}
|
|
|
|
flightgear::View*
|
|
FGViewMgr::next_view()
|
|
{
|
|
setView((current+1 < (int)views.size()) ? (current + 1) : 0);
|
|
_viewNumberProp->fireValueChanged();
|
|
return views[current];
|
|
}
|
|
|
|
flightgear::View*
|
|
FGViewMgr::prev_view()
|
|
{
|
|
setView((0 < current) ? (current - 1) : (views.size() - 1));
|
|
_viewNumberProp->fireValueChanged();
|
|
return views[current];
|
|
}
|
|
|
|
void
|
|
FGViewMgr::add_view( flightgear::View * v )
|
|
{
|
|
views.push_back(v);
|
|
v->init();
|
|
}
|
|
|
|
int FGViewMgr::getView () const
|
|
{
|
|
return current;
|
|
}
|
|
|
|
void
|
|
FGViewMgr::setView (int newview)
|
|
{
|
|
if (newview == current) {
|
|
return;
|
|
}
|
|
|
|
// negative numbers -> set view with node index -newview
|
|
if (newview < 0) {
|
|
for (int i = 0; i < (int)config_list.size(); i++) {
|
|
int index = -config_list[i]->getIndex();
|
|
if (index == newview)
|
|
newview = i;
|
|
}
|
|
if (newview < 0)
|
|
return;
|
|
}
|
|
|
|
// if newview number too low wrap to last view...
|
|
if (newview < 0)
|
|
newview = (int)views.size() - 1;
|
|
|
|
// if newview number to high wrap to zero...
|
|
if (newview >= (int)views.size())
|
|
newview = 0;
|
|
|
|
if (get_current_view()) {
|
|
get_current_view()->unbind();
|
|
}
|
|
|
|
// set new view
|
|
current = newview;
|
|
|
|
if (get_current_view()) {
|
|
get_current_view()->bind();
|
|
}
|
|
}
|
|
|
|
|
|
// Register the subsystem.
|
|
SGSubsystemMgr::Registrant<FGViewMgr> registrantFGViewMgr(
|
|
SGSubsystemMgr::DISPLAY);
|