X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FMain%2Fviewer.cxx;h=67f4cec18d12a88b35522953ff736f9a9f4e00ae;hb=b3e969726249e772da4c9d1aa6eb212e6472aed3;hp=1f6c1d450006198e338014844447d331be0817cb;hpb=8ef4374edb8b61c0ba19d6c270fb21a91a29867d;p=flightgear.git diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index 1f6c1d450..67f4cec18 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -38,12 +38,12 @@ #include #include #include +#include #include #include
#include #include -#include #include "viewer.hxx" @@ -57,7 +57,8 @@ // by considering them to be 3x3 until the very end -- NHV static void MakeVIEW_OFFSET( sgMat4 dst, const float angle1, const sgVec3 axis1, - const float angle2, const sgVec3 axis2 ) + const float angle2, const sgVec3 axis2, + const float angle3, const sgVec3 axis3 ) { // make rotmatrix1 from angle and axis float s = (float) sin ( angle1 ) ; @@ -101,20 +102,59 @@ static void MakeVIEW_OFFSET( sgMat4 dst, mat2[2][1] = tmp * axis2[1] - s * axis2[0] ; mat2[2][2] = tmp * axis2[2] + c ; + + // make rotmatrix3 from angle and axis (roll) + s = (float) sin ( angle3 ) ; + c = (float) cos ( angle3 ) ; + t = SG_ONE - c ; + + sgMat3 mat3; + tmp = t * axis3[0]; + mat3[0][0] = tmp * axis3[0] + c ; + mat3[0][1] = tmp * axis3[1] + s * axis3[2] ; + mat3[0][2] = tmp * axis3[2] - s * axis3[1] ; + + tmp = t * axis2[1]; + mat3[1][0] = tmp * axis3[0] - s * axis3[2] ; + mat3[1][1] = tmp * axis3[1] + c ; + mat3[1][2] = tmp * axis3[2] + s * axis3[0] ; + + tmp = t * axis3[2]; + mat3[2][0] = tmp * axis3[0] + s * axis3[1] ; + mat3[2][1] = tmp * axis3[1] - s * axis3[0] ; + mat3[2][2] = tmp * axis3[2] + c ; + + sgMat3 matt; + // multiply matrices for ( int j = 0 ; j < 3 ; j++ ) { - dst[0][j] = mat2[0][0] * mat1[0][j] + + matt[0][j] = mat2[0][0] * mat1[0][j] + mat2[0][1] * mat1[1][j] + mat2[0][2] * mat1[2][j]; - dst[1][j] = mat2[1][0] * mat1[0][j] + + matt[1][j] = mat2[1][0] * mat1[0][j] + mat2[1][1] * mat1[1][j] + mat2[1][2] * mat1[2][j]; - dst[2][j] = mat2[2][0] * mat1[0][j] + + matt[2][j] = mat2[2][0] * mat1[0][j] + mat2[2][1] * mat1[1][j] + mat2[2][2] * mat1[2][j]; } + + // multiply matrices + for ( int j = 0 ; j < 3 ; j++ ) { + dst[0][j] = mat3[0][0] * matt[0][j] + + mat3[0][1] * matt[1][j] + + mat3[0][2] * matt[2][j]; + + dst[1][j] = mat3[1][0] * matt[0][j] + + mat3[1][1] * matt[1][j] + + mat3[1][2] * matt[2][j]; + + dst[2][j] = mat3[2][0] * matt[0][j] + + mat3[2][1] * matt[1][j] + + mat3[2][2] * matt[2][j]; + } // fill in 4x4 matrix elements dst[0][3] = SG_ZERO; dst[1][3] = SG_ZERO; @@ -131,13 +171,14 @@ static void MakeVIEW_OFFSET( sgMat4 dst, //////////////////////////////////////////////////////////////////////// // Constructor... -FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, +FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, bool at_model, int at_model_index, - double x_offset_m, double y_offset_m, double z_offset_m, + double damp_roll, double damp_pitch, double damp_heading, + double x_offset_m, double y_offset_m, double z_offset_m, double heading_offset_deg, double pitch_offset_deg, double roll_offset_deg, double fov_deg, double target_x_offset_m, double target_y_offset_m, - double target_z_offset_m, double near_m ): + double target_z_offset_m, double near_m, bool internal ): _dirty(true), _lon_deg(0), _lat_deg(0), @@ -148,6 +189,10 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, _roll_deg(0), _pitch_deg(0), _heading_deg(0), + _damp_sync(0), + _damp_roll(0), + _damp_pitch(0), + _damp_heading(0), _scaling_type(FG_SCALING_MAX) { sgdZeroVec3(_absolute_view_pos); @@ -156,6 +201,16 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, _from_model_index = from_model_index; _at_model = at_model; _at_model_index = at_model_index; + + _internal = internal; + + if (damp_roll > 0.0) + _damp_roll = 1.0 / pow(10.0, fabs(damp_roll)); + if (damp_pitch > 0.0) + _damp_pitch = 1.0 / pow(10.0, fabs(damp_pitch)); + if (damp_heading > 0.0) + _damp_heading = 1.0 / pow(10.0, fabs(damp_heading)); + _x_offset_m = x_offset_m; _y_offset_m = y_offset_m; _z_offset_m = z_offset_m; @@ -186,15 +241,15 @@ void FGViewer::init () { if ( _from_model ) - _location = (FGLocation *) globals->get_aircraft_model()->get3DModel()->getFGLocation(); + _location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation(); else - _location = (FGLocation *) new FGLocation; + _location = (SGLocation *) new SGLocation; if ( _type == FG_LOOKAT ) { if ( _at_model ) - _target_location = (FGLocation *) globals->get_aircraft_model()->get3DModel()->getFGLocation(); + _target_location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation(); else - _target_location = (FGLocation *) new FGLocation; + _target_location = (SGLocation *) new SGLocation; } } @@ -217,6 +272,12 @@ FGViewer::setType ( int type ) _type = FG_LOOKAT; } +void +FGViewer::setInternal ( bool internal ) +{ + _internal = internal; +} + void FGViewer::setLongitude_deg (double lon_deg) { @@ -477,23 +538,24 @@ FGViewer::getZeroElevViewPos () } void -FGViewer::updateFromModelLocation (FGLocation * location) +FGViewer::updateFromModelLocation (SGLocation * location) { sgCopyMat4(LOCAL, location->getCachedTransformMatrix()); } void -FGViewer::updateAtModelLocation (FGLocation * location) +FGViewer::updateAtModelLocation (SGLocation * location) { sgCopyMat4(ATLOCAL, location->getCachedTransformMatrix()); } void -FGViewer::recalcOurOwnLocation (FGLocation * location, double lon_deg, double lat_deg, double alt_ft, +FGViewer::recalcOurOwnLocation (SGLocation * location, double lon_deg, double lat_deg, double alt_ft, double roll_deg, double pitch_deg, double heading_deg) { // update from our own data... + dampEyeData(roll_deg, pitch_deg, heading_deg); location->setPosition( lon_deg, lat_deg, alt_ft ); location->setOrientation( roll_deg, pitch_deg, heading_deg ); sgCopyMat4(LOCAL, @@ -544,7 +606,6 @@ FGViewer::recalcLookFrom () sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] ); sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] ); - // 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) @@ -552,7 +613,8 @@ FGViewer::recalcLookFrom () // Orientation Offsets matrix MakeVIEW_OFFSET( VIEW_OFFSET, _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up, - _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right, + _roll_offset_deg * SG_DEGREES_TO_RADIANS, forward ); // Make the VIEW matrix. sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO); @@ -586,7 +648,7 @@ void FGViewer::recalcLookAt () { - sgVec3 right; + sgVec3 right, forward; sgVec3 eye_pos, at_pos; sgVec3 position_offset; // eye position offsets (xyz) sgVec3 target_position_offset; // target position offsets (xyz) @@ -631,6 +693,7 @@ FGViewer::recalcLookAt () // 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] ); // rotate model or local matrix to get a matrix to apply Eye Position Offsets sgMat4 VIEW_UP; // L0 forward L1 right L2 up @@ -642,7 +705,8 @@ FGViewer::recalcLookAt () // get Orientation Offsets matrix MakeVIEW_OFFSET( VIEW_OFFSET, (_heading_offset_deg - 180) * SG_DEGREES_TO_RADIANS, _view_up, - _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right ); + _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right, + _roll_offset_deg * SG_DEGREES_TO_RADIANS, forward ); // add in the position offsets sgSetVec3( position_offset, _y_offset_m, _x_offset_m, _z_offset_m ); @@ -668,7 +732,7 @@ FGViewer::recalcLookAt () } // copy results from location class to viewer... -// FIXME: some of these should be changed to reference directly to FGLocation... +// FIXME: some of these should be changed to reference directly to SGLocation... void FGViewer::copyLocationData() { @@ -706,6 +770,64 @@ FGViewer::copyLocationData() sgCopyVec3(_view_pos, _relative_view_pos); } +void +FGViewer::dampEyeData (double &roll_deg, double &pitch_deg, double &heading_deg) +{ + const double interval = 0.01; + + static FGViewer *last_view = 0; + if (last_view != this) { + _damp_sync = 0.0; + _damped_roll_deg = roll_deg; + _damped_pitch_deg = pitch_deg; + _damped_heading_deg = heading_deg; + last_view = this; + return; + } + + if (_damp_sync < interval) { + if (_damp_roll > 0.0) + roll_deg = _damped_roll_deg; + if (_damp_pitch > 0.0) + pitch_deg = _damped_pitch_deg; + if (_damp_heading > 0.0) + heading_deg = _damped_heading_deg; + return; + } + + while (_damp_sync >= interval) { + _damp_sync -= interval; + + double d; + if (_damp_roll > 0.0) { + d = _damped_roll_deg - roll_deg; + if (d >= 180.0) + _damped_roll_deg -= 360.0; + else if (d < -180.0) + _damped_roll_deg += 360.0; + roll_deg = _damped_roll_deg = roll_deg * _damp_roll + _damped_roll_deg * (1 - _damp_roll); + } + + if (_damp_pitch > 0.0) { + d = _damped_pitch_deg - pitch_deg; + if (d >= 180.0) + _damped_pitch_deg -= 360.0; + else if (d < -180.0) + _damped_pitch_deg += 360.0; + pitch_deg = _damped_pitch_deg = pitch_deg * _damp_pitch + _damped_pitch_deg * (1 - _damp_pitch); + } + + if (_damp_heading > 0.0) { + d = _damped_heading_deg - heading_deg; + if (d >= 180.0) + _damped_heading_deg -= 360.0; + else if (d < -180.0) + _damped_heading_deg += 360.0; + heading_deg = _damped_heading_deg = heading_deg * _damp_heading + _damped_heading_deg * (1 - _damp_heading); + } + } +} + double FGViewer::get_h_fov() { @@ -754,6 +876,8 @@ FGViewer::get_v_fov() void FGViewer::update (double dt) { + _damp_sync += dt; + int i; int dt_ms = int(dt * 1000); for ( i = 0; i < dt_ms; i++ ) { @@ -805,4 +929,27 @@ FGViewer::update (double dt) } } } + + + for ( i = 0; i < dt_ms; i++ ) { + if ( fabs( _goal_roll_offset_deg - _roll_offset_deg ) < 1 ) { + setRollOffset_deg( _goal_roll_offset_deg ); + break; + } else { + // move current_view.roll_offset_deg towards + // current_view.goal_roll_offset + if ( _goal_roll_offset_deg > _roll_offset_deg ) + { + incRollOffset_deg( 1.0 ); + } else { + incRollOffset_deg( -1.0 ); + } + if ( _roll_offset_deg > 90 ) { + setRollOffset_deg(90); + } else if ( _roll_offset_deg < -90 ) { + setRollOffset_deg( -90 ); + } + } + } + }