From 7e5d6d1d75e56f3537acbf28230dd307da965d96 Mon Sep 17 00:00:00 2001 From: frohlich Date: Wed, 1 Nov 2006 21:22:25 +0000 Subject: [PATCH] Modified Files: Time/tmp.cxx Main/viewer.hxx Main/viewer.cxx Main/renderer.cxx Get rid of an other OSGFIXME. The view matrix had some plib specials included. The viewer is now updated for that. --- src/Main/renderer.cxx | 39 ++-- src/Main/viewer.cxx | 482 ++++++++++++++---------------------------- src/Main/viewer.hxx | 81 +++---- src/Time/tmp.cxx | 10 +- 4 files changed, 203 insertions(+), 409 deletions(-) diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index 8e0cfb55d..c691479d2 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -278,6 +278,12 @@ FGRenderer::init( void ) { sceneView->setUpdateVisitor(new SGUpdateVisitor); sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); + + sceneView->getCamera()->setViewMatrix(osg::Matrix(0, 0,-1, 0, + 1, 0, 0, 0, + 0,-1, 0, 0, + 0, 0, 0, 1)); + sceneView->getCamera()->setClearMask(0); osg::StateSet* stateSet = mRoot->getOrCreateStateSet(); @@ -412,6 +418,7 @@ FGRenderer::update( bool refresh_camera_settings ) { bool enhanced_lighting = fgGetBool("/sim/rendering/enhanced-lighting"); bool distance_attenuation = fgGetBool("/sim/rendering/distance-attenuation"); + // OSGFIXME SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting, distance_attenuation ); @@ -461,26 +468,12 @@ FGRenderer::update( bool refresh_camera_settings ) { resize( fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize") ); - // OSGFXME: compute the view directly without indirection through ssg - sgMat4 viewmat; - sgTransposeNegateMat4(viewmat, (sgVec4 *)current__view->get_VIEW()); - sgMat4 cameraMatrix = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, -1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } - }; - sgPreMultMat4(cameraMatrix, viewmat); - - osg::Matrixd m; - for (unsigned i = 0; i < 4; ++i) - for (unsigned j = 0; j < 4; ++j) - m(i, j) = cameraMatrix[i][j]; - - osg::Quat attitude; - attitude.set(m); - mCameraView->setPosition(osg::Vec3d(m(3,0), m(3,1), m(3,2))); - mCameraView->setAttitude(attitude); + SGVec3d center = globals->get_scenery()->get_center(); + SGVec3d position = current__view->getViewPosition(); + SGQuatd attitude = current__view->getViewOrientation(); + SGVec3d osgPosition = attitude.transform(center - position); + mCameraView->setPosition(osgPosition.osg()); + mCameraView->setAttitude(inverse(attitude).osg()); } if ( skyblend ) { @@ -520,9 +513,9 @@ FGRenderer::update( bool refresh_camera_settings ) { static SGSkyState sstate; - sstate.view_pos = SGVec3f(current__view->get_view_pos()); - sstate.zero_elev = SGVec3f(current__view->get_zero_elev()); - sstate.view_up = SGVec3f(current__view->get_world_up()); + sstate.view_pos = current__view->get_view_pos(); + sstate.zero_elev = current__view->get_zero_elev(); + sstate.view_up = current__view->get_world_up(); sstate.lon = current__view->getLongitude_deg() * SGD_DEGREES_TO_RADIANS; sstate.lat = current__view->getLatitude_deg() diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index c6304468d..c29b99dbe 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -51,124 +51,6 @@ #include "viewer.hxx" -////////////////////////////////////////////////////////////////// -// Norman's Optimized matrix rotators! // -////////////////////////////////////////////////////////////////// - - -// Since these are pure rotation matrices we can save some bookwork -// 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 angle3, const sgVec3 axis3 ) -{ - // make rotmatrix1 from angle and axis - float s = (float) sin ( angle1 ) ; - float c = (float) cos ( angle1 ) ; - float t = SG_ONE - c ; - - sgMat3 mat1; - float tmp = t * axis1[0]; - mat1[0][0] = tmp * axis1[0] + c ; - mat1[0][1] = tmp * axis1[1] + s * axis1[2] ; - mat1[0][2] = tmp * axis1[2] - s * axis1[1] ; - - tmp = t * axis1[1]; - mat1[1][0] = tmp * axis1[0] - s * axis1[2] ; - mat1[1][1] = tmp * axis1[1] + c ; - mat1[1][2] = tmp * axis1[2] + s * axis1[0] ; - - tmp = t * axis1[2]; - mat1[2][0] = tmp * axis1[0] + s * axis1[1] ; - mat1[2][1] = tmp * axis1[1] - s * axis1[0] ; - mat1[2][2] = tmp * axis1[2] + c ; - - // make rotmatrix2 from angle and axis - s = (float) sin ( angle2 ) ; - c = (float) cos ( angle2 ) ; - t = SG_ONE - c ; - - sgMat3 mat2; - tmp = t * axis2[0]; - mat2[0][0] = tmp * axis2[0] + c ; - mat2[0][1] = tmp * axis2[1] + s * axis2[2] ; - mat2[0][2] = tmp * axis2[2] - s * axis2[1] ; - - tmp = t * axis2[1]; - mat2[1][0] = tmp * axis2[0] - s * axis2[2] ; - mat2[1][1] = tmp * axis2[1] + c ; - mat2[1][2] = tmp * axis2[2] + s * axis2[0] ; - - tmp = t * axis2[2]; - mat2[2][0] = tmp * axis2[0] + s * axis2[1] ; - 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 * axis3[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++ ) { - matt[0][j] = mat2[0][0] * mat1[0][j] + - mat2[0][1] * mat1[1][j] + - mat2[0][2] * mat1[2][j]; - - matt[1][j] = mat2[1][0] * mat1[0][j] + - mat2[1][1] * mat1[1][j] + - mat2[1][2] * mat1[2][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; - 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; -} - - //////////////////////////////////////////////////////////////////////// // Implementation of FGViewer. //////////////////////////////////////////////////////////////////////// @@ -197,9 +79,11 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, _damp_roll(0), _damp_pitch(0), _damp_heading(0), - _scaling_type(FG_SCALING_MAX) + _scaling_type(FG_SCALING_MAX), + _location(0), + _target_location(0) { - sgdZeroVec3(_absolute_view_pos); + _absolute_view_pos = SGVec3d(0, 0, 0); _type = Type; _from_model = from_model; _from_model_index = from_model_index; @@ -215,9 +99,9 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, 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; + _offset_m.x() = x_offset_m; + _offset_m.y() = y_offset_m; + _offset_m.z() = z_offset_m; _heading_offset_deg = heading_offset_deg; _pitch_offset_deg = pitch_offset_deg; _roll_offset_deg = roll_offset_deg; @@ -230,9 +114,9 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index, _fov_deg = 55; } _aspect_ratio_multiplier = aspect_ratio_multiplier; - _target_x_offset_m = target_x_offset_m; - _target_y_offset_m = target_y_offset_m; - _target_z_offset_m = target_z_offset_m; + _target_offset_m.x() = target_x_offset_m; + _target_offset_m.y() = target_y_offset_m; + _target_offset_m.z() = target_z_offset_m; _ground_level_nearplane_m = near_m; // a reasonable guess for init, so that the math doesn't blow up } @@ -248,7 +132,7 @@ FGViewer::init () if ( _from_model ) _location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation(); else - _location = (SGLocation *) new SGLocation; + _location = new SGLocation; if ( _type == FG_LOOKAT ) { if ( _at_model ) @@ -407,51 +291,51 @@ void FGViewer::setXOffset_m (double x_offset_m) { _dirty = true; - _x_offset_m = x_offset_m; + _offset_m.x() = x_offset_m; } void FGViewer::setYOffset_m (double y_offset_m) { _dirty = true; - _y_offset_m = y_offset_m; + _offset_m.y() = y_offset_m; } void FGViewer::setZOffset_m (double z_offset_m) { _dirty = true; - _z_offset_m = z_offset_m; + _offset_m.z() = z_offset_m; } void FGViewer::setTargetXOffset_m (double target_x_offset_m) { _dirty = true; - _target_x_offset_m = target_x_offset_m; + _target_offset_m.x() = target_x_offset_m; } void FGViewer::setTargetYOffset_m (double target_y_offset_m) { _dirty = true; - _target_y_offset_m = target_y_offset_m; + _target_offset_m.y() = target_y_offset_m; } void FGViewer::setTargetZOffset_m (double target_z_offset_m) { _dirty = true; - _target_z_offset_m = target_z_offset_m; + _target_offset_m.z() = target_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; + _offset_m.x() = x_offset_m; + _offset_m.y() = y_offset_m; + _offset_m.z() = z_offset_m; } void @@ -523,38 +407,7 @@ FGViewer::get_absolute_view_pos () { if (_dirty) recalc(); - return _absolute_view_pos; -} - -float * -FGViewer::getRelativeViewPos () -{ - if (_dirty) - recalc(); - return _relative_view_pos; -} - -void -FGViewer::updateFromModelLocation (SGLocation * location) -{ - sgCopyMat4(LOCAL, location->getTransformMatrix()); -} - -void -FGViewer::updateAtModelLocation (SGLocation * location) -{ - sgCopyMat4(ATLOCAL, location->getTransformMatrix()); -} - -void -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, location->getTransformMatrix()); + return _absolute_view_pos.data(); } // recalc() is done every time one of the setters is called (making the @@ -569,6 +422,36 @@ FGViewer::recalc () recalcLookAt(); } + SGVec3d center = globals->get_scenery()->get_center(); + _view_pos = toVec3f(_absolute_view_pos - center); + + SGGeod geodEyePoint = SGGeod::fromCart(_absolute_view_pos); + geodEyePoint.setElevationM(0); + _zero_elev = toVec3f(SGVec3d::fromGeod(geodEyePoint) - center); + + SGQuatd hlOr = SGQuatd::fromLonLat(geodEyePoint); + _surface_south = toVec3f(hlOr.backTransform(-SGVec3d::e1())); + _surface_east = toVec3f(hlOr.backTransform(SGVec3d::e2())); + _world_up = toVec3f(hlOr.backTransform(-SGVec3d::e3())); + + // 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(); + + // 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(); + } + set_clean(); } @@ -576,189 +459,134 @@ FGViewer::recalc () void FGViewer::recalcLookFrom () { - sgVec3 right, forward; - sgVec3 position_offset; // eye position offsets (xyz) - - // LOOKFROM mode... - - // Update location data... - if ( _from_model ) { - // update or data from model location - updateFromModelLocation(_location); - } else { + // Update location data ... + if ( !_from_model ) { + _location->setPosition( _lon_deg, _lat_deg, _alt_ft ); + _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg ); + _location->getTransformMatrix(); + } + double lat = _location->getLatitude_deg(); + double lon = _location->getLongitude_deg(); + double alt = _location->getAltitudeASL_ft(); + double head = _location->getHeading_deg(); + double pitch = _location->getPitch_deg(); + double roll = _location->getRoll_deg(); + if ( !_from_model ) { // update from our own data... - recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft, - _roll_deg, _pitch_deg, _heading_deg ); + dampEyeData(roll, pitch, head); } - // 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] ); - - // 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 * SG_DEGREES_TO_RADIANS, _view_up, - _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); - 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); + // The geodetic position of our base view position + SGGeod geodPos = SGGeod::fromDegFt(lon, lat, alt); + // The rotation rotating from the earth centerd frame to + // the horizontal local frame + SGQuatd hlOr = SGQuatd::fromLonLat(geodPos); + // the rotation from the horizontal local frame to the basic view orientation + SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll); + // The cartesian position of the basic view coordinate + SGVec3d position = SGVec3d::fromGeod(geodPos); + // the rotation offset, don't know why heading is negative here ... + SGQuatd viewOffsetOr = + SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg, + _roll_offset_deg); - // rotate model or local 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]); - - // Eye Position Offsets to vector - sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m ); - sgXformVec3( position_offset, position_offset, VIEW_UP); - - // add the offsets including rotations to the translation vector - sgAddVec3( _view_pos, position_offset ); - - // multiply the OFFSETS (for heading and pitch) into the VIEW - sgPostMultMat4(VIEW, VIEW_OFFSET); - - // add the position data to the matrix - sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE); + // The offset vector is meant: x +right/-left, y +up/-down, z, +back/-fwd + // We work in the body coordinate system which is slightly different + SGVec3d off(-_offset_m.z(), _offset_m.x(), -_offset_m.y()); + // Compute the eyepoints orientation and position + // wrt the earth centered frame - that is global coorinates + SGQuatd ec2body = hlOr*hlToBody; + _absolute_view_pos = position + ec2body.backTransform(off); + mViewOrientation = ec2body*viewOffsetOr; } void FGViewer::recalcLookAt () { - sgVec3 right, forward; - sgVec3 eye_pos, at_pos; - sgVec3 position_offset; // eye position offsets (xyz) - sgVec3 target_position_offset; // target position offsets (xyz) - - // The position vectors originate from the view point or target location - // depending on the type of view. - - // LOOKAT mode... - - // Update location data for target... + // The geodetic position of our target to look at + SGGeod geodTargetPos; + SGQuatd geodTargetOr; if ( _at_model ) { - // update or data from model location - updateAtModelLocation(_target_location); + geodTargetPos = SGGeod::fromDegFt(_target_location->getLongitude_deg(), + _target_location->getLatitude_deg(), + _target_location->getAltitudeASL_ft()); + double head = _target_location->getHeading_deg(); + double pitch = _target_location->getPitch_deg(); + double roll = _target_location->getRoll_deg(); + geodTargetOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll); } else { + dampEyeData(_target_roll_deg, _target_pitch_deg, _target_heading_deg); + _target_location->setPosition( _target_lon_deg, _target_lat_deg, _target_alt_ft ); + _target_location->setOrientation( _target_roll_deg, _target_pitch_deg, _target_heading_deg ); + _target_location->getTransformMatrix(); + // 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 ); + geodTargetPos = SGGeod::fromDegFt(_target_lon_deg, + _target_lat_deg, + _target_alt_ft); + geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg, + _target_pitch_deg, + _target_roll_deg); } - // calculate the "at" target object positon relative to eye or view's tile center... - SGVec3d center = globals->get_scenery()->get_center(); - sgdVec3 dVec3; - sgdSetVec3(dVec3, center[0], center[1], center[2]); - sgdSubVec3(dVec3, _target_location->get_absolute_view_pos(), dVec3 ); - sgSetVec3(at_pos, dVec3[0], dVec3[1], dVec3[2]); + SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(geodTargetPos); - // Update location data for eye... + + SGGeod geodEyePos; + SGQuatd geodEyeOr; if ( _from_model ) { - // update or data from model location - updateFromModelLocation(_location); + geodEyePos = SGGeod::fromDegFt(_location->getLongitude_deg(), + _location->getLatitude_deg(), + _location->getAltitudeASL_ft()); + double head = _location->getHeading_deg(); + double pitch = _location->getPitch_deg(); + double roll = _location->getRoll_deg(); + geodEyeOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll); } else { + dampEyeData(_roll_deg, _pitch_deg, _heading_deg); + _location->setPosition( _lon_deg, _lat_deg, _alt_ft ); + _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg ); + _location->getTransformMatrix(); + // update from our own data, just the rotation here... - recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft, - _roll_deg, _pitch_deg, _heading_deg ); + geodEyePos = SGGeod::fromDegFt(_lon_deg, _lat_deg, _alt_ft); + geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg, + _pitch_deg, + _roll_deg); } - // save the eye positon... - sgCopyVec3(eye_pos, _location->get_view_pos(center)); - - // copy data from location class to local items... - copyLocationData(); + SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(geodEyePos); - // 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] ); + // the rotation offset, don't know why heading is negative here ... + SGQuatd eyeOffsetOr = + SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg, + _roll_offset_deg); - // rotate model or local 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]); + // Offsets to the eye position + SGVec3d eyeOff(-_offset_m.z(), _offset_m.y(), -_offset_m.x()); + SGQuatd ec2eye = geodEyeHlOr*geodEyeOr; + SGVec3d eyeCart = SGVec3d::fromGeod(geodEyePos); + eyeCart += (ec2eye*eyeOffsetOr).backTransform(eyeOff); - // 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, - _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 ); - sgXformVec3( position_offset, position_offset, VIEW_UP); - - // apply the Orientation offsets - sgXformVec3( position_offset, position_offset, VIEW_OFFSET ); - - // add the Position offsets from object to the eye position - sgAddVec3( eye_pos, eye_pos, position_offset ); + SGVec3d atCart = SGVec3d::fromGeod(geodTargetPos); // add target offsets to at_position... - sgSetVec3(target_position_offset, _target_z_offset_m, _target_x_offset_m, - _target_y_offset_m ); - sgXformVec3(target_position_offset, target_position_offset, ATLOCAL); - sgAddVec3( at_pos, at_pos, target_position_offset); - - sgAddVec3( eye_pos, eye_pos, target_position_offset); - - // Make the VIEW matrix for a "LOOKAT". - sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up ); - -} - -// copy results from location class to viewer... -// FIXME: some of these should be changed to reference directly to SGLocation... -void -FGViewer::copyLocationData() -{ - SGVec3d center = globals->get_scenery()->get_center(); - // Get our friendly vectors from the eye location... - sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos()); - sgCopyVec3(_relative_view_pos, _location->get_view_pos(center)); - 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()); - - // 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(); - - // 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, _relative_view_pos); - sgAddScaledVec3(_zero_elev, _world_up, -_alt_ft*SG_FEET_TO_METER); - sgCopyVec3(_view_pos, _relative_view_pos); + SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(), + -_target_offset_m.y()); + target_pos_off = (geodTargetHlOr*geodTargetOr).backTransform(target_pos_off); + atCart += target_pos_off; + eyeCart += target_pos_off; + + // Compute the eyepoints orientation and position + // wrt the earth centered frame - that is global coorinates + _absolute_view_pos = eyeCart; + + // the view direction + SGVec3d dir = normalize(atCart - eyeCart); + // the up directon + SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, 1)); + // rotate dir to the 0-th unit vector + // rotate up to 2-th unit vector + mViewOrientation = SGQuatd::fromRotateTo(dir, 0, up, 2); } void diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index 4a7f42b63..2e46afba6 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -130,12 +130,12 @@ public: // 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; } - virtual double getTargetXOffset_m () const { return _target_x_offset_m; } - virtual double getTargetYOffset_m () const { return _target_y_offset_m; } - virtual double getTargetZOffset_m () const { return _target_z_offset_m; } + virtual double getXOffset_m () const { return _offset_m.x(); } + virtual double getYOffset_m () const { return _offset_m.y(); } + virtual double getZOffset_m () const { return _offset_m.z(); } + virtual double getTargetXOffset_m () const { return _target_offset_m.x(); } + virtual double getTargetYOffset_m () const { return _target_offset_m.y(); } + virtual double getTargetZOffset_m () const { return _target_offset_m.z(); } virtual void setXOffset_m (double x_offset_m); virtual void setYOffset_m (double y_offset_m); virtual void setZOffset_m (double z_offset_m); @@ -210,23 +210,20 @@ public: // Vectors and positions... // Get zero view_pos - virtual float * get_view_pos() {if ( _dirty ) { recalc(); } return _view_pos; } + const SGVec3f& 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; } + const SGVec3f& 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 (); + const SGVec3f& get_world_up() {if ( _dirty ) { recalc(); } return _world_up; } // Get surface east vector - virtual float *get_surface_east() { if ( _dirty ) { recalc(); } return _surface_east; } + const SGVec3f& get_surface_east() { if ( _dirty ) { recalc(); } return _surface_east; } // Get surface south vector - virtual float *get_surface_south() {if ( _dirty ) { recalc(); } return _surface_south; } + const SGVec3f& get_surface_south() {if ( _dirty ) { recalc(); } return _surface_south; } - // Matrices... - virtual const sgVec4 *get_VIEW() { if ( _dirty ) { recalc(); } return VIEW; } - virtual const sgVec4 *get_UP() { if ( _dirty ) { recalc(); } return UP; } + const SGVec3d& getViewPosition() { if ( _dirty ) { recalc(); } return _absolute_view_pos; } + const SGQuatd& getViewOrientation() { if ( _dirty ) { recalc(); } return mViewOrientation; } ////////////////////////////////////////////////////////////////////// // Part 4: View and frustrum data setters and getters @@ -276,8 +273,9 @@ private: // flag forcing a recalc of derived view parameters bool _dirty; - mutable sgdVec3 _absolute_view_pos; - mutable sgVec3 _relative_view_pos; + SGQuatd mViewOrientation; + SGVec3d _absolute_view_pos; + SGVec3f _relative_view_pos; double _lon_deg; double _lat_deg; @@ -305,16 +303,12 @@ private: // Position offsets from FDM origin. 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; + SGVec3d _offset_m; // Target offsets from FDM origin (for "lookat" targets) The X // axis is positive out the tail, Y is out the right wing, and Z // is positive up. distance in meters - double _target_x_offset_m; - double _target_y_offset_m; - double _target_z_offset_m; + SGVec3d _target_offset_m; // orientation offsets from reference (_goal* are for smoothed transitions) @@ -346,49 +340,35 @@ private: SGLocation * _target_location; // the nominal field of view (angle, in degrees) - double _fov_deg; + double _fov_deg; // Ratio of window width and height; height = width * // aspect_ratio. This value is automatically calculated based on // window dimentions. - double _aspect_ratio; + double _aspect_ratio; // default = 1.0, this value is user configurable and is // multiplied into the aspect_ratio to get the actual vertical fov double _aspect_ratio_multiplier; - bool _reverse_view_offset; - // view position in opengl world coordinates (this is the // abs_view_pos translated to scenery.center) - sgVec3 _view_pos; + SGVec3f _view_pos; // cartesion coordinates of current lon/lat if at sea level // translated to scenery.center - sgVec3 _zero_elev; + SGVec3f _zero_elev; // surface vector heading south - sgVec3 _surface_south; + SGVec3f _surface_south; // surface vector heading east (used to unambiguously align sky // with sun) - sgVec3 _surface_east; + SGVec3f _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; - - // up vector for the view (usually point straight up through the - // top of the aircraft - sgVec3 _view_up; - - // sg versions of our friendly matrices - sgMat4 VIEW, UP; - sgMat4 LOCAL, ATLOCAL, TRANS, LARC_TO_SSG; - - // Transformation matrix for the view direction offset relative to - // the AIRCRAFT matrix - sgMat4 VIEW_OFFSET; + SGVec3f _world_up; ////////////////////////////////////////////////////////////////// // private functions // @@ -397,12 +377,7 @@ private: void recalc (); void recalcLookFrom(); void recalcLookAt(); - void copyLocationData(); - void updateFromModelLocation (SGLocation * location); - void updateAtModelLocation (SGLocation * location); - void recalcOurOwnLocation (SGLocation * location, double lon_deg, double lat_deg, double alt_ft, - double roll_deg, double pitch_deg, double heading_deg); - void dampEyeData (double &roll_deg, double &pitch_deg, double &heading_deg); + void dampEyeData(double &roll_deg, double &pitch_deg, double &heading_deg); // add to _heading_offset_deg inline void incHeadingOffset_deg( double amt ) { @@ -422,10 +397,6 @@ private: _roll_offset_deg += amt; } - inline void set_reverse_view_offset( bool val ) { - _reverse_view_offset = val; - } - }; diff --git a/src/Time/tmp.cxx b/src/Time/tmp.cxx index 180396484..7e9e75189 100644 --- a/src/Time/tmp.cxx +++ b/src/Time/tmp.cxx @@ -115,7 +115,7 @@ void fgUpdateSunPos( void ) { // << ","<< l->sun_vec[2] << endl; // calculate the sun's relative angle to local up - sgCopyVec3( nup, v->get_world_up() ); + sgCopyVec3( nup, v->get_world_up().data() ); sgSetVec3( nsun, l->get_sunpos().x(), l->get_sunpos().y(), l->get_sunpos().z() ); sgNormalizeVec3(nup); @@ -141,7 +141,9 @@ void fgUpdateSunPos( void ) { // earth's surface the sun is directly over, map into onto the // local plane representing "horizontal". - sgmap_vec_onto_cur_surface_plane( v->get_world_up(), v->get_view_pos(), + SGVec3f world_up = v->get_world_up(); + SGVec3f view_pos = v->get_view_pos(); + sgmap_vec_onto_cur_surface_plane( world_up.data(), view_pos.data(), to_sun, surface_to_sun ); sgNormalizeVec3(surface_to_sun); // cout << "(sg) Surface direction to sun is " @@ -155,13 +157,13 @@ void fgUpdateSunPos( void ) { // v->get_surface_east(). We do this so we can sort out the // acos() ambiguity. I wish I could think of a more efficient // way. :-( - east_dot = sgScalarProductVec3( surface_to_sun, v->get_surface_east() ); + east_dot = sgScalarProductVec3( surface_to_sun, v->get_surface_east().data() ); // cout << " East dot product = " << east_dot << endl; // calculate the angle between v->surface_to_sun and // v->surface_south. this is how much we have to rotate the sky // for it to align with the sun - dot = sgScalarProductVec3( surface_to_sun, v->get_surface_south() ); + dot = sgScalarProductVec3( surface_to_sun, v->get_surface_south().data() ); // cout << " Dot product = " << dot << endl; if (dot > 1.0) { -- 2.39.5