1 // view.hxx -- class for managing a view in the flightgear world.
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
8 // Copyright (C) 1997 - 2000 Curtis L. Olson - http://www.flightgear.org/~curt
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.
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.
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.
31 #include <simgear/compiler.h>
32 #include <simgear/constants.h>
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>
39 #define FG_FOV_MIN 0.1
40 #define FG_FOV_MAX 179.9
45 // Define a structure containing view information
46 class View : public SGSubsystem {
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
62 static View* createFromProperties(SGPropertyNode_ptr props);
67 //////////////////////////////////////////////////////////////////////
68 // Part 1: standard SGSubsystem implementation.
69 //////////////////////////////////////////////////////////////////////
73 virtual void unbind ();
74 virtual void update (double dt);
77 //////////////////////////////////////////////////////////////////////
78 // Part 2: user settings.
79 //////////////////////////////////////////////////////////////////////
81 void resetOffsetsAndFOV();
83 ViewType getType() const { return _type; }
84 void setType( int type );
86 bool getInternal() const { return _internal; }
87 void setInternal( bool internal );
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.
96 const SGGeod& getPosition() const { return _position; }
98 // Reference geodetic target position...
99 const SGGeod& getTargetPosition() const { return _target; }
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
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,
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; }
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
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; }
157 void setGoalHeadingOffset_deg (double goal_heading_offset_deg);
158 void setHeadingOffset_deg (double heading_offset_deg);
160 //////////////////////////////////////////////////////////////////////
161 // Part 3: output vectors and matrices in FlightGear coordinates.
162 //////////////////////////////////////////////////////////////////////
164 // Vectors and positions...
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; }
171 //////////////////////////////////////////////////////////////////////
172 // Part 4: View and frustrum data setters and getters
173 //////////////////////////////////////////////////////////////////////
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.
179 // this is currently just a wrapper for the default CameraGroups' aspect
180 double get_aspect_ratio() const;
182 //////////////////////////////////////////////////////////////////////
183 // Part 5: misc setters and getters
184 //////////////////////////////////////////////////////////////////////
186 void set_dirty() { _dirty = true; }
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 );
201 void set_clean() { _dirty = false; }
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);
208 void setPosition (const SGGeod& geod);
209 void setTargetPosition (const SGGeod& geod);
211 double getAbsolutePosition_x() const;
212 double getAbsolutePosition_y() const;
213 double getAbsolutePosition_z() const;
215 double getRawOrientation_w() const;
216 double getRawOrientation_x() const;
217 double getRawOrientation_y() const;
218 double getRawOrientation_z() const;
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;
226 double getOrientation_w() const;
227 double getOrientation_x() const;
228 double getOrientation_y() const;
229 double getOrientation_z() const;
231 double getOrOffset_w() const;
232 double getOrOffset_x() const;
233 double getOrOffset_y() const;
234 double getOrOffset_z() const;
236 double getLon_deg() const;
237 double getLat_deg() const;
238 double getElev_ft() const;
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);
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
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);
286 void set_aspect_ratio_multiplier( double m ) {
287 _aspect_ratio_multiplier = m;
289 double get_aspect_ratio_multiplier() const {
290 return _aspect_ratio_multiplier;
293 double getNear_m () const { return _ground_level_nearplane_m; }
294 void setNear_m (double near_m) {
295 _ground_level_nearplane_m = near_m;
298 void set_fov( double fov_deg ) {
302 //////////////////////////////////////////////////////////////////
304 //////////////////////////////////////////////////////////////////
306 std::string _name, _typeString;
308 // flag forcing a recalc of derived view parameters
311 simgear::TiedPropertyList _tiedProperties;
313 SGQuatd mViewOrientation;
314 SGQuatd mViewOffsetOr;
315 SGVec3d _absolute_view_pos;
323 double _target_roll_deg;
324 double _target_pitch_deg;
325 double _target_heading_deg;
327 double _configRollOffsetDeg,
328 _configHeadingOffsetDeg,
329 _configPitchOffsetDeg;
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
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
339 SGVec3d _configOffset_m;
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;
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;
355 // used to set nearplane when at ground level for this view
356 double _ground_level_nearplane_m;
359 ScalingType _scaling_type;
361 // internal view (e.g. cockpit) flag
364 // view is looking from a model
366 int _from_model_index; // number of model (for multi model)
368 // view is looking at a model
370 int _at_model_index; // number of model (for multi model)
372 // the nominal field of view (angle, in degrees)
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;
379 class PositionAttitudeProperties : public SGPropertyChangeListener
382 PositionAttitudeProperties();
384 void init(SGPropertyNode_ptr parent, const std::string& prefix);
386 virtual ~PositionAttitudeProperties();
388 SGGeod position() const;
389 SGVec3d attitude() const; // as heading pitch roll
392 virtual void valueChanged(SGPropertyNode* prop);
396 PositionAttitudeProperties(const PositionAttitudeProperties&);
398 SGPropertyNode_ptr resolvePathProperty(SGPropertyNode_ptr p);
400 SGPropertyNode_ptr _lonProp,
406 SGPropertyNode_ptr _lonPathProp,
414 PositionAttitudeProperties _eyeProperties;
415 PositionAttitudeProperties _targetProperties;
417 //////////////////////////////////////////////////////////////////
418 // private functions //
419 //////////////////////////////////////////////////////////////////
422 void recalcLookFrom();
425 void setDampTarget(double h, double p, double r);
426 void getDampOutput(double& roll, double& pitch, double& heading);
428 void updateDampOutput(double dt);
430 // add to _heading_offset_deg
431 inline void incHeadingOffset_deg( double amt ) {
433 _heading_offset_deg += amt;
436 // add to _pitch_offset_deg
437 inline void incPitchOffset_deg( double amt ) {
439 _pitch_offset_deg += amt;
442 // add to _roll_offset_deg
443 inline void incRollOffset_deg( double amt ) {
445 _roll_offset_deg += amt;
450 } // of namespace flightgear
453 #endif // _VIEWER_HXX