]> git.mxchange.org Git - flightgear.git/commitdiff
David Culp:
authorehofman <ehofman>
Thu, 26 Aug 2004 08:38:43 +0000 (08:38 +0000)
committerehofman <ehofman>
Thu, 26 Aug 2004 08:38:43 +0000 (08:38 +0000)
Here is an update for the submodel system.  This will allow submodels to be
defined for any aircraft, and there are no default submodels.  To use this
submodel system you need to set up a binding (slight change in property name
from last one, but you can use any property name you like, as long as it
matches the name in the submodels.xml file, see below):

 <button n="0">
  <desc>Trigger</desc>
  <binding>
   <command>property-assign</command>
   <property>/systems/submodels/trigger</property>
   <value type="bool">true</value>
  </binding>
  <mod-up>
   <binding>
    <command>property-assign</command>
    <property>/systems/submodels/trigger</property>
    <value type="bool">false</value>
   </binding>
  </mod-up>
 </button>

Then in your *-set.xml file you need to define a path to the configuration
file (similar to the way the electrical system is now done):

<sim>
 ...
  <systems>
   <electrical>
    <path>Aircraft/Generic/generic-electrical.xml</path>
   </electrical>
   <submodels>
    <serviceable type="bool">true</serviceable>
    <path>Aircraft/FW190/submodels.xml</path>
   </submodels>
  </systems>
 ...
</sim>

Then you put the submodel configuration file in your aircraft's directory.
I've attached a file, submodels.xml, that can be used to define a gun that
works just like the former one did.

There are two things remaining to be done.  One is to change the function
SubmodelSystem::transform() to properly position the submodel.  This will
require some complicated matrix code that I might borrow from Yasim.

src/Systems/submodel.cxx
src/Systems/submodel.hxx

index 9cd1d3d572bf1b38290683980a33b059fe2e5769..8e473651b48667cd07be81c2b3f392d6af5738ce 100644 (file)
@@ -4,6 +4,10 @@
 // This file is in the Public Domain and comes with no warranty.
 
 #include "submodel.hxx"
+
+#include <simgear/structure/exception.hxx>
+#include <simgear/misc/sg_path.hxx>
+
 #include <Main/fg_props.hxx>
 #include <Main/util.hxx>
 #include <AIModel/AIManager.hxx>
@@ -11,7 +15,6 @@
 
 SubmodelSystem::SubmodelSystem ()
 {
-  firing = false;
   x_offset = y_offset = 0.0;
   z_offset = -4.0;
   pitch_offset = 2.0;
@@ -25,13 +28,9 @@ SubmodelSystem::~SubmodelSystem ()
 void
 SubmodelSystem::init ()
 {
-    _serviceable_node = fgGetNode("/systems/submodel/serviceable", true);
-       
-    _trigger_node = fgGetNode("/systems/submodel/trigger", true);
-    _trigger_node->setBoolValue(false);
+    load();
+    _serviceable_node = fgGetNode("/sim/systems/submodels/serviceable", true);
        
-    _amount_node = fgGetNode("/systems/submodel/amount", true);
-        
     _user_lat_node = fgGetNode("/position/latitude-deg", true);
     _user_lon_node = fgGetNode("/position/longitude-deg", true);
     _user_alt_node = fgGetNode("/position/altitude-ft", true);
@@ -43,9 +42,6 @@ SubmodelSystem::init ()
 
     _user_speed_node = fgGetNode("/velocities/uBody-fps", true);
 
-    elapsed_time = 0.0;
-    initial_velocity = 2750.0;  // feet per second, .50 caliber
-
     ai = (FGAIManager*)globals->get_subsystem("ai_model");
 }
 
@@ -62,39 +58,95 @@ SubmodelSystem::unbind ()
 void
 SubmodelSystem::update (double dt)
 {
-  if (_trigger_node->getBoolValue()) {
-    if (_serviceable_node->getBoolValue()) {
-      if (_amount_node->getIntValue() > 0) {
-        firing = true;
-        release(dt);
-      } 
-    }
-  } else {
-    if (firing){
-      firing = false;
-      elapsed_time = 0.0;
-    }
+  if (!(_serviceable_node->getBoolValue())) return;
+
+  submodel_iterator = submodels.begin();
+  while(submodel_iterator != submodels.end()) {
+
+    if ((*submodel_iterator)->trigger->getBoolValue()) {
+        if ((*submodel_iterator)->count > 0) {
+          release( (*submodel_iterator), dt);
+        } 
+    } 
+    ++submodel_iterator;
   }
+   
 }
 
 bool
-SubmodelSystem::release (double dt)
+SubmodelSystem::release (submodel* sm, double dt)
 {
-  // releases a submodel every 0.25 seconds
-  elapsed_time += dt;
-  if (elapsed_time < 0.25) return false;
-  elapsed_time = 0.0;
-
-  int rval = ai->createBallistic( "Models/Geometry/tracer.ac",
-        _user_lat_node->getDoubleValue(),
-        _user_lon_node->getDoubleValue(),
-        _user_alt_node->getDoubleValue() + z_offset,
-        _user_heading_node->getDoubleValue() + yaw_offset,
-        _user_pitch_node->getDoubleValue() + pitch_offset,
-        _user_speed_node->getDoubleValue() + initial_velocity );
-
-  _amount_node->setIntValue( _amount_node->getIntValue() - 1); 
+  sm->timer += dt;
+  if (sm->timer < sm->delay) return false;
+  sm->timer = 0.0;
+
+  transform(sm);  // calculate submodel's initial conditions in world-coordinates
+
+  int rval = ai->createBallistic( sm->model, IC.lat, IC.lon, IC.alt, IC.azimuth,
+                                  IC.elevation, IC.speed );
+  sm->count--; 
   return true;                    
 }
 
+void
+SubmodelSystem::load ()
+{
+    int i;
+    SGPropertyNode *path = fgGetNode("/sim/systems/submodels/path");
+    SGPropertyNode root;
+
+    if (path) {
+      SGPath config( globals->get_fg_root() );
+      config.append( path->getStringValue() );
+
+      try {
+        readProperties(config.str(), &root);
+      } catch (const sg_exception &e) {
+        SG_LOG(SG_GENERAL, SG_ALERT,
+        "Unable to read submodels file: ");
+        cout << config.str() << endl;
+        return;
+      }
+    }
+
+   int count = root.nChildren();
+   for (i = 0; i < count; i++) { 
+     // cout << "Reading submodel " << i << endl;        
+     submodel* sm = new submodel;
+     submodels.push_back( sm );
+     SGPropertyNode * entry_node = root.getChild(i);
+     sm->trigger        = fgGetNode(entry_node->getStringValue("trigger", "none"), true);
+     sm->name           = entry_node->getStringValue("name", "none_defined");
+     sm->model          = entry_node->getStringValue("model", "Models/Geometry/tracer.ac");
+     sm->speed          = entry_node->getDoubleValue("speed", 0.0);
+     sm->repeat         = entry_node->getBoolValue  ("repeat", false); 
+     sm->delay          = entry_node->getDoubleValue("delay", 0.25); 
+     sm->count          = entry_node->getIntValue   ("count", 1); 
+     sm->slaved         = entry_node->getBoolValue  ("slaved", false); 
+     sm->x_offset       = entry_node->getDoubleValue("x-offset", 0.0); 
+     sm->y_offset       = entry_node->getDoubleValue("y_offset", 0.0); 
+     sm->z_offset       = entry_node->getDoubleValue("z-offset", 0.0); 
+     sm->yaw_offset     = entry_node->getDoubleValue("yaw-offset", 0.0); 
+     sm->pitch_offset   = entry_node->getDoubleValue("pitch-offset", 0.0);
+
+     sm->trigger->setBoolValue(false);
+     sm->timer = 0.0;
+   }
+
+
+  submodel_iterator = submodels.begin();
+  // cout << submodels.size() << " submodels read." << endl;
+}
+
+void
+SubmodelSystem::transform( submodel* sm) 
+{
+IC.lat = _user_lat_node->getDoubleValue();
+IC.lon = _user_lon_node->getDoubleValue();
+IC.alt = _user_alt_node->getDoubleValue();
+IC.azimuth = _user_heading_node->getDoubleValue() + sm->yaw_offset;
+IC.elevation = _user_pitch_node->getDoubleValue() + sm->pitch_offset;
+IC.speed = _user_speed_node->getDoubleValue() + sm->speed;
+}
+
 // end of submodel.cxx
index 3b96ec02ec2d58faac5ba7d7c7c6ca042f8e355e..8fe23f6d25bccc92b3d281b8e95fd0d9431b6688 100644 (file)
 #include <simgear/props/props.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <AIModel/AIManager.hxx>
+#include <vector>
+#include <string>
+SG_USING_STD(vector);
+SG_USING_STD(string);
 
 
 class SubmodelSystem : public SGSubsystem
@@ -21,24 +25,56 @@ class SubmodelSystem : public SGSubsystem
 
 public:
 
+ typedef struct {
+  SGPropertyNode_ptr trigger;
+  string             name;
+  string             model;
+  double             speed;
+  bool               slaved;
+  bool               repeat;
+  double             delay;
+  double             timer;
+  int                count;
+  double             x_offset;
+  double             y_offset;
+  double             z_offset;
+  double             yaw_offset;
+  double             pitch_offset;
+ } submodel; 
+
+ typedef struct {
+  double     lat;
+  double     lon;
+  double     alt;
+  double     azimuth;
+  double     elevation;
+  double     speed;
+ } IC_struct;  
+
     SubmodelSystem ();
     ~SubmodelSystem ();
 
+    void load ();
     void init ();
     void bind ();
     void unbind ();
     void update (double dt);
-    bool release (double dt);
+    bool release (submodel* sm, double dt);
+    void transform (submodel* sm);
 
 private:
 
+    typedef vector <submodel*> submodel_vector_type;
+    typedef submodel_vector_type::iterator submodel_vector_iterator;
+
+    submodel_vector_type       submodels;
+    submodel_vector_iterator   submodel_iterator;
+
+
     double x_offset, y_offset, z_offset;
     double pitch_offset, yaw_offset;
 
     SGPropertyNode_ptr _serviceable_node;
-    SGPropertyNode_ptr _trigger_node;
-    SGPropertyNode_ptr _amount_node;
-
     SGPropertyNode_ptr _user_lat_node;
     SGPropertyNode_ptr _user_lon_node;
     SGPropertyNode_ptr _user_heading_node;
@@ -48,10 +84,8 @@ private:
     SGPropertyNode_ptr _user_yaw_node;
     SGPropertyNode_ptr _user_speed_node;
 
-    double elapsed_time;
     FGAIManager* ai;
-    double initial_velocity;
-    bool firing;
+    IC_struct  IC;
 };
 
 #endif // __SYSTEMS_SUBMODEL_HXX