X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Fviewer.cxx;h=4b77efb8cbd4c28a09797d020a140903d3c08ad7;hb=f6e80608797fa9ab9d44444eb7b031e412b83067;hp=f9e62dbcf763c6c8d57a70fa1062ef7469375514;hpb=56473dc28d960524ccdf83b33f477adcade1fcd4;p=flightgear.git diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index f9e62dbcf..4b77efb8c 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -39,7 +39,6 @@ #include #include -//#include
#include #include
@@ -446,36 +445,16 @@ void FGViewer::updateFromModelLocation (FGLocation * location) { sgCopyMat4(LOCAL, location->getCachedTransformMatrix()); - _lon_deg = location->getLongitude_deg(); - _lat_deg = location->getLatitude_deg(); - _alt_ft = location->getAltitudeASL_ft(); - _roll_deg = location->getRoll_deg(); - _pitch_deg = location->getPitch_deg(); - _heading_deg = location->getHeading_deg(); - sgCopyVec3(_zero_elev_view_pos, location->get_zero_elev()); - sgCopyVec3(_relative_view_pos, location->get_view_pos()); - sgdCopyVec3(_absolute_view_pos, location->get_absolute_view_pos()); - sgCopyMat4(UP, location->getCachedUpMatrix()); - sgCopyVec3(_world_up, location->get_world_up()); - // these are the vectors that the sun and moon code like to get... - sgCopyVec3(_surface_east, location->get_surface_east()); - sgCopyVec3(_surface_south, location->get_surface_south()); } void -FGViewer::recalcOurOwnLocation (double lon_deg, double lat_deg, double alt_ft, +FGViewer::recalcOurOwnLocation (FGLocation * location, double lon_deg, double lat_deg, double alt_ft, double roll_deg, double pitch_deg, double heading_deg) { // update from our own data... - _location->setPosition( lon_deg, lat_deg, alt_ft ); - _location->setOrientation( roll_deg, pitch_deg, heading_deg ); - sgCopyMat4(LOCAL, _location->getTransformMatrix()); - sgCopyVec3(_zero_elev_view_pos, _location->get_zero_elev()); - sgCopyVec3(_relative_view_pos, _location->get_view_pos()); - sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos()); - // these are the vectors that the sun and moon code like to get... - sgCopyVec3(_surface_east, _location->get_surface_east()); - sgCopyVec3(_surface_south, _location->get_surface_south()); + location->setPosition( lon_deg, lat_deg, alt_ft ); + location->setOrientation( roll_deg, pitch_deg, heading_deg ); + sgCopyMat4(LOCAL, location->getTransformMatrix()); } // recalc() is done every time one of the setters is called (making the @@ -484,198 +463,188 @@ FGViewer::recalcOurOwnLocation (double lon_deg, double lat_deg, double alt_ft, void FGViewer::recalc () { - sgVec3 right, forward; - sgMat4 tmpROT; // temp rotation work matrices - sgVec3 eye_pos, at_pos; - sgVec3 position_offset; // eye position offsets (xyz) - - // The position vectors originate from the view point or target location - // depending on the type of view. - if (_type == FG_LOOKFROM) { - // LOOKFROM mode... - if ( _from_model ) { - // update or data from model location - updateFromModelLocation(_location); - } else { - // update from our own data... - recalcOurOwnLocation( _lon_deg, _lat_deg, _alt_ft, - _roll_deg, _pitch_deg, _heading_deg ); - // get world up data from just recalced location - sgCopyMat4(UP, _location->getUpMatrix()); - sgCopyVec3(_world_up, _location->get_world_up()); - } - + recalcLookFrom(); } else { + recalcLookAt(); + } - // LOOKAT mode... - if ( _from_model ) { - // update or data from model location - updateFromModelLocation(_location); - } else { - // update from our own data, just the rotation here... - recalcOurOwnLocation( _lon_deg, _lat_deg, _alt_ft, - _roll_deg, _pitch_deg, _heading_deg ); - // get world up data from just recalced location - sgCopyMat4(UP, _location->getUpMatrix()); - sgCopyVec3(_world_up, _location->get_world_up()); - } - // save they eye positon... - sgCopyVec3(eye_pos, _location->get_view_pos()); - // save the eye rotation before getting target values!!! - sgCopyMat4(tmpROT, LOCAL); - - if ( _at_model ) { - // update or data from model location - updateFromModelLocation(_target_location); - } else { - // if not model then calculate our own target position... - recalcOurOwnLocation( _target_lon_deg, _target_lat_deg, _target_alt_ft, - _target_roll_deg, _target_pitch_deg, _target_heading_deg ); - } - // restore the eye rotation (the from position rotation) - sgCopyMat4(LOCAL, tmpROT); + set_clean(); +} - } +// recalculate for LookFrom view type... +void +FGViewer::recalcLookFrom () +{ - // the coordinates generated by the above "recalcPositionVectors" - sgCopyVec3(_zero_elev, _zero_elev_view_pos); - sgCopyVec3(_view_pos, _relative_view_pos); + sgVec3 right, forward; + sgVec3 eye_pos; + sgVec3 position_offset; // eye position offsets (xyz) + + // LOOKFROM mode... - // FIXME: - // Doing this last recalc here for published values...where the airplane is - // This should be per aircraft or model (for published values) before - // multiple FDM can be done. - // This info should come directly from the model (not through viewer), - // because in some cases there is no model directly assigned as a lookfrom - // position. The problem that arises is related to the FDM interface looking - // indirectly to the viewer to find the altitude of the aircraft on the runway. - // - // Note that recalcPositionVectors can be removed from viewer when this - // issue is addressed. - // - if (!_from_model) { - recalcPositionVectors(fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg"), - fgGetDouble("/position/altitude-ft")); + // Update location data... + if ( _from_model ) { + // update or data from model location + updateFromModelLocation(_location); + } else { + // update from our own data... + recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft, + _roll_deg, _pitch_deg, _heading_deg ); } + // copy data from location class to local items... + copyLocationData(); + // make sg vectors view up, right and forward vectors from LOCAL sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] ); sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] ); sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] ); - if (_type == FG_LOOKAT) { - // Note that when in "lookat" view the "world up" vector is always applied - // to the viewer. World up is based on verticle at a given lon/lat (see - // matrix "UP" above). + // Note that when in "lookfrom" view the "view up" vector is always applied + // to the viewer. View up is based on verticle of the aircraft itself. (see + // "LOCAL" matrix above) - // Orientation Offsets matrix - MakeVIEW_OFFSET( VIEW_OFFSET, - (_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up, - _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); - - // add in the Orientation Offsets here - sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m ); - sgXformVec3( position_offset, position_offset, UP); + // Orientation Offsets matrix + MakeVIEW_OFFSET( VIEW_OFFSET, + _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up, + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); - sgXformVec3( position_offset, position_offset, VIEW_OFFSET ); + // Make the VIEW matrix. + sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO); + sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO); + sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO); + sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE); - // add the Position offsets from object to the eye position - sgAddVec3( eye_pos, eye_pos, position_offset ); + // rotate matrix to get a matrix to apply Eye Position Offsets + sgMat4 VIEW_UP; // L0 forward L1 right L2 up + sgCopyVec4(VIEW_UP[0], LOCAL[1]); + sgCopyVec4(VIEW_UP[1], LOCAL[2]); + sgCopyVec4(VIEW_UP[2], LOCAL[0]); + sgZeroVec4(VIEW_UP[3]); - // at position (what we are looking at) - sgCopyVec3( at_pos, _view_pos ); + // Eye Position Offsets to vector + sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m ); + sgXformVec3( position_offset, position_offset, VIEW_UP); - // Make the VIEW matrix for a "LOOKAT". - sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up ); - } + // add the offsets including rotations to the translation vector + sgAddVec3( _view_pos, position_offset ); - if (_type == FG_LOOKFROM) { + // multiply the OFFSETS (for heading and pitch) into the VIEW + sgPostMultMat4(VIEW, VIEW_OFFSET); - // Note that when in "lookfrom" view the "view up" vector is always applied - // to the viewer. View up is based on verticle of the aircraft itself. (see - // "LOCAL" matrix above) + // add the position data to the matrix + sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE); - // Orientation Offsets matrix - MakeVIEW_OFFSET( VIEW_OFFSET, - _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up, - _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); +} - // Make the VIEW matrix. - sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO); - sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO); - sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO); - sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE); +void +FGViewer::recalcLookAt () +{ - // rotate matrix to get a matrix to apply Eye Position Offsets - sgMat4 VIEW_UP; // L0 forward L1 right L2 up - sgCopyVec4(VIEW_UP[0], LOCAL[1]); - sgCopyVec4(VIEW_UP[1], LOCAL[2]); - sgCopyVec4(VIEW_UP[2], LOCAL[0]); - sgZeroVec4(VIEW_UP[3]); + sgVec3 right; + sgVec3 eye_pos, at_pos; + sgVec3 position_offset; // eye position offsets (xyz) - // Eye Position Offsets to vector - sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m ); - sgXformVec3( position_offset, position_offset, VIEW_UP); + // The position vectors originate from the view point or target location + // depending on the type of view. - // add the offsets including rotations to the translation vector - sgAddVec3( _view_pos, position_offset ); + // LOOKAT mode... - // multiply the OFFSETS (for heading and pitch) into the VIEW - sgPostMultMat4(VIEW, VIEW_OFFSET); + // Update location data for target... + if ( _at_model ) { + // update or data from model location + updateFromModelLocation(_target_location); + } else { + // if not model then calculate our own target position... + recalcOurOwnLocation( _target_location, _target_lon_deg, _target_lat_deg, _target_alt_ft, + _target_roll_deg, _target_pitch_deg, _target_heading_deg ); + } + // calculate the "at" target object positon relative to eye or view's tile center... + sgdVec3 dVec3; + sgdSetVec3(dVec3, _location->get_tile_center()[0], _location->get_tile_center()[1], _location->get_tile_center()[2]); + sgdSubVec3(dVec3, _target_location->get_absolute_view_pos(), dVec3 ); + sgSetVec3(at_pos, dVec3[0], dVec3[1], dVec3[2]); + + // Update location data for eye... + if ( _from_model ) { + // update or data from model location + updateFromModelLocation(_location); + } else { + // update from our own data, just the rotation here... + recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft, + _roll_deg, _pitch_deg, _heading_deg ); + } + // save the eye positon... + sgCopyVec3(eye_pos, _location->get_view_pos()); - // add the position data to the matrix - sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE); + // copy data from location class to local items... + copyLocationData(); - } + // make sg vectors view up, right and forward vectors from LOCAL + sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] ); + sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] ); - set_clean(); -} + // Note that when in "lookat" view the "world up" vector is always applied + // to the viewer. World up is based on verticle at a given lon/lat (see + // matrix "UP" above). -void -FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const -{ - double sea_level_radius_m; - double lat_geoc_rad; + // Orientation Offsets matrix + MakeVIEW_OFFSET( VIEW_OFFSET, + (_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up, + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); + + // add in the Orientation Offsets here + sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m ); + sgXformVec3( position_offset, position_offset, UP); + + sgXformVec3( position_offset, position_offset, VIEW_OFFSET ); + // add the Position offsets from object to the eye position + sgAddVec3( eye_pos, eye_pos, position_offset ); - // Convert from geodetic to geocentric - // coordinates. - sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS, - alt_ft * SG_FEET_TO_METER, - &sea_level_radius_m, - &lat_geoc_rad); + // Make the VIEW matrix for a "LOOKAT". + sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up ); - // Calculate the cartesian coordinates - // of point directly below at sea level. - // 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(); - sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]); +} + +// copy results from location class to viewer... +// FIXME: some of these should be changed to reference directly to FGLocation... +void +FGViewer::copyLocationData() +{ + // Get our friendly vectors from the eye location... + sgCopyVec3(_zero_elev_view_pos, _location->get_zero_elev()); + sgCopyVec3(_relative_view_pos, _location->get_view_pos()); + sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos()); + sgCopyMat4(UP, _location->getCachedUpMatrix()); + sgCopyVec3(_world_up, _location->get_world_up()); + // these are the vectors that the sun and moon code like to get... + sgCopyVec3(_surface_east, _location->get_surface_east()); + sgCopyVec3(_surface_south, _location->get_surface_south()); - // Calculate the absolute view position - // in fgfs coordinates. - // 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]); + // Update viewer's postion data for the eye location... + _lon_deg = _location->getLongitude_deg(); + _lat_deg = _location->getLatitude_deg(); + _alt_ft = _location->getAltitudeASL_ft(); + _roll_deg = _location->getRoll_deg(); + _pitch_deg = _location->getPitch_deg(); + _heading_deg = _location->getHeading_deg(); - // Calculate the relative view position - // from the scenery center. - // aka Relative View Position - sgdVec3 scenery_center; - sgdSetVec3(scenery_center, - scenery.get_next_center().x(), - scenery.get_next_center().y(), - scenery.get_next_center().z()); - sgdVec3 view_pos; - sgdSubVec3(view_pos, _absolute_view_pos, scenery_center); - sgSetVec3(_relative_view_pos, view_pos); + // Update viewer's postion data for the target (at object) location + if (_type == FG_LOOKAT) { + _target_lon_deg = _target_location->getLongitude_deg(); + _target_lat_deg = _target_location->getLatitude_deg(); + _target_alt_ft = _target_location->getAltitudeASL_ft(); + _target_roll_deg = _target_location->getRoll_deg(); + _target_pitch_deg = _target_location->getPitch_deg(); + _target_heading_deg = _target_location->getHeading_deg(); + } + // copy coordinates to outputs for viewer... + sgCopyVec3(_zero_elev, _zero_elev_view_pos); + sgCopyVec3(_view_pos, _relative_view_pos); } double @@ -699,6 +668,8 @@ FGViewer::get_h_fov() return 0.0; } + + double FGViewer::get_v_fov() { @@ -722,10 +693,11 @@ FGViewer::get_v_fov() } void -FGViewer::update (int dt) +FGViewer::update (double dt) { int i; - for ( i = 0; i < dt; i++ ) { + int dt_ms = int(dt * 1000); + for ( i = 0; i < dt_ms; i++ ) { if ( fabs( _goal_heading_offset_deg - _heading_offset_deg) < 1 ) { setHeadingOffset_deg( _goal_heading_offset_deg ); break; @@ -754,7 +726,7 @@ FGViewer::update (int dt) } } - for ( i = 0; i < dt; i++ ) { + for ( i = 0; i < dt_ms; i++ ) { if ( fabs( _goal_pitch_offset_deg - _pitch_offset_deg ) < 1 ) { setPitchOffset_deg( _goal_pitch_offset_deg ); break;