]> git.mxchange.org Git - flightgear.git/blobdiff - src/Viewer/viewmgr.cxx
Reset: uninstall deletion-manager
[flightgear.git] / src / Viewer / viewmgr.cxx
index 76a1eb3df6fe9096523eba916694616ba9257719..6d7035777efd3b9ba9b7ab18db3b6d138e2d4dba 100644 (file)
 
 #include "viewmgr.hxx"
 
-#include <string.h>            // strcmp
+#include <string.h>        // strcmp
 
 #include <simgear/compiler.h>
-#include <simgear/sound/soundmgr_openal.hxx>
 #include <Main/fg_props.hxx>
 #include "viewer.hxx"
 
@@ -44,13 +43,15 @@ FGViewMgr::FGViewMgr( void ) :
   abs_viewer_position(SGVec3d::zeros()),
   current(0),
   current_view_orientation(SGQuatd::zeros()),
-  current_view_or_offset(SGQuatd::zeros()),
-  smgr(globals->get_soundmgr())
+  current_view_or_offset(SGQuatd::zeros())
 {
+  globals->set_viewmgr(this);
 }
 
 // Destructor
-FGViewMgr::~FGViewMgr( void ) {
+FGViewMgr::~FGViewMgr( void )
+{
+  globals->set_viewmgr(NULL);
 }
 
 void
@@ -63,11 +64,20 @@ FGViewMgr::init ()
   
   inited = true;
   
+  // stash properties
+  current_x_offs = fgGetNode("/sim/current-view/x-offset-m", true);
+  current_y_offs = fgGetNode("/sim/current-view/y-offset-m", true);
+  current_z_offs = fgGetNode("/sim/current-view/z-offset-m", true);
+  target_x_offs  = fgGetNode("/sim/current-view/target-x-offset-m", true);
+  target_y_offs  = fgGetNode("/sim/current-view/target-y-offset-m", true);
+  target_z_offs  = fgGetNode("/sim/current-view/target-z-offset-m", true);
+
   double aspect_ratio_multiplier
       = fgGetDouble("/sim/current-view/aspect-ratio-multiplier");
 
   for (unsigned int i = 0; i < config_list.size(); i++) {
     SGPropertyNode *n = config_list[i];
+    SGPropertyNode *config = n->getChild("config", 0, true);
 
     // find out if this is an internal view (e.g. in cockpit, low near plane)
     bool internal = n->getBoolValue("internal", false);
@@ -77,37 +87,37 @@ FGViewMgr::init ()
     // model-from-type as well.
 
     // find out if this is a model we are looking from...
-    bool from_model = n->getBoolValue("config/from-model");
-    int from_model_index = n->getIntValue("config/from-model-idx");
+    bool from_model = config->getBoolValue("from-model");
+    int from_model_index = config->getIntValue("from-model-idx");
 
-    double x_offset_m = n->getDoubleValue("config/x-offset-m");
-    double y_offset_m = n->getDoubleValue("config/y-offset-m");
-    double z_offset_m = n->getDoubleValue("config/z-offset-m");
+    double x_offset_m = config->getDoubleValue("x-offset-m");
+    double y_offset_m = config->getDoubleValue("y-offset-m");
+    double z_offset_m = config->getDoubleValue("z-offset-m");
 
-    double heading_offset_deg = n->getDoubleValue("config/heading-offset-deg");
-    n->setDoubleValue("config/heading-offset-deg", heading_offset_deg);
-    double pitch_offset_deg = n->getDoubleValue("config/pitch-offset-deg");
-    n->setDoubleValue("config/pitch-offset-deg", pitch_offset_deg);
-    double roll_offset_deg = n->getDoubleValue("config/roll-offset-deg");
-    n->setDoubleValue("config/roll-offset-deg", roll_offset_deg);
+    double heading_offset_deg = config->getDoubleValue("heading-offset-deg");
+    config->setDoubleValue("heading-offset-deg", heading_offset_deg);
+    double pitch_offset_deg = config->getDoubleValue("pitch-offset-deg");
+    config->setDoubleValue("pitch-offset-deg", pitch_offset_deg);
+    double roll_offset_deg = config->getDoubleValue("roll-offset-deg");
+    config->setDoubleValue("roll-offset-deg", roll_offset_deg);
 
-    double fov_deg = n->getDoubleValue("config/default-field-of-view-deg");
-    double near_m = n->getDoubleValue("config/ground-level-nearplane-m");
+    double fov_deg = config->getDoubleValue("default-field-of-view-deg");
+    double near_m = config->getDoubleValue("ground-level-nearplane-m");
 
     // supporting two types "lookat" = 1 and "lookfrom" = 0
     const char *type = n->getStringValue("type");
     if (!strcmp(type, "lookat")) {
 
-      bool at_model = n->getBoolValue("config/at-model");
-      int at_model_index = n->getIntValue("config/at-model-idx");
+      bool at_model = config->getBoolValue("at-model");
+      int at_model_index = config->getIntValue("at-model-idx");
 
-      double damp_roll = n->getDoubleValue("config/at-model-roll-damping");
-      double damp_pitch = n->getDoubleValue("config/at-model-pitch-damping");
-      double damp_heading = n->getDoubleValue("config/at-model-heading-damping");
+      double damp_roll = config->getDoubleValue("at-model-roll-damping");
+      double damp_pitch = config->getDoubleValue("at-model-pitch-damping");
+      double damp_heading = config->getDoubleValue("at-model-heading-damping");
 
-      double target_x_offset_m = n->getDoubleValue("config/target-x-offset-m");
-      double target_y_offset_m = n->getDoubleValue("config/target-y-offset-m");
-      double target_z_offset_m = n->getDoubleValue("config/target-z-offset-m");
+      double target_x_offset_m = config->getDoubleValue("target-x-offset-m");
+      double target_y_offset_m = config->getDoubleValue("target-y-offset-m");
+      double target_z_offset_m = config->getDoubleValue("target-z-offset-m");
 
       add_view(new FGViewer ( FG_LOOKAT, from_model, from_model_index,
                               at_model, at_model_index,
@@ -131,9 +141,21 @@ FGViewMgr::init ()
   do_bind();
 }
 
+void
+FGViewMgr::shutdown()
+{
+    if (!inited) {
+        return;
+    }
+    
+    inited = false;
+}
+
 void
 FGViewMgr::reinit ()
 {
+  int current_view_index = current;
+
   // reset offsets and fov to configuration defaults
   for (unsigned int i = 0; i < config_list.size(); i++) {
     SGPropertyNode *n = config_list[i];
@@ -165,7 +187,7 @@ FGViewMgr::reinit ()
     fgSetDouble("/sim/current-view/target-z-offset-m",
         n->getDoubleValue("config/target-z-offset-m"));
   }
-  setView(0);
+  setView(current_view_index);
 }
 
 typedef double (FGViewMgr::*double_getter)() const;
@@ -179,11 +201,7 @@ FGViewMgr::bind()
 
 void
 FGViewMgr::do_bind()
-{
-  velocityNorthFPS = fgGetNode("velocities/speed-north-fps", true);
-  velocityEastFPS = fgGetNode("velocities/speed-east-fps", true);
-  velocityDownFPS = fgGetNode("velocities/speed-down-fps", true);
-  
+{  
   // these are bound to the current view properties
   _tiedProperties.setRoot(fgGetNode("/sim/current-view", true));
   _tiedProperties.Tie("heading-offset-deg", this,
@@ -213,7 +231,12 @@ FGViewMgr::do_bind()
 
   _tiedProperties.Tie("view-number", this,
                       &FGViewMgr::getView, &FGViewMgr::setView);
-  fgSetArchivable("/sim/current-view/view-number", false);
+  SGPropertyNode* view_number =
+    _tiedProperties.getRoot()->getNode("view-number");
+  view_number->setAttribute(SGPropertyNode::ARCHIVE, false);
+
+  // Keep view on reset/reinit
+  view_number->setAttribute(SGPropertyNode::PRESERVE, true);
 
   _tiedProperties.Tie("axes/long", this,
                       (double_getter)0, &FGViewMgr::setViewAxisLong);
@@ -240,6 +263,11 @@ FGViewMgr::do_bind()
   _tiedProperties.Tie(n->getNode("viewer-y-m", true),SGRawValuePointer<double>(&abs_viewer_position[1]));
   _tiedProperties.Tie(n->getNode("viewer-z-m", true),SGRawValuePointer<double>(&abs_viewer_position[2]));
 
+  _tiedProperties.Tie("viewer-lon-deg", this, &FGViewMgr::getViewLon_deg);
+  _tiedProperties.Tie("viewer-lat-deg", this, &FGViewMgr::getViewLat_deg);
+  _tiedProperties.Tie("viewer-elev-ft", this, &FGViewMgr::getViewElev_ft);
+  
+  
   _tiedProperties.Tie("debug/orientation-w", this,
                       &FGViewMgr::getCurrentViewOrientation_w);
   _tiedProperties.Tie("debug/orientation-x", this,
@@ -272,88 +300,83 @@ void
 FGViewMgr::unbind ()
 {
   _tiedProperties.Untie();
+    config_list.clear();
+    view_number.clear();
 }
 
 void
 FGViewMgr::update (double dt)
 {
-  FGViewer *loop_view = (FGViewer *)get_current_view();
-  if (loop_view == 0) return;
+  FGViewer* currentView = (FGViewer *)get_current_view();
+  if (!currentView) return;
 
   SGPropertyNode *n = config_list[current];
+  SGPropertyNode *config = n->getChild("config", 0, true);
   double lon_deg, lat_deg, alt_ft, roll_deg, pitch_deg, heading_deg;
 
   // Set up view location and orientation
 
-  if (!n->getBoolValue("config/from-model")) {
-    lon_deg = fgGetDouble(n->getStringValue("config/eye-lon-deg-path"));
-    lat_deg = fgGetDouble(n->getStringValue("config/eye-lat-deg-path"));
-    alt_ft = fgGetDouble(n->getStringValue("config/eye-alt-ft-path"));
-    roll_deg = fgGetDouble(n->getStringValue("config/eye-roll-deg-path"));
-    pitch_deg = fgGetDouble(n->getStringValue("config/eye-pitch-deg-path"));
-    heading_deg = fgGetDouble(n->getStringValue("config/eye-heading-deg-path"));
+  if (!config->getBoolValue("from-model")) {
+    lon_deg = fgGetDouble(config->getStringValue("eye-lon-deg-path"));
+    lat_deg = fgGetDouble(config->getStringValue("eye-lat-deg-path"));
+    alt_ft = fgGetDouble(config->getStringValue("eye-alt-ft-path"));
+    roll_deg = fgGetDouble(config->getStringValue("eye-roll-deg-path"));
+    pitch_deg = fgGetDouble(config->getStringValue("eye-pitch-deg-path"));
+    heading_deg = fgGetDouble(config->getStringValue("eye-heading-deg-path"));
 
-    loop_view->setPosition(lon_deg, lat_deg, alt_ft);
-    loop_view->setOrientation(roll_deg, pitch_deg, heading_deg);
+    currentView->setPosition(lon_deg, lat_deg, alt_ft);
+    currentView->setOrientation(roll_deg, pitch_deg, heading_deg);
   } else {
     // force recalc in viewer
-    loop_view->set_dirty();
+    currentView->set_dirty();
   }
 
   // if lookat (type 1) then get target data...
-  if (loop_view->getType() == FG_LOOKAT) {
-    if (!n->getBoolValue("config/from-model")) {
-      lon_deg = fgGetDouble(n->getStringValue("config/target-lon-deg-path"));
-      lat_deg = fgGetDouble(n->getStringValue("config/target-lat-deg-path"));
-      alt_ft = fgGetDouble(n->getStringValue("config/target-alt-ft-path"));
-      roll_deg = fgGetDouble(n->getStringValue("config/target-roll-deg-path"));
-      pitch_deg = fgGetDouble(n->getStringValue("config/target-pitch-deg-path"));
-      heading_deg = fgGetDouble(n->getStringValue("config/target-heading-deg-path"));
-
-      loop_view->setTargetPosition(lon_deg, lat_deg, alt_ft);
-      loop_view->setTargetOrientation(roll_deg, pitch_deg, heading_deg);
+  if (currentView->getType() == FG_LOOKAT) {
+    if (!config->getBoolValue("from-model")) {
+      lon_deg = fgGetDouble(config->getStringValue("target-lon-deg-path"));
+      lat_deg = fgGetDouble(config->getStringValue("target-lat-deg-path"));
+      alt_ft = fgGetDouble(config->getStringValue("target-alt-ft-path"));
+      roll_deg = fgGetDouble(config->getStringValue("target-roll-deg-path"));
+      pitch_deg = fgGetDouble(config->getStringValue("target-pitch-deg-path"));
+      heading_deg = fgGetDouble(config->getStringValue("target-heading-deg-path"));
+
+      currentView->setTargetPosition(lon_deg, lat_deg, alt_ft);
+      currentView->setTargetOrientation(roll_deg, pitch_deg, heading_deg);
     } else {
-      loop_view->set_dirty();
+      currentView->set_dirty();
     }
   }
 
-  setViewXOffset_m(fgGetDouble("/sim/current-view/x-offset-m"));
-  setViewYOffset_m(fgGetDouble("/sim/current-view/y-offset-m"));
-  setViewZOffset_m(fgGetDouble("/sim/current-view/z-offset-m"));
+  setViewXOffset_m(current_x_offs->getDoubleValue());
+  setViewYOffset_m(current_y_offs->getDoubleValue());
+  setViewZOffset_m(current_z_offs->getDoubleValue());
 
-  setViewTargetXOffset_m(fgGetDouble("/sim/current-view/target-x-offset-m"));
-  setViewTargetYOffset_m(fgGetDouble("/sim/current-view/target-y-offset-m"));
-  setViewTargetZOffset_m(fgGetDouble("/sim/current-view/target-z-offset-m"));
+  setViewTargetXOffset_m(target_x_offs->getDoubleValue());
+  setViewTargetYOffset_m(target_y_offs->getDoubleValue());
+  setViewTargetZOffset_m(target_z_offs->getDoubleValue());
 
-  current_view_orientation = loop_view->getViewOrientation();
-  current_view_or_offset = loop_view->getViewOrientationOffset();
+  current_view_orientation = currentView->getViewOrientation();
+  current_view_or_offset = currentView->getViewOrientationOffset();
 
   // Update the current view
   do_axes();
-  loop_view->update(dt);
-  abs_viewer_position = loop_view->getViewPosition();
-
-  // update audio listener values
-  // set the viewer position in Cartesian coordinates in meters
-  smgr->set_position( abs_viewer_position, loop_view->getPosition() );
-  smgr->set_orientation( current_view_orientation );
-
-  // get the model velocity
-  SGVec3d velocity = SGVec3d::zeros();
-  if ( !stationary() ) {
-    velocity = SGVec3d( velocityNorthFPS->getDoubleValue(),
-                        velocityEastFPS->getDoubleValue(),
-                        velocityDownFPS->getDoubleValue() );
+  currentView->update(dt);
+  abs_viewer_position = currentView->getViewPosition();
+  
+  // expose the raw (OpenGL) orientation to the property tree,
+  // for the sound-manager
+  for (int i=0; i<4; ++i) {
+    _tiedProperties.getRoot()->getChild("raw-orientation", i, true)->setDoubleValue(current_view_orientation[i]);
   }
-  smgr->set_velocity( velocity );
 }
 
 void
 FGViewMgr::copyToCurrent()
 {
-  if (!inited) {
-    return;
-  }
+    if (!inited) {
+        return;
+    }
   
     SGPropertyNode *n = config_list[current];
     fgSetString("/sim/current-view/name", n->getStringValue("name"));
@@ -400,60 +423,60 @@ FGViewMgr::copyToCurrent()
 
 void FGViewMgr::clear()
 {
-  views.clear();
+    views.clear();
 }
 
 FGViewer*
 FGViewMgr::get_current_view()
 {
-       if ( current < (int)views.size() ) {
-           return views[current];
-       } else {
-           return NULL;
-       }
+    if ( current < (int)views.size() ) {
+        return views[current];
+    } else {
+        return NULL;
+    }
 }
 
 const FGViewer*
 FGViewMgr::get_current_view() const
 {
-       if ( current < (int)views.size() ) {
-           return views[current];
-       } else {
-           return NULL;
-       }
+    if ( current < (int)views.size() ) {
+        return views[current];
+    } else {
+        return NULL;
+    }
 }
 
 
 FGViewer*
 FGViewMgr::get_view( int i )
 {
-       if ( i < 0 ) { i = 0; }
-       if ( i >= (int)views.size() ) { i = views.size() - 1; }
-       return views[i];
+    if ( i < 0 ) { i = 0; }
+    if ( i >= (int)views.size() ) { i = views.size() - 1; }
+    return views[i];
 }
 
 const FGViewer*
 FGViewMgr::get_view( int i ) const
 {
-       if ( i < 0 ) { i = 0; }
-       if ( i >= (int)views.size() ) { i = views.size() - 1; }
-       return views[i];
+    if ( i < 0 ) { i = 0; }
+    if ( i >= (int)views.size() ) { i = views.size() - 1; }
+    return views[i];
 }
 
 FGViewer*
 FGViewMgr::next_view()
 {
-       setView((current+1 < (int)views.size()) ? (current + 1) : 0);
-       view_number->fireValueChanged();
-       return views[current];
+    setView((current+1 < (int)views.size()) ? (current + 1) : 0);
+    view_number->fireValueChanged();
+    return views[current];
 }
 
 FGViewer*
 FGViewMgr::prev_view()
 {
-       setView((0 < current) ? (current - 1) : (views.size() - 1));
-       view_number->fireValueChanged();
-       return views[current];
+    setView((0 < current) ? (current - 1) : (views.size() - 1));
+    view_number->fireValueChanged();
+    return views[current];
 }
 
 void
@@ -619,20 +642,6 @@ FGViewMgr::setViewZOffset_m (double z)
   }
 }
 
-bool
-FGViewMgr::stationary () const
-{
-  const FGViewer * view = get_current_view();
-  if (view != 0) {
-    if (((FGViewer *)view)->getXOffset_m() == 0.0 &&
-        ((FGViewer *)view)->getYOffset_m() == 0.0 &&
-        ((FGViewer *)view)->getZOffset_m() == 0.0)
-      return true;
-  }
-
-  return false;
-}
-
 double
 FGViewMgr::getViewTargetXOffset_m () const
 {
@@ -785,6 +794,28 @@ FGViewMgr::setViewAxisLat (double axis)
   axis_lat = axis;
 }
 
+double
+FGViewMgr::getViewLon_deg() const
+{
+  const FGViewer* view = get_current_view();
+  return (view != NULL) ? view->getPosition().getLongitudeDeg() : 0.0;
+}
+
+double
+FGViewMgr::getViewLat_deg() const
+{
+  const FGViewer* view = get_current_view();
+  return (view != NULL) ? view->getPosition().getLatitudeDeg() : 0.0;
+}
+
+double
+FGViewMgr::getViewElev_ft() const
+{
+  const FGViewer* view = get_current_view();
+  return (view != NULL) ? view->getPosition().getElevationFt() : 0.0;
+}
+
+
 // reference frame orientation.
 // This is the view orientation you get when you have no
 // view offset, i.e. the offset operator is the identity.
@@ -883,7 +914,7 @@ double FGViewMgr::getCurrentViewOrientation_z() const{
 void
 FGViewMgr::do_axes ()
 {
-                               // Take no action when hat is centered
+                // Take no action when hat is centered
   if ( ( axis_long <  0.01 ) &&
        ( axis_long > -0.01 ) &&
        ( axis_lat  <  0.01 ) &&
@@ -894,21 +925,21 @@ FGViewMgr::do_axes ()
   double viewDir = 999;
 
   /* Do all the quick and easy cases */
-  if (axis_long < 0) {         // Longitudinal axis forward
+  if (axis_long < 0) {        // Longitudinal axis forward
     if (axis_lat == axis_long)
       viewDir = fgGetDouble("/sim/view/config/front-left-direction-deg");
     else if (axis_lat == - axis_long)
       viewDir = fgGetDouble("/sim/view/config/front-right-direction-deg");
     else if (axis_lat == 0)
       viewDir = fgGetDouble("/sim/view/config/front-direction-deg");
-  } else if (axis_long > 0) {  // Longitudinal axis backward
+  } else if (axis_long > 0) {    // Longitudinal axis backward
     if (axis_lat == - axis_long)
       viewDir = fgGetDouble("/sim/view/config/back-left-direction-deg");
     else if (axis_lat == axis_long)
       viewDir = fgGetDouble("/sim/view/config/back-right-direction-deg");
     else if (axis_lat == 0)
       viewDir = fgGetDouble("/sim/view/config/back-direction-deg");
-  } else if (axis_long == 0) { // Longitudinal axis neutral
+  } else if (axis_long == 0) {    // Longitudinal axis neutral
     if (axis_lat < 0)
       viewDir = fgGetDouble("/sim/view/config/left-direction-deg");
     else if (axis_lat > 0)
@@ -916,7 +947,7 @@ FGViewMgr::do_axes ()
     else return; /* And assertion failure maybe? */
   }
 
-                               // Do all the difficult cases
+                // Do all the difficult cases
   if ( viewDir > 900 )
     viewDir = SGD_RADIANS_TO_DEGREES * atan2 ( -axis_lat, -axis_long );
   if ( viewDir < -1 ) viewDir += 360;