]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/viewer.cxx
Avoid SGLocation usage.
[flightgear.git] / src / Main / viewer.cxx
index c29b99dbe74a7f14667d269b7f323dbacd96ce75..af9fe455ee859d9a2a5e92159e42d1abee5191db 100644 (file)
 
 #include <simgear/debug/logstream.hxx>
 #include <simgear/constants.h>
-#include <simgear/math/point3d.hxx>
 #include <simgear/math/polar3d.hxx>
 #include <simgear/math/sg_geodesy.hxx>
-#include <simgear/scene/model/location.hxx>
 #include <simgear/scene/model/placement.hxx>
 #include <simgear/math/vector.hxx>
 
@@ -50,6 +48,9 @@
 
 #include "viewer.hxx"
 
+#include "CameraGroup.hxx"
+
+using namespace flightgear;
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of FGViewer.
@@ -80,8 +81,7 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
     _damp_pitch(0),
     _damp_heading(0),
     _scaling_type(FG_SCALING_MAX),
-    _location(0),
-    _target_location(0)
+    _cameraGroup(CameraGroup::getDefault())
 {
     _absolute_view_pos = SGVec3d(0, 0, 0);
     _type = Type;
@@ -129,17 +129,6 @@ FGViewer::~FGViewer( void ) {
 void
 FGViewer::init ()
 {
-  if ( _from_model )
-    _location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation();
-  else
-    _location = new SGLocation;
-
-  if ( _type == FG_LOOKAT ) {
-    if ( _at_model )
-      _target_location = (SGLocation *) globals->get_aircraft_model()->get3DModel()->getSGLocation();
-    else
-      _target_location = (SGLocation *) new SGLocation;
-  }
 }
 
 void
@@ -402,14 +391,6 @@ FGViewer::setOrientationOffsets (double roll_offset_deg, double pitch_offset_deg
   _heading_offset_deg = heading_offset_deg;
 }
 
-double *
-FGViewer::get_absolute_view_pos () 
-{
-  if (_dirty)
-    recalc();
-  return _absolute_view_pos.data();
-}
-
 // recalc() is done every time one of the setters is called (making the 
 // cached data "dirty") on the next "get".  It calculates all the outputs 
 // for viewer.
@@ -422,36 +403,6 @@ 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();
 }
 
@@ -460,17 +411,24 @@ void
 FGViewer::recalcLookFrom ()
 {
   // 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, lon, alt, head, pitch, roll;
+  if ( _from_model ) {
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    lat = placement->getLatitudeDeg();
+    lon = placement->getLongitudeDeg();
+    alt = placement->getElevationFt();
+
+    head = placement->getHeadingDeg();
+    pitch = placement->getPitchDeg();
+    roll = placement->getRollDeg();
+  } else {
+    lat = _lat_deg;
+    lon = _lon_deg;
+    alt = _alt_ft;
+    head = _heading_deg;
+    pitch = _pitch_deg;
+    roll = _roll_deg;
   }
-  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...
     dampEyeData(roll, pitch, head);
@@ -479,25 +437,24 @@ FGViewer::recalcLookFrom ()
   // 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 horizontal local OpenGL frame
+  SGQuatd hlOr = SGQuatd::viewHL(geodPos);
+
   // the rotation from the horizontal local frame to the basic view orientation
   SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
+  hlToBody = SGQuatd::simToView(hlToBody);
+
   // 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 viewOffsetOr = SGQuatd::simToView(
     SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
-                                 _roll_offset_deg);
-
-  // 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());
+                                 _roll_offset_deg));
 
   // 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);
+  _absolute_view_pos = position + ec2body.backTransform(_offset_m);
   mViewOrientation = ec2body*viewOffsetOr;
 }
 
@@ -508,18 +465,18 @@ FGViewer::recalcLookAt ()
   SGGeod geodTargetPos;
   SGQuatd geodTargetOr;
   if ( _at_model ) {
-    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();
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    double lat = placement->getLatitudeDeg();
+    double lon = placement->getLongitudeDeg();
+    double alt = placement->getElevationFt();
+    geodTargetPos = SGGeod::fromDegFt(lon, lat, alt);
+
+    double head = placement->getHeadingDeg();
+    double pitch = placement->getPitchDeg();
+    double roll = placement->getRollDeg();
     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...
     geodTargetPos = SGGeod::fromDegFt(_target_lon_deg,
@@ -535,18 +492,18 @@ FGViewer::recalcLookAt ()
   SGGeod geodEyePos;
   SGQuatd geodEyeOr;
   if ( _from_model ) {
-    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();
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    double lat = placement->getLatitudeDeg();
+    double lon = placement->getLongitudeDeg();
+    double alt = placement->getElevationFt();
+    geodEyePos = SGGeod::fromDegFt(lon, lat, alt);
+
+    double head = placement->getHeadingDeg();
+    double pitch = placement->getPitchDeg();
+    double roll = placement->getRollDeg();
     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...
     geodEyePos = SGGeod::fromDegFt(_lon_deg, _lat_deg, _alt_ft);
@@ -562,7 +519,7 @@ FGViewer::recalcLookAt ()
                                  _roll_offset_deg);
 
   // Offsets to the eye position
-  SGVec3d eyeOff(-_offset_m.z(), _offset_m.y(), -_offset_m.x());
+  SGVec3d eyeOff(-_offset_m.z(), _offset_m.x(), -_offset_m.y());
   SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
   SGVec3d eyeCart = SGVec3d::fromGeod(geodEyePos);
   eyeCart += (ec2eye*eyeOffsetOr).backTransform(eyeOff);
@@ -583,14 +540,14 @@ FGViewer::recalcLookAt ()
   // the view direction
   SGVec3d dir = normalize(atCart - eyeCart);
   // the up directon
-  SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, 1));
+  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);
+  mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);
 }
 
 void
-FGViewer::dampEyeData (double &roll_deg, double &pitch_deg, double &heading_deg)
+FGViewer::dampEyeData(double &roll_deg, double &pitch_deg, double &heading_deg)
 {
   const double interval = 0.01;
 
@@ -776,5 +733,7 @@ FGViewer::update (double dt)
       }
     }
   }
-
+  recalc();
+  _cameraGroup->update(_absolute_view_pos.osg(), mViewOrientation.osg());
+  _cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio());
 }