]> git.mxchange.org Git - flightgear.git/blobdiff - src/Model/model.cxx
Make sure that all elapsed time gets passed to update when a subsystem
[flightgear.git] / src / Model / model.cxx
index 84fdc229c2a84b98e69fae072895408a65d99613..00773806e5d0ff90359812115550497734126954 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <plib/sg.h>
 #include <plib/ssg.h>
+#include <plib/ul.h>
 
 #include <simgear/compiler.h>
 #include <simgear/debug/logstream.hxx>
@@ -142,7 +143,7 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
  */
 static void
 make_offsets_matrix (sgMat4 * result, double h_rot, double p_rot, double r_rot,
-                    double x_off, double y_off, double z_off)
+                     double x_off, double y_off, double z_off)
 {
   sgMat4 rot_matrix;
   sgMat4 pos_matrix;
@@ -156,15 +157,15 @@ make_offsets_matrix (sgMat4 * result, double h_rot, double p_rot, double r_rot,
  * Read an interpolation table from properties.
  */
 static SGInterpTable *
-read_interpolation_table (const SGPropertyNode * props)
+read_interpolation_table (SGPropertyNode_ptr props)
 {
-  const SGPropertyNode * table_node = props->getNode("interpolation");
+  SGPropertyNode_ptr table_node = props->getNode("interpolation");
   if (table_node != 0) {
     SGInterpTable * table = new SGInterpTable();
     vector<SGPropertyNode_ptr> entries = table_node->getChildren("entry");
     for (unsigned int i = 0; i < entries.size(); i++)
       table->addEntry(entries[i]->getDoubleValue("ind", 0.0),
-                     entries[i]->getDoubleValue("dep", 0.0));
+                      entries[i]->getDoubleValue("dep", 0.0));
     return table;
   } else {
     return 0;
@@ -174,11 +175,12 @@ read_interpolation_table (const SGPropertyNode * props)
 
 static void
 make_animation (ssgBranch * model,
-                const char * object_name,
-                SGPropertyNode * node)
+                const char * name,
+                vector<SGPropertyNode_ptr> &name_nodes,
+                SGPropertyNode_ptr node)
 {
   Animation * animation = 0;
-  const char * type = node->getStringValue("type");
+  const char * type = node->getStringValue("type", "none");
   if (!strcmp("none", type)) {
     animation = new NullAnimation(node);
   } else if (!strcmp("range", type)) {
@@ -189,6 +191,8 @@ make_animation (ssgBranch * model,
     animation = new SelectAnimation(node);
   } else if (!strcmp("spin", type)) {
     animation = new SpinAnimation(node);
+  } else if (!strcmp("timed", type)) {
+    animation = new TimedAnimation(node);
   } else if (!strcmp("rotate", type)) {
     animation = new RotateAnimation(node);
   } else if (!strcmp("translate", type)) {
@@ -198,11 +202,15 @@ make_animation (ssgBranch * model,
     SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type);
   }
 
+  if (name != 0)
+      animation->setName((char *)name);
+
   ssgEntity * object;
-  if (object_name != 0) {
-    object = find_named_node(model, object_name);
+  if (name_nodes.size() > 0) {
+    object = find_named_node(model, name_nodes[0]->getStringValue());
     if (object == 0) {
-      SG_LOG(SG_INPUT, SG_WARN, "Object " << object_name << " not found");
+      SG_LOG(SG_INPUT, SG_WARN, "Object " << name_nodes[0]->getStringValue()
+             << " not found");
       delete animation;
       animation = 0;
     }
@@ -212,6 +220,21 @@ make_animation (ssgBranch * model,
   
   ssgBranch * branch = animation->getBranch();
   splice_branch(branch, object);
+
+  for (int i = 1; i < name_nodes.size(); i++) {
+      const char * name = name_nodes[i]->getStringValue();
+      object = find_named_node(model, name);
+      if (object == 0) {
+          SG_LOG(SG_INPUT, SG_WARN, "Object " << name << " not found");
+          delete animation;
+          animation = 0;
+      }
+      ssgBranch * oldParent = object->getParent(0);
+      branch->addKid(object);
+      oldParent->removeKid(object);
+  }
+
+  animation->init();
   branch->setUserData(animation);
   branch->setTravCallback(SSG_CALLBACK_PRETRAV, animation_callback);
 }
@@ -229,9 +252,15 @@ fgLoad3DModel (const string &path)
   SGPropertyNode props;
 
                                 // Load the 3D aircraft object itself
-  SGPath xmlpath = globals->get_fg_root();
+  SGPath xmlpath;
   SGPath modelpath = path;
-  xmlpath.append(modelpath.str());
+  if ( ulIsAbsolutePathName( path.c_str() ) ) {
+    xmlpath = modelpath;
+  }
+  else {
+    xmlpath = globals->get_fg_root();
+    xmlpath.append(modelpath.str());
+  }
 
                                 // Check for an XML wrapper
   if (xmlpath.str().substr(xmlpath.str().size() - 4, 4) == ".xml") {
@@ -241,7 +270,7 @@ fgLoad3DModel (const string &path)
       modelpath.append(props.getStringValue("/path"));
     } else {
       if (model == 0)
-       model = new ssgBranch;
+        model = new ssgBranch;
     }
   }
 
@@ -255,54 +284,51 @@ fgLoad3DModel (const string &path)
   }
 
                                 // Set up the alignment node
-  ssgTransform * align = new ssgTransform;
-  align->addKid(model);
+  ssgTransform * alignmainmodel = new ssgTransform;
+  alignmainmodel->addKid(model);
   sgMat4 res_matrix;
   make_offsets_matrix(&res_matrix,
-                     props.getFloatValue("/offsets/heading-deg", 0.0),
-                     props.getFloatValue("/offsets/roll-deg", 0.0),
-                     props.getFloatValue("/offsets/pitch-deg", 0.0),
-                     props.getFloatValue("/offsets/x-m", 0.0),
-                     props.getFloatValue("/offsets/y-m", 0.0),
-                     props.getFloatValue("/offsets/z-m", 0.0));
-  align->setTransform(res_matrix);
-
-                                // Load animations
-  vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
-  unsigned int i;
-  for (i = 0; i < animation_nodes.size(); i++) {
-    vector<SGPropertyNode_ptr> name_nodes =
-      animation_nodes[i]->getChildren("object-name");
-    if (name_nodes.size() < 1) {
-        make_animation(model, 0, animation_nodes[i]);
-    } else {
-      for (unsigned int j = 0; j < name_nodes.size(); j++) {
-        make_animation(model, name_nodes[j]->getStringValue(), animation_nodes[i]);
-      }
-    }
-  }
+                      props.getFloatValue("/offsets/heading-deg", 0.0),
+                      props.getFloatValue("/offsets/roll-deg", 0.0),
+                      props.getFloatValue("/offsets/pitch-deg", 0.0),
+                      props.getFloatValue("/offsets/x-m", 0.0),
+                      props.getFloatValue("/offsets/y-m", 0.0),
+                      props.getFloatValue("/offsets/z-m", 0.0));
+  alignmainmodel->setTransform(res_matrix);
 
                                 // Load panels
+  unsigned int i;
   vector<SGPropertyNode_ptr> panel_nodes = props.getChildren("panel");
   for (i = 0; i < panel_nodes.size(); i++) {
-    printf("Reading a panel in model.cxx\n");
+    SG_LOG(SG_INPUT, SG_DEBUG, "Loading a panel");
     FGPanelNode * panel = new FGPanelNode(panel_nodes[i]);
+    if (panel_nodes[i]->hasValue("name"))
+        panel->setName((char *)panel_nodes[i]->getStringValue("name"));
     model->addKid(panel);
   }
 
-                               // Load sub-models
+                                // Load animations
+  vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
+  for (i = 0; i < animation_nodes.size(); i++) {
+    const char * name = animation_nodes[i]->getStringValue("name", 0);
+    vector<SGPropertyNode_ptr> name_nodes =
+      animation_nodes[i]->getChildren("object-name");
+    make_animation(model, name, name_nodes, animation_nodes[i]);
+  }
+
+                                // Load sub-models
   vector<SGPropertyNode_ptr> model_nodes = props.getChildren("model");
   for (i = 0; i < model_nodes.size(); i++) {
     SGPropertyNode_ptr node = model_nodes[i];
     ssgTransform * align = new ssgTransform;
     sgMat4 res_matrix;
     make_offsets_matrix(&res_matrix,
-                       node->getFloatValue("offsets/heading-deg", 0.0),
-                       node->getFloatValue("offsets/roll-deg", 0.0),
-                       node->getFloatValue("offsets/pitch-deg", 0.0),
-                       node->getFloatValue("offsets/x-m", 0.0),
-                       node->getFloatValue("offsets/y-m", 0.0),
-                       node->getFloatValue("offsets/z-m", 0.0));
+                        node->getFloatValue("offsets/heading-deg", 0.0),
+                        node->getFloatValue("offsets/roll-deg", 0.0),
+                        node->getFloatValue("offsets/pitch-deg", 0.0),
+                        node->getFloatValue("offsets/x-m", 0.0),
+                        node->getFloatValue("offsets/y-m", 0.0),
+                        node->getFloatValue("offsets/z-m", 0.0));
     align->setTransform(res_matrix);
 
     ssgBranch * kid = fgLoad3DModel(node->getStringValue("path"));
@@ -310,7 +336,7 @@ fgLoad3DModel (const string &path)
     model->addKid(align);
   }
 
-  return model;
+  return alignmainmodel;
 }
 
 
@@ -329,6 +355,16 @@ Animation::~Animation ()
 {
 }
 
+void
+Animation::init ()
+{
+}
+
+void
+Animation::update ()
+{
+}
+
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -344,11 +380,6 @@ NullAnimation::~NullAnimation ()
 {
 }
 
-void
-NullAnimation::update ()
-{
-}
-
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -368,11 +399,6 @@ RangeAnimation::~RangeAnimation ()
 {
 }
 
-void
-RangeAnimation::update ()
-{
-}
-
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -388,11 +414,6 @@ BillboardAnimation::~BillboardAnimation ()
 {
 }
 
-void
-BillboardAnimation::update ()
-{
-}
-
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -403,7 +424,7 @@ SelectAnimation::SelectAnimation (SGPropertyNode_ptr props)
   : Animation(props, new ssgSelector),
     _condition(0)
 {
-  SGPropertyNode * node = props->getChild("condition");
+  SGPropertyNode_ptr node = props->getChild("condition");
   if (node != 0)
     _condition = fgReadCondition(node);
 }
@@ -466,6 +487,37 @@ SpinAnimation::update ()
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of TimedAnimation
+////////////////////////////////////////////////////////////////////////
+
+TimedAnimation::TimedAnimation (SGPropertyNode_ptr props)
+  : Animation(props, new ssgSelector),
+    _duration_sec(props->getDoubleValue("duration-sec", 1.0)),
+    _last_time_sec(0),
+    _step(-1)
+{
+}
+
+TimedAnimation::~TimedAnimation ()
+{
+}
+
+void
+TimedAnimation::update ()
+{
+    float sim_time_sec = globals->get_sim_time_sec();
+    if ((sim_time_sec - _last_time_sec) >= _duration_sec) {
+        _last_time_sec = sim_time_sec;
+        _step++;
+        if (_step >= getBranch()->getNumKids())
+            _step = 0;
+        ((ssgSelector *)getBranch())->selectStep(_step);
+    }
+}
+
+
 \f
 ////////////////////////////////////////////////////////////////////////
 // Implementation of RotateAnimation
@@ -501,7 +553,7 @@ void
 RotateAnimation::update ()
 {
   if (_table == 0) {
-    _position_deg = (_prop->getDoubleValue() + _offset_deg) * _factor;
+   _position_deg = _prop->getDoubleValue() * _factor + _offset_deg;
    if (_has_min && _position_deg < _min_deg)
      _position_deg = _min_deg;
    if (_has_max && _position_deg > _max_deg)
@@ -670,7 +722,7 @@ FGModelPlacement::setHeadingDeg (double heading_deg)
 
 void
 FGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
-                                 double heading_deg)
+                                  double heading_deg)
 {
   _roll_deg = roll_deg;
   _pitch_deg = pitch_deg;