]> git.mxchange.org Git - flightgear.git/blob - src/Main/viewmgr.cxx
27410d4c49a5991e86d79d9838d7bb3b8ddfa731
[flightgear.git] / src / Main / viewmgr.cxx
1 // viewmgr.cxx -- class for managing all the views in the flightgear world.
2 //
3 // Written by Curtis Olson, started October 2000.
4 //   partially rewritten by Jim Wilson March 2002
5 //
6 // Copyright (C) 2000  Curtis L. Olson  - curt@flightgear.org
7 //
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.
12 //
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.
17 //
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.
21 //
22 // $Id$
23
24 #include <plib/sg.h>
25
26 #include <GUI/sgVec3Slider.hxx> // FIXME: this should NOT be needed
27
28 #include "viewmgr.hxx"
29 #include "fg_props.hxx"
30
31
32 // Constructor
33 FGViewMgr::FGViewMgr( void ) :
34   axis_long(0),
35   axis_lat(0),
36   current(0)
37 {
38 }
39
40
41 // Destructor
42 FGViewMgr::~FGViewMgr( void ) {
43 }
44
45 void
46 FGViewMgr::init ()
47 {
48   add_view(new FGViewer, 0);
49   add_view(new FGViewer, 1);
50 }
51
52 typedef double (FGViewMgr::*double_getter)() const;
53
54 void
55 FGViewMgr::bind ()
56 {
57   fgTie("/sim/view/offset-deg", this,
58         &FGViewMgr::getViewOffset_deg, &FGViewMgr::setViewOffset_deg);
59   fgSetArchivable("/sim/view/offset-deg");
60   fgTie("/sim/view/goal-offset-deg", this,
61         &FGViewMgr::getGoalViewOffset_deg, &FGViewMgr::setGoalViewOffset_deg);
62   fgSetArchivable("/sim/view/goal-offset-deg");
63   fgTie("/sim/view/tilt-deg", this,
64         &FGViewMgr::getViewTilt_deg, &FGViewMgr::setViewTilt_deg);
65   fgSetArchivable("/sim/view/tilt-deg");
66   fgTie("/sim/view/goal-tilt-deg", this,
67         &FGViewMgr::getGoalViewTilt_deg, &FGViewMgr::setGoalViewTilt_deg);
68   fgSetArchivable("/sim/view/goal-tilt-deg");
69   fgTie("/sim/view/pilot/x-offset-m", this,
70         &FGViewMgr::getPilotXOffset_m, &FGViewMgr::setPilotXOffset_m);
71   fgSetArchivable("/sim/view/pilot/x-offset-m");
72   fgTie("/sim/view/pilot/y-offset-m", this,
73         &FGViewMgr::getPilotYOffset_m, &FGViewMgr::setPilotYOffset_m);
74   fgSetArchivable("/sim/view/pilot/y-offset-m");
75   fgTie("/sim/view/pilot/z-offset-m", this,
76         &FGViewMgr::getPilotZOffset_m, &FGViewMgr::setPilotZOffset_m);
77   fgSetArchivable("/sim/view/pilot/z-offset-m");
78   fgTie("/sim/field-of-view", this,
79         &FGViewMgr::getFOV_deg, &FGViewMgr::setFOV_deg);
80   fgSetArchivable("/sim/field-of-view");
81   fgTie("/sim/view/axes/long", this,
82         (double_getter)0, &FGViewMgr::setViewAxisLong);
83   fgTie("/sim/view/axes/lat", this,
84         (double_getter)0, &FGViewMgr::setViewAxisLat);
85 }
86
87 void
88 FGViewMgr::unbind ()
89 {
90   fgUntie("/sim/view/offset-deg");
91   fgUntie("/sim/view/goal-offset-deg");
92   fgUntie("/sim/view/tilt-deg");
93   fgUntie("/sim/view/goal-tilt-deg");
94   fgUntie("/sim/view/pilot/x-offset-m");
95   fgUntie("/sim/view/pilot/y-offset-m");
96   fgUntie("/sim/view/pilot/z-offset-m");
97   fgUntie("/sim/field-of-view");
98   fgUntie("/sim/view/axes/long");
99   fgUntie("/sim/view/axes/lat");
100 }
101
102 void
103 FGViewMgr::update (int dt)
104 {
105   FGViewer * view = get_current_view();
106   if (view == 0)
107     return;
108
109                                 // Grab some values we'll need.
110   double lon_rad = fgGetDouble("/position/longitude-deg")
111     * SGD_DEGREES_TO_RADIANS;
112   double lat_rad = fgGetDouble("/position/latitude-deg")
113     * SGD_DEGREES_TO_RADIANS;
114   double alt_m = fgGetDouble("/position/altitude-ft")
115     * SG_FEET_TO_METER;
116   double roll_rad = fgGetDouble("/orientation/roll-deg")
117     * SGD_DEGREES_TO_RADIANS;
118   double pitch_rad = fgGetDouble("/orientation/pitch-deg")
119     * SGD_DEGREES_TO_RADIANS;
120   double heading_rad = fgGetDouble("/orientation/heading-deg")
121     * SGD_DEGREES_TO_RADIANS;
122
123                                 // Set up the pilot view
124   FGViewer *pilot_view = (FGViewer *)get_view( 0 );
125   pilot_view ->setPosition(
126         fgGetDouble("/position/longitude-deg"),
127         fgGetDouble("/position/latitude-deg"),
128         fgGetDouble("/position/altitude-ft"));
129   pilot_view->setOrientation(
130         fgGetDouble("/orientation/roll-deg"),
131         fgGetDouble("/orientation/pitch-deg"),
132         fgGetDouble("/orientation/heading-deg"));
133   if (fgGetString("/sim/flight-model") == "ada") {
134     //+ve x is aft, +ve z is up (see viewer.hxx)
135     pilot_view->setPositionOffsets( -5.0, 0.0, 1.0 );
136   }
137
138                                 // Set up the chase view
139
140   FGViewer *chase_view = (FGViewer *)get_view( 1 );
141
142   // get xyz Position offsets directly from GUI/sgVec3Slider
143   // FIXME: change GUI/sgVec3Slider to store the xyz in properties
144   // it would probably be faster than the way PilotOffsetGet()
145   // triggers a recalc all the time.
146   sgVec3 *pPO = PilotOffsetGet();
147   sgVec3 zPO;
148   sgCopyVec3( zPO, *pPO );
149   chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
150
151   chase_view->setOrientation(
152         fgGetDouble("/orientation/roll-deg"),
153         fgGetDouble("/orientation/pitch-deg"),
154         fgGetDouble("/orientation/heading-deg"));
155
156   chase_view ->setTargetPosition(
157         fgGetDouble("/position/longitude-deg"),
158         fgGetDouble("/position/latitude-deg"),
159         fgGetDouble("/position/altitude-ft"));
160   chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
161   chase_view->set_view_forward( pilot_view->get_view_pos() );
162
163                                 // Update the current view
164   do_axes();
165   view->update(dt);
166 }
167
168 double
169 FGViewMgr::getViewOffset_deg () const
170 {
171   const FGViewer * view = get_current_view();
172   return (view == 0 ? 0 : view->getHeadingOffset_deg());
173 }
174
175 void
176 FGViewMgr::setViewOffset_deg (double offset)
177 {
178   FGViewer * view = get_current_view();
179   if (view != 0)
180     view->setHeadingOffset_deg(offset);
181 }
182
183 double
184 FGViewMgr::getGoalViewOffset_deg () const
185 {
186   const FGViewer * view = get_current_view();
187   return (view == 0 ? 0 : view->get_goal_view_offset());
188 }
189
190 void
191 FGViewMgr::setGoalViewOffset_deg (double offset)
192 {
193   FGViewer * view = get_current_view();
194   if (view != 0)
195     view->set_goal_view_offset(offset);
196 }
197
198 double
199 FGViewMgr::getViewTilt_deg () const
200 {
201   const FGViewer * view = get_current_view();
202   return (view == 0 ? 0 : view->getPitchOffset_deg());
203 }
204
205 void
206 FGViewMgr::setViewTilt_deg (double tilt)
207 {
208   FGViewer * view = get_current_view();
209   if (view != 0)
210     view->setPitchOffset_deg(tilt);
211 }
212
213 double
214 FGViewMgr::getGoalViewTilt_deg () const
215 {
216   const FGViewer * view = get_current_view();
217   return (view == 0 ? 0 : view->get_goal_view_tilt());
218 }
219
220 void
221 FGViewMgr::setGoalViewTilt_deg (double tilt)
222 {
223   FGViewer * view = get_current_view();
224   if (view != 0)
225     view->set_goal_view_tilt(tilt);
226 }
227
228 double
229 FGViewMgr::getPilotXOffset_m () const
230 {
231                                 // FIXME: hard-coded pilot view position
232   const FGViewer * pilot_view = get_view(0);
233   if (pilot_view != 0) {
234     return ((FGViewer *)pilot_view)->getXOffset_m();
235   } else {
236     return 0;
237   }
238 }
239
240 void
241 FGViewMgr::setPilotXOffset_m (double x)
242 {
243                                 // FIXME: hard-coded pilot view position
244   FGViewer * pilot_view = get_view(0);
245   if (pilot_view != 0) {
246     pilot_view->setXOffset_m(x);
247   }
248 }
249
250 double
251 FGViewMgr::getPilotYOffset_m () const
252 {
253                                 // FIXME: hard-coded pilot view position
254   const FGViewer * pilot_view = get_view(0);
255   if (pilot_view != 0) {
256     return ((FGViewer *)pilot_view)->getYOffset_m();
257   } else {
258     return 0;
259   }
260 }
261
262 void
263 FGViewMgr::setPilotYOffset_m (double y)
264 {
265                                 // FIXME: hard-coded pilot view position
266   FGViewer * pilot_view = get_view(0);
267   if (pilot_view != 0) {
268     pilot_view->setYOffset_m(y);
269   }
270 }
271
272 double
273 FGViewMgr::getPilotZOffset_m () const
274 {
275                                 // FIXME: hard-coded pilot view position
276   const FGViewer * pilot_view = get_view(0);
277   if (pilot_view != 0) {
278     return ((FGViewer *)pilot_view)->getZOffset_m();
279   } else {
280     return 0;
281   }
282 }
283
284 void
285 FGViewMgr::setPilotZOffset_m (double z)
286 {
287                                 // FIXME: hard-coded pilot view position
288   FGViewer * pilot_view = get_view(0);
289   if (pilot_view != 0) {
290     pilot_view->setZOffset_m(z);
291   }
292 }
293
294 double
295 FGViewMgr::getFOV_deg () const
296 {
297   const FGViewer * view = get_current_view();
298   return (view == 0 ? 0 : view->get_fov());
299 }
300
301 void
302 FGViewMgr::setFOV_deg (double fov)
303 {
304   FGViewer * view = get_current_view();
305   if (view != 0)
306     view->set_fov(fov);
307 }
308
309 void
310 FGViewMgr::setViewAxisLong (double axis)
311 {
312   axis_long = axis;
313 }
314
315 void
316 FGViewMgr::setViewAxisLat (double axis)
317 {
318   axis_lat = axis;
319 }
320
321 void
322 FGViewMgr::do_axes ()
323 {
324                                 // Take no action when hat is centered
325   if ( ( axis_long <  0.01 ) &&
326        ( axis_long > -0.01 ) &&
327        ( axis_lat  <  0.01 ) &&
328        ( axis_lat  > -0.01 )
329      )
330     return;
331
332   double viewDir = 999;
333
334   /* Do all the quick and easy cases */
335   if (axis_long < 0) {          // Longitudinal axis forward
336     if (axis_lat == axis_long)
337       viewDir = 45;
338     else if (axis_lat == - axis_long)
339       viewDir = 315;
340     else if (axis_lat == 0)
341       viewDir = 0;
342   } else if (axis_long > 0) {   // Longitudinal axis backward
343     if (axis_lat == - axis_long)
344       viewDir = 135;
345     else if (axis_lat == axis_long)
346       viewDir = 225;
347     else if (axis_lat == 0)
348       viewDir = 180;
349   } else if (axis_long == 0) {  // Longitudinal axis neutral
350     if (axis_lat < 0)
351       viewDir = 90;
352     else if (axis_lat > 0)
353       viewDir = 270;
354     else return; /* And assertion failure maybe? */
355   }
356
357                                 // Do all the difficult cases
358   if ( viewDir > 900 )
359     viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
360   if ( viewDir < -1 ) viewDir += 360;
361
362   get_current_view()->set_goal_view_offset(viewDir);
363 }
364