]> git.mxchange.org Git - flightgear.git/commitdiff
replay system: allow to resume simulation at any point of replay-time.
authorThorstenB <brehmt@gmail.com>
Sun, 9 Oct 2011 17:46:49 +0000 (19:46 +0200)
committerThorstenB <brehmt@gmail.com>
Sun, 9 Oct 2011 18:36:01 +0000 (20:36 +0200)
Currently supported for YASim only.

src/Aircraft/replay.cxx
src/FDM/YASim/Gear.cpp
src/FDM/YASim/YASim.cxx
src/FDM/YASim/YASim.hxx
src/FDM/fdm_shell.cxx
src/FDM/fdm_shell.hxx

index 8dd04d8713dbb517b4619277b7c50bb0fd996b58..7ef44c20205f8fb3b486693cdc04a14856d03297 100644 (file)
@@ -31,7 +31,6 @@
 #include <simgear/structure/exception.hxx>
 
 #include <Main/fg_props.hxx>
-#include <FDM/fdm_shell.hxx>
 
 #include "replay.hxx"
 #include "flightrecorder.hxx"
@@ -235,43 +234,52 @@ FGReplay::update( double dt )
 
     if ( disable_replay->getBoolValue() )
     {
-        current_replay_state = replay_master->getIntValue();
-        replay_master->setIntValue(0);
-        replay_time->setDoubleValue(0);
-        replay_time_str->setStringValue("");
-        disable_replay->setBoolValue(0);
-        speed_up->setDoubleValue(1.0);
-        fgSetString("/sim/messages/copilot", "Replay stopped");
+        if (fgGetBool("/sim/freeze/master",false)||
+            fgGetBool("/sim/freeze/clock",false))
+        {
+            fgSetBool("/sim/freeze/master",false);
+            fgSetBool("/sim/freeze/clock",false);
+            last_replay_state = 1;
+        }
+        else
+        if ((replay_master->getIntValue() != 3)||
+            (last_replay_state == 3))
+        {
+            current_replay_state = replay_master->getIntValue();
+            replay_master->setIntValue(0);
+            replay_time->setDoubleValue(0);
+            replay_time_str->setStringValue("");
+            disable_replay->setBoolValue(0);
+            speed_up->setDoubleValue(1.0);
+            speed_up->setDoubleValue(1.0);
+            if (fgGetBool("/sim/replay/mute",false))
+            {
+                fgSetBool("/sim/sound/enabled",true);
+                fgSetBool("/sim/replay/mute",false);
+            }
+            fgSetString("/sim/messages/copilot", "Replay stopped. Your controls!");
+        }
     }
 
     int replay_state = replay_master->getIntValue();
-
-    if ((replay_state > 0)&&
-       (last_replay_state == 0))
-    {
-        // replay is starting, suspend FDM
-        /* FIXME we need to suspend/resume the FDM - not the entire FDM shell.
-         * FDM isn't available via the global subsystem manager yet, so need a
-         * method at the FDMshell for now */
-        ((FDMShell*) globals->get_subsystem("flight"))->getFDM()->suspend();
-    }
-    else
     if ((replay_state == 0)&&
         (last_replay_state > 0))
     {
         if (current_replay_state == 3)
         {
-            // "my controls!" requested: pilot takes control at current replay position...
+            // take control at current replay position ("My controls!").
             // May need to uncrash the aircraft here :)
             fgSetBool("/sim/crashed", false);
         }
         else
         {
-            // replay was active, restore most recent frame
+            // normal replay exit, restore most recent frame
             replay(DBL_MAX);
         }
-        // replay is finished, resume FDM
-        ((FDMShell*) globals->get_subsystem("flight"))->getFDM()->resume();
+
+        // replay is finished
+        last_replay_state = replay_state;
+        return;
     }
 
     // remember recent state
@@ -282,7 +290,8 @@ FGReplay::update( double dt )
         case 0:
             // replay inactive, keep recording
             break;
-        case 1:
+        case 1: // normal replay
+        case 3: // prepare to resume normal flight at current replay position 
         {
             // replay active
             double current_time = replay_time->getDoubleValue();
@@ -312,8 +321,6 @@ FGReplay::update( double dt )
             return; // don't record the replay session 
         }
         case 2: // normal replay operation
-        case 3: // replay operation, prepare to resume normal flight at current replay position 
-            // replay paused, no-op
             return; // don't record the replay session
         default:
             throw sg_range_exception("unknown FGReplay state");
index ce2517c7356194d0432aa8400b1c44fcd736f531..b4c7673cb541eddf4ead3f9c35c0fe4177c3e389 100644 (file)
@@ -284,16 +284,20 @@ void Gear::calcForce(RigidBody* body, State *s, float* v, float* rot)
 
     // Don't bother if it's not down
     if(_extension < 1)
-       return;
+    {
+        _wow = 0;
+        _frac = 0;
+        return;
+    }
 
     // Dont bother if we are in the "wrong" ground
     if (!((_onWater&&!_ground_isSolid)||(_onSolid&&_ground_isSolid)))  {
-       _wow = 0;
-       _frac = 0;
+         _wow = 0;
+         _frac = 0;
         _compressDist = 0;
         _rollSpeed = 0;
         _casterAngle = 0;
-       return;
+        return;
     }
 
     // The ground plane transformed to the local frame.
index 95261df5597b4c95973fbf43d535bf0770af0285..35495f11944a67d154ddee2d1ad4237531901424 100644 (file)
@@ -195,9 +195,10 @@ void YASim::update(double dt)
     int iterations = _calc_multiloop(dt);
 
     // If we're crashed, then we don't care
-    if(_fdm->getAirplane()->getModel()->isCrashed()) {
+    if(fgGetBool("/sim/crashed") || _fdm->getAirplane()->getModel()->isCrashed()) {
         if(!fgGetBool("/sim/crashed"))
             fgSetBool("/sim/crashed", true);
+        _fdm->getAirplane()->getModel()->setCrashed(false);
         return;
     }
 
@@ -311,7 +312,7 @@ void YASim::copyToYASim(bool copyState)
     Math::set3(v, s.v);
 
     if(copyState || needCopy)
-       model->setState(&s);
+        model->setState(&s);
 
     // wind
     Math::tmul33(xyz2ned, wind, wind);
@@ -505,3 +506,19 @@ void YASim::copyFromYASim()
     }
 
 }
+
+/** Reinit the FDM.
+ * This is only used after a replay session and when the user requested to resume at
+ * a past point of time. In thise case the FDM must reload all values from the property
+ * tree (as given by the replay system). */
+void YASim::reinit()
+{
+    // Process inputs. Use excessive value for dt to make sure all transition effects
+    // have reached their final state (i.e. gear is extended/retracted) - which is vital
+    // for many properties to be complete before the first FDM run (otherwise the gear may
+    // still be up, thrust-reversers/speed-brakes/... may still be partially deployed...).
+    _fdm->getExternalInput(1000);
+
+    // get current FDM values from the property tree
+    copyToYASim(true);
+}
index 2e8f77732c5ccebeac71159d89583047507a3415..eb67cadecf93fe03e96e0757be145786e6ae97b7 100644 (file)
@@ -13,6 +13,7 @@ public:
     // Load externally set stuff into the FDM
     virtual void init();
     virtual void bind();
+    virtual void reinit();
 
     // Run an iteration
     virtual void update(double dt);
index faa37d788520db2368f12916fc8a78ff7ccd151c..f06303e2024b565ec1ce2d87fa100f34c39c1d5a 100644 (file)
@@ -81,6 +81,7 @@ void FDMShell::init()
   _pressure_inhg    = _props->getNode("environment/pressure-inhg",          true);
   _density_slugft   = _props->getNode("environment/density-slugft3",        true);
   _data_logging     = _props->getNode("/sim/temp/fdm-data-logging",         true);
+  _replay_master    = _props->getNode("/sim/freeze/replay-state",           true);
 
   createImplementation();
 }
@@ -170,8 +171,20 @@ void FDMShell::update(double dt)
     _impl->ToggleDataLogging(doLog);
   }
 
-  if (!_impl->is_suspended())
-      _impl->update(dt);
+  switch(_replay_master->getIntValue())
+  {
+      case 0:
+          // normal FDM operation
+          _impl->update(dt);
+          break;
+      case 3:
+          // resume FDM operation at current replay position
+          _impl->reinit();
+          break;
+      default:
+          // replay is active
+          break;
+  }
 }
 
 void FDMShell::createImplementation()
@@ -261,14 +274,3 @@ void FDMShell::createImplementation()
     }
 
 }
-
-/*
- * Return FDM subsystem.
- */
-
-SGSubsystem* FDMShell::getFDM()
-{
-    /* FIXME we could drop/replace this method, when _impl was a added
-     * to the global subsystem manager - like other proper subsystems... */
-    return _impl;
-}
index 293796c7676995887ef95529a629729d37ff3291..3979067e1a247a657491bffd0722de2aeedf256f 100644 (file)
@@ -41,7 +41,7 @@ class FDMShell : public SGSubsystem
 {
 public:
   FDMShell();
-  ~FDMShell();
+  virtual ~FDMShell();
   
   virtual void init();
   virtual void reinit();
@@ -50,7 +50,6 @@ public:
   virtual void unbind();
   
   virtual void update(double dt);
-  SGSubsystem* getFDM();
 
 private:
 
@@ -63,7 +62,7 @@ private:
   
   SGPropertyNode_ptr _wind_north, _wind_east,_wind_down;
   SGPropertyNode_ptr _control_fdm_atmo,_temp_degc,_pressure_inhg;
-  SGPropertyNode_ptr _density_slugft, _data_logging;
+  SGPropertyNode_ptr _density_slugft, _data_logging, _replay_master;
 };
 
 #endif // of FG_FDM_SHELL_HXX