]> git.mxchange.org Git - flightgear.git/commitdiff
Modified Files:
authorfrohlich <frohlich>
Wed, 1 Nov 2006 21:22:25 +0000 (21:22 +0000)
committerfrohlich <frohlich>
Wed, 1 Nov 2006 21:22:25 +0000 (21:22 +0000)
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
src/Main/viewer.cxx
src/Main/viewer.hxx
src/Time/tmp.cxx

index 8e0cfb55d65f13ada8ece5cf83b80d8a996eb6f2..c691479d24eaec89560e08dc63deba9196a41cbd 100644 (file)
@@ -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()
index c6304468d1b6fe4ea15207206741c36b769bcd43..c29b99dbe74a7f14667d269b7f323dbacd96ce75 100644 (file)
 #include "viewer.hxx"
 
 \f
-//////////////////////////////////////////////////////////////////
-// 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
index 4a7f42b63b11dcd8f42462629b2a13c2a3fba15b..2e46afba6c03a77cb4a1cb56551d2df4c1fe7311 100644 (file)
@@ -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;
-    }
-
 };
 
 
index 1803964846717155fa9c969f996a0b5b44c25b73..7e9e751893e9ce5546f1ef154ba0ce887ccf1e84 100644 (file)
@@ -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) {