]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/viewer.cxx
initlialize _playing for FGATC. Proper listerner orientation based on view offset...
[flightgear.git] / src / Main / viewer.cxx
index f2ffd56c9d57a5fae327aae613bc7e6fc6068f45..8dcfb982dbf5f4913eb0c573e2d9e55019293c7d 100644 (file)
 
 #include "fg_props.hxx"
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
 #include <simgear/debug/logstream.hxx>
 #include <simgear/constants.h>
-#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>
 
@@ -68,12 +61,6 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
                     double target_x_offset_m, double target_y_offset_m,
                     double target_z_offset_m, double near_m, bool internal ):
     _dirty(true),
-    _lon_deg(0),
-    _lat_deg(0),
-    _alt_ft(0),
-    _target_lon_deg(0),
-    _target_lat_deg(0),
-    _target_alt_ft(0),
     _roll_deg(0),
     _pitch_deg(0),
     _heading_deg(0),
@@ -82,8 +69,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),
+    _aspect_ratio(0),
     _cameraGroup(CameraGroup::getDefault())
 {
     _absolute_view_pos = SGVec3d(0, 0, 0);
@@ -116,6 +102,7 @@ FGViewer::FGViewer( fgViewType Type, bool from_model, int from_model_index,
     } else {
       _fov_deg = 55;
     }
+    _aspect_ratio = 1;
     _aspect_ratio_multiplier = aspect_ratio_multiplier;
     _target_offset_m.x() = target_x_offset_m;
     _target_offset_m.y() = target_y_offset_m;
@@ -132,17 +119,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
@@ -170,64 +146,18 @@ FGViewer::setInternal ( bool internal )
   _internal = internal;
 }
 
-void
-FGViewer::setLongitude_deg (double lon_deg)
-{
-  _dirty = true;
-  _lon_deg = lon_deg;
-}
-
-void
-FGViewer::setLatitude_deg (double lat_deg)
-{
-  _dirty = true;
-  _lat_deg = lat_deg;
-}
-
-void
-FGViewer::setAltitude_ft (double alt_ft)
-{
-  _dirty = true;
-  _alt_ft = alt_ft;
-}
-
 void
 FGViewer::setPosition (double lon_deg, double lat_deg, double alt_ft)
 {
   _dirty = true;
-  _lon_deg = lon_deg;
-  _lat_deg = lat_deg;
-  _alt_ft = alt_ft;
-}
-
-void
-FGViewer::setTargetLongitude_deg (double lon_deg)
-{
-  _dirty = true;
-  _target_lon_deg = lon_deg;
-}
-
-void
-FGViewer::setTargetLatitude_deg (double lat_deg)
-{
-  _dirty = true;
-  _target_lat_deg = lat_deg;
-}
-
-void
-FGViewer::setTargetAltitude_ft (double alt_ft)
-{
-  _dirty = true;
-  _target_alt_ft = alt_ft;
+  _position = SGGeod::fromDegFt(lon_deg, lat_deg, alt_ft);
 }
 
 void
 FGViewer::setTargetPosition (double lon_deg, double lat_deg, double alt_ft)
 {
   _dirty = true;
-  _target_lon_deg = lon_deg;
-  _target_lat_deg = lat_deg;
-  _target_alt_ft = alt_ft;
+  _target = SGGeod::fromDegFt(lon_deg, lat_deg, alt_ft);
 }
 
 void
@@ -417,33 +347,6 @@ FGViewer::recalc ()
     recalcLookAt();
   }
 
-  SGGeod geodEyePoint = SGGeod::fromCart(_absolute_view_pos);
-  geodEyePoint.setElevationM(0);
-  _zero_elev = SGVec3d::fromGeod(geodEyePoint);
-  
-  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();
 }
 
@@ -452,113 +355,99 @@ 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();
+  if ( _from_model ) {
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    _position = placement->getPosition();
+  
+    _heading_deg = placement->getHeadingDeg();
+    _pitch_deg = placement->getPitchDeg();
+    _roll_deg = placement->getRollDeg();
   }
-  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();
+
+  double head = _heading_deg;
+  double pitch = _pitch_deg;
+  double roll = _roll_deg;
   if ( !_from_model ) {
     // update from our own data...
     dampEyeData(roll, pitch, head);
   }
 
-  // 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 OpenGL frame
-  SGQuatd hlOr = SGQuatd::viewHL(geodPos);
+  // the horizontal local frame
+  SGQuatd hlOr = SGQuatd::fromLonLat(_position);
 
-  // the rotation from the horizontal local frame to the basic view orientation
+  // 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::simToView(
-    SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
-                                 _roll_offset_deg));
+  // The rotation offset, don't know why heading is negative here ...
+  mViewOffsetOr
+      = SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg, _pitch_offset_deg,
+                                     _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(_offset_m);
-  mViewOrientation = ec2body*viewOffsetOr;
+
+  // The cartesian position of the basic view coordinate
+  SGVec3d position = SGVec3d::fromGeod(_position);
+
+  // This is rotates the x-forward, y-right, z-down coordinate system the where
+  // simulation runs into the OpenGL camera system with x-right, y-up, z-back.
+  SGQuatd q(-0.5, -0.5, 0.5, 0.5);
+
+  _absolute_view_pos = position + (ec2body*q).backTransform(_offset_m);
+  mViewOrientation = ec2body*mViewOffsetOr*q;
 }
 
 void
 FGViewer::recalcLookAt ()
 {
   // The geodetic position of our target to look at
-  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();
-    geodTargetOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    _target = placement->getPosition();
+    _target_heading_deg = placement->getHeadingDeg();
+    _target_pitch_deg = placement->getPitchDeg();
+    _target_roll_deg = placement->getRollDeg();
   } else {
+    // if not model then calculate our own target position...
     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,
-                                      _target_lat_deg,
-                                      _target_alt_ft);
-    geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg,
-                                                _target_pitch_deg,
-                                                _target_roll_deg);
   }
-  SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(geodTargetPos);
+
+  SGQuatd geodTargetOr = SGQuatd::fromYawPitchRollDeg(_target_heading_deg,
+                                                      _target_pitch_deg,
+                                                      _target_roll_deg);
+  SGQuatd geodTargetHlOr = SGQuatd::fromLonLat(_target);
 
 
-  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();
-    geodEyeOr = SGQuatd::fromYawPitchRollDeg(head, pitch, roll);
+    SGModelPlacement* placement = globals->get_aircraft_model()->get3DModel();
+    _position = placement->getPosition();
+    _heading_deg = placement->getHeadingDeg();
+    _pitch_deg = placement->getPitchDeg();
+    _roll_deg = placement->getRollDeg();
   } 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);
-    geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg,
-                                             _pitch_deg,
-                                             _roll_deg);
+    dampEyeData(_roll_deg, _pitch_deg, _heading_deg);
   }
-  SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(geodEyePos);
+  SGQuatd geodEyeOr = SGQuatd::fromYawPitchRollDeg(_heading_deg,
+                                                   _pitch_deg,
+                                                   _roll_deg);
+  SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(_position);
 
   // the rotation offset, don't know why heading is negative here ...
-  SGQuatd eyeOffsetOr =
+  mViewOffsetOr =
     SGQuatd::fromYawPitchRollDeg(-_heading_offset_deg + 180, _pitch_offset_deg,
                                  _roll_offset_deg);
 
   // Offsets to the eye position
   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);
+  SGVec3d eyeCart = SGVec3d::fromGeod(_position);
+  eyeCart += (ec2eye*mViewOffsetOr).backTransform(eyeOff);
 
-  SGVec3d atCart = SGVec3d::fromGeod(geodTargetPos);
+  SGVec3d atCart = SGVec3d::fromGeod(_target);
 
   // add target offsets to at_position...
   SGVec3d target_pos_off(-_target_offset_m.z(), _target_offset_m.x(),
@@ -575,8 +464,10 @@ FGViewer::recalcLookAt ()
   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
+  // rotate -dir to the 2-th unit vector
+  // rotate up to 1-th unit vector
+  // Note that this matches the OpenGL camera coordinate system
+  // with x-right, y-up, z-back.
   mViewOrientation = SGQuatd::fromRotateTo(-dir, 2, up, 1);
 }
 
@@ -768,6 +659,6 @@ FGViewer::update (double dt)
     }
   }
   recalc();
-  _cameraGroup->update(_absolute_view_pos.osg(), mViewOrientation.osg());
+  _cameraGroup->update(toOsg(_absolute_view_pos), toOsg(mViewOrientation));
   _cameraGroup->setCameraParameters(get_v_fov(), get_aspect_ratio());
 }