1 // viewer.hxx -- class for managing a viewer 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 - curt@flightgear.org
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., 675 Mass Ave, Cambridge, MA 02139, USA.
32 # error This library requires C++
35 #include <simgear/compiler.h>
36 #include <simgear/constants.h>
38 #include <plib/sg.h> // plib include
43 #define FG_FOV_MIN 0.1
44 #define FG_FOV_MAX 179.9
47 // Define a structure containing view information
48 class FGViewer : public FGSubsystem {
58 enum fgScalingType { // nominal Field Of View actually applies to ...
59 FG_SCALING_WIDTH, // window width
60 FG_SCALING_MAX, // max(width, height)
61 // FG_SCALING_G_MEAN, // geometric_mean(width, height)
62 // FG_SCALING_INDEPENDENT // whole screen
69 virtual ~FGViewer( void );
71 //////////////////////////////////////////////////////////////////////
72 // Part 1: standard FGSubsystem implementation.
73 //////////////////////////////////////////////////////////////////////
77 virtual void unbind ();
81 //////////////////////////////////////////////////////////////////////
82 // Part 2: user settings.
83 //////////////////////////////////////////////////////////////////////
85 virtual fgViewType getType() const { return _type; }
86 virtual void setType( int type );
88 // Reference geodetic position of view from position...
89 virtual double getLongitude_deg () const { return _lon_deg; }
90 virtual double getLatitude_deg () const { return _lat_deg; }
91 virtual double getAltitudeASL_ft () const { return _alt_ft; }
92 // Set individual coordinates for the view point position.
93 virtual void setLongitude_deg (double lon_deg);
94 virtual void setLatitude_deg (double lat_deg);
95 virtual void setAltitude_ft (double alt_ft);
96 // Set the geodetic position for the view point.
97 virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
99 // Reference geodetic target position...
100 virtual double getTargetLongitude_deg () const { return _target_lon_deg; }
101 virtual double getTargetLatitude_deg () const { return _target_lat_deg; }
102 virtual double getTargetAltitudeASL_ft () const { return _target_alt_ft; }
103 // Set individual coordinates for the Target point position.
104 virtual void setTargetLongitude_deg (double lon_deg);
105 virtual void setTargetLatitude_deg (double lat_deg);
106 virtual void setTargetAltitude_ft (double alt_ft);
107 // Set the geodetic position for the Target point.
108 virtual void setTargetPosition (double lon_deg, double lat_deg, double alt_ft);
110 // Refence orientation...
111 virtual double getRoll_deg () const { return _roll_deg; }
112 virtual double getPitch_deg () const {return _pitch_deg; }
113 virtual double getHeading_deg () const {return _heading_deg; }
114 virtual void setRoll_deg (double roll_deg);
115 virtual void setPitch_deg (double pitch_deg);
116 virtual void setHeading_deg (double heading_deg);
117 virtual void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
119 // Position offsets from reference
120 virtual double getXOffset_m () const { return _x_offset_m; }
121 virtual double getYOffset_m () const { return _y_offset_m; }
122 virtual double getZOffset_m () const { return _z_offset_m; }
123 virtual void setXOffset_m (double x_offset_m);
124 virtual void setYOffset_m (double y_offset_m);
125 virtual void setZOffset_m (double z_offset_m);
126 virtual void setPositionOffsets (double x_offset_m,
130 // Orientation offsets from reference
131 virtual double getRollOffset_deg () const { return _roll_offset_deg; }
132 virtual double getPitchOffset_deg () const { return _pitch_offset_deg; }
133 virtual double getHeadingOffset_deg () const { return _heading_offset_deg; }
134 virtual void setRollOffset_deg (double roll_offset_deg);
135 virtual void setPitchOffset_deg (double pitch_offset_deg);
136 virtual void setHeadingOffset_deg (double heading_offset_deg);
137 virtual void setOrientationOffsets (double roll_offset_deg,
138 double heading_offset_deg,
139 double pitch_offset_deg);
143 //////////////////////////////////////////////////////////////////////
144 // Part 3: output vectors and matrices in FlightGear coordinates.
145 //////////////////////////////////////////////////////////////////////
147 // Vectors and positions...
150 virtual float * get_view_pos() {if ( _dirty ) { recalc(); } return view_pos; }
151 // Get the absolute view position in fgfs coordinates.
152 virtual double * get_absolute_view_pos ();
154 virtual float * get_zero_elev() {if ( _dirty ) { recalc(); } return zero_elev; }
155 // Get world up vector
156 virtual float *get_world_up() {if ( _dirty ) { recalc(); } return world_up; }
157 // Get the relative (to scenery center) view position in fgfs coordinates.
158 virtual float * getRelativeViewPos ();
159 // Get the absolute zero-elevation view position in fgfs coordinates.
160 virtual float * getZeroElevViewPos ();
161 // Get surface east vector
162 virtual float *get_surface_east() { if ( _dirty ) { recalc(); } return surface_east; }
163 // Get surface south vector
164 virtual float *get_surface_south() {if ( _dirty ) { recalc(); } return surface_south; }
167 virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; }
168 virtual const sgVec4 *get_VIEW_ROT() { if ( _dirty ) { recalc(); } return VIEW_ROT; }
169 virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
171 // virtual double get_ground_elev() { if ( _dirty ) { recalc(); } return ground_elev; }
176 // flag forcing a recalc of derived view parameters
180 void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const;
182 mutable sgdVec3 _absolute_view_pos;
183 mutable sgVec3 _relative_view_pos;
184 mutable sgVec3 _zero_elev_view_pos;
189 double _target_lon_deg;
190 double _target_lat_deg;
191 double _target_alt_ft;
197 // Position offsets from center of gravity. The X axis is positive
198 // out the tail, Y is out the right wing, and Z is positive up.
199 // distance in meters
204 // orientation offsets from reference
205 double _roll_offset_deg;
206 double _pitch_offset_deg;
207 double _heading_offset_deg;
212 fgScalingType scalingType;
214 // the nominal field of view (angle, in degrees)
217 // ratio of window width and height; height = width * aspect_ratio
220 bool reverse_view_offset;
222 // the goal view offset angle (used for smooth view changes)
223 double goal_view_offset;
225 double goal_view_tilt;
227 // view position in opengl world coordinates (this is the
228 // abs_view_pos translated to scenery.center)
231 // radius to sea level from center of the earth (m)
232 double sea_level_radius;
234 // cartesion coordinates of current lon/lat if at sea level
235 // translated to scenery.center
238 // height ASL of the terrain for our current view position
239 // (future?) double ground_elev;
241 // surface vector heading south
242 sgVec3 surface_south;
244 // surface vector heading east (used to unambiguously align sky
248 // world up vector (normal to the plane tangent to the earth's
249 // surface at the spot we are directly above
252 // sg versions of our friendly matrices
253 sgMat4 VIEW, VIEW_ROT, UP;
255 // up vector for the view (usually point straight up through the
256 // top of the aircraft
259 // the vector pointing straight out the nose of the aircraft
262 // Transformation matrix for the view direction offset relative to
263 // the AIRCRAFT matrix
266 // sg versions of our friendly matrices (from lookat)
267 sgMat4 LOCAL, TRANS, LARC_TO_SSG;
269 inline void set_dirty() { _dirty = true; }
270 inline void set_clean() { _dirty = false; }
273 void fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center,
277 void fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 );
278 void fgMakeLOCAL( sgMat4 dst, const double Theta,
279 const double Phi, const double Psi);
285 //////////////////////////////////////////////////////////////////////
287 //////////////////////////////////////////////////////////////////////
289 inline void set_fov( double fov_deg ) {
293 inline void set_aspect_ratio( double r ) {
296 inline void inc_view_offset( double amt ) {
298 _heading_offset_deg += amt;
300 inline void set_goal_view_offset( double a) {
302 goal_view_offset = a;
303 while ( goal_view_offset < 0.0 ) {
304 goal_view_offset += 360;
306 while ( goal_view_offset > 360 ) {
307 goal_view_offset -= 360;
310 inline void set_reverse_view_offset( bool val ) {
311 reverse_view_offset = val;
313 inline void inc_view_tilt( double amt ) {
315 _pitch_offset_deg += amt;
317 inline void set_goal_view_tilt( double a) {
320 while ( goal_view_tilt < -90 ) {
321 goal_view_tilt = -90.0;
323 while ( goal_view_tilt > 90.0 ) {
324 goal_view_tilt = 90.0;
327 inline void set_sea_level_radius( double r ) {
328 // data should be in meters from the center of the earth
330 sea_level_radius = r;
334 inline void set_view_forward( sgVec3 vf ) {
336 sgCopyVec3( view_forward, vf );
338 inline void set_view_up( sgVec3 vf ) {
340 sgCopyVec3( view_up, vf );
342 /* end from lookat */
345 //////////////////////////////////////////////////////////////////////
346 // accessor functions
347 //////////////////////////////////////////////////////////////////////
348 inline int get_type() const { return _type ; }
349 inline int is_a( int t ) const { return get_type() == t ; }
350 inline bool is_dirty() const { return _dirty; }
351 inline double get_fov() const { return fov; }
352 inline double get_aspect_ratio() const { return aspect_ratio; }
353 inline bool get_reverse_view_offset() const { return reverse_view_offset; }
354 inline double get_goal_view_offset() const { return goal_view_offset; }
355 inline double get_goal_view_tilt() const { return goal_view_tilt; }
356 inline double get_sea_level_radius() const { return sea_level_radius; }
357 // Get horizontal field of view angle, in degrees.
359 // Get vertical field of view angle, in degrees.
363 inline float *get_view_forward() { return view_forward; }
364 inline float *get_view_up() { return view_up; }
365 /* end from lookat */
367 //////////////////////////////////////////////////////////////////////
368 // derived values accessor functions
369 //////////////////////////////////////////////////////////////////////
374 #endif // _VIEWER_HXX