]> git.mxchange.org Git - flightgear.git/commitdiff
Separate the model geodetic position and orientation into a separate
authordavid <david>
Mon, 10 Jun 2002 13:20:26 +0000 (13:20 +0000)
committerdavid <david>
Mon, 10 Jun 2002 13:20:26 +0000 (13:20 +0000)
class, FGModelPlacement, while FG3DModel retains control of animation.
This way, we can have a single, top-level placement, but multiple
layers of nested models underneath.  To include a nested model, use
something like this in the XML wrapper:

  <model>
   <path>Models/Stuff/my-component.xml</path>
   <offsets>
    <roll-offset-deg>45</roll-offset-deg>
   </offsets>
  </model>

src/Model/acmodel.cxx
src/Model/acmodel.hxx
src/Model/model.cxx
src/Model/model.hxx
src/Model/modelmgr.cxx
src/Model/modelmgr.hxx

index 30bebb0c1c0ab0ce78cf2a66725c8bee5072336a..9e9dd6dc0fc745c1164c2b143bbe80073e3409f0 100644 (file)
@@ -51,7 +51,7 @@ FGAircraftModel::~FGAircraftModel ()
 void 
 FGAircraftModel::init ()
 {
-  _aircraft = new FG3DModel;
+  _aircraft = new FGModelPlacement;
   string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
   try {
     _aircraft->init(path);
index 4e691ca0a12244ea43895b45ce8e86aa61375edb..b2674e70fe3418e23c565fd0993a77e4ad3e0ca3 100644 (file)
@@ -21,7 +21,7 @@ SG_USING_STD(vector);
 // Don't pull in the headers, since we don't need them here.
 class ssgRoot;
 class ssgSelector;
-class FG3DModel;
+class FGModelPlacement;
 
 
 class FGAircraftModel : public FGSubsystem
@@ -36,11 +36,11 @@ public:
   virtual void unbind ();
   virtual void update (double dt);
   virtual void draw ();
-  virtual FG3DModel * get3DModel() { return _aircraft; }
+  virtual FGModelPlacement * get3DModel() { return _aircraft; }
 
 private:
 
-  FG3DModel * _aircraft;
+  FGModelPlacement * _aircraft;
   ssgSelector * _selector;
   ssgRoot * _scene;
   float _nearplane;
index f13c8e13a575e39586cdf8adb9146f3830c08e16..430c48cc01d41f4ec1f57a14d6ba549811de2b6f 100644 (file)
@@ -125,6 +125,21 @@ set_translation (sgMat4 &matrix, double position_m, sgVec3 &axis)
 }
 
 
+/**
+ * Make an offset matrix from rotations and position offset.
+ */
+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)
+{
+  sgMat4 rot_matrix;
+  sgMat4 pos_matrix;
+  sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot);
+  sgMakeTransMat4(pos_matrix, x_off, y_off, z_off);
+  sgMultMat4(*result, pos_matrix, rot_matrix);
+}
+
+
 /**
  * Read an interpolation table from properties.
  */
@@ -151,9 +166,7 @@ read_interpolation_table (const SGPropertyNode * props)
 ////////////////////////////////////////////////////////////////////////
 
 FG3DModel::FG3DModel ()
-  : _model(0),
-    _selector(new ssgSelector),
-    _position(new ssgTransform)
+  : _model(0)
 {
 }
 
@@ -198,30 +211,16 @@ FG3DModel::init (const string &path)
                                 // Set up the alignment node
   ssgTransform * align = new ssgTransform;
   align->addKid(_model);
-  sgMat4 rot_matrix;
-  sgMat4 off_matrix;
   sgMat4 res_matrix;
-  float h_rot = props.getFloatValue("/offsets/heading-deg", 0.0);
-  float p_rot = props.getFloatValue("/offsets/roll-deg", 0.0);
-  float r_rot = props.getFloatValue("/offsets/pitch-deg", 0.0);
-  float x_off = props.getFloatValue("/offsets/x-m", 0.0);
-  float y_off = props.getFloatValue("/offsets/y-m", 0.0);
-  float z_off = props.getFloatValue("/offsets/z-m", 0.0);
-  sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot);
-  sgMakeTransMat4(off_matrix, x_off, y_off, z_off);
-  sgMultMat4(res_matrix, off_matrix, rot_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);
 
-                                // Set up the position node
-  _position->addKid(align);
-
-                                // Set up the selector node
-  _selector->addKid(_position);
-  _selector->clrTraversalMaskBits(SSGTRAV_HOT);
-
-                                // Set up a location class
-  _location = (FGLocation *) new FGLocation;
-
                                 // Load animations
   vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
   unsigned int i;
@@ -238,6 +237,27 @@ FG3DModel::init (const string &path)
           _animations.push_back(animation);
       }
     }
+  }
+
+                               // 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));
+    align->setTransform(res_matrix);
+    FG3DModel * kid = new FG3DModel;
+    kid->init(node->getStringValue("path"));
+    align->addKid(kid->getSceneGraph());
+    _model->addKid(align);
+    _children.push_back(kid);
   }
 }
 
@@ -246,90 +266,10 @@ FG3DModel::update (double dt)
 {
   unsigned int i;
 
+  for (i = 0; i < _children.size(); i++)
+    _children[i]->update(dt);
   for (i = 0; i < _animations.size(); i++)
     _animations[i]->update(dt);
-
-  _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
-  _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
-
-  sgMat4 POS;
-  sgCopyMat4(POS, _location->getTransformMatrix());
-  
-  sgVec3 trans;
-  sgCopyVec3(trans, _location->get_view_pos());
-
-  for(i = 0; i < 4; i++) {
-    float tmp = POS[i][3];
-    for( int j=0; j<3; j++ ) {
-      POS[i][j] += (tmp * trans[j]);
-    }
-  }
-  _position->setTransform(POS);
-}
-
-bool
-FG3DModel::getVisible () const
-{
-  return (_selector->getSelect() != 0);
-}
-
-void
-FG3DModel::setVisible (bool visible)
-{
-  _selector->select(visible);
-}
-
-void
-FG3DModel::setLongitudeDeg (double lon_deg)
-{
-  _lon_deg = lon_deg;
-}
-
-void
-FG3DModel::setLatitudeDeg (double lat_deg)
-{
-  _lat_deg = lat_deg;
-}
-
-void
-FG3DModel::setElevationFt (double elev_ft)
-{
-  _elev_ft = elev_ft;
-}
-
-void
-FG3DModel::setPosition (double lon_deg, double lat_deg, double elev_ft)
-{
-  _lon_deg = lon_deg;
-  _lat_deg = lat_deg;
-  _elev_ft = elev_ft;
-}
-
-void
-FG3DModel::setRollDeg (double roll_deg)
-{
-  _roll_deg = roll_deg;
-}
-
-void
-FG3DModel::setPitchDeg (double pitch_deg)
-{
-  _pitch_deg = pitch_deg;
-}
-
-void
-FG3DModel::setHeadingDeg (double heading_deg)
-{
-  _heading_deg = heading_deg;
-}
-
-void
-FG3DModel::setOrientation (double roll_deg, double pitch_deg,
-                           double heading_deg)
-{
-  _roll_deg = roll_deg;
-  _pitch_deg = pitch_deg;
-  _heading_deg = heading_deg;
 }
 
 FG3DModel::Animation *
@@ -711,4 +651,126 @@ FG3DModel::TranslateAnimation::update (double dt)
 }
 
 
+\f
+////////////////////////////////////////////////////////////////////////
+// Implementation of FGModelPlacement.
+////////////////////////////////////////////////////////////////////////
+
+FGModelPlacement::FGModelPlacement ()
+  : _model(new FG3DModel),
+    _lon_deg(0),
+    _lat_deg(0),
+    _elev_ft(0),
+    _roll_deg(0),
+    _pitch_deg(0),
+    _heading_deg(0),
+    _selector(new ssgSelector),
+    _position(new ssgTransform),
+    _location(new FGLocation)
+{
+}
+
+FGModelPlacement::~FGModelPlacement ()
+{
+  delete _model;
+  delete _selector;
+}
+
+void
+FGModelPlacement::init (const string &path)
+{
+  _model->init(path);
+  _position->addKid(_model->getSceneGraph());
+  _selector->addKid(_position);
+  _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+}
+
+void
+FGModelPlacement::update (double dt)
+{
+  _model->update(dt);
+
+  _location->setPosition( _lon_deg, _lat_deg, _elev_ft );
+  _location->setOrientation( _roll_deg, _pitch_deg, _heading_deg );
+
+  sgMat4 POS;
+  sgCopyMat4(POS, _location->getTransformMatrix());
+  
+  sgVec3 trans;
+  sgCopyVec3(trans, _location->get_view_pos());
+
+  for(int i = 0; i < 4; i++) {
+    float tmp = POS[i][3];
+    for( int j=0; j<3; j++ ) {
+      POS[i][j] += (tmp * trans[j]);
+    }
+  }
+  _position->setTransform(POS);
+}
+
+bool
+FGModelPlacement::getVisible () const
+{
+  return (_selector->getSelect() != 0);
+}
+
+void
+FGModelPlacement::setVisible (bool visible)
+{
+  _selector->select(visible);
+}
+
+void
+FGModelPlacement::setLongitudeDeg (double lon_deg)
+{
+  _lon_deg = lon_deg;
+}
+
+void
+FGModelPlacement::setLatitudeDeg (double lat_deg)
+{
+  _lat_deg = lat_deg;
+}
+
+void
+FGModelPlacement::setElevationFt (double elev_ft)
+{
+  _elev_ft = elev_ft;
+}
+
+void
+FGModelPlacement::setPosition (double lon_deg, double lat_deg, double elev_ft)
+{
+  _lon_deg = lon_deg;
+  _lat_deg = lat_deg;
+  _elev_ft = elev_ft;
+}
+
+void
+FGModelPlacement::setRollDeg (double roll_deg)
+{
+  _roll_deg = roll_deg;
+}
+
+void
+FGModelPlacement::setPitchDeg (double pitch_deg)
+{
+  _pitch_deg = pitch_deg;
+}
+
+void
+FGModelPlacement::setHeadingDeg (double heading_deg)
+{
+  _heading_deg = heading_deg;
+}
+
+void
+FGModelPlacement::setOrientation (double roll_deg, double pitch_deg,
+                                 double heading_deg)
+{
+  _roll_deg = roll_deg;
+  _pitch_deg = pitch_deg;
+  _heading_deg = heading_deg;
+}
+
 // end of model.cxx
index bc48663acd0a16c467ac508496482d5949882ece..cc5142519d7029adcacd476a60e18d8d1c7ef7e8 100644 (file)
@@ -39,6 +39,7 @@ class FGLocation;
 #undef max
 #endif
 
+
 class FG3DModel
 {
 public:
@@ -49,57 +50,21 @@ public:
   virtual void init (const string &path);
   virtual void update (double dt);
 
-  virtual bool getVisible () const;
-  virtual void setVisible (bool visible);
-
-  virtual double getLongitudeDeg () const { return _lon_deg; }
-  virtual double getLatitudeDeg () const { return _lat_deg; }
-  virtual double getElevationFt () const { return _elev_ft; }
-
-  virtual void setLongitudeDeg (double lon_deg);
-  virtual void setLatitudeDeg (double lat_deg);
-  virtual void setElevationFt (double elev_ft);
-  virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
-
-  virtual double getRollDeg () const { return _roll_deg; }
-  virtual double getPitchDeg () const { return _pitch_deg; }
-  virtual double getHeadingDeg () const { return _heading_deg; }
-
-  virtual void setRollDeg (double roll_deg);
-  virtual void setPitchDeg (double pitch_deg);
-  virtual void setHeadingDeg (double heading_deg);
-  virtual void setOrientation (double roll_deg, double pitch_deg,
-                              double heading_deg);
-
-  virtual ssgEntity * getSceneGraph () const { return (ssgEntity *)_selector; }
-
-  virtual FGLocation * getFGLocation () const { return _location; }
+  virtual ssgEntity * getSceneGraph () const { return (ssgEntity *)_model; }
 
 private:
 
   class Animation;
   Animation * make_animation (const char * object_name, SGPropertyNode * node);
 
-                               // Geodetic position
-  double _lon_deg;
-  double _lat_deg;
-  double _elev_ft;
-
-                               // Orientation
-  double _roll_deg;
-  double _pitch_deg;
-  double _heading_deg;
+                               // Child models.
+  vector<FG3DModel *> _children;
 
                                // Animations
   vector <Animation *> _animations;
 
                                // Scene graph
   ssgBranch * _model;
-  ssgSelector * _selector;
-  ssgTransform * _position;
-
-                               // Location
-  FGLocation * _location;
 
 
   \f
@@ -278,6 +243,65 @@ private:
 
 };
 
+
+class FGModelPlacement
+{
+public:
+
+  FGModelPlacement ();
+  virtual ~FGModelPlacement ();
+
+  virtual void init (const string &path);
+  virtual void update (double dt);
+
+  virtual ssgEntity * getSceneGraph () { return (ssgEntity *)_selector; }
+
+  virtual FGLocation * getFGLocation () { return _location; }
+
+  virtual bool getVisible () const;
+  virtual void setVisible (bool visible);
+
+  virtual double getLongitudeDeg () const { return _lon_deg; }
+  virtual double getLatitudeDeg () const { return _lat_deg; }
+  virtual double getElevationFt () const { return _elev_ft; }
+
+  virtual void setLongitudeDeg (double lon_deg);
+  virtual void setLatitudeDeg (double lat_deg);
+  virtual void setElevationFt (double elev_ft);
+  virtual void setPosition (double lon_deg, double lat_deg, double elev_ft);
+
+  virtual double getRollDeg () const { return _roll_deg; }
+  virtual double getPitchDeg () const { return _pitch_deg; }
+  virtual double getHeadingDeg () const { return _heading_deg; }
+
+  virtual void setRollDeg (double roll_deg);
+  virtual void setPitchDeg (double pitch_deg);
+  virtual void setHeadingDeg (double heading_deg);
+  virtual void setOrientation (double roll_deg, double pitch_deg,
+                              double heading_deg);
+
+private:
+  
+  FG3DModel * _model;
+
+                               // Geodetic position
+  double _lon_deg;
+  double _lat_deg;
+  double _elev_ft;
+
+                               // Orientation
+  double _roll_deg;
+  double _pitch_deg;
+  double _heading_deg;
+
+  ssgSelector * _selector;
+  ssgTransform * _position;
+
+                               // Location
+  FGLocation * _location;
+
+};
+
 #endif // __MODEL_HXX
 
 
index 5d7f2afd44e18de53812bce3a278c63ef3509a1c..ce15e6078c6b1a85ad659e98ca077d071cc92803 100644 (file)
@@ -36,7 +36,7 @@ FGModelMgr::init ()
     SG_LOG(SG_GENERAL, SG_INFO,
           "Adding model " << node->getStringValue("name", "[unnamed]"));
     Instance * instance = new Instance;
-    FG3DModel * model = new FG3DModel;
+    FGModelPlacement * model = new FGModelPlacement;
     instance->model = model;
     model->init(node->getStringValue("path", "Models/Geometry/glider.ac"));
 
@@ -102,7 +102,7 @@ FGModelMgr::update (double dt)
 {
   for (unsigned int i = 0; i < _instances.size(); i++) {
     Instance * instance = _instances[i];
-    FG3DModel * model = instance->model;
+    FGModelPlacement * model = instance->model;
 
                                // Optionally set position from properties
     if (instance->lon_deg_node != 0)
index 8f953875a5c0130d27858ce3859f6a1e373a63df..d0b7841cd7410007b5a4bb3b34bc74ff7a61bd19 100644 (file)
@@ -21,7 +21,7 @@ SG_USING_STD(vector);
 // Don't pull in headers, since we don't need them here.
 class ssgSelector;
 class SGPropertyNode;
-class FG3DModel;
+class FGModelPlacement;
 
 
 /**
@@ -46,7 +46,7 @@ private:
   {
     Instance ();
     virtual ~Instance ();
-    FG3DModel * model;
+    FGModelPlacement * model;
     SGPropertyNode * lon_deg_node;
     SGPropertyNode * lat_deg_node;
     SGPropertyNode * elev_ft_node;