1 // viewmgr.cxx -- class for managing all the views in the flightgear world.
3 // Written by Curtis Olson, started October 2000.
4 // partially rewritten by Jim Wilson March 2002
6 // Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include "viewmgr.hxx"
30 #include <simgear/compiler.h>
31 #include <simgear/scene/util/OsgMath.hxx>
33 #include <Main/fg_props.hxx>
36 #include "CameraGroup.hxx"
39 FGViewMgr::FGViewMgr( void ) :
41 config_list(fgGetNode("/sim", true)->getChildren("view")),
47 FGViewMgr::~FGViewMgr( void )
55 SG_LOG(SG_VIEW, SG_WARN, "duplicate init of view manager");
61 for (unsigned int i = 0; i < config_list.size(); i++) {
62 SGPropertyNode *n = config_list[i];
63 SGPropertyNode *config = n->getChild("config", 0, true);
65 flightgear::View* v = flightgear::View::createFromProperties(config);
71 get_current_view()->bind();
77 // force update now so many properties of the current view are valid,
78 // eg view position and orientation (as exposed via globals)
96 viewer_list::iterator it;
97 for (it = views.begin(); it != views.end(); ++it) {
98 (*it)->resetOffsetsAndFOV();
105 // these are bound to the current view properties
106 _tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
109 _tiedProperties.Tie("view-number", this,
110 &FGViewMgr::getView, &FGViewMgr::setView, false);
111 _viewNumberProp = _tiedProperties.getRoot()->getNode("view-number");
112 _viewNumberProp->setAttribute(SGPropertyNode::ARCHIVE, false);
113 _viewNumberProp->setAttribute(SGPropertyNode::PRESERVE, true);
120 flightgear::View* v = get_current_view();
125 _tiedProperties.Untie();
126 _viewNumberProp.clear();
130 FGViewMgr::update (double dt)
132 flightgear::View* currentView = get_current_view();
137 // Update the current view
138 currentView->update(dt);
141 // update the camera now
142 osg::ref_ptr<flightgear::CameraGroup> cameraGroup = flightgear::CameraGroup::getDefault();
143 cameraGroup->update(toOsg(currentView->getViewPosition()),
144 toOsg(currentView->getViewOrientation()));
145 cameraGroup->setCameraParameters(currentView->get_v_fov(),
146 cameraGroup->getMasterAspectRatio());
149 void FGViewMgr::clear()
155 FGViewMgr::get_current_view()
157 if ( current < (int)views.size() ) {
158 return views[current];
164 const flightgear::View*
165 FGViewMgr::get_current_view() const
167 if ( current < (int)views.size() ) {
168 return views[current];
176 FGViewMgr::get_view( int i )
178 if ( i < 0 ) { i = 0; }
179 if ( i >= (int)views.size() ) { i = views.size() - 1; }
183 const flightgear::View*
184 FGViewMgr::get_view( int i ) const
186 if ( i < 0 ) { i = 0; }
187 if ( i >= (int)views.size() ) { i = views.size() - 1; }
192 FGViewMgr::next_view()
194 setView((current+1 < (int)views.size()) ? (current + 1) : 0);
195 _viewNumberProp->fireValueChanged();
196 return views[current];
200 FGViewMgr::prev_view()
202 setView((0 < current) ? (current - 1) : (views.size() - 1));
203 _viewNumberProp->fireValueChanged();
204 return views[current];
208 FGViewMgr::add_view( flightgear::View * v )
214 int FGViewMgr::getView () const
220 FGViewMgr::setView (int newview)
222 if (newview == current) {
226 // negative numbers -> set view with node index -newview
228 for (int i = 0; i < (int)config_list.size(); i++) {
229 int index = -config_list[i]->getIndex();
230 if (index == newview)
237 // if newview number too low wrap to last view...
239 newview = (int)views.size() - 1;
241 // if newview number to high wrap to zero...
242 if (newview >= (int)views.size())
245 if (get_current_view()) {
246 get_current_view()->unbind();
252 if (get_current_view()) {
253 get_current_view()->bind();
256 // force an update now, to avoid returning bogus data.
257 // real fix would to be make all the accessors use the dirty mechanism
258 // on FGViewer, so update() is a no-op.