From 780b4a813e9c6753355238158f069f4e3ec8937f Mon Sep 17 00:00:00 2001 From: david Date: Mon, 25 Mar 2002 14:32:13 +0000 Subject: [PATCH] Minor patch from David Megginson: Fix FGViewer::update so that pitch offset and goal pitch offset work together nicely (the offset was snapping to 90/-90 when only one of the two was changed). Viewer improvements from Jim Wilson: These files get the 3d cockpit working and fix a few issues in the viewer code. XYZ offsets are now defined as follows: X -left/right+ (along wing axis), Y -up/down+ perpendicular to the aircraft, Z is -in/out+ the aircraft's body axis. I've also done some cleaning up of unused and mostly unusable interfaces, added commentary to the *.hxx, combined together some duplicate code and eliminated a couple unecessary operations. I also moved what was left of the "protected" zone to "private" since we aren't subclassing this anymore. --- src/Main/model.cxx | 77 +++++------ src/Main/viewer.cxx | 305 +++++++++++++++++-------------------------- src/Main/viewer.hxx | 248 +++++++++++++++++++---------------- src/Main/viewmgr.cxx | 2 +- 4 files changed, 297 insertions(+), 335 deletions(-) diff --git a/src/Main/model.cxx b/src/Main/model.cxx index 771a4f87d..21670faf1 100644 --- a/src/Main/model.cxx +++ b/src/Main/model.cxx @@ -148,6 +148,8 @@ FGAircraftModel::unbind () void FGAircraftModel::update (int dt) { + sgMat4 VIEW_ROT; + _current_timestamp.stamp(); long elapsed_ms = (_current_timestamp - _last_timestamp) / 1000; _last_timestamp.stamp(); @@ -165,7 +167,11 @@ FGAircraftModel::update (int dt) (FGViewer *)globals->get_viewmgr()->get_view( 0 ); sgMat4 sgTRANS; - sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() ); + // FIXME: this needs to be unlinked from the viewer + // The lon/lat/alt should come from properties and the + // calculation for relative position should probably be + // added to SimGear. + sgMakeTransMat4( sgTRANS, pilot_view->getRelativeViewPos() ); sgVec3 ownship_up; sgSetVec3( ownship_up, 0.0, 0.0, 1.0); @@ -175,47 +181,41 @@ FGAircraftModel::update (int dt) sgMat4 sgTUX; sgCopyMat4( sgTUX, sgROT ); - sgMat4 VIEW_ROT; - sgCopyMat4( VIEW_ROT, pilot_view->get_VIEW_ROT()); + if (view_number == 0) { - // FIXME: orientation is not applied - // correctly when view is not forward - sgMakeRotMat4( sgROT, -pilot_view->getHeadingOffset_deg(), - pilot_view->get_world_up() ); - - /* Warning lame hack from Wilson ahead */ - /* get the pitch value */ - /* double it to counter the value already in the VIEW_ROT */ - 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 - */ - sgMat4 PunROT; - PunROT[0][0] = SG_ONE; - PunROT[0][1] = SG_ZERO; - PunROT[0][2] = SG_ZERO; - PunROT[0][3] = SG_ZERO; - PunROT[1][0] = SG_ZERO; - PunROT[1][1] = cos((1 - sgROT[0][0]) * -pitch); - PunROT[1][2] = -sin((1 - sgROT[0][0]) * -pitch); - PunROT[1][3] = SG_ZERO; - PunROT[2][0] = SG_ZERO; - PunROT[2][1] = sin((1 - sgROT[0][0]) * -pitch); - PunROT[2][2] = cos((1 - sgROT[0][0]) * -pitch); - PunROT[2][3] = SG_ZERO; - PunROT[3][0] = SG_ZERO; - PunROT[3][1] = SG_ZERO; - PunROT[3][2] = SG_ZERO; - PunROT[3][3] = SG_ONE; - - sgPostMultMat4( sgTUX, PunROT ); - sgPostMultMat4( sgTUX, VIEW_ROT ); - sgPostMultMat4( sgTUX, sgROT ); + + // FIXME: This needs to be unlinked from the viewer + // The lon/lat/alt should come from properties and the + // calculation for relative position should probably be + // added to SimGear. + // Note that the function for building the LOCAL matrix + // or redone using plib. Should probably be moved to Simgear. + // (cockpit_ROT = LOCAL from viewer). + sgMat4 tmpROT; + sgCopyMat4( tmpROT, pilot_view->get_COCKPIT_ROT() ); + sgMat4 cockpit_ROT; + sgCopyMat4( cockpit_ROT, tmpROT ); + + // Make the Cockpit rotation matrix (just juggling the vectors). + cockpit_ROT[0][0] = tmpROT[1][0]; // right + cockpit_ROT[0][1] = tmpROT[1][1]; + cockpit_ROT[0][2] = tmpROT[1][2]; + cockpit_ROT[1][0] = tmpROT[2][0]; // forward + cockpit_ROT[1][1] = tmpROT[2][1]; + cockpit_ROT[1][2] = tmpROT[2][2]; + cockpit_ROT[2][0] = tmpROT[0][0]; // view_up + cockpit_ROT[2][1] = tmpROT[0][1]; + cockpit_ROT[2][2] = tmpROT[0][2]; + + sgPostMultMat4( sgTUX, cockpit_ROT ); sgPostMultMat4( sgTUX, sgTRANS ); - /* end lame hack */ } else { + // FIXME: Model rotation need to be unlinked from the viewer. + // When the cockpit rotation gets removed from viewer + // then it'll be easy to apply offsets and get the equivelant + // of this "VIEW_ROT" thing. + sgCopyMat4( VIEW_ROT, pilot_view->get_VIEW_ROT()); sgPostMultMat4( sgTUX, VIEW_ROT ); sgPostMultMat4( sgTUX, sgTRANS ); } @@ -383,3 +383,4 @@ FGAircraftModel::Animation::setRotation() // end of model.cxx + diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index a40f82275..0fc291b54 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -52,8 +52,8 @@ // Constructor FGViewer::FGViewer( void ): - scalingType(FG_SCALING_MAX), - fov(55.0), + _scaling_type(FG_SCALING_MAX), + _fov_deg(55.0), _dirty(true), _lon_deg(0), _lat_deg(0), @@ -74,7 +74,6 @@ FGViewer::FGViewer( void ): _goal_pitch_offset_deg(0.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 } @@ -267,10 +266,10 @@ FGViewer::setGoalPitchOffset_deg (double goal_pitch_offset_deg) { _dirty = true; _goal_pitch_offset_deg = goal_pitch_offset_deg; - while ( _goal_pitch_offset_deg < -90 ) { + if ( _goal_pitch_offset_deg < -90 ) { _goal_pitch_offset_deg = -90.0; } - while ( _goal_pitch_offset_deg > 90.0 ) { + if ( _goal_pitch_offset_deg > 90.0 ) { _goal_pitch_offset_deg = 90.0; } @@ -330,131 +329,147 @@ void FGViewer::recalc () { sgVec3 minus_z, right, forward, tilt; - sgMat4 VIEWo; sgMat4 tmpROT; // temp rotation work matrices + sgMat4 VIEW_HEADINGOFFSET, VIEW_PITCHOFFSET; sgVec3 tmpVec3; // temp work vector (3) // The position vectors originate from the view point or target location // depending on the type of view. - + // FIXME: In particular this routine will need to support both locations + // and chase view (aka lookat) is only unique in that the + // eye position is calculated in relation to the object's position. + // FIXME: Later note: actually the object (target) info needs to be held + // by the model class. if (_type == FG_RPH) { + // position is the location of the pilot recalcPositionVectors( _lon_deg, _lat_deg, _alt_ft ); + // Make the world up rotation matrix for rph + sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg ); } else { + // position is the location of the object being looked at recalcPositionVectors( _target_lon_deg, _target_lat_deg, _target_alt_ft ); + // Make the world up rotation matrix for lookat + sgMakeRotMat4( UP, _target_lon_deg, 0.0, -_target_lat_deg ); } + // the coordinates generated by the above "recalcPositionVectors" + sgCopyVec3(_zero_elev, _zero_elev_view_pos); + sgCopyVec3(_view_pos, _relative_view_pos); - 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] ); + // get the world up radial vector from planet center + // (ie. effect of aircraft location on earth "sphere" approximation) + 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 ); + // Creat local matrix with current geodetic position. Converting + // the orientation (pitch/roll/heading) to vectors. + fgMakeLOCAL( LOCAL, _pitch_deg * SG_DEGREES_TO_RADIANS, + _roll_deg * SG_DEGREES_TO_RADIANS, + -_heading_deg * SG_DEGREES_TO_RADIANS); + // Adjust LOCAL to current world_up vector (adjustment for planet location) + sgPostMultMat4( LOCAL, UP ); + // make sg vectors view up, right and forward vectors from LOCAL + sgSetVec3( _view_up, LOCAL[0][0], LOCAL[0][1], LOCAL[0][2] ); + sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] ); + sgSetVec3( forward, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] ); - // 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 ); + // create xyz offsets Vector + sgVec3 position_offset; + sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m ); - // 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; + // generate the heading offset matrix using heading_offset angle(s) + if (_type == FG_LOOKAT) { + // Note that when in "chase view" the offset is in relation to the + // orientation heading (_heading_deg) of the model being looked at as + // it is used to rotate around the model. + sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg -_heading_deg, _world_up ); } - if (_type == FG_RPH) { + // generate the view offset matrix using orientation offset (heading) + sgMakeRotMat4( VIEW_HEADINGOFFSET, _heading_offset_deg, _view_up ); + } - // 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] ); + // create a tilt matrix using orientation offset (pitch) + sgMakeRotMat4( VIEW_PITCHOFFSET, _pitch_offset_deg, right ); + + sgCopyMat4(VIEW_OFFSET, VIEW_HEADINGOFFSET); + sgPreMultMat4(VIEW_OFFSET, VIEW_PITCHOFFSET); - // 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] ); + if (_type == FG_LOOKAT) { + + // transfrom "offset" and "orientation offset" to vector + sgXformVec3( position_offset, position_offset, UP ); + sgXformVec3( position_offset, position_offset, VIEW_HEADINGOFFSET ); + sgXformPnt3( position_offset, position_offset, VIEW_PITCHOFFSET ); - // 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 ); + sgVec3 object_pos, eye_pos; + // copy to coordinates to object... + sgCopyVec3( object_pos, _view_pos ); - // 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 ); + // add the offsets from object to the coordinates to get "eye" + sgAddVec3( eye_pos, _view_pos, position_offset ); - sgVec3 trans_vec; - sgAddVec3( trans_vec, view_pos, pilot_offset_world ); + // Make the VIEW matrix for "lookat". + sgMakeLookAtMat4( VIEW, eye_pos, object_pos, _view_up ); + } + + if (_type == FG_RPH) { - // VIEW = VIEW_ROT * TRANS - sgCopyMat4( VIEW, VIEW_ROT ); - sgPostMultMat4ByTransMat4( VIEW, trans_vec ); + sgXformVec3( position_offset, position_offset, LOCAL); + // add the offsets including rotations to the coordinates + sgAddVec3( _view_pos, position_offset ); + // Make the VIEW matrix. + VIEW[0][0] = right[0]; + VIEW[0][1] = right[1]; + VIEW[0][2] = right[2]; + VIEW[1][0] = forward[0]; + VIEW[1][1] = forward[1]; + VIEW[1][2] = forward[2]; + VIEW[2][0] = _view_up[0]; + VIEW[2][1] = _view_up[1]; + VIEW[2][2] = _view_up[2]; + // multiply the OFFSETS (for heading and pitch) into the VIEW + sgPostMultMat4(VIEW, VIEW_OFFSET); + + // add the position data to the matrix + VIEW[3][0] = _view_pos[0]; + VIEW[3][1] = _view_pos[1]; + VIEW[3][2] = _view_pos[2]; + VIEW[3][3] = 1.0f; + + + // copy the LOCAL matrix to COCKPIT_ROT for publication... + sgCopyMat4( COCKPIT_ROT, LOCAL ); } + // 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; + // 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); + 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); + sgNegateVec3(world_down, _world_up); + sgVectorProductVec3(_surface_east, _surface_south, world_down); set_clean(); } @@ -506,16 +521,16 @@ FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) double FGViewer::get_h_fov() { - switch (scalingType) { + switch (_scaling_type) { case FG_SCALING_WIDTH: // h_fov == fov - return fov; + return _fov_deg; case FG_SCALING_MAX: - if (aspect_ratio < 1.0) { + if (_aspect_ratio < 1.0) { // h_fov == fov - return fov; + return _fov_deg; } else { // v_fov == fov - return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) / aspect_ratio) * + return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) / _aspect_ratio) * SG_RADIANS_TO_DEGREES * 2; } default: @@ -526,18 +541,18 @@ FGViewer::get_h_fov() double FGViewer::get_v_fov() { - switch (scalingType) { + switch (_scaling_type) { case FG_SCALING_WIDTH: // h_fov == fov - return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) * aspect_ratio) * + return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) * _aspect_ratio) * SG_RADIANS_TO_DEGREES * 2; case FG_SCALING_MAX: - if (aspect_ratio < 1.0) { + if (_aspect_ratio < 1.0) { // h_fov == fov - return atan(tan(fov/2 * SG_DEGREES_TO_RADIANS) * aspect_ratio) * + return atan(tan(_fov_deg/2 * SG_DEGREES_TO_RADIANS) * _aspect_ratio) * SG_RADIANS_TO_DEGREES * 2; } else { // v_fov == fov - return fov; + return _fov_deg; } default: assert(false); @@ -558,21 +573,21 @@ FGViewer::update (int dt) if ( _goal_heading_offset_deg > _heading_offset_deg ) { if ( _goal_heading_offset_deg - _heading_offset_deg < 180 ){ - inc_view_offset( 0.5 ); + incHeadingOffset_deg( 0.5 ); } else { - inc_view_offset( -0.5 ); + incHeadingOffset_deg( -0.5 ); } } else { if ( _heading_offset_deg - _goal_heading_offset_deg < 180 ){ - inc_view_offset( -0.5 ); + incHeadingOffset_deg( -0.5 ); } else { - inc_view_offset( 0.5 ); + incHeadingOffset_deg( 0.5 ); } } if ( _heading_offset_deg > 360 ) { - inc_view_offset( -360 ); + incHeadingOffset_deg( -360 ); } else if ( _heading_offset_deg < 0 ) { - inc_view_offset( 360 ); + incHeadingOffset_deg( 360 ); } } } @@ -583,20 +598,12 @@ FGViewer::update (int dt) break; } else { // move current_view.pitch_offset_deg towards - // current_view.goal_view_tilt + // current_view.goal_pitch_offset if ( _goal_pitch_offset_deg > _pitch_offset_deg ) { - if ( _goal_pitch_offset_deg - _pitch_offset_deg < 0 ){ - inc_view_tilt( 1.0 ); - } else { - inc_view_tilt( -1.0 ); - } + incPitchOffset_deg( 1.0 ); } else { - if ( _pitch_offset_deg - _goal_pitch_offset_deg < 0 ){ - inc_view_tilt( -1.0 ); - } else { - inc_view_tilt( 1.0 ); - } + incPitchOffset_deg( -1.0 ); } if ( _pitch_offset_deg > 90 ) { setPitchOffset_deg(90); @@ -607,76 +614,6 @@ FGViewer::update (int dt) } } - -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) { @@ -708,6 +645,4 @@ void FGViewer::fgMakeLOCAL( sgMat4 dst, const double Theta, dst[3][3] = SG_ONE ; } -/* end from rph */ - diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index 2b6a5f52d..aeff7b110 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -85,38 +85,43 @@ public: virtual fgViewType getType() const { return _type; } virtual void setType( int type ); - // Reference geodetic position of view from position... + // Reference geodetic position of view from position... + // These are the actual aircraft position (pilot in + // pilot view, model in model view). + // FIXME: the model view position (ie target positions) + // should be in the model class. 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... + // 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 + + + // Position offsets from reference + // These offsets position they "eye" in the scene according to a given + // location. For example in pilot view they are used to position the + // head inside the aircraft. + // Note that in pilot view these are applied "before" the orientation + // rotations (see below) so that the orientation rotations have the + // effect of the pilot staying in his seat and "looking out" in + // different directions. + // In chase view these are applied "after" the application of the + // orientation rotations listed below. This has the effect of the + // eye moving around and "looking at" the object (model) from + // different angles. 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; } @@ -127,9 +132,38 @@ public: double y_offset_m, double z_offset_m); - // Orientation offsets from reference - // Goal settings are for smooth transition from prior - // offset when changing view direction. + + + + // Reference orientation rotations... + // These are rotations that represent the plane attitude effect on + // the view (in Pilot view). IE The view frustrum rotates as the plane + // turns, pitches, and rolls. + // In model view (lookat/chaseview) these end up changing the angle that + // the eye is looking at the ojbect (ie the model). + // FIXME: the FGModel class should have its own version of these so that + // it can generate it's own model rotations. + 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); + + + + + // Orientation offsets rotations from reference orientation. + // Goal settings are for smooth transition from prior + // offset when changing view direction. + // These offsets are in ADDITION to the orientation rotations listed + // above. + // In pilot view they are applied after the position offsets in order to + // give the effect of the pilot looking around. + // In lookat view they are applied before the position offsets so that + // the effect is the eye moving around looking at the object (ie the model) + // from different angles. 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; } @@ -154,39 +188,57 @@ public: // 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. + // 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. + // 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. + // 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; } + // 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... + // 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_COCKPIT_ROT() { if ( _dirty ) { recalc(); } return COCKPIT_ROT; } virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; } - // (future?) - // virtual double get_ground_elev() { if ( _dirty ) { recalc(); } return ground_elev; } + // Public flags... + virtual bool get_reverse_view_offset() const { return _reverse_view_offset; } + + ////////////////////////////////////////////////////////////////////// + // Part 4: frustrum data setters and getters + ////////////////////////////////////////////////////////////////////// + + virtual void set_fov( double fov_deg ) { + _fov_deg = fov_deg; + } + virtual double get_fov() const { return _fov_deg; } + virtual double get_h_fov(); // Get horizontal fov, in degrees. + virtual double get_v_fov(); // Get vertical fov, in degrees. + + virtual void set_aspect_ratio( double r ) { + _aspect_ratio = r; + } + virtual double get_aspect_ratio() const { return _aspect_ratio; } private: + ////////////////////////////////////////////////////////////////// + // private data // + ////////////////////////////////////////////////////////////////// + // flag forcing a recalc of derived view parameters bool _dirty; - void recalc (); - void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const; - mutable sgdVec3 _absolute_view_pos; mutable sgVec3 _relative_view_pos; mutable sgVec3 _zero_elev_view_pos; @@ -217,60 +269,57 @@ private: double _goal_pitch_offset_deg; double _goal_heading_offset_deg; -protected: - fgViewType _type; - fgScalingType scalingType; + fgScalingType _scaling_type; // the nominal field of view (angle, in degrees) - double fov; + double _fov_deg; // ratio of window width and height; height = width * aspect_ratio - double aspect_ratio; + double _aspect_ratio; - bool reverse_view_offset; + bool _reverse_view_offset; // view position in opengl world coordinates (this is the // abs_view_pos translated to scenery.center) - sgVec3 view_pos; - - // radius to sea level from center of the earth (m) - double sea_level_radius; + sgVec3 _view_pos; // cartesion coordinates of current lon/lat if at sea level // translated to scenery.center - sgVec3 zero_elev; - - // height ASL of the terrain for our current view position - // (future?) double ground_elev; + sgVec3 _zero_elev; // surface vector heading south - sgVec3 surface_south; + sgVec3 _surface_south; // surface vector heading east (used to unambiguously align sky // with sun) - sgVec3 surface_east; + sgVec3 _surface_east; // world up vector (normal to the plane tangent to the earth's // surface at the spot we are directly above - sgVec3 world_up; - - // sg versions of our friendly matrices - sgMat4 VIEW, VIEW_ROT, UP; + sgVec3 _world_up; // up vector for the view (usually point straight up through the // top of the aircraft - sgVec3 view_up; + sgVec3 _view_up; + +// // the vector pointing straight out the nose of the aircraft +// sgVec3 _view_forward; - // the vector pointing straight out the nose of the aircraft - sgVec3 view_forward; + // sg versions of our friendly matrices + sgMat4 VIEW, VIEW_ROT, UP, COCKPIT_ROT; + sgMat4 LOCAL, TRANS, LARC_TO_SSG; // Transformation matrix for the view direction offset relative to // the AIRCRAFT matrix sgMat4 VIEW_OFFSET; - // sg versions of our friendly matrices (from lookat) - sgMat4 LOCAL, TRANS, LARC_TO_SSG; + ////////////////////////////////////////////////////////////////// + // private functions // + ////////////////////////////////////////////////////////////////// + + void recalc (); + void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const; inline void set_dirty() { _dirty = true; } inline void set_clean() { _dirty = false; } @@ -285,68 +334,44 @@ protected: const double Phi, const double Psi); -public: - - - ////////////////////////////////////////////////////////////////////// - // setter functions - ////////////////////////////////////////////////////////////////////// - - inline void set_fov( double fov_deg ) { - fov = fov_deg; - } - - inline void set_aspect_ratio( double r ) { - aspect_ratio = r; - } - inline void inc_view_offset( double amt ) { + // add to _heading_offset_deg + inline void incHeadingOffset_deg( double amt ) { set_dirty(); _heading_offset_deg += amt; } - inline void set_reverse_view_offset( bool val ) { - reverse_view_offset = val; - } - inline void inc_view_tilt( double amt ) { + + // add to _pitch_offset_deg + inline void incPitchOffset_deg( double amt ) { set_dirty(); _pitch_offset_deg += amt; } - inline void set_sea_level_radius( double r ) { - // data should be in meters from the center of the earth - set_dirty(); - sea_level_radius = r; - } - /* from lookat */ - inline void set_view_forward( sgVec3 vf ) { - set_dirty(); - sgCopyVec3( view_forward, vf ); - } - inline void set_view_up( sgVec3 vf ) { - set_dirty(); - sgCopyVec3( view_up, vf ); + inline void set_reverse_view_offset( bool val ) { + _reverse_view_offset = val; } - /* end from lookat */ + + +// public: + + + ////////////////////////////////////////////////////////////////////// + // setter functions + ////////////////////////////////////////////////////////////////////// + +// inline void set_sea_level_radius( double r ) { +// // data should be in meters from the center of the earth +// set_dirty(); +// sea_level_radius = r; +// } ////////////////////////////////////////////////////////////////////// // 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 double get_fov() const { return fov; } - inline double get_aspect_ratio() const { return aspect_ratio; } - inline bool get_reverse_view_offset() const { return reverse_view_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 */ +// 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 double get_sea_level_radius() const { return sea_level_radius; } ////////////////////////////////////////////////////////////////////// // derived values accessor functions @@ -359,3 +384,4 @@ public: + diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index 169f10efd..c405937ec 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -160,7 +160,6 @@ FGViewMgr::update (int dt) 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(); @@ -365,3 +364,4 @@ FGViewMgr::do_axes () } + -- 2.39.5