]> git.mxchange.org Git - flightgear.git/blob - src/Viewer/view.hxx
Code cleanups, code updates and fix at least on (possible) devide-by-zero
[flightgear.git] / src / Viewer / view.hxx
1 // view.hxx -- class for managing a view in the flightgear world.
2 //
3 // Written by Curtis Olson, started August 1997.
4 //                          overhaul started October 2000.
5 //   partially rewritten by Jim Wilson jim@kelcomaine.com using interface
6 //                          by David Megginson March 2002
7 //
8 // Copyright (C) 1997 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23 //
24 // $Id$
25
26
27 #ifndef _VIEWER_HXX
28 #define _VIEWER_HXX                                
29
30
31 #include <simgear/compiler.h>
32 #include <simgear/constants.h>
33
34 #include <simgear/props/props.hxx>
35 #include <simgear/props/tiedpropertylist.hxx>
36 #include <simgear/structure/subsystem_mgr.hxx>
37 #include <simgear/math/SGMath.hxx>
38
39 #define FG_FOV_MIN 0.1
40 #define FG_FOV_MAX 179.9
41
42 namespace flightgear
43 {
44
45 // Define a structure containing view information
46 class View : public SGSubsystem {
47
48 public:
49
50     enum ScalingType {  // nominal Field Of View actually applies to ...
51         FG_SCALING_WIDTH,       // window width
52         FG_SCALING_MAX          // max(width, height)
53         // FG_SCALING_G_MEAN,      // geometric_mean(width, height)
54         // FG_SCALING_INDEPENDENT  // whole screen
55     };
56
57     enum ViewType {
58         FG_LOOKFROM = 0,
59         FG_LOOKAT = 1
60     };
61
62     static View* createFromProperties(SGPropertyNode_ptr props);
63
64     // Destructor
65     virtual ~View();
66
67     //////////////////////////////////////////////////////////////////////
68     // Part 1: standard SGSubsystem implementation.
69     //////////////////////////////////////////////////////////////////////
70
71     virtual void init ();
72     virtual void bind ();
73     virtual void unbind ();
74     virtual void update (double dt);
75
76
77     //////////////////////////////////////////////////////////////////////
78     // Part 2: user settings.
79     //////////////////////////////////////////////////////////////////////
80
81     void resetOffsetsAndFOV();
82
83     ViewType getType() const { return _type; }
84     void setType( int type );
85
86     bool getInternal() const { return _internal; }
87     void setInternal( bool internal );
88
89     // Reference geodetic position of view from position...
90     //   These are the actual aircraft position (pilot in
91     //   pilot view, model in model view).
92     //   FIXME: the model view position (ie target positions) 
93     //   should be in the model class.
94
95
96     const SGGeod& getPosition() const { return _position; }
97
98     // Reference geodetic target position...
99     const SGGeod& getTargetPosition() const { return _target; }
100
101
102
103     // Position offsets from reference
104     //   These offsets position they "eye" in the scene according to a given
105     //   location.  For example in pilot view they are used to position the 
106     //   head inside the aircraft.
107     //   Note that in pilot view these are applied "before" the orientation 
108     //   rotations (see below) so that the orientation rotations have the 
109     //   effect of the pilot staying in his seat and "looking out" in 
110     //   different directions.
111     //   In chase view these are applied "after" the application of the 
112     //   orientation rotations listed below.  This has the effect of the 
113     //   eye moving around and "looking at" the object (model) from 
114     //   different angles.
115     SGVec3d getOffset_m () const { return _offset_m; }
116     double getXOffset_m () const { return _offset_m.x(); }
117     double getYOffset_m () const { return _offset_m.y(); }
118     double getZOffset_m () const { return _offset_m.z(); }
119     double getTargetXOffset_m () const { return _target_offset_m.x(); }
120     double getTargetYOffset_m () const { return _target_offset_m.y(); }
121     double getTargetZOffset_m () const { return _target_offset_m.z(); }
122     void setXOffset_m (double x_offset_m);
123     void setYOffset_m (double y_offset_m);
124     void setZOffset_m (double z_offset_m);
125     void setTargetXOffset_m (double x_offset_m);
126     void setTargetYOffset_m (double y_offset_m);
127     void setTargetZOffset_m (double z_offset_m);
128     void setPositionOffsets (double x_offset_m,
129                                      double y_offset_m,
130                                      double z_offset_m);
131
132     // Reference orientation rotations...
133     //   These are rotations that represent the plane attitude effect on
134     //   the view (in Pilot view).  IE The view frustrum rotates as the plane
135     //   turns, pitches, and rolls.
136     //   In model view (lookat/chaseview) these end up changing the angle that
137     //   the eye is looking at the ojbect (ie the model).
138     //   FIXME: the FGModel class should have its own version of these so that
139     //   it can generate it's own model rotations.
140     double getHeading_deg () const {return _heading_deg; }
141
142
143     // Orientation offsets rotations from reference orientation.
144     // Goal settings are for smooth transition from prior
145     // offset when changing view direction.
146     //   These offsets are in ADDITION to the orientation rotations listed
147     //   above.
148     //   In pilot view they are applied after the position offsets in order to
149     //   give the effect of the pilot looking around.
150     //   In lookat view they are applied before the position offsets so that
151     //   the effect is the eye moving around looking at the object (ie the model)
152     //   from different angles.
153     double getRollOffset_deg () const { return _roll_offset_deg; }
154     double getPitchOffset_deg () const { return _pitch_offset_deg; }
155     double getHeadingOffset_deg () const { return _heading_offset_deg; }
156
157     void setGoalHeadingOffset_deg (double goal_heading_offset_deg);
158     void setHeadingOffset_deg (double heading_offset_deg);
159
160     //////////////////////////////////////////////////////////////////////
161     // Part 3: output vectors and matrices in FlightGear coordinates.
162     //////////////////////////////////////////////////////////////////////
163
164     // Vectors and positions...
165
166     const SGVec3d& get_view_pos() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
167     const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; }
168     const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; }
169     const SGQuatd& getViewOrientationOffset() { if ( _dirty ) { recalc(); } return mViewOffsetOr; }
170
171     //////////////////////////////////////////////////////////////////////
172     // Part 4: View and frustrum data setters and getters
173     //////////////////////////////////////////////////////////////////////
174
175     double get_fov() const { return _fov_deg; }
176     double get_h_fov();    // Get horizontal fov, in degrees.
177     double get_v_fov();    // Get vertical fov, in degrees.
178
179     // this is currently just a wrapper for the default CameraGroups' aspect
180     double get_aspect_ratio() const;
181
182     //////////////////////////////////////////////////////////////////////
183     // Part 5: misc setters and getters
184     //////////////////////////////////////////////////////////////////////
185
186     void set_dirty() { _dirty = true; }
187
188 private:
189
190     // Constructor
191     View( ViewType Type, bool from_model, int from_model_index,
192          bool at_model, int at_model_index,
193          double damp_roll, double damp_pitch, double damp_heading,
194          double x_offset_m, double y_offset_m, double z_offset_m,
195          double heading_offset_deg, double pitch_offset_deg,
196          double roll_offset_deg,
197          double fov_deg, double aspect_ratio_multiplier,
198          double target_x_offset_m, double target_y_offset_m,
199          double target_z_offset_m, double near_m, bool internal );
200
201     void set_clean() { _dirty = false; }
202     void updateData();
203
204     void setHeadingOffset_deg_property (double heading_offset_deg);
205     void setPitchOffset_deg_property(double pitch_offset_deg);
206     void setRollOffset_deg_property(double roll_offset_deg);
207
208     void setPosition (const SGGeod& geod);
209     void setTargetPosition (const SGGeod& geod);
210
211     double getAbsolutePosition_x() const;
212     double getAbsolutePosition_y() const;
213     double getAbsolutePosition_z() const;
214
215     double getRawOrientation_w() const;
216     double getRawOrientation_x() const;
217     double getRawOrientation_y() const;
218     double getRawOrientation_z() const;
219
220     // quaternion accessors, for debugging:
221     double getFrame_w() const;
222     double getFrame_x() const;
223     double getFrame_y() const;
224     double getFrame_z() const;
225
226     double getOrientation_w() const;
227     double getOrientation_x() const;
228     double getOrientation_y() const;
229     double getOrientation_z() const;
230
231     double getOrOffset_w() const;
232     double getOrOffset_x() const;
233     double getOrOffset_y() const;
234     double getOrOffset_z() const;
235
236     double getLon_deg() const;
237     double getLat_deg() const;
238     double getElev_ft() const;
239
240     // Reference orientation rotations...
241     //   These are rotations that represent the plane attitude effect on
242     //   the view (in Pilot view).  IE The view frustrum rotates as the plane
243     //   turns, pitches, and rolls.
244     //   In model view (lookat/chaseview) these end up changing the angle that
245     //   the eye is looking at the ojbect (ie the model).
246     //   FIXME: the FGModel class should have its own version of these so that
247     //   it can generate it's own model rotations.
248     double getRoll_deg () const { return _roll_deg; }
249     double getPitch_deg () const {return _pitch_deg; }
250     void setRoll_deg (double roll_deg);
251     void setPitch_deg (double pitch_deg);
252     void setHeading_deg (double heading_deg);
253     void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
254     double getTargetRoll_deg () const { return _target_roll_deg; }
255     double getTargetPitch_deg () const {return _target_pitch_deg; }
256     double getTargetHeading_deg () const {return _target_heading_deg; }
257     void setTargetRoll_deg (double roll_deg);
258     void setTargetPitch_deg (double pitch_deg);
259     void setTargetHeading_deg (double heading_deg);
260     void setTargetOrientation (double roll_deg, double pitch_deg, double heading_deg);
261
262
263
264
265     // Orientation offsets rotations from reference orientation.
266     // Goal settings are for smooth transition from prior
267     // offset when changing view direction.
268     //   These offsets are in ADDITION to the orientation rotations listed
269     //   above.
270     //   In pilot view they are applied after the position offsets in order to
271     //   give the effect of the pilot looking around.
272     //   In lookat view they are applied before the position offsets so that
273     //   the effect is the eye moving around looking at the object (ie the model)
274     //   from different angles.
275     double getGoalRollOffset_deg () const { return _goal_roll_offset_deg; }
276     double getGoalPitchOffset_deg () const { return _goal_pitch_offset_deg; }
277     double getGoalHeadingOffset_deg () const {return _goal_heading_offset_deg; }
278     void setRollOffset_deg (double roll_offset_deg);
279     void setPitchOffset_deg (double pitch_offset_deg);
280     void setGoalRollOffset_deg (double goal_roll_offset_deg);
281     void setGoalPitchOffset_deg (double goal_pitch_offset_deg);
282     void setOrientationOffsets (double roll_offset_deg,
283                                 double heading_offset_deg,
284                                 double pitch_offset_deg);
285     
286     void set_aspect_ratio_multiplier( double m ) {
287         _aspect_ratio_multiplier = m;
288     }
289     double get_aspect_ratio_multiplier() const {
290         return _aspect_ratio_multiplier;
291     }
292
293     double getNear_m () const { return _ground_level_nearplane_m; }
294     void setNear_m (double near_m) {
295         _ground_level_nearplane_m = near_m;
296     }
297
298     void set_fov( double fov_deg ) {
299         _fov_deg = fov_deg;
300     }
301
302     //////////////////////////////////////////////////////////////////
303     // private data                                                 //
304     //////////////////////////////////////////////////////////////////
305
306     std::string _name, _typeString;
307     
308     // flag forcing a recalc of derived view parameters
309     bool _dirty;
310
311     simgear::TiedPropertyList _tiedProperties;
312
313     SGQuatd mViewOrientation;
314     SGQuatd mViewOffsetOr;
315     SGVec3d _absolute_view_pos;
316
317     SGGeod _position;
318     SGGeod _target;
319
320     double _roll_deg;
321     double _pitch_deg;
322     double _heading_deg;
323     double _target_roll_deg;
324     double _target_pitch_deg;
325     double _target_heading_deg;
326
327     double _configRollOffsetDeg,
328         _configHeadingOffsetDeg,
329         _configPitchOffsetDeg;
330
331     SGVec3d _dampTarget; ///< current target value we are damping towards
332     SGVec3d _dampOutput; ///< current output of damping filter
333     SGVec3d _dampFactor; ///< weighting of the damping filter
334     
335     // Position offsets from FDM origin.  The X axis is positive
336     // out the tail, Y is out the right wing, and Z is positive up.
337     // distance in meters
338     SGVec3d _offset_m;
339     SGVec3d _configOffset_m;
340
341     // Target offsets from FDM origin (for "lookat" targets) The X
342     // axis is positive out the tail, Y is out the right wing, and Z
343     // is positive up.  distance in meters
344     SGVec3d _target_offset_m;
345     SGVec3d _configTargetOffset_m;
346
347     // orientation offsets from reference (_goal* are for smoothed transitions)
348     double _roll_offset_deg;
349     double _pitch_offset_deg;
350     double _heading_offset_deg;
351     double _goal_roll_offset_deg;
352     double _goal_pitch_offset_deg;
353     double _goal_heading_offset_deg;
354
355     // used to set nearplane when at ground level for this view
356     double _ground_level_nearplane_m;
357
358     ViewType _type;
359     ScalingType _scaling_type;
360
361     // internal view (e.g. cockpit) flag
362     bool _internal;
363
364     // view is looking from a model
365     bool _from_model;
366     int _from_model_index;  // number of model (for multi model)
367
368     // view is looking at a model
369     bool _at_model;
370     int _at_model_index;  // number of model (for multi model)
371
372     // the nominal field of view (angle, in degrees)
373     double _fov_deg;
374     double _configFOV_deg;
375     // default = 1.0, this value is user configurable and is
376     // multiplied into the aspect_ratio to get the actual vertical fov
377     double _aspect_ratio_multiplier;
378
379     class PositionAttitudeProperties : public SGPropertyChangeListener
380     {
381     public:
382         PositionAttitudeProperties();
383         
384         void init(SGPropertyNode_ptr parent, const std::string& prefix);
385
386         virtual ~PositionAttitudeProperties();
387
388         SGGeod position() const;
389         SGVec3d attitude() const; // as heading pitch roll
390
391     protected:
392         virtual void valueChanged(SGPropertyNode* prop);
393
394     private:
395 // disable copy
396         PositionAttitudeProperties(const PositionAttitudeProperties&);
397
398         SGPropertyNode_ptr resolvePathProperty(SGPropertyNode_ptr p);
399
400         SGPropertyNode_ptr _lonProp,
401             _latProp,
402             _altProp,
403             _headingProp,
404             _pitchProp,
405             _rollProp;
406         SGPropertyNode_ptr _lonPathProp,
407             _latPathProp,
408             _altPathProp,
409             _headingPathProp,
410             _pitchPathProp,
411             _rollPathProp;
412     };
413
414     PositionAttitudeProperties _eyeProperties;
415     PositionAttitudeProperties _targetProperties;
416
417     //////////////////////////////////////////////////////////////////
418     // private functions                                            //
419     //////////////////////////////////////////////////////////////////
420
421     void recalc ();
422     void recalcLookFrom();
423     void recalcLookAt();
424
425     void setDampTarget(double h, double p, double r);
426     void getDampOutput(double& roll, double& pitch, double& heading);
427     
428     void updateDampOutput(double dt);
429     
430     // add to _heading_offset_deg
431     inline void incHeadingOffset_deg( double amt ) {
432         set_dirty();
433         _heading_offset_deg += amt;
434     }
435
436     // add to _pitch_offset_deg
437     inline void incPitchOffset_deg( double amt ) {
438         set_dirty();
439         _pitch_offset_deg += amt;
440     }
441
442     // add to _roll_offset_deg
443     inline void incRollOffset_deg( double amt ) {
444         set_dirty();
445         _roll_offset_deg += amt;
446     }
447
448 }; // of class View
449
450 } // of namespace flightgear
451
452
453 #endif // _VIEWER_HXX