]> git.mxchange.org Git - flightgear.git/commitdiff
Separated 3D model-handling code from main.cxx out into its own
authordavid <david>
Sat, 23 Feb 2002 21:20:00 +0000 (21:20 +0000)
committerdavid <david>
Sat, 23 Feb 2002 21:20:00 +0000 (21:20 +0000)
subsystem, FGAircraftModel.

src/Main/Makefile.am
src/Main/main.cxx
src/Main/model.cxx [new file with mode: 0644]
src/Main/model.hxx [new file with mode: 0644]

index 9044087adfcd58c00a0265c827451df9ffe49e6a..ad7df67edcfe62ebcd218abfc3b983c9082c4d78 100644 (file)
@@ -47,6 +47,7 @@ fgfs_SOURCES = \
        fg_props.cxx fg_props.hxx \
         fgfs.cxx fgfs.hxx \
        globals.cxx globals.hxx \
+        model.cxx model.hxx \
        options.cxx options.hxx \
        splash.cxx splash.hxx \
        viewer.cxx viewer.hxx \
index fdbc4b9eb625a819e5196de1b712c03e7d7a0094..cd56e6971f1522a7c902ecae626318a527f98c58 100644 (file)
@@ -151,6 +151,7 @@ sgVec3 rway_ols;
 #include "splash.hxx"
 #include "viewmgr.hxx"
 #include "options.hxx"
+#include "model.hxx"
 
 #ifdef macintosh
 #  include <console.h>         // -dw- for command line dialog
@@ -173,14 +174,6 @@ void fgReshape( int width, int height );
 ssgRoot *scene = NULL;
 ssgBranch *terrain = NULL;
 
-// aircraft model stuff
-ssgSelector *acmodel_selector = NULL;
-ssgTransform *acmodel_pos = NULL;
-ssgSelector *prop_selector = NULL;
-ssgSelector *flaps_selector = NULL;
-int acmodel_npropsettings;
-int acmodel_proprpms[4][2];  // different propeller settings
-
 ssgRoot *lighting = NULL;
 ssgBranch *ground = NULL;
 ssgBranch *airport = NULL;
@@ -675,57 +668,7 @@ void fgRenderFrame( void ) {
            ssgSetNearFar( 0.5f, 120000.0f );
        }
 
-       if ( globals->get_viewmgr()->get_current() == 0 ) {
-           // disable aircraft model
-           acmodel_selector->select(0);
-       } else { 
-           // enable aircraft model and set up its position and orientation
-           acmodel_selector->select(1);
-
-           FGViewerRPH *pilot_view =
-               (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
-
-           sgMat4 sgTRANS;
-           sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() );
-
-           sgVec3 ownship_up;
-           sgSetVec3( ownship_up, 0.0, 0.0, 1.0);
-
-           sgMat4 sgROT;
-           sgMakeRotMat4( sgROT, -90.0, ownship_up );
-
-           // sgMat4 sgTMP;
-           // sgMat4 sgTUX;
-           // sgMultMat4( sgTMP, sgROT, pilot_view.VIEW_ROT );
-           // sgMultMat4( sgTUX, sgTMP, sgTRANS );
-
-           // sgTUX = ( sgROT * pilot_view.VIEW_ROT ) * sgTRANS
-           sgMat4 sgTUX;
-           sgCopyMat4( sgTUX, sgROT );
-           sgPostMultMat4( sgTUX, pilot_view->get_VIEW_ROT() );
-           sgPostMultMat4( sgTUX, sgTRANS );
-       
-           sgCoord tuxpos;
-           sgSetCoord( &tuxpos, sgTUX );
-           acmodel_pos->setTransform( &tuxpos );
-
-           // set up moving parts
-           if (flaps_selector != NULL) {
-               flaps_selector->select( (globals->get_controls()->get_flaps() > 0.5f) ? 1 : 2 );
-           }
-
-           if (prop_selector != NULL) {
-             int propsel_mask = 0;
-             double rpm = fgGetDouble("/engines/engine[0]/rpm");
-             for (int i = 0; i < acmodel_npropsettings; i++) {
-               if (rpm >= acmodel_proprpms[i][0] &&
-                   rpm <= acmodel_proprpms[i][1]) {
-                 propsel_mask |= 1 << i;
-               }
-             }
-             prop_selector->select(propsel_mask);
-           }
-       }
+       current_model.update(0); // FIXME: use real delta time
 
        // $$$ begin - added VS Renganthan 17 Oct 2K
        fgUpdateDCS();
@@ -1621,92 +1564,7 @@ int mainLoop( int argc, char **argv ) {
     // ADA
 
     // temporary visible aircraft "own ship"
-    acmodel_selector = new ssgSelector;
-    acmodel_pos = new ssgTransform;
-
-    ssgEntity *acmodel_obj = NULL;
-    if (fgGetString("/sim/flight-model") == "ada") {
-        // ada exteranl aircraft model loading
-        if( !ship_pos[0]->getKid(0) ) {
-            // fall back to default
-            ssgEntity *acmodel_obj = ssgLoad( (char *)"glider.ac" );
-            if( !acmodel_obj ) {
-                SG_LOG( SG_GENERAL, SG_ALERT, "FAILED to LOAD an AC model! ..." );
-                exit(-1);
-            }
-            acmodel_pos->addKid( acmodel_obj );
-        } else {
-            acmodel_obj = ship_pos[0]->getKid(0);
-        }
-    } else {
-        // default aircraft model loading
-
-        // Get the model location, and load textures from the same
-        // directory.  Use an absolute path for the model to avoid
-        // incompatibilities in different versions of PLIB.
-        string acmodel_path =
-            fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
-        SGPath full_model = globals->get_fg_root();
-        full_model.append(acmodel_path);
-
-        ssgTexturePath( (char *)full_model.dir().c_str() );
-        acmodel_obj = ssgLoad( (char *)full_model.c_str() );
-        if( !acmodel_obj ) {
-            // fall back to default
-            acmodel_obj = ssgLoad( (char *)"Models/Geometry/glider.ac" );
-            if( !acmodel_obj ) {
-                SG_LOG( SG_GENERAL, SG_ALERT, "FAILED to LOAD an AC model! ..." );
-                exit(-1);
-            }
-        }
-    }
-
-    // find moving parts (if this is an MDL model)
-    flaps_selector = (ssgSelector*)fgFindNode( acmodel_obj, "FLAPS" );
-    prop_selector  = (ssgSelector*)fgFindNode( acmodel_obj, "PROP"  );
-
-    acmodel_npropsettings = 0;
-    if (prop_selector != NULL) {
-      for (ssgEntity* kid = prop_selector->getKid(0); kid != NULL;
-          kid = prop_selector->getNextKid()) {
-       int prop_low, prop_high;
-       if ( sscanf(kid->getName(), "PROP_%d_%d", 
-                   &prop_low, &prop_high) == 2 ) {
-         prop_low  = (int)((float)prop_low  * (5000.0f / 32767.0f));
-         prop_high = (int)((float)prop_high * (5000.0f / 32767.0f));
-         acmodel_proprpms[acmodel_npropsettings][0] = prop_low ;
-         acmodel_proprpms[acmodel_npropsettings][1] = prop_high;
-         acmodel_npropsettings++;
-
-         SG_LOG( SG_GENERAL, SG_INFO, "PROPELLER SETTING " << prop_low <<
-                 " " << prop_high );
-       }
-      }
-    }
-
-    // align the model properly for FGFS
-    ssgTransform *acmodel_align = new ssgTransform;
-    acmodel_align->addKid(acmodel_obj);
-    sgMat4 rot_matrix;
-    sgMat4 off_matrix;
-    sgMat4 res_matrix;
-    float h_rot = fgGetFloat("/sim/model/heading-offset-deg", 0.0);
-    float p_rot = fgGetFloat("/sim/model/roll-offset-deg", 0.0);
-    float r_rot = fgGetFloat("/sim/model/pitch-offset-deg", 0.0);
-    float x_off = fgGetFloat("/sim/model/x-offset-m", 0.0);
-    float y_off = fgGetFloat("/sim/model/y-offset-m", 0.0);
-    float z_off = fgGetFloat("/sim/model/z-offset-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);
-    acmodel_align->setTransform(res_matrix);
-
-    acmodel_pos->addKid( acmodel_align );
-    acmodel_selector->addKid( acmodel_pos );
-    //ssgFlatten( acmodel_obj );
-    //ssgStripify( acmodel_selector );
-    acmodel_selector->clrTraversalMaskBits( SSGTRAV_HOT );
-    scene->addKid( acmodel_selector );
+    current_model.init();
 
 #ifdef FG_NETWORK_OLK
     // Do the network intialization
diff --git a/src/Main/model.cxx b/src/Main/model.cxx
new file mode 100644 (file)
index 0000000..1efb633
--- /dev/null
@@ -0,0 +1,191 @@
+// model.cxx - manage a 3D aircraft model.
+// Written by David Megginson, started 2002.
+//
+// This file is in the Public Domain, and comes with no warranty.
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <plib/sg.h>
+#include <plib/ssg.h>
+
+#include <simgear/compiler.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/misc/exception.hxx>
+
+#include "globals.hxx"
+#include "fg_props.hxx"
+#include "viewmgr.hxx"
+#include "model.hxx"
+
+extern unsigned long int fgSimTime; // FIXME: this is ugly
+
+extern ssgRoot * scene;                // FIXME: from main.cxx
+
+FGAircraftModel current_model; // FIXME: add to globals
+
+
+static ssgEntity *
+find_named_node (ssgEntity * node, const string &name)
+{
+  char * node_name = node->getName();
+  if (node_name != 0 && name == node_name)
+    return node;
+  else if (node->isAKindOf(ssgTypeBranch())) {
+    int nKids = node->getNumKids();
+    for (int i = 0; i < nKids; i++) {
+      ssgEntity * result =
+       find_named_node(((ssgBranch*)node)->getKid(i), name);
+      if (result != 0)
+       return result;
+    }
+    return 0;
+  }
+}
+
+FGAircraftModel::FGAircraftModel ()
+  : _object(0),
+    _selector(new ssgSelector),
+    _position(new ssgTransform),
+    _prop_position(0)
+{
+}
+
+FGAircraftModel::~FGAircraftModel ()
+{
+  // since the nodes are attached to the scene graph, they'll be
+  // deleted automatically
+}
+
+void 
+FGAircraftModel::init ()
+{
+  // TODO: optionally load an XML file with a pointer to the 3D object
+  // and placement and animation info
+
+                               // Load the 3D aircraft object itself
+  SGPath path = globals->get_fg_root();
+  path.append(fgGetString("/sim/model/path", "Models/Geometry/glider.ac"));
+  ssgTexturePath((char *)path.dir().c_str());
+  _object = ssgLoad((char *)path.c_str());
+  if (_object == 0) {
+    _object = ssgLoad((char *)"Models/Geometry/glider.ac");
+    if (_object == 0)
+      throw sg_exception("Failed to load an aircraft model");
+  }
+
+                               // Find the propeller
+  ssgEntity * prop_node = find_named_node(_object, "Propeller");
+  if (prop_node != 0) {
+    std::cout << "Found propeller node" << std::endl;
+    std::cout << "User data is " << int(prop_node->getUserData()) << std::endl;
+    _prop_position = new ssgTransform;
+    int nParents = prop_node->getNumParents();
+    _prop_position->addKid(prop_node);
+    std::cout << "Found " << nParents << " parent(s)" << std::endl;
+    for (int i = 0; i < nParents; i++) {
+      ssgBranch * parent = prop_node->getParent(i);
+      parent->replaceKid(prop_node, _prop_position);
+    }
+  } else {
+    std::cout << "Did not find propeller node" << std::endl;
+  }
+
+                               // Set up the alignment node
+  ssgTransform * align = new ssgTransform;
+  align->addKid(_object);
+  sgMat4 rot_matrix;
+  sgMat4 off_matrix;
+  sgMat4 res_matrix;
+  float h_rot = fgGetFloat("/sim/model/heading-offset-deg", 0.0);
+  float p_rot = fgGetFloat("/sim/model/roll-offset-deg", 0.0);
+  float r_rot = fgGetFloat("/sim/model/pitch-offset-deg", 0.0);
+  float x_off = fgGetFloat("/sim/model/x-offset-m", 0.0);
+  float y_off = fgGetFloat("/sim/model/y-offset-m", 0.0);
+  float z_off = fgGetFloat("/sim/model/z-offset-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);
+  align->setTransform(res_matrix);
+
+                               // Set up the position node
+  _position->addKid(align);
+
+                               // Set up the selector node
+  _selector->addKid(_position);
+  _selector->clrTraversalMaskBits(SSGTRAV_HOT);
+  scene->addKid(_selector);
+}
+
+void 
+FGAircraftModel::bind ()
+{
+}
+
+void 
+FGAircraftModel::unbind ()
+{
+}
+
+void
+FGAircraftModel::update (int dt)
+{
+  // START TEMPORARY KLUDGE
+  static float prop_rotation = 0;
+  static sgMat4 prop_matrix;
+
+  _current_timestamp.stamp();
+  long ms = (_current_timestamp - _last_timestamp) / 1000;
+  _last_timestamp.stamp();
+
+  double rpms = fgGetDouble("/engines/engine[0]/rpm") / 60000.0;
+  prop_rotation += (ms * rpms * 360);
+  while (prop_rotation >= 360)
+    prop_rotation -= 360;
+  // END TEMPORARY KLUDGE
+
+  if (globals->get_viewmgr()->get_current() == 0
+      && !fgGetBool("/sim/model/enable-interior")) {
+    _selector->select(false);
+  } else {
+                               // TODO: use correct alignment in pilot
+                               // view.
+    _selector->select(true);
+    FGViewerRPH *pilot_view =
+      (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 );
+    
+    sgMat4 sgTRANS;
+    sgMakeTransMat4( sgTRANS, pilot_view->get_view_pos() );
+    
+    sgVec3 ownship_up;
+    sgSetVec3( ownship_up, 0.0, 0.0, 1.0);
+    
+    sgMat4 sgROT;
+    sgMakeRotMat4( sgROT, -90.0, ownship_up );
+    
+    sgMat4 sgTUX;
+    sgCopyMat4( sgTUX, sgROT );
+    sgPostMultMat4( sgTUX, pilot_view->get_VIEW_ROT() );
+    sgPostMultMat4( sgTUX, sgTRANS );
+    
+    sgCoord tuxpos;
+    sgSetCoord( &tuxpos, sgTUX );
+    _position->setTransform( &tuxpos );
+
+    // START TEMPORARY KLUDGE
+    if (_prop_position != 0) {
+      double offset = fgGetDouble("/tmp/offset", -.75);
+      sgMat4 tmp;
+      sgMakeTransMat4(prop_matrix, 0, 0, offset);
+      sgMakeRotMat4(tmp, 0, 0, prop_rotation);
+      sgPostMultMat4(prop_matrix, tmp);
+      sgMakeTransMat4(tmp, 0, 0, -offset);
+      sgPostMultMat4(prop_matrix, tmp);
+      _prop_position->setTransform(prop_matrix);
+    }
+    // END_TEMPORARY KLUDGE
+  }
+}
+
+// end of model.cxx
diff --git a/src/Main/model.hxx b/src/Main/model.hxx
new file mode 100644 (file)
index 0000000..ab28905
--- /dev/null
@@ -0,0 +1,44 @@
+// model.hxx - manage a 3D aircraft model.
+// Written by David Megginson, started 2002.
+//
+// This file is in the Public Domain, and comes with no warranty.
+
+#ifndef __MODEL_HXX
+#define __MODEL_HXX 1
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include "fgfs.hxx"
+#include <simgear/timing/timestamp.hxx>
+
+class FGAircraftModel : public FGSubsystem
+{
+public:
+
+  FGAircraftModel ();
+  virtual ~FGAircraftModel ();
+
+  virtual void init ();
+  virtual void bind ();
+  virtual void unbind ();
+  virtual void update (int dt);
+
+private:
+
+  ssgEntity * _object;
+  ssgSelector * _selector;
+  ssgTransform * _position;
+
+  SGTimeStamp _last_timestamp;
+  SGTimeStamp _current_timestamp;
+
+  ssgTransform * _prop_position;
+
+};
+
+extern FGAircraftModel current_model;
+
+#endif // __MODEL_HXX
+