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 - curt@flightgear.org
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., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <string.h> // strcmp
28 #include <GUI/sgVec3Slider.hxx> // FIXME: this should NOT be needed
30 #include "viewmgr.hxx"
31 #include "fg_props.hxx"
35 FGViewMgr::FGViewMgr( void ) :
44 FGViewMgr::~FGViewMgr( void ) {
50 add_view(new FGViewer, 0);
51 add_view(new FGViewer, 1);
54 typedef double (FGViewMgr::*double_getter)() const;
59 fgTie("/sim/view/offset-deg", this,
60 &FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg);
61 fgSetArchivable("/sim/view/offset-deg");
62 fgTie("/sim/view/goal-offset-deg", this,
63 &FGViewMgr::getGoalViewOffset_deg, &FGViewMgr::setGoalViewOffset_deg);
64 fgSetArchivable("/sim/view/goal-offset-deg");
65 fgTie("/sim/view/tilt-deg", this,
66 &FGViewMgr::getViewTilt_deg, &FGViewMgr::setViewTilt_deg);
67 fgSetArchivable("/sim/view/tilt-deg");
68 fgTie("/sim/view/goal-tilt-deg", this,
69 &FGViewMgr::getGoalViewTilt_deg, &FGViewMgr::setGoalViewTilt_deg);
70 fgSetArchivable("/sim/view/goal-tilt-deg");
71 fgTie("/sim/view/pilot/x-offset-m", this,
72 &FGViewMgr::getPilotXOffset_m, &FGViewMgr::setPilotXOffset_m);
73 fgSetArchivable("/sim/view/pilot/x-offset-m");
74 fgTie("/sim/view/pilot/y-offset-m", this,
75 &FGViewMgr::getPilotYOffset_m, &FGViewMgr::setPilotYOffset_m);
76 fgSetArchivable("/sim/view/pilot/y-offset-m");
77 fgTie("/sim/view/pilot/z-offset-m", this,
78 &FGViewMgr::getPilotZOffset_m, &FGViewMgr::setPilotZOffset_m);
79 fgSetArchivable("/sim/view/pilot/z-offset-m");
80 fgTie("/sim/field-of-view", this,
81 &FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
82 fgSetArchivable("/sim/field-of-view");
83 fgTie("/sim/view/axes/long", this,
84 (double_getter)0, &FGViewMgr::setViewAxisLong);
85 fgTie("/sim/view/axes/lat", this,
86 (double_getter)0, &FGViewMgr::setViewAxisLat);
92 fgUntie("/sim/view/offset-deg");
93 fgUntie("/sim/view/goal-offset-deg");
94 fgUntie("/sim/view/tilt-deg");
95 fgUntie("/sim/view/goal-tilt-deg");
96 fgUntie("/sim/view/pilot/x-offset-m");
97 fgUntie("/sim/view/pilot/y-offset-m");
98 fgUntie("/sim/view/pilot/z-offset-m");
99 fgUntie("/sim/field-of-view");
100 fgUntie("/sim/view/axes/long");
101 fgUntie("/sim/view/axes/lat");
105 FGViewMgr::update (int dt)
107 FGViewer * view = get_current_view();
111 // Grab some values we'll need.
112 double lon_rad = fgGetDouble("/position/longitude-deg")
113 * SGD_DEGREES_TO_RADIANS;
114 double lat_rad = fgGetDouble("/position/latitude-deg")
115 * SGD_DEGREES_TO_RADIANS;
116 double alt_m = fgGetDouble("/position/altitude-ft")
118 double roll_rad = fgGetDouble("/orientation/roll-deg")
119 * SGD_DEGREES_TO_RADIANS;
120 double pitch_rad = fgGetDouble("/orientation/pitch-deg")
121 * SGD_DEGREES_TO_RADIANS;
122 double heading_rad = fgGetDouble("/orientation/heading-deg")
123 * SGD_DEGREES_TO_RADIANS;
125 // Set up the pilot view
126 FGViewer *pilot_view = (FGViewer *)get_view( 0 );
127 pilot_view ->setPosition(
128 fgGetDouble("/position/longitude-deg"),
129 fgGetDouble("/position/latitude-deg"),
130 fgGetDouble("/position/altitude-ft"));
131 pilot_view->setOrientation(
132 fgGetDouble("/orientation/roll-deg"),
133 fgGetDouble("/orientation/pitch-deg"),
134 fgGetDouble("/orientation/heading-deg"));
135 if (!strcmp(fgGetString("/sim/flight-model"), "ada")) {
136 //+ve x is aft, +ve z is up (see viewer.hxx)
137 pilot_view->setPositionOffsets( -5.0, 0.0, 1.0 );
140 // Set up the chase view
142 FGViewer *chase_view = (FGViewer *)get_view( 1 );
144 // get xyz Position offsets directly from GUI/sgVec3Slider
145 // FIXME: change GUI/sgVec3Slider to store the xyz in properties
146 // it would probably be faster than the way PilotOffsetGet()
147 // triggers a recalc all the time.
148 sgVec3 *pPO = PilotOffsetGet();
150 sgCopyVec3( zPO, *pPO );
151 chase_view->setPositionOffsets(zPO[1], zPO[0], zPO[2] );
153 chase_view->setOrientation(
154 fgGetDouble("/orientation/roll-deg"),
155 fgGetDouble("/orientation/pitch-deg"),
156 fgGetDouble("/orientation/heading-deg"));
157 chase_view ->setPosition(
158 fgGetDouble("/position/longitude-deg"),
159 fgGetDouble("/position/latitude-deg"),
160 fgGetDouble("/position/altitude-ft"));
161 chase_view ->setTargetPosition(
162 fgGetDouble("/position/longitude-deg"),
163 fgGetDouble("/position/latitude-deg"),
164 fgGetDouble("/position/altitude-ft"));
166 // Update the current view
172 FGViewMgr::getViewOffset_deg () const
174 const FGViewer * view = get_current_view();
175 return (view == 0 ? 0 : view->getHeadingOffset_deg());
179 FGViewMgr::setViewOffset_deg (double offset)
181 FGViewer * view = get_current_view();
183 view->setGoalHeadingOffset_deg(offset);
184 view->setHeadingOffset_deg(offset);
189 FGViewMgr::getGoalViewOffset_deg () const
191 const FGViewer * view = get_current_view();
192 return (view == 0 ? 0 : view->getGoalHeadingOffset_deg());
196 FGViewMgr::setGoalViewOffset_deg (double offset)
198 FGViewer * view = get_current_view();
200 view->setGoalHeadingOffset_deg(offset);
204 FGViewMgr::getViewTilt_deg () const
206 const FGViewer * view = get_current_view();
207 return (view == 0 ? 0 : view->getPitchOffset_deg());
211 FGViewMgr::setViewTilt_deg (double tilt)
213 FGViewer * view = get_current_view();
215 view->setGoalPitchOffset_deg(tilt);
216 view->setPitchOffset_deg(tilt);
221 FGViewMgr::getGoalViewTilt_deg () const
223 const FGViewer * view = get_current_view();
224 return (view == 0 ? 0 : view->getGoalPitchOffset_deg());
228 FGViewMgr::setGoalViewTilt_deg (double tilt)
230 FGViewer * view = get_current_view();
232 view->setGoalPitchOffset_deg(tilt);
236 FGViewMgr::getPilotXOffset_m () const
238 // FIXME: hard-coded pilot view position
239 const FGViewer * pilot_view = get_view(0);
240 if (pilot_view != 0) {
241 return ((FGViewer *)pilot_view)->getXOffset_m();
248 FGViewMgr::setPilotXOffset_m (double x)
250 // FIXME: hard-coded pilot view position
251 FGViewer * pilot_view = get_view(0);
252 if (pilot_view != 0) {
253 pilot_view->setXOffset_m(x);
258 FGViewMgr::getPilotYOffset_m () const
260 // FIXME: hard-coded pilot view position
261 const FGViewer * pilot_view = get_view(0);
262 if (pilot_view != 0) {
263 return ((FGViewer *)pilot_view)->getYOffset_m();
270 FGViewMgr::setPilotYOffset_m (double y)
272 // FIXME: hard-coded pilot view position
273 FGViewer * pilot_view = get_view(0);
274 if (pilot_view != 0) {
275 pilot_view->setYOffset_m(y);
280 FGViewMgr::getPilotZOffset_m () const
282 // FIXME: hard-coded pilot view position
283 const FGViewer * pilot_view = get_view(0);
284 if (pilot_view != 0) {
285 return ((FGViewer *)pilot_view)->getZOffset_m();
292 FGViewMgr::setPilotZOffset_m (double z)
294 // FIXME: hard-coded pilot view position
295 FGViewer * pilot_view = get_view(0);
296 if (pilot_view != 0) {
297 pilot_view->setZOffset_m(z);
302 FGViewMgr::getFOV_deg () const
304 const FGViewer * view = get_current_view();
305 return (view == 0 ? 0 : view->get_fov());
309 FGViewMgr::setFOV_deg (double fov)
311 FGViewer * view = get_current_view();
317 FGViewMgr::setViewAxisLong (double axis)
323 FGViewMgr::setViewAxisLat (double axis)
329 FGViewMgr::do_axes ()
331 // Take no action when hat is centered
332 if ( ( axis_long < 0.01 ) &&
333 ( axis_long > -0.01 ) &&
334 ( axis_lat < 0.01 ) &&
339 double viewDir = 999;
341 /* Do all the quick and easy cases */
342 if (axis_long < 0) { // Longitudinal axis forward
343 if (axis_lat == axis_long)
345 else if (axis_lat == - axis_long)
347 else if (axis_lat == 0)
349 } else if (axis_long > 0) { // Longitudinal axis backward
350 if (axis_lat == - axis_long)
352 else if (axis_lat == axis_long)
354 else if (axis_lat == 0)
356 } else if (axis_long == 0) { // Longitudinal axis neutral
359 else if (axis_lat > 0)
361 else return; /* And assertion failure maybe? */
364 // Do all the difficult cases
366 viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
367 if ( viewDir < -1 ) viewDir += 360;
369 get_current_view()->setGoalHeadingOffset_deg(viewDir);