]> git.mxchange.org Git - flightgear.git/blob - src/Main/viewmgr.cxx
Initial revision.
[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 <string.h>             // strcmp
25
26 #include <plib/sg.h>
27
28 #include <GUI/sgVec3Slider.hxx> // FIXME: this should NOT be needed
29
30 #include "viewmgr.hxx"
31 #include "fg_props.hxx"
32
33
34 // Constructor
35 FGViewMgr::FGViewMgr( void ) :
36   axis_long(0),
37   axis_lat(0),
38   current(0)
39 {
40 }
41
42
43 // Destructor
44 FGViewMgr::~FGViewMgr( void ) {
45 }
46
47 void
48 FGViewMgr::init ()
49 {
50   add_view(new FGViewer, 0);
51   add_view(new FGViewer, 1);
52 }
53
54 typedef double (FGViewMgr::*double_getter)() const;
55
56 void
57 FGViewMgr::bind ()
58 {
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);
87 }
88
89 void
90 FGViewMgr::unbind ()
91 {
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");
102 }
103
104 void
105 FGViewMgr::update (int dt)
106 {
107   FGViewer * view = get_current_view();
108   if (view == 0)
109     return;
110
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")
117     * SG_FEET_TO_METER;
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;
124
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 );
138   }
139
140                                 // Set up the chase view
141
142   FGViewer *chase_view = (FGViewer *)get_view( 1 );
143
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();
149   sgVec3 zPO;
150   sgCopyVec3( zPO, *pPO );
151   chase_view->setPositionOffsets(zPO[1], zPO[0], zPO[2] );
152
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"));
165
166                                 // Update the current view
167   do_axes();
168   view->update(dt);
169 }
170
171 double
172 FGViewMgr::getViewOffset_deg () const
173 {
174   const FGViewer * view = get_current_view();
175   return (view == 0 ? 0 : view->getHeadingOffset_deg());
176 }
177
178 void
179 FGViewMgr::setViewOffset_deg (double offset)
180 {
181   FGViewer * view = get_current_view();
182   if (view != 0) {
183     view->setGoalHeadingOffset_deg(offset);
184     view->setHeadingOffset_deg(offset);
185   }
186 }
187
188 double
189 FGViewMgr::getGoalViewOffset_deg () const
190 {
191   const FGViewer * view = get_current_view();
192   return (view == 0 ? 0 : view->getGoalHeadingOffset_deg());
193 }
194
195 void
196 FGViewMgr::setGoalViewOffset_deg (double offset)
197 {
198   FGViewer * view = get_current_view();
199   if (view != 0)
200     view->setGoalHeadingOffset_deg(offset);
201 }
202
203 double
204 FGViewMgr::getViewTilt_deg () const
205 {
206   const FGViewer * view = get_current_view();
207   return (view == 0 ? 0 : view->getPitchOffset_deg());
208 }
209
210 void
211 FGViewMgr::setViewTilt_deg (double tilt)
212 {
213   FGViewer * view = get_current_view();
214   if (view != 0) {
215     view->setGoalPitchOffset_deg(tilt);
216     view->setPitchOffset_deg(tilt);
217   }
218 }
219
220 double
221 FGViewMgr::getGoalViewTilt_deg () const
222 {
223   const FGViewer * view = get_current_view();
224   return (view == 0 ? 0 : view->getGoalPitchOffset_deg());
225 }
226
227 void
228 FGViewMgr::setGoalViewTilt_deg (double tilt)
229 {
230   FGViewer * view = get_current_view();
231   if (view != 0)
232     view->setGoalPitchOffset_deg(tilt);
233 }
234
235 double
236 FGViewMgr::getPilotXOffset_m () const
237 {
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();
242   } else {
243     return 0;
244   }
245 }
246
247 void
248 FGViewMgr::setPilotXOffset_m (double x)
249 {
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);
254   }
255 }
256
257 double
258 FGViewMgr::getPilotYOffset_m () const
259 {
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();
264   } else {
265     return 0;
266   }
267 }
268
269 void
270 FGViewMgr::setPilotYOffset_m (double y)
271 {
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);
276   }
277 }
278
279 double
280 FGViewMgr::getPilotZOffset_m () const
281 {
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();
286   } else {
287     return 0;
288   }
289 }
290
291 void
292 FGViewMgr::setPilotZOffset_m (double z)
293 {
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);
298   }
299 }
300
301 double
302 FGViewMgr::getFOV_deg () const
303 {
304   const FGViewer * view = get_current_view();
305   return (view == 0 ? 0 : view->get_fov());
306 }
307
308 void
309 FGViewMgr::setFOV_deg (double fov)
310 {
311   FGViewer * view = get_current_view();
312   if (view != 0)
313     view->set_fov(fov);
314 }
315
316 void
317 FGViewMgr::setViewAxisLong (double axis)
318 {
319   axis_long = axis;
320 }
321
322 void
323 FGViewMgr::setViewAxisLat (double axis)
324 {
325   axis_lat = axis;
326 }
327
328 void
329 FGViewMgr::do_axes ()
330 {
331                                 // Take no action when hat is centered
332   if ( ( axis_long <  0.01 ) &&
333        ( axis_long > -0.01 ) &&
334        ( axis_lat  <  0.01 ) &&
335        ( axis_lat  > -0.01 )
336      )
337     return;
338
339   double viewDir = 999;
340
341   /* Do all the quick and easy cases */
342   if (axis_long < 0) {          // Longitudinal axis forward
343     if (axis_lat == axis_long)
344       viewDir = 45;
345     else if (axis_lat == - axis_long)
346       viewDir = 315;
347     else if (axis_lat == 0)
348       viewDir = 0;
349   } else if (axis_long > 0) {   // Longitudinal axis backward
350     if (axis_lat == - axis_long)
351       viewDir = 135;
352     else if (axis_lat == axis_long)
353       viewDir = 225;
354     else if (axis_lat == 0)
355       viewDir = 180;
356   } else if (axis_long == 0) {  // Longitudinal axis neutral
357     if (axis_lat < 0)
358       viewDir = 90;
359     else if (axis_lat > 0)
360       viewDir = 270;
361     else return; /* And assertion failure maybe? */
362   }
363
364                                 // Do all the difficult cases
365   if ( viewDir > 900 )
366     viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
367   if ( viewDir < -1 ) viewDir += 360;
368
369   get_current_view()->setGoalHeadingOffset_deg(viewDir);
370 }
371
372
373
374
375