float get_view_direction( void )
{
- double view_off = SGD_2PI - globals->get_current_view()->get_view_offset();
+ double view_off = SGD_2PI - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
double view = ( current_aircraft.fdm_state->get_Psi() + view_off)
* SGD_RADIANS_TO_DEGREES;
glViewport( 0, 0, iwidth, iheight );
}
+
return false;
if(globals->get_viewmgr()->get_current() != 0)
return false;
- if(globals->get_current_view()->get_view_offset() != 0 &&
+ if(globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS != 0 &&
!fgGetBool("/sim/virtual-cockpit"))
return false;
return true;
// Generate a "look at" matrix using OpenGL (!) coordinate
// conventions.
float lookat[3];
- float pitch = view->get_view_tilt();
- float rot = view->get_view_offset();
+ float pitch = view->getPitchOffset_deg() * SGD_DEGREES_TO_RADIANS;
+ float rot = view->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
lookat[0] = -sin(rot);
lookat[1] = sin(pitch) / cos(pitch);
lookat[2] = -cos(rot);
// end of panel.cxx
+
static inline void set_goal_view_offset( float offset )
{
- globals->get_current_view()->set_goal_view_offset(offset);
+ globals->get_current_view()->set_goal_view_offset(offset * SGD_RADIANS_TO_DEGREES);
}
static inline void set_view_offset( float offset )
{
- globals->get_current_view()->set_view_offset(offset);
+ globals->get_current_view()->setHeadingOffset_deg(offset * SGD_RADIANS_TO_DEGREES);
+}
+
+static inline void set_goal_view_tilt( float tilt )
+{
+ globals->get_current_view()->set_goal_view_tilt(tilt);
+}
+
+static inline void set_view_tilt( float tilt )
+{
+ globals->get_current_view()->setPitchOffset_deg(tilt);
}
static inline float get_view_offset() {
- return globals->get_current_view()->get_view_offset();
+ return globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS;
}
static inline float get_goal_view_offset() {
- return globals->get_current_view()->get_goal_view_offset();
+ return globals->get_current_view()->get_goal_view_offset() * SGD_DEGREES_TO_RADIANS;
}
static inline void move_brake(float offset) {
offset -= SGD_2PI;
}
set_goal_view_offset(offset);
+ set_goal_view_tilt(asin( GuiQuat_mat[1][2]) * SGD_RADIANS_TO_DEGREES );
#ifdef NO_SMOOTH_MOUSE_VIEW
set_view_offset(offset);
+ set_view_tilt(asin( GuiQuat_mat[1][2]) * SGD_RADIANS_TO_DEGREES );
#endif
break;
y = _Vy;
sgCopyVec4(curGuiQuat, _quat);
set_goal_view_offset(_view_offset);
+ set_goal_view_tilt(0.0);
#ifdef NO_SMOOTH_MOUSE_VIEW
set_view_offset(_view_offset);
#endif
Quat0();
_view_offset = get_goal_view_offset();
set_goal_view_offset(0.0);
+ set_goal_view_tilt(0.0);
#ifdef NO_SMOOTH_MOUSE_VIEW
set_view_offset(0.0);
+ set_view_tilt(0.0);
#endif
}
glutWarpPointer( x , y);
Quat0();
build_rotmatrix(GuiQuat_mat, curGuiQuat);
set_goal_view_offset(0.0);
+ set_goal_view_tilt(0.0);
#ifdef NO_SMOOTH_MOUSE_VIEW
set_view_offset(0.0);
+ set_view_tilt(0.0);
#endif // NO_SMOOTH_MOUSE_VIEW
#endif // RESET_VIEW_ON_LEAVING_MOUSE_VIEW
glutSetCursor(GLUT_CURSOR_INHERIT);
glutPostRedisplay ();
}
+
+
options.cxx options.hxx \
splash.cxx splash.hxx \
viewer.cxx viewer.hxx \
- viewer_lookat.cxx viewer_lookat.hxx \
- viewer_rph.cxx viewer_rph.hxx \
viewmgr.cxx viewmgr.hxx
fgfs_LDADD = \
else
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
endif
+
static bool
do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
{
- globals->get_current_view()->set_view_offset(0.0);
+ globals->get_current_view()->setHeadingOffset_deg(0.0);
globals->get_viewmgr()->next_view();
if ( fgGetString("/sim/flight-model") == "ada" ) {
globals->get_props()->setBoolValue( "/sim/hud/visibility", true );
}
// end of fg_commands.hxx
+
do_animation(_animations[i], elapsed_ms);
_selector->select(true);
- FGViewerRPH *pilot_view =
- (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
+ FGViewer *pilot_view =
+ (FGViewer *)globals->get_viewmgr()->get_view( 0 );
sgMat4 sgTRANS;
sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() );
if (view_number == 0) {
// FIXME: orientation is not applied
// correctly when view is not forward
- sgMakeRotMat4( sgROT, -pilot_view->get_view_offset()
- * SGD_RADIANS_TO_DEGREES, pilot_view->get_world_up() );
+ sgMakeRotMat4( sgROT, -pilot_view->getHeadingOffset_deg(),
+ pilot_view->get_world_up() );
/* Warning lame hack from Wilson ahead */
/* get the pitch value */
- sgVec3 rph;
- sgCopyVec3(rph, pilot_view->get_rph());
/* double it to counter the value already in the VIEW_ROT */
- float pitch = rph[1] * 2;
+ float pitch = pilot_view->getPitch_deg() * SGD_DEGREES_TO_RADIANS * 2;
/* make a ROT matrix
with the values waited by the X coordinate from the offset
rotation see sgROT above
// end of model.cxx
+
+
+
+
} else {
default_view_offset = atof( woffset.c_str() ) * SGD_DEGREES_TO_RADIANS;
}
- FGViewerRPH *pilot_view =
- (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
- pilot_view->set_view_offset( default_view_offset );
- pilot_view->set_goal_view_offset( default_view_offset );
- fgSetDouble("/sim/view/offset-deg", default_view_offset);
+ FGViewer *pilot_view =
+ (FGViewer *)globals->get_viewmgr()->get_view( 0 );
+ pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
+ pilot_view->set_goal_view_offset( default_view_offset * SGD_RADIANS_TO_DEGREES );
+ fgSetDouble("/sim/view/offset-deg", default_view_offset * SGD_RADIANS_TO_DEGREES );
// $$$ end - added VS Renganathan, 14 Oct 2K
} else if ( arg.find( "--visibility=" ) == 0 ) {
fgSetDouble("/environment/visibility-m", atof(arg.substr(13)));
<< " instances allowed." << endl
<< endl;
}
+
+
//
// Written by Curtis Olson, started August 1997.
// overhaul started October 2000.
+// partially rewritten by Jim Wilson jim@kelcomaine.com using interface
+// by David Megginson March 2002
//
// Copyright (C) 1997 - 2000 Curtis L. Olson - curt@flightgear.org
//
#include <Scenery/scenery.hxx>
-#include "viewer.hxx"
+/* from lookat */
+#include <simgear/math/vector.hxx>
+#include "globals.hxx"
+/* end from lookat */
+#include "viewer.hxx"
\f
////////////////////////////////////////////////////////////////////////
-// Implementation of FGViewPoint.
+// Implementation of FGViewer.
////////////////////////////////////////////////////////////////////////
-FGViewPoint::FGViewPoint ()
- : _dirty(true),
+// Constructor
+FGViewer::FGViewer( void ):
+ scalingType(FG_SCALING_MAX),
+ fov(55.0),
+ goal_view_offset(0.0),
+ goal_view_tilt(0.0),
+ _dirty(true),
_lon_deg(0),
_lat_deg(0),
- _alt_ft(0)
+ _alt_ft(0),
+ _target_lon_deg(0),
+ _target_lat_deg(0),
+ _target_alt_ft(0),
+ _roll_deg(0),
+ _pitch_deg(0),
+ _heading_deg(0),
+ _x_offset_m(0),
+ _y_offset_m(0),
+ _z_offset_m(0),
+ _heading_offset_deg(0),
+ _pitch_offset_deg(0),
+ _roll_offset_deg(0)
+{
+ sgdZeroVec3(_absolute_view_pos);
+ sea_level_radius = SG_EQUATORIAL_RADIUS_M;
+ //a reasonable guess for init, so that the math doesn't blow up
+}
+
+
+// Destructor
+FGViewer::~FGViewer( void ) {
+}
+
+void
+FGViewer::init ()
+{
+ if ( _type == FG_LOOKAT ) {
+ set_reverse_view_offset(true);
+ }
+
+ if ( _type == FG_RPH ) {
+ set_reverse_view_offset(false);
+ }
+}
+
+void
+FGViewer::bind ()
+{
+}
+
+void
+FGViewer::unbind ()
{
}
-FGViewPoint::~FGViewPoint ()
+void
+FGViewer::setType ( int type )
{
+ if (type == 0)
+ _type = FG_RPH;
+ if (type == 1)
+ _type = FG_LOOKAT;
}
void
-FGViewPoint::setPosition (double lon_deg, double lat_deg, double alt_ft)
+FGViewer::setLongitude_deg (double lon_deg)
{
_dirty = true;
_lon_deg = lon_deg;
+}
+
+void
+FGViewer::setLatitude_deg (double lat_deg)
+{
+ _dirty = true;
_lat_deg = lat_deg;
+}
+
+void
+FGViewer::setAltitude_ft (double alt_ft)
+{
+ _dirty = true;
_alt_ft = alt_ft;
}
-const double *
-FGViewPoint::getAbsoluteViewPos () const
+void
+FGViewer::setPosition (double lon_deg, double lat_deg, double alt_ft)
+{
+ _dirty = true;
+ _lon_deg = lon_deg;
+ _lat_deg = lat_deg;
+ _alt_ft = alt_ft;
+}
+
+void
+FGViewer::setTargetLongitude_deg (double lon_deg)
+{
+ _dirty = true;
+ _target_lon_deg = lon_deg;
+}
+
+void
+FGViewer::setTargetLatitude_deg (double lat_deg)
+{
+ _dirty = true;
+ _target_lat_deg = lat_deg;
+}
+
+void
+FGViewer::setTargetAltitude_ft (double alt_ft)
+{
+ _dirty = true;
+ _target_alt_ft = alt_ft;
+}
+
+void
+FGViewer::setTargetPosition (double lon_deg, double lat_deg, double alt_ft)
+{
+ _dirty = true;
+ _target_lon_deg = lon_deg;
+ _target_lat_deg = lat_deg;
+ _target_alt_ft = alt_ft;
+}
+
+void
+FGViewer::setRoll_deg (double roll_deg)
+{
+ _dirty = true;
+ _roll_deg = roll_deg;
+}
+
+void
+FGViewer::setPitch_deg (double pitch_deg)
+{
+ _dirty = true;
+ _pitch_deg = pitch_deg;
+}
+
+void
+FGViewer::setHeading_deg (double heading_deg)
+{
+ _dirty = true;
+ _heading_deg = heading_deg;
+}
+
+void
+FGViewer::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
+{
+ _dirty = true;
+ _roll_deg = roll_deg;
+ _pitch_deg = pitch_deg;
+ _heading_deg = heading_deg;
+}
+
+void
+FGViewer::setXOffset_m (double x_offset_m)
+{
+ _dirty = true;
+ _x_offset_m = x_offset_m;
+}
+
+void
+FGViewer::setYOffset_m (double y_offset_m)
+{
+ _dirty = true;
+ _y_offset_m = y_offset_m;
+}
+
+void
+FGViewer::setZOffset_m (double z_offset_m)
+{
+ _dirty = true;
+ _z_offset_m = z_offset_m;
+}
+
+void
+FGViewer::setPositionOffsets (double x_offset_m, double y_offset_m, double z_offset_m)
+{
+ _dirty = true;
+ _x_offset_m = x_offset_m;
+ _y_offset_m = y_offset_m;
+ _z_offset_m = z_offset_m;
+}
+
+void
+FGViewer::setRollOffset_deg (double roll_offset_deg)
+{
+ _dirty = true;
+ _roll_offset_deg = roll_offset_deg;
+}
+
+void
+FGViewer::setPitchOffset_deg (double pitch_offset_deg)
+{
+ _dirty = true;
+ _pitch_offset_deg = pitch_offset_deg;
+}
+
+void
+FGViewer::setHeadingOffset_deg (double heading_offset_deg)
+{
+ _dirty = true;
+ _heading_offset_deg = heading_offset_deg;
+}
+
+void
+FGViewer::setOrientationOffsets (double roll_offset_deg, double pitch_offset_deg, double heading_offset_deg)
+{
+ _dirty = true;
+ _roll_offset_deg = roll_offset_deg;
+ _pitch_offset_deg = pitch_offset_deg;
+ _heading_offset_deg = heading_offset_deg;
+}
+
+double *
+FGViewer::get_absolute_view_pos ()
{
if (_dirty)
recalc();
return _absolute_view_pos;
}
-const float *
-FGViewPoint::getRelativeViewPos () const
+float *
+FGViewer::getRelativeViewPos ()
{
if (_dirty)
recalc();
return _relative_view_pos;
}
-const float *
-FGViewPoint::getZeroElevViewPos () const
+float *
+FGViewer::getZeroElevViewPos ()
{
if (_dirty)
recalc();
return _zero_elev_view_pos;
}
+
+// recalc() is done every time one of the setters is called (making the
+// cached data "dirty"). It calculates all the outputs for viewer.
+void
+FGViewer::recalc ()
+{
+ sgVec3 minus_z, right, forward, tilt;
+ sgMat4 VIEWo;
+ sgMat4 tmpROT; // temp rotation work matrices
+ sgVec3 tmpVec3; // temp work vector (3)
+
+
+ // The position vectors originate from the view point or target location
+ // depending on the type of view.
+
+ if (_type == FG_RPH) {
+ recalcPositionVectors( _lon_deg, _lat_deg, _alt_ft );
+ } else {
+ recalcPositionVectors( _target_lon_deg, _target_lat_deg, _target_alt_ft );
+ }
+
+ sgCopyVec3(zero_elev, _zero_elev_view_pos);
+ sgCopyVec3(view_pos, _relative_view_pos);
+
+ if (_type == FG_LOOKAT) {
+
+ // Make the world up rotation matrix for lookat
+ sgMakeRotMat4( UP, _target_lon_deg, 0.0, -_target_lat_deg );
+
+ // get the world up verctor from the worldup rotation matrix
+ sgSetVec3( world_up, UP[0][0], UP[0][1], UP[0][2] );
+
+ sgCopyVec3( view_up, world_up );
+
+
+ // create offset vector
+ sgVec3 lookat_offset;
+ sgSetVec3( lookat_offset, _x_offset_m, _y_offset_m, _z_offset_m );
+
+ // Apply heading orientation and orientation offset to lookat_offset...
+ sgMakeRotMat4( tmpROT, _heading_offset_deg -_heading_deg, world_up);
+ sgXformVec3( lookat_offset, lookat_offset, UP );
+ sgXformVec3( lookat_offset, lookat_offset, tmpROT );
+
+ // Apply orientation offset tilt...
+ // FIXME: Need to get and use a "right" vector instead of 1-0-0
+ sgSetVec3 (tmpVec3, 1, 0, 0);
+ sgMakeRotMat4( tmpROT, _pitch_offset_deg, tmpVec3 );
+ sgXformPnt3( lookat_offset, lookat_offset, tmpROT );
+
+ // add the offsets including rotations to the coordinates
+ sgAddVec3( view_pos, lookat_offset );
+
+ // Make the VIEW matrix.
+ fgMakeLookAtMat4( VIEW, view_pos, view_forward, view_up );
+
+
+ // the VIEW matrix includes both rotation and translation. Let's
+ // knock out the translation part to make the VIEW_ROT matrix
+ sgCopyMat4( VIEW_ROT, VIEW );
+ VIEW_ROT[3][0] = VIEW_ROT[3][1] = VIEW_ROT[3][2] = 0.0;
+
+ }
+
+ if (_type == FG_RPH) {
+
+ // code to calculate LOCAL matrix calculated from Phi, Theta, and
+ // Psi (roll, pitch, yaw) in case we aren't running LaRCsim as our
+ // flight model
+
+ fgMakeLOCAL( LOCAL, _pitch_deg * SG_DEGREES_TO_RADIANS,
+ _roll_deg * SG_DEGREES_TO_RADIANS,
+ -_heading_deg * SG_DEGREES_TO_RADIANS);
+
+ // Make the world up rotation matrix for pilot view
+ sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg );
+
+ // get the world up verctor from the worldup rotation matrix
+ sgSetVec3( world_up, UP[0][0], UP[0][1], UP[0][2] );
+
+ // VIEWo becomes the rotation matrix with world_up incorporated
+ sgCopyMat4( VIEWo, LOCAL );
+ sgPostMultMat4( VIEWo, UP );
+
+ // generate the sg view up and forward vectors
+ sgSetVec3( view_up, VIEWo[0][0], VIEWo[0][1], VIEWo[0][2] );
+ sgSetVec3( right, VIEWo[1][0], VIEWo[1][1], VIEWo[1][2] );
+ sgSetVec3( forward, VIEWo[2][0], VIEWo[2][1], VIEWo[2][2] );
+
+ // apply the offsets in world coordinates
+ sgVec3 pilot_offset_world;
+ sgSetVec3( pilot_offset_world,
+ _z_offset_m, _y_offset_m, -_x_offset_m );
+ sgXformVec3( pilot_offset_world, pilot_offset_world, VIEWo );
+
+ // generate the view offset matrix using orientation offset (heading)
+ sgMakeRotMat4( VIEW_OFFSET, _heading_offset_deg, view_up );
+
+ // create a tilt matrix using orientation offset (pitch)
+ sgMat4 VIEW_TILT;
+ sgMakeRotMat4( VIEW_TILT, _pitch_offset_deg, right );
+ sgPreMultMat4(VIEW_OFFSET, VIEW_TILT);
+ sgXformVec3( view_forward, forward, VIEW_OFFSET );
+ SG_LOG( SG_VIEW, SG_DEBUG, "(RPH) view forward = "
+ << view_forward[0] << "," << view_forward[1] << ","
+ << view_forward[2] );
+
+ // VIEW_ROT = LARC_TO_SSG * ( VIEWo * VIEW_OFFSET )
+ fgMakeViewRot( VIEW_ROT, VIEW_OFFSET, VIEWo );
+
+ sgVec3 trans_vec;
+ sgAddVec3( trans_vec, view_pos, pilot_offset_world );
+
+ // VIEW = VIEW_ROT * TRANS
+ sgCopyMat4( VIEW, VIEW_ROT );
+ sgPostMultMat4ByTransMat4( VIEW, trans_vec );
+
+ }
+
+ // Given a vector pointing straight down (-Z), map into onto the
+ // local plane representing "horizontal". This should give us the
+ // local direction for moving "south".
+ sgSetVec3( minus_z, 0.0, 0.0, -1.0 );
+
+ sgmap_vec_onto_cur_surface_plane(world_up, view_pos, minus_z,
+ surface_south);
+ sgNormalizeVec3(surface_south);
+
+ // now calculate the surface east vector
+ sgVec3 world_down;
+ sgNegateVec3(world_down, world_up);
+ sgVectorProductVec3(surface_east, surface_south, world_down);
+
+ set_clean();
+}
+
void
-FGViewPoint::recalc () const
+FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const
{
double sea_level_radius_m;
double lat_geoc_rad;
+
// Convert from geodetic to geocentric
// coordinates.
- sgGeodToGeoc(_lat_deg * SGD_DEGREES_TO_RADIANS,
- _alt_ft * SG_FEET_TO_METER,
+ sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS,
+ alt_ft * SG_FEET_TO_METER,
&sea_level_radius_m,
&lat_geoc_rad);
// Calculate the cartesian coordinates
// of point directly below at sea level.
- Point3D p = Point3D(_lon_deg * SG_DEGREES_TO_RADIANS,
+ // aka Zero Elevation Position
+ Point3D p = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
lat_geoc_rad,
sea_level_radius_m);
Point3D tmp = sgPolarToCart3d(p) - scenery.get_next_center();
// Calculate the absolute view position
// in fgfs coordinates.
- p.setz(p.radius() + _alt_ft * SG_FEET_TO_METER);
+ // aka Absolute View Position
+ p.setz(p.radius() + alt_ft * SG_FEET_TO_METER);
tmp = sgPolarToCart3d(p);
sgdSetVec3(_absolute_view_pos, tmp[0], tmp[1], tmp[2]);
// Calculate the relative view position
// from the scenery center.
+ // aka Relative View Position
sgdVec3 scenery_center;
sgdSetVec3(scenery_center,
scenery.get_next_center().x(),
sgdVec3 view_pos;
sgdSubVec3(view_pos, _absolute_view_pos, scenery_center);
sgSetVec3(_relative_view_pos, view_pos);
-}
-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of FGViewer.
-////////////////////////////////////////////////////////////////////////
-
-// Constructor
-FGViewer::FGViewer( void ):
- scalingType(FG_SCALING_MAX),
- fov(55.0),
- view_offset(0.0),
- goal_view_offset(0.0),
- view_tilt(0.0),
- goal_view_tilt(0.0)
-{
- sgSetVec3( pilot_offset, 0.0, 0.0, 0.0 );
- sgdZeroVec3(geod_view_pos);
- sgdZeroVec3(abs_view_pos);
- sea_level_radius = SG_EQUATORIAL_RADIUS_M;
- //a reasonable guess for init, so that the math doesn't blow up
-}
-
-
-// Destructor
-FGViewer::~FGViewer( void ) {
-}
-
-void
-FGViewer::init ()
-{
-}
-
-void
-FGViewer::bind ()
-{
-}
-
-void
-FGViewer::unbind ()
-{
}
double
{
int i;
for ( i = 0; i < dt; i++ ) {
- if ( fabs(get_goal_view_offset() - get_view_offset()) < 0.05 ) {
- set_view_offset( get_goal_view_offset() );
+ if ( fabs(get_goal_view_offset() - getHeadingOffset_deg()) < 1 ) {
+ setHeadingOffset_deg( get_goal_view_offset() );
break;
} else {
- // move current_view.view_offset towards
+ // move current_view.headingoffset towards
// current_view.goal_view_offset
- if ( get_goal_view_offset() > get_view_offset() )
+ if ( get_goal_view_offset() > getHeadingOffset_deg() )
{
- if ( get_goal_view_offset() - get_view_offset() < SGD_PI ){
- inc_view_offset( 0.01 );
+ if ( get_goal_view_offset() - getHeadingOffset_deg() < 180 ){
+ inc_view_offset( 0.5 );
} else {
- inc_view_offset( -0.01 );
+ inc_view_offset( -0.5 );
}
} else {
- if ( get_view_offset() - get_goal_view_offset() < SGD_PI ){
- inc_view_offset( -0.01 );
+ if ( getHeadingOffset_deg() - get_goal_view_offset() < 180 ){
+ inc_view_offset( -0.5 );
} else {
- inc_view_offset( 0.01 );
+ inc_view_offset( 0.5 );
}
}
- if ( get_view_offset() > SGD_2PI ) {
- inc_view_offset( -SGD_2PI );
- } else if ( get_view_offset() < 0 ) {
- inc_view_offset( SGD_2PI );
+ if ( getHeadingOffset_deg() > 360 ) {
+ inc_view_offset( -360 );
+ } else if ( getHeadingOffset_deg() < 0 ) {
+ inc_view_offset( 360 );
}
}
}
for ( i = 0; i < dt; i++ ) {
- if ( fabs(get_goal_view_tilt() - get_view_tilt()) < 0.05 ) {
- set_view_tilt( get_goal_view_tilt() );
+ if ( fabs(get_goal_view_tilt() - getPitchOffset_deg()) < 1 ) {
+ setPitchOffset_deg( get_goal_view_tilt() );
break;
} else {
- // move current_view.view_tilt towards
+ // move current_view.pitch_offset_deg towards
// current_view.goal_view_tilt
- if ( get_goal_view_tilt() > get_view_tilt() )
+ if ( get_goal_view_tilt() > getPitchOffset_deg() )
{
- if ( get_goal_view_tilt() - get_view_tilt() < SGD_PI ){
- inc_view_tilt( 0.01 );
+ if ( get_goal_view_tilt() - getPitchOffset_deg() < 0 ){
+ inc_view_tilt( 1.0 );
} else {
- inc_view_tilt( -0.01 );
+ inc_view_tilt( -1.0 );
}
} else {
- if ( get_view_tilt() - get_goal_view_tilt() < SGD_PI ){
- inc_view_tilt( -0.01 );
+ if ( getPitchOffset_deg() - get_goal_view_tilt() < 0 ){
+ inc_view_tilt( -1.0 );
} else {
- inc_view_tilt( 0.01 );
+ inc_view_tilt( 1.0 );
}
}
- if ( get_view_tilt() > SGD_2PI ) {
- inc_view_tilt( -SGD_2PI );
- } else if ( get_view_tilt() < 0 ) {
- inc_view_tilt( SGD_2PI );
+ if ( getPitchOffset_deg() > 90 ) {
+ setPitchOffset_deg(90);
+ } else if ( getPitchOffset_deg() < -90 ) {
+ setPitchOffset_deg( -90 );
}
}
}
}
+
+
+void FGViewer::fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center,
+ const sgVec3 up )
+{
+ // Caveats:
+ // 1) In order to compute the line of sight, the eye point must not be equal
+ // to the center point.
+ // 2) The up vector must not be parallel to the line of sight from the eye
+ // to the center point.
+
+ /* Compute the direction vectors */
+ sgVec3 x,y,z;
+
+ /* Y vector = center - eye */
+ sgSubVec3 ( y, center, eye ) ;
+
+ /* Z vector = up */
+ sgCopyVec3 ( z, up ) ;
+
+ /* X vector = Y cross Z */
+ sgVectorProductVec3 ( x, y, z ) ;
+
+ /* Recompute Z = X cross Y */
+ sgVectorProductVec3 ( z, x, y ) ;
+
+ /* Normalize everything */
+ sgNormaliseVec3 ( x ) ;
+ sgNormaliseVec3 ( y ) ;
+ sgNormaliseVec3 ( z ) ;
+
+ /* Build the matrix */
+#define M(row,col) dst[row][col]
+ M(0,0) = x[0]; M(0,1) = x[1]; M(0,2) = x[2]; M(0,3) = 0.0;
+ M(1,0) = y[0]; M(1,1) = y[1]; M(1,2) = y[2]; M(1,3) = 0.0;
+ M(2,0) = z[0]; M(2,1) = z[1]; M(2,2) = z[2]; M(2,3) = 0.0;
+ M(3,0) = eye[0]; M(3,1) = eye[1]; M(3,2) = eye[2]; M(3,3) = 1.0;
+#undef M
+}
+/* end from lookat */
+
+/* from rph */
+// VIEW_ROT = LARC_TO_SSG * ( VIEWo * VIEW_OFFSET )
+// This takes advantage of the fact that VIEWo and VIEW_OFFSET
+// only have entries in the upper 3x3 block
+// and that LARC_TO_SSG is just a shift of rows NHV
+void FGViewer::fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 )
+{
+ for ( int j = 0 ; j < 3 ; j++ ) {
+ dst[2][j] = m2[0][0] * m1[0][j] +
+ m2[0][1] * m1[1][j] +
+ m2[0][2] * m1[2][j];
+
+ dst[0][j] = m2[1][0] * m1[0][j] +
+ m2[1][1] * m1[1][j] +
+ m2[1][2] * m1[2][j];
+
+ dst[1][j] = m2[2][0] * m1[0][j] +
+ m2[2][1] * m1[1][j] +
+ m2[2][2] * m1[2][j];
+ }
+ dst[0][3] =
+ dst[1][3] =
+ dst[2][3] =
+ dst[3][0] =
+ dst[3][1] =
+ dst[3][2] = SG_ZERO;
+ dst[3][3] = SG_ONE;
+}
+
+
+void FGViewer::fgMakeLOCAL( sgMat4 dst, const double Theta,
+ const double Phi, const double Psi)
+{
+ SGfloat cosTheta = (SGfloat) cos(Theta);
+ SGfloat sinTheta = (SGfloat) sin(Theta);
+ SGfloat cosPhi = (SGfloat) cos(Phi);
+ SGfloat sinPhi = (SGfloat) sin(Phi);
+ SGfloat sinPsi = (SGfloat) sin(Psi) ;
+ SGfloat cosPsi = (SGfloat) cos(Psi) ;
+
+ dst[0][0] = cosPhi * cosTheta;
+ dst[0][1] = sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
+ dst[0][2] = sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
+ dst[0][3] = SG_ZERO;
+
+ dst[1][0] = -sinPhi * cosTheta;
+ dst[1][1] = cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
+ dst[1][2] = cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
+ dst[1][3] = SG_ZERO ;
+
+ dst[2][0] = sinTheta;
+ dst[2][1] = cosTheta * -sinPsi;
+ dst[2][2] = cosTheta * cosPsi;
+ dst[2][3] = SG_ZERO;
+
+ dst[3][0] = SG_ZERO;
+ dst[3][1] = SG_ZERO;
+ dst[3][2] = SG_ZERO;
+ dst[3][3] = SG_ONE ;
+}
+
+/* end from rph */
+
//
// Written by Curtis Olson, started August 1997.
// overhaul started October 2000.
+// partially rewritten by Jim Wilson jim@kelcomaine.com using interface
+// by David Megginson March 2002
//
// Copyright (C) 1997 - 2000 Curtis L. Olson - curt@flightgear.org
//
#define FG_FOV_MAX 179.9
-/**
- * Representation of a single viewpoint in the FlightGear world.
- */
-class FGViewPoint
-{
+// Define a structure containing view information
+class FGViewer : public FGSubsystem {
+
public:
- FGViewPoint ();
- virtual ~FGViewPoint ();
- /**
- * Set the geodetic position for the view point.
- */
- virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
+ enum fgViewType {
+ FG_RPH = 0,
+ FG_LOOKAT = 1,
+ FG_HPR = 2
+ };
+ enum fgScalingType { // nominal Field Of View actually applies to ...
+ FG_SCALING_WIDTH, // window width
+ FG_SCALING_MAX, // max(width, height)
+ // FG_SCALING_G_MEAN, // geometric_mean(width, height)
+ // FG_SCALING_INDEPENDENT // whole screen
+ };
- /**
- * Get the longitude in degrees.
- */
- virtual double getLongitude_deg () const { return _lon_deg; }
+ // Constructor
+ FGViewer( void );
- /**
- * Get the latitude in degrees.
- */
- virtual double getLatitude_deg () const { return _lat_deg; }
+ // Destructor
+ virtual ~FGViewer( void );
- /**
- * Get the altitude in feet ASL.
- */
- virtual double getAltitudeASL_ft () const { return _alt_ft; }
+ //////////////////////////////////////////////////////////////////////
+ // Part 1: standard FGSubsystem implementation.
+ //////////////////////////////////////////////////////////////////////
- /**
- * Get the absolute view position in fgfs coordinates.
- */
- virtual const double * getAbsoluteViewPos () const;
+ virtual void init ();
+ virtual void bind ();
+ virtual void unbind ();
+ void update (int dt);
- /**
- * Get the relative view position in fgfs coordinates.
- *
- * The position is relative to the scenery centre.
- */
- virtual const float * getRelativeViewPos () const;
+ //////////////////////////////////////////////////////////////////////
+ // Part 2: user settings.
+ //////////////////////////////////////////////////////////////////////
+ virtual fgViewType getType() const { return _type; }
+ virtual void setType( int type );
+
+ // Reference geodetic position of view from position...
+ virtual double getLongitude_deg () const { return _lon_deg; }
+ virtual double getLatitude_deg () const { return _lat_deg; }
+ virtual double getAltitudeASL_ft () const { return _alt_ft; }
+ // Set individual coordinates for the view point position.
+ virtual void setLongitude_deg (double lon_deg);
+ virtual void setLatitude_deg (double lat_deg);
+ virtual void setAltitude_ft (double alt_ft);
+ // Set the geodetic position for the view point.
+ virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
+
+ // Reference geodetic target position...
+ virtual double getTargetLongitude_deg () const { return _target_lon_deg; }
+ virtual double getTargetLatitude_deg () const { return _target_lat_deg; }
+ virtual double getTargetAltitudeASL_ft () const { return _target_alt_ft; }
+ // Set individual coordinates for the Target point position.
+ virtual void setTargetLongitude_deg (double lon_deg);
+ virtual void setTargetLatitude_deg (double lat_deg);
+ virtual void setTargetAltitude_ft (double alt_ft);
+ // Set the geodetic position for the Target point.
+ virtual void setTargetPosition (double lon_deg, double lat_deg, double alt_ft);
+
+ // Refence orientation...
+ virtual double getRoll_deg () const { return _roll_deg; }
+ virtual double getPitch_deg () const {return _pitch_deg; }
+ virtual double getHeading_deg () const {return _heading_deg; }
+ virtual void setRoll_deg (double roll_deg);
+ virtual void setPitch_deg (double pitch_deg);
+ virtual void setHeading_deg (double heading_deg);
+ virtual void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
+
+ // Position offsets from reference
+ virtual double getXOffset_m () const { return _x_offset_m; }
+ virtual double getYOffset_m () const { return _y_offset_m; }
+ virtual double getZOffset_m () const { return _z_offset_m; }
+ virtual void setXOffset_m (double x_offset_m);
+ virtual void setYOffset_m (double y_offset_m);
+ virtual void setZOffset_m (double z_offset_m);
+ virtual void setPositionOffsets (double x_offset_m,
+ double y_offset_m,
+ double z_offset_m);
+
+ // Orientation offsets from reference
+ virtual double getRollOffset_deg () const { return _roll_offset_deg; }
+ virtual double getPitchOffset_deg () const { return _pitch_offset_deg; }
+ virtual double getHeadingOffset_deg () const { return _heading_offset_deg; }
+ virtual void setRollOffset_deg (double roll_offset_deg);
+ virtual void setPitchOffset_deg (double pitch_offset_deg);
+ virtual void setHeadingOffset_deg (double heading_offset_deg);
+ virtual void setOrientationOffsets (double roll_offset_deg,
+ double heading_offset_deg,
+ double pitch_offset_deg);
- /**
- * Get the absolute zero-elevation view position in fgfs coordinates.
- */
- virtual const float * getZeroElevViewPos () const;
-private:
- void recalc () const;
+ //////////////////////////////////////////////////////////////////////
+ // Part 3: output vectors and matrices in FlightGear coordinates.
+ //////////////////////////////////////////////////////////////////////
- mutable sgdVec3 _absolute_view_pos;
- mutable sgVec3 _relative_view_pos;
- mutable sgVec3 _zero_elev_view_pos;
+ // Vectors and positions...
+
+ // Get zero view_pos
+ virtual float * get_view_pos() {if ( _dirty ) { recalc(); } return view_pos; }
+ // Get the absolute view position in fgfs coordinates.
+ virtual double * get_absolute_view_pos ();
+ // Get zero elev
+ virtual float * get_zero_elev() {if ( _dirty ) { recalc(); } return zero_elev; }
+ // Get world up vector
+ virtual float *get_world_up() {if ( _dirty ) { recalc(); } return world_up; }
+ // Get the relative (to scenery center) view position in fgfs coordinates.
+ virtual float * getRelativeViewPos ();
+ // Get the absolute zero-elevation view position in fgfs coordinates.
+ virtual float * getZeroElevViewPos ();
+ // Get surface east vector
+ virtual float *get_surface_east() { if ( _dirty ) { recalc(); } return surface_east; }
+ // Get surface south vector
+ virtual float *get_surface_south() {if ( _dirty ) { recalc(); } return surface_south; }
+
+ // Matrices...
+ virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; }
+ virtual const sgVec4 *get_VIEW_ROT() { if ( _dirty ) { recalc(); } return VIEW_ROT; }
+ virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; }
+ // (future?)
+ // virtual double get_ground_elev() { if ( _dirty ) { recalc(); } return ground_elev; }
- bool _dirty;
- double _lon_deg;
- double _lat_deg;
- double _alt_ft;
-};
+private:
+ // flag forcing a recalc of derived view parameters
+ bool _dirty;
-// Define a structure containing view information
-class FGViewer {
+ void recalc ();
+ void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const;
-public:
+ mutable sgdVec3 _absolute_view_pos;
+ mutable sgVec3 _relative_view_pos;
+ mutable sgVec3 _zero_elev_view_pos;
- enum fgViewType {
- FG_RPH = 0,
- FG_LOOKAT = 1,
- FG_HPR = 2
- };
+ double _lon_deg;
+ double _lat_deg;
+ double _alt_ft;
+ double _target_lon_deg;
+ double _target_lat_deg;
+ double _target_alt_ft;
- enum fgScalingType { // nominal Field Of View actually applies to ...
- FG_SCALING_WIDTH, // window width
- FG_SCALING_MAX, // max(width, height)
- // FG_SCALING_G_MEAN, // geometric_mean(width, height)
- // FG_SCALING_INDEPENDENT // whole screen
- };
+ double _roll_deg;
+ double _pitch_deg;
+ double _heading_deg;
-private:
+ // Position offsets from center of gravity. The X axis is positive
+ // out the tail, Y is out the right wing, and Z is positive up.
+ // distance in meters
+ double _x_offset_m;
+ double _y_offset_m;
+ double _z_offset_m;
- // flag forcing a recalc of derived view parameters
- bool dirty;
+ // orientation offsets from reference
+ double _roll_offset_deg;
+ double _pitch_offset_deg;
+ double _heading_offset_deg;
protected:
fgViewType _type;
fgScalingType scalingType;
- FGViewPoint view_point;
-
// the nominal field of view (angle, in degrees)
double fov;
// ratio of window width and height; height = width * aspect_ratio
double aspect_ratio;
- // the current view offset angle from forward (rotated about the
- // view_up vector)
- double view_offset;
bool reverse_view_offset;
// the goal view offset angle (used for smooth view changes)
double goal_view_offset;
- // the view tilt angles
- double view_tilt;
double goal_view_tilt;
- // geodetic view position
- sgdVec3 geod_view_pos;
-
- // absolute view position in earth coordinates
- sgdVec3 abs_view_pos;
-
// view position in opengl world coordinates (this is the
// abs_view_pos translated to scenery.center)
sgVec3 view_pos;
// height ASL of the terrain for our current view position
// (future?) double ground_elev;
- // pilot offset from center of gravity. The X axis is positive
- // out the tail, Y is out the right wing, and Z is positive up.
- // Distances in meters of course.
- sgVec3 pilot_offset;
-
// surface vector heading south
sgVec3 surface_south;
// sg versions of our friendly matrices
sgMat4 VIEW, VIEW_ROT, UP;
- inline void set_dirty() { dirty = true; }
- inline void set_clean() { dirty = false; }
+ // up vector for the view (usually point straight up through the
+ // top of the aircraft
+ sgVec3 view_up;
- // Update the view volume, position, and orientation
- virtual void update() = 0;
+ // the vector pointing straight out the nose of the aircraft
+ sgVec3 view_forward;
-public:
+ // Transformation matrix for the view direction offset relative to
+ // the AIRCRAFT matrix
+ sgMat4 VIEW_OFFSET;
- // Constructor
- FGViewer( void );
+ // sg versions of our friendly matrices (from lookat)
+ sgMat4 LOCAL, TRANS, LARC_TO_SSG;
- // Destructor
- virtual ~FGViewer( void );
+ inline void set_dirty() { _dirty = true; }
+ inline void set_clean() { _dirty = false; }
+
+ // from lookat
+ void fgMakeLookAtMat4 ( sgMat4 dst, const sgVec3 eye, const sgVec3 center,
+ const sgVec3 up );
+
+ // from rph
+ void fgMakeViewRot( sgMat4 dst, const sgMat4 m1, const sgMat4 m2 );
+ void fgMakeLOCAL( sgMat4 dst, const double Theta,
+ const double Phi, const double Psi);
+
+
+public:
- virtual void init ();
- virtual void bind ();
- virtual void unbind ();
- virtual void update (int dt);
//////////////////////////////////////////////////////////////////////
// setter functions
inline void set_aspect_ratio( double r ) {
aspect_ratio = r;
}
- inline void set_view_offset( double a ) {
- set_dirty();
- view_offset = a;
- }
inline void inc_view_offset( double amt ) {
set_dirty();
- view_offset += amt;
+ _heading_offset_deg += amt;
}
inline void set_goal_view_offset( double a) {
set_dirty();
goal_view_offset = a;
while ( goal_view_offset < 0.0 ) {
- goal_view_offset += SGD_2PI;
+ goal_view_offset += 360;
}
- while ( goal_view_offset > SGD_2PI ) {
- goal_view_offset -= SGD_2PI;
+ while ( goal_view_offset > 360 ) {
+ goal_view_offset -= 360;
}
}
inline void set_reverse_view_offset( bool val ) {
reverse_view_offset = val;
}
- inline void set_view_tilt( double a ) {
- set_dirty();
- view_tilt = a;
- }
inline void inc_view_tilt( double amt ) {
set_dirty();
- view_tilt += amt;
+ _pitch_offset_deg += amt;
}
inline void set_goal_view_tilt( double a) {
set_dirty();
goal_view_tilt = a;
- while ( goal_view_tilt < 0 ) {
- goal_view_tilt += 360.0;
+ while ( goal_view_tilt < -90 ) {
+ goal_view_tilt = -90.0;
}
- while ( goal_view_tilt > 360.0 ) {
- goal_view_tilt -= 360.0;
+ while ( goal_view_tilt > 90.0 ) {
+ goal_view_tilt = 90.0;
}
}
- inline void set_geod_view_pos( double lon, double lat, double alt ) {
- // data should be in radians and meters asl
+ inline void set_sea_level_radius( double r ) {
+ // data should be in meters from the center of the earth
set_dirty();
- // cout << "set_geod_view_pos = " << lon << ", " << lat << ", " << alt
- // << endl;
- sgdSetVec3( geod_view_pos, lon, lat, alt );
+ sea_level_radius = r;
}
- inline void set_pilot_offset( float x, float y, float z ) {
+
+ /* from lookat */
+ inline void set_view_forward( sgVec3 vf ) {
set_dirty();
- sgSetVec3( pilot_offset, x, y, z );
+ sgCopyVec3( view_forward, vf );
}
- inline void set_sea_level_radius( double r ) {
- // data should be in meters from the center of the earth
+ inline void set_view_up( sgVec3 vf ) {
set_dirty();
- sea_level_radius = r;
+ sgCopyVec3( view_up, vf );
}
+ /* end from lookat */
+
//////////////////////////////////////////////////////////////////////
// accessor functions
//////////////////////////////////////////////////////////////////////
inline int get_type() const { return _type ; }
inline int is_a( int t ) const { return get_type() == t ; }
- inline bool is_dirty() const { return dirty; }
+ inline bool is_dirty() const { return _dirty; }
inline double get_fov() const { return fov; }
inline double get_aspect_ratio() const { return aspect_ratio; }
- inline double get_view_offset() const { return view_offset; }
inline bool get_reverse_view_offset() const { return reverse_view_offset; }
inline double get_goal_view_offset() const { return goal_view_offset; }
- inline double get_view_tilt() const { return view_tilt; }
inline double get_goal_view_tilt() const { return goal_view_tilt; }
- inline double *get_geod_view_pos() { return geod_view_pos; }
- inline float *get_pilot_offset() { return pilot_offset; }
inline double get_sea_level_radius() const { return sea_level_radius; }
// Get horizontal field of view angle, in degrees.
double get_h_fov();
// Get vertical field of view angle, in degrees.
double get_v_fov();
+ /* from lookat */
+ inline float *get_view_forward() { return view_forward; }
+ inline float *get_view_up() { return view_up; }
+ /* end from lookat */
+
//////////////////////////////////////////////////////////////////////
// derived values accessor functions
//////////////////////////////////////////////////////////////////////
- inline double *get_abs_view_pos() {
- if ( dirty ) { update(); }
- return abs_view_pos;
- }
- inline float *get_view_pos() {
- if ( dirty ) { update(); }
- return view_pos;
- }
- inline float *get_zero_elev() {
- if ( dirty ) { update(); }
- return zero_elev;
- }
- // (future?)
- // inline double get_ground_elev() {
- // if ( dirty ) { update(); }
- // return ground_elev;
- // }
- inline float *get_surface_south() {
- if ( dirty ) { update(); }
- return surface_south;
- }
- inline float *get_surface_east() {
- if ( dirty ) { update(); }
- return surface_east;
- }
- inline float *get_world_up() {
- if ( dirty ) { update(); }
- return world_up;
- }
- inline const sgVec4 *get_VIEW() {
- if ( dirty ) { update(); }
- return VIEW;
- }
- inline const sgVec4 *get_VIEW_ROT() {
- if ( dirty ) { update(); }
- return VIEW_ROT;
- }
- inline const sgVec4 *get_UP() {
- if ( dirty ) { update(); }
- return UP;
- }
+
};
// viewmgr.cxx -- class for managing all the views in the flightgear world.
//
// Written by Curtis Olson, started October 2000.
+// partially rewritten by Jim Wilson March 2002
//
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
//
void
FGViewMgr::init ()
{
- add_view(new FGViewerRPH);
- add_view(new FGViewerLookAt);
+ add_view(new FGViewer, 0);
+ add_view(new FGViewer, 1);
}
typedef double (FGViewMgr::*double_getter)() const;
* SGD_DEGREES_TO_RADIANS;
// Set up the pilot view
- FGViewerRPH *pilot_view = (FGViewerRPH *)get_view( 0 );
- pilot_view ->set_geod_view_pos(lon_rad, lat_rad, alt_m);
- pilot_view->set_rph(roll_rad, pitch_rad, heading_rad);
+ FGViewer *pilot_view = (FGViewer *)get_view( 0 );
+ pilot_view ->setPosition(
+ fgGetDouble("/position/longitude-deg"),
+ fgGetDouble("/position/latitude-deg"),
+ fgGetDouble("/position/altitude-ft"));
+ pilot_view->setOrientation(
+ fgGetDouble("/orientation/roll-deg"),
+ fgGetDouble("/orientation/pitch-deg"),
+ fgGetDouble("/orientation/heading-deg"));
if (fgGetString("/sim/flight-model") == "ada") {
//+ve x is aft, +ve z is up (see viewer.hxx)
- pilot_view->set_pilot_offset( -5.0, 0.0, 1.0 );
+ pilot_view->setPositionOffsets( -5.0, 0.0, 1.0 );
}
// Set up the chase view
- // FIXME: the matrix math belongs in
- // the viewer, not here.
- FGViewerLookAt *chase_view = (FGViewerLookAt *)get_view( 1 );
-
- sgVec3 po; // chase view pilot_offset
- sgVec3 wup; // chase view world up
- sgSetVec3( po, 0.0, 0.0, 100.0 );
- sgCopyVec3( wup, pilot_view->get_world_up() );
- sgMat4 CXFM; // chase view + pilot offset xform
- sgMakeRotMat4( CXFM,
- chase_view->get_view_offset() * SGD_RADIANS_TO_DEGREES -
- heading_rad * SGD_RADIANS_TO_DEGREES,
- wup );
- sgVec3 npo; // new pilot offset after rotation
- sgVec3 *pPO = PilotOffsetGet();
- sgXformVec3( po, *pPO, pilot_view->get_UP() );
- sgXformVec3( npo, po, CXFM );
+ FGViewer *chase_view = (FGViewer *)get_view( 1 );
- chase_view->set_geod_view_pos(lon_rad, lat_rad, alt_m);
- chase_view->set_pilot_offset( npo[0], npo[1], npo[2] );
- chase_view->set_view_forward( pilot_view->get_view_pos() );
- chase_view->set_view_up( wup );
+ // get xyz Position offsets directly from GUI/sgVec3Slider
+ // FIXME: change GUI/sgVec3Slider to store the xyz in properties
+ // it would probably be faster than the way PilotOffsetGet()
+ // triggers a recalc all the time.
+ sgVec3 *pPO = PilotOffsetGet();
+ sgVec3 zPO;
+ sgCopyVec3( zPO, *pPO );
+ chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
+
+ chase_view->setOrientation(
+ fgGetDouble("/orientation/roll-deg"),
+ fgGetDouble("/orientation/pitch-deg"),
+ fgGetDouble("/orientation/heading-deg"));
+
+ chase_view ->setTargetPosition(
+ fgGetDouble("/position/longitude-deg"),
+ fgGetDouble("/position/latitude-deg"),
+ fgGetDouble("/position/altitude-ft"));
+ chase_view->setPositionOffsets(zPO[0], zPO[1], zPO[2] );
+ chase_view->set_view_forward( pilot_view->get_view_pos() );
// Update the current view
do_axes();
FGViewMgr::getViewOffset_deg () const
{
const FGViewer * view = get_current_view();
- return (view == 0 ? 0 : view->get_view_offset() * SGD_RADIANS_TO_DEGREES);
+ return (view == 0 ? 0 : view->getHeadingOffset_deg());
}
void
{
FGViewer * view = get_current_view();
if (view != 0)
- view->set_view_offset(offset * SGD_DEGREES_TO_RADIANS);
+ view->setHeadingOffset_deg(offset);
}
double
FGViewMgr::getGoalViewOffset_deg () const
{
const FGViewer * view = get_current_view();
- return (view == 0 ? 0 : view->get_goal_view_offset() * SGD_RADIANS_TO_DEGREES);
+ return (view == 0 ? 0 : view->get_goal_view_offset());
}
void
{
FGViewer * view = get_current_view();
if (view != 0)
- view->set_goal_view_offset(offset * SGD_DEGREES_TO_RADIANS);
+ view->set_goal_view_offset(offset);
}
double
FGViewMgr::getViewTilt_deg () const
{
const FGViewer * view = get_current_view();
- return (view == 0 ? 0 : view->get_view_tilt() * SGD_RADIANS_TO_DEGREES);
+ return (view == 0 ? 0 : view->getPitchOffset_deg());
}
void
{
FGViewer * view = get_current_view();
if (view != 0)
- view->set_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
+ view->setPitchOffset_deg(tilt);
}
double
FGViewMgr::getGoalViewTilt_deg () const
{
const FGViewer * view = get_current_view();
- return (view == 0 ? 0 : view->get_goal_view_tilt() * SGD_RADIANS_TO_DEGREES);
+ return (view == 0 ? 0 : view->get_goal_view_tilt());
}
void
{
FGViewer * view = get_current_view();
if (view != 0)
- view->set_goal_view_tilt(tilt * SGD_DEGREES_TO_RADIANS);
+ view->set_goal_view_tilt(tilt);
}
double
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
- return offset[0];
+ return ((FGViewer *)pilot_view)->getXOffset_m();
} else {
return 0;
}
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = pilot_view->get_pilot_offset();
- pilot_view->set_pilot_offset(x, offset[1], offset[2]);
+ pilot_view->setXOffset_m(x);
}
}
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
- return offset[1];
+ return ((FGViewer *)pilot_view)->getYOffset_m();
} else {
return 0;
}
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = pilot_view->get_pilot_offset();
- pilot_view->set_pilot_offset(offset[0], y, offset[2]);
+ pilot_view->setYOffset_m(y);
}
}
// FIXME: hard-coded pilot view position
const FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = ((FGViewer *)pilot_view)->get_pilot_offset();
- return offset[2];
+ return ((FGViewer *)pilot_view)->getZOffset_m();
} else {
return 0;
}
// FIXME: hard-coded pilot view position
FGViewer * pilot_view = get_view(0);
if (pilot_view != 0) {
- float * offset = pilot_view->get_pilot_offset();
- pilot_view->set_pilot_offset(offset[0], offset[1], z);
+ pilot_view->setZOffset_m(z);
}
}
viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
if ( viewDir < -1 ) viewDir += 360;
- get_current_view()->set_goal_view_offset(viewDir*SGD_DEGREES_TO_RADIANS);
+ get_current_view()->set_goal_view_offset(viewDir);
}
+
#include <vector>
#include "fgfs.hxx"
-#include "viewer_lookat.hxx"
-#include "viewer_rph.hxx"
+#include "viewer.hxx"
SG_USING_STD(vector);
// setters
inline void clear() { views.clear(); }
inline void set_view( const int v ) { current = v; }
- inline void add_view( FGViewer * v ) {
+ inline void add_view( FGViewer * v, int type ) {
views.push_back(v);
+ v->setType(type);
+ v->init();
}
private:
#endif // _VIEWMGR_HXX
+
+
+
+
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
// calculate approximate distance from view point
sgdCopyVec3( abs_view_pos,
- globals->get_current_view()->get_abs_view_pos() );
+ globals->get_current_view()->get_absolute_view_pos() );
SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
<< abs_view_pos[0] << ","
return false;
}
}
+
scenery.get_center()[0],
scenery.get_center()[1],
scenery.get_center()[2] );
- hit = fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
+ hit = fgCurrentElev(globals->get_current_view()->get_absolute_view_pos(),
sc,
current_tile->get_terra_transform(),
&hit_list,
tile_cache.next();
}
}
+
SG_LOG( SG_EVENT, SG_ALERT, "Psi rotation bad = " << f->get_Psi() );
exit(-1);
}
- if ( globals->get_current_view()->get_view_offset() < -2.0 * SGD_2PI ||
- globals->get_current_view()->get_view_offset() > 2.0 * SGD_2PI ) {
+ if ( globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS < -2.0 * SGD_2PI ||
+ globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS > 2.0 * SGD_2PI ) {
SG_LOG( SG_EVENT, SG_ALERT, "current view()->view offset bad = "
- << globals->get_current_view()->get_view_offset() );
+ << globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS );
exit(-1);
}
// first determine the difference between our view angle and local
// direction to the sun
rotation = -(sun_rotation + SGD_PI)
- - (f->get_Psi() - globals->get_current_view()->get_view_offset());
+ - (f->get_Psi() - globals->get_current_view()->getHeadingOffset_deg() * SGD_DEGREES_TO_RADIANS);
if ( globals->get_current_view()->get_reverse_view_offset() ) {
rotation += SGD_PI;
}
}
+