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.
6 // Copyright (C) 1997 - 2000 Curtis L. Olson - curt@flightgear.org
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.
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.
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.
30 # error This library requires C++
33 #include <simgear/compiler.h>
34 #include <simgear/constants.h>
36 #include <plib/sg.h> // plib include
41 #define FG_FOV_MIN 0.1
42 #define FG_FOV_MAX 179.9
46 * Representation of a single viewpoint in the FlightGear world.
52 virtual ~FGViewPoint ();
55 * Set the geodetic position for the view point.
57 virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
61 * Get the longitude in degrees.
63 virtual double getLongitude_deg () const { return _lon_deg; }
66 * Get the latitude in degrees.
68 virtual double getLatitude_deg () const { return _lat_deg; }
71 * Get the altitude in feet ASL.
73 virtual double getAltitudeASL_ft () const { return _alt_ft; }
76 * Get the absolute view position in fgfs coordinates.
78 virtual const double * getAbsoluteViewPos () const;
82 * Get the relative view position in fgfs coordinates.
84 * The position is relative to the scenery centre.
86 virtual const float * getRelativeViewPos () const;
90 * Get the absolute zero-elevation view position in fgfs coordinates.
92 virtual const float * getZeroElevViewPos () const;
98 mutable sgdVec3 _absolute_view_pos;
99 mutable sgVec3 _relative_view_pos;
100 mutable sgVec3 _zero_elev_view_pos;
110 // Define a structure containing view information
121 enum fgScalingType { // nominal Field Of View actually applies to ...
122 FG_SCALING_WIDTH, // window width
123 FG_SCALING_MAX, // max(width, height)
124 // FG_SCALING_G_MEAN, // geometric_mean(width, height)
125 // FG_SCALING_INDEPENDENT // whole screen
130 // flag forcing a recalc of derived view parameters
136 fgScalingType scalingType;
138 FGViewPoint view_point;
140 // the nominal field of view (angle, in degrees)
143 // ratio of window width and height; height = width * aspect_ratio
146 // the current view offset angle from forward (rotated about the
149 bool reverse_view_offset;
151 // the goal view offset angle (used for smooth view changes)
152 double goal_view_offset;
154 // the view tilt angles
156 double goal_view_tilt;
158 // geodetic view position
159 sgdVec3 geod_view_pos;
161 // absolute view position in earth coordinates
162 sgdVec3 abs_view_pos;
164 // view position in opengl world coordinates (this is the
165 // abs_view_pos translated to scenery.center)
168 // radius to sea level from center of the earth (m)
169 double sea_level_radius;
171 // cartesion coordinates of current lon/lat if at sea level
172 // translated to scenery.center
175 // height ASL of the terrain for our current view position
176 // (future?) double ground_elev;
178 // pilot offset from center of gravity. The X axis is positive
179 // out the tail, Y is out the right wing, and Z is positive up.
180 // Distances in meters of course.
183 // surface vector heading south
184 sgVec3 surface_south;
186 // surface vector heading east (used to unambiguously align sky
190 // world up vector (normal to the plane tangent to the earth's
191 // surface at the spot we are directly above
194 // sg versions of our friendly matrices
195 sgMat4 VIEW, VIEW_ROT, UP;
197 inline void set_dirty() { dirty = true; }
198 inline void set_clean() { dirty = false; }
200 // Update the view volume, position, and orientation
201 virtual void update() = 0;
209 virtual ~FGViewer( void );
211 virtual void init ();
212 virtual void bind ();
213 virtual void unbind ();
214 virtual void update (int dt);
216 //////////////////////////////////////////////////////////////////////
218 //////////////////////////////////////////////////////////////////////
220 inline void set_fov( double fov_deg ) {
224 inline void set_aspect_ratio( double r ) {
227 inline void set_view_offset( double a ) {
231 inline void inc_view_offset( double amt ) {
235 inline void set_goal_view_offset( double a) {
237 goal_view_offset = a;
238 while ( goal_view_offset < 0.0 ) {
239 goal_view_offset += SGD_2PI;
241 while ( goal_view_offset > SGD_2PI ) {
242 goal_view_offset -= SGD_2PI;
245 inline void set_reverse_view_offset( bool val ) {
246 reverse_view_offset = val;
248 inline void set_view_tilt( double a ) {
252 inline void inc_view_tilt( double amt ) {
256 inline void set_goal_view_tilt( double a) {
259 while ( goal_view_tilt < 0 ) {
260 goal_view_tilt += 360.0;
262 while ( goal_view_tilt > 360.0 ) {
263 goal_view_tilt -= 360.0;
266 inline void set_geod_view_pos( double lon, double lat, double alt ) {
267 // data should be in radians and meters asl
269 // cout << "set_geod_view_pos = " << lon << ", " << lat << ", " << alt
271 sgdSetVec3( geod_view_pos, lon, lat, alt );
273 inline void set_pilot_offset( float x, float y, float z ) {
275 sgSetVec3( pilot_offset, x, y, z );
277 inline void set_sea_level_radius( double r ) {
278 // data should be in meters from the center of the earth
280 sea_level_radius = r;
283 //////////////////////////////////////////////////////////////////////
284 // accessor functions
285 //////////////////////////////////////////////////////////////////////
286 inline int get_type() const { return _type ; }
287 inline int is_a( int t ) const { return get_type() == t ; }
288 inline bool is_dirty() const { return dirty; }
289 inline double get_fov() const { return fov; }
290 inline double get_aspect_ratio() const { return aspect_ratio; }
291 inline double get_view_offset() const { return view_offset; }
292 inline bool get_reverse_view_offset() const { return reverse_view_offset; }
293 inline double get_goal_view_offset() const { return goal_view_offset; }
294 inline double get_view_tilt() const { return view_tilt; }
295 inline double get_goal_view_tilt() const { return goal_view_tilt; }
296 inline double *get_geod_view_pos() { return geod_view_pos; }
297 inline float *get_pilot_offset() { return pilot_offset; }
298 inline double get_sea_level_radius() const { return sea_level_radius; }
299 // Get horizontal field of view angle, in degrees.
301 // Get vertical field of view angle, in degrees.
304 //////////////////////////////////////////////////////////////////////
305 // derived values accessor functions
306 //////////////////////////////////////////////////////////////////////
307 inline double *get_abs_view_pos() {
308 if ( dirty ) { update(); }
311 inline float *get_view_pos() {
312 if ( dirty ) { update(); }
315 inline float *get_zero_elev() {
316 if ( dirty ) { update(); }
320 // inline double get_ground_elev() {
321 // if ( dirty ) { update(); }
322 // return ground_elev;
324 inline float *get_surface_south() {
325 if ( dirty ) { update(); }
326 return surface_south;
328 inline float *get_surface_east() {
329 if ( dirty ) { update(); }
332 inline float *get_world_up() {
333 if ( dirty ) { update(); }
336 inline const sgVec4 *get_VIEW() {
337 if ( dirty ) { update(); }
340 inline const sgVec4 *get_VIEW_ROT() {
341 if ( dirty ) { update(); }
344 inline const sgVec4 *get_UP() {
345 if ( dirty ) { update(); }
351 #endif // _VIEWER_HXX