]> git.mxchange.org Git - flightgear.git/commitdiff
Mathias Fröhlich:
authorehofman <ehofman>
Fri, 26 Nov 2004 10:24:48 +0000 (10:24 +0000)
committerehofman <ehofman>
Fri, 26 Nov 2004 10:24:48 +0000 (10:24 +0000)
This patch makes the aircraft carrier's hardware  appear in the scenegraph.

src/AIModel/AIBase.hxx
src/AIModel/AICarrier.cxx
src/AIModel/AICarrier.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIScenario.cxx
src/FDM/groundcache.cxx

index 7bb3b607ca335df40f20fed8481646ab78561506..bca2aea11cc8983622dc838e07fcd42c7359a324 100644 (file)
@@ -21,6 +21,7 @@
 #define _FG_AIBASE_HXX
 
 #include <string>
+#include <list>
 
 #include <simgear/constants.h>
 #include <simgear/math/point3d.hxx>
@@ -29,6 +30,7 @@
 #include <Main/fg_props.hxx>
 
 SG_USING_STD(string);
+SG_USING_STD(list);
 
 class FGAIManager;
 class FGAIFlightPlan;
@@ -67,6 +69,9 @@ typedef struct {
    bool wind;                 // if true, model reacts to parent wind
    double mass;               // in slugs
    bool aero_stabilised;      // if true, ballistic object aligns with trajectory
+   list<string> solid_objects;    // List of solid object names
+   list<string> wire_objects;     // List of wire object names
+   list<string> catapult_objects; // List of catapult object names
    double radius;             // used by ship ojects, in feet
     
 } FGAIModelEntity;
index bb52128188ca1e1394af6b725b9d466a87c47123..d6e29b746ba2ae884988cb064168b0940c9bbb7d 100644 (file)
@@ -21,6 +21,9 @@
 #  include <config.h>
 #endif
 
+#include <string>
+#include <vector>
+
 #include "AICarrier.hxx"
 
 
@@ -30,10 +33,179 @@ FGAICarrier::FGAICarrier(FGAIManager* mgr) : FGAIShip(mgr) {
 FGAICarrier::~FGAICarrier() {
 }
 
+void FGAICarrier::setSolidObjects(const list<string>& so) {
+  solid_objects = so;
+}
+
+void FGAICarrier::setWireObjects(const list<string>& wo) {
+  wire_objects = wo;
+}
+
+void FGAICarrier::setCatapultObjects(const list<string>& co) {
+  catapult_objects = co;
+}
+
+void FGAICarrier::getVelocityWrtEarth(sgVec3 v) {
+  sgCopyVec3(v, vel_wrt_earth );
+}
 
 void FGAICarrier::update(double dt) {
    FGAIShip::update(dt);
+
+   // Update the velocity information stored in those nodes.
+   double v_north = 0.51444444*speed*cos(hdg * SGD_DEGREES_TO_RADIANS);
+   double v_east  = 0.51444444*speed*sin(hdg * SGD_DEGREES_TO_RADIANS);
+
+   double sin_lat = sin(pos.lat() * SGD_DEGREES_TO_RADIANS);
+   double cos_lat = cos(pos.lat() * SGD_DEGREES_TO_RADIANS);
+   double sin_lon = sin(pos.lon() * SGD_DEGREES_TO_RADIANS);
+   double cos_lon = cos(pos.lon() * SGD_DEGREES_TO_RADIANS);
+   sgSetVec3( vel_wrt_earth,
+              - cos_lon*sin_lat*v_north - sin_lon*v_east,
+              - sin_lon*sin_lat*v_north + cos_lon*v_east,
+                cos_lat*v_north );
+
+}
+
+bool FGAICarrier::init() {
+   if (!FGAIShip::init())
+      return false;
+
+   // process the 3d model here
+   // mark some objects solid, mark the wires ...
+
+   // The model should be used for altitude computations.
+   // To avoid that every detail in a carrier 3D model will end into
+   // the aircraft local cache, only set the HOT traversal bit on
+   // selected objects.
+   ssgEntity *sel = aip.getSceneGraph();
+   // Clear the HOT traversal flag
+   mark_nohot(sel);
+   // Selectively set that flag again for wires/cats/solid objects.
+   // Attach a pointer to this carrier class to those objects.
+   mark_wires(sel, wire_objects);
+   mark_cat(sel, catapult_objects);
+   mark_solid(sel, solid_objects);
+
+   return true;
 }
 
+void FGAICarrier::mark_nohot(ssgEntity* e) {
+  if (e->isAKindOf(ssgTypeBranch())) {
+    ssgBranch* br = (ssgBranch*)e;
+    ssgEntity* kid;
+    for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
+      mark_nohot(kid);
 
+    br->clrTraversalMaskBits(SSGTRAV_HOT);
+    
+  } else if (e->isAKindOf(ssgTypeLeaf())) {
+
+    e->clrTraversalMaskBits(SSGTRAV_HOT);
+
+  }
+}
+
+bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects) {
+  bool found = false;
+  if (e->isAKindOf(ssgTypeBranch())) {
+
+    ssgBranch* br = (ssgBranch*)e;
+    ssgEntity* kid;
+    for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
+      found = mark_wires(kid, wire_objects) || found;
+
+    if (found)
+      br->setTraversalMaskBits(SSGTRAV_HOT);
+    
+  } else if (e->isAKindOf(ssgTypeLeaf())) {
+    list<string>::const_iterator it;
+    for (it = wire_objects.begin(); it != wire_objects.end(); ++it) {
+      if (e->getName() && (*it) == e->getName()) {
+        e->setTraversalMaskBits(SSGTRAV_HOT);
+        e->setUserData( FGAICarrierHardware::newWire( this ) );
+        ssgLeaf *l = (ssgLeaf*)e;
+        if ( l->getNumLines() != 1 ) {
+          SG_LOG(SG_GENERAL, SG_ALERT,
+                 "AICarrier: Found wires not modelled with exactly one line!");
+        }
+
+        found = true;
+      }
+    }
+  }
+  return found;
+}
+
+bool FGAICarrier::mark_solid(ssgEntity* e, const list<string>& solid_objects) {
+  bool found = false;
+  if (e->isAKindOf(ssgTypeBranch())) {
+    ssgBranch* br = (ssgBranch*)e;
+    ssgEntity* kid;
+    for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
+      found = mark_solid(kid, solid_objects) || found;
+
+    if (found)
+      br->setTraversalMaskBits(SSGTRAV_HOT);
+    
+  } else if (e->isAKindOf(ssgTypeLeaf())) {
+    list<string>::const_iterator it;
+    for (it = solid_objects.begin(); it != solid_objects.end(); ++it) {
+      if (e->getName() && (*it) == e->getName()) {
+        e->setTraversalMaskBits(SSGTRAV_HOT);
+        e->setUserData( FGAICarrierHardware::newSolid( this ) );
+        found = true;
+      }
+    }
+  }
+  return found;
+}
+
+bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) {
+  bool found = false;
+  if (e->isAKindOf(ssgTypeBranch())) {
+    ssgBranch* br = (ssgBranch*)e;
+    ssgEntity* kid;
+    for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
+      found = mark_cat(kid, cat_objects) || found;
+
+    if (found)
+      br->setTraversalMaskBits(SSGTRAV_HOT);
+    
+  } else if (e->isAKindOf(ssgTypeLeaf())) {
+    list<string>::const_iterator it;
+    for (it = cat_objects.begin(); it != cat_objects.end(); ++it) {
+      if (e->getName() && (*it) == e->getName()) {
+        e->setTraversalMaskBits(SSGTRAV_HOT);
+        e->setUserData( FGAICarrierHardware::newCatapult( this ) );
+        ssgLeaf *l = (ssgLeaf*)e;
+        if ( l->getNumLines() != 1 ) {
+          SG_LOG(SG_GENERAL, SG_ALERT,
+                 "AICarrier: Found a cat not modelled with exactly one line!");
+        }
+        // Now some special code to make shure the cat points in the right
+        // direction. The 0 index must be the backward end, the 1 index
+        // the forward end.
+        // Forward is positive x-direction in our 3D model, also the model
+        // as such is flattened when it is loaded, so we do not need to care
+        // for transforms ...
+        short v[2];
+        l->getLine(0, v, v+1 );
+        sgVec3 ends[2];
+        for (int k=0; k<2; ++k)
+          sgCopyVec3( ends[k], l->getVertex( v[k] ) );
+
+        // When the 1 end is behind the 0 end, swap the coordinates.
+        if (ends[0][0] < ends[1][0]) {
+          sgCopyVec3( l->getVertex( v[0] ), ends[1] );
+          sgCopyVec3( l->getVertex( v[1] ), ends[0] );
+        }
+
+        found = true;
+      }
+    }
+  }
+  return found;
+}
 
+int FGAICarrierHardware::unique_id = 1;
index c536c457e8a0b93f1c12aab83a5d18462bff53cc..32cea59835dc09beb4e233ec597b44a57252c5e5 100644 (file)
 #ifndef _FG_AICARRIER_HXX
 #define _FG_AICARRIER_HXX
 
+#include <string>
+#include <list>
+#include <plib/ssg.h>
+#include <simgear/compiler.h>
+
+SG_USING_STD(string);
+SG_USING_STD(list);
+
 #include "AIShip.hxx"
 class FGAIManager;
+class FGAICarrier;
+
+class FGAICarrierHardware : public ssgBase {
+public:
+
+  enum Type { Catapult, Wire, Solid };
+
+  FGAICarrier *carrier;
+  int id;
+  Type type;
+
+  static FGAICarrierHardware* newCatapult(FGAICarrier *c) {
+    FGAICarrierHardware* ch = new FGAICarrierHardware;
+    ch->carrier = c;
+    ch->type = Catapult;
+    ch->id = unique_id++;
+    return ch;
+  }
+  static FGAICarrierHardware* newWire(FGAICarrier *c) {
+    FGAICarrierHardware* ch = new FGAICarrierHardware;
+    ch->carrier = c;
+    ch->type = Wire;
+    ch->id = unique_id++;
+    return ch;
+  }
+  static FGAICarrierHardware* newSolid(FGAICarrier *c) {
+    FGAICarrierHardware* ch = new FGAICarrierHardware;
+    ch->carrier = c;
+    ch->type = Solid;
+    ch->id = unique_id++;
+    return ch;
+  }
+
+private:
+  static int unique_id;
+};
 
 class FGAICarrier  : public FGAIShip {
        
@@ -30,10 +74,29 @@ public:
        
        FGAICarrier(FGAIManager* mgr);
        ~FGAICarrier();
+
+        void setSolidObjects(const list<string>& solid_objects);
+        void setWireObjects(const list<string>& wire_objects);
+        void setCatapultObjects(const list<string>& catapult_objects);
+
+       void getVelocityWrtEarth(sgVec3 v);
        
+       bool init();
+
 private:
 
        void update(double dt);
+       void mark_nohot(ssgEntity*);
+       bool mark_wires(ssgEntity*, const list<string>&);
+       bool mark_cat(ssgEntity*, const list<string>&);
+       bool mark_solid(ssgEntity*, const list<string>&);
+
+       list<string> solid_objects;       // List of solid object names
+       list<string> wire_objects;        // List of wire object names
+       list<string> catapult_objects;    // List of catapult object names
+
+       // Velocity wrt earth.
+       sgVec3 vel_wrt_earth;
 };
 
 #endif  // _FG_AICARRIER_HXX
index f9b641c4dbd1fadbd993b6302208e11e80009031..04919f7d347bec792af38f6d09e82fe51f7549ad 100644 (file)
@@ -192,7 +192,7 @@ FGAIManager::createCarrier( FGAIModelEntity *entity ) {
     
     //cout << "creating carrier" << endl;
 
-        FGAIShip* ai_carrier = new FGAICarrier(this);
+        FGAICarrier* ai_carrier = new FGAICarrier(this);
         ai_list.push_back(ai_carrier);
         ++numObjects[0];
         ++numObjects[FGAIBase::otShip];
@@ -203,6 +203,9 @@ FGAIManager::createCarrier( FGAIModelEntity *entity ) {
         ai_carrier->setLongitude(entity->longitude);
         ai_carrier->setLatitude(entity->latitude);
         ai_carrier->setBank(entity->rudder);
+        ai_carrier->setSolidObjects(entity->solid_objects);
+        ai_carrier->setWireObjects(entity->wire_objects);
+        ai_carrier->setCatapultObjects(entity->catapult_objects);
         ai_carrier->setRadius(entity->radius);
 
         if ( entity->fp ) {
index 37f5d8427632a226b27587282889fe7cf45a240b..0e92bc7c1efd04a152a43b3efaf490bfbcc7d878 100644 (file)
@@ -16,6 +16,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
+#include <cstdio>
 
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/debug/logstream.hxx>
@@ -32,7 +33,8 @@
 #include "AIScenario.hxx"
 #include "AIFlightPlan.hxx"
 
-
+static list<string>
+getAllNodeVals(const char* name, SGPropertyNode * entry_node);
 
 FGAIScenario::FGAIScenario(string &filename)
 {
@@ -92,6 +94,10 @@ FGAIScenario::FGAIScenario(string &filename)
      en->y_pivot         = entry_node->getDoubleValue("y-pivot", 0.0); 
      en->z_pivot         = entry_node->getDoubleValue("z-pivot", 0.0); */
      
+     en->wire_objects     = getAllNodeVals("wire", entry_node);
+     en->catapult_objects = getAllNodeVals("catapult", entry_node);
+     en->solid_objects    = getAllNodeVals("solid", entry_node);
+
      en->fp             = NULL;
      if (en->flightplan != ""){
         en->fp = new FGAIFlightPlan( en->flightplan );
@@ -126,5 +132,25 @@ int FGAIScenario::nEntries( void )
   return entries.size();
 }
 
+static list<string>
+getAllNodeVals(const char* name, SGPropertyNode * entry_node)
+{
+  list<string> retval;
+  int i=0;
+  do {
+    char nodename[100];
+    snprintf(nodename, sizeof(nodename), "%s[%d]", name, i);
+    const char* objname = entry_node->getStringValue(nodename, 0);
+    if (objname == 0)
+      return retval;
+
+    retval.push_back(string(objname));
+    ++i;
+  } while (1);
+
+  return retval;
+}
+
+
 // end scenario.cxx
 
index 50eee1e607c1e71c07bf7ad534c3a96e9aefa97c..683bb27d117d916619bf9de45d07106bd21e9a79 100644 (file)
@@ -49,31 +49,31 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l )
   GroundProperty *gp = new GroundProperty;
   gp->wire_id = -1;
   
-//   FGAICarrierHardware *ud =
-//     dynamic_cast<FGAICarrierHardware*>(l->getUserData());
-//   if (ud) {
-//     switch (ud->type) {
-//     case FGAICarrierHardware::Wire:
-//       gp->type = FGInterface::Wire;
-//       gp->wire_id = ud->id;
-//       break;
-//     case FGAICarrierHardware::Catapult:
-//       gp->type = FGInterface::Catapult;
-//       break;
-//     default:
-//       gp->type = FGInterface::Solid;
-//       break;
-//     }
-
-//     // Copy the velocity from the carrier class.
-//     ud->carrier->getVelocityWrtEarth( gp->vel );
-//   }
-
-//   else {
+  FGAICarrierHardware *ud =
+    dynamic_cast<FGAICarrierHardware*>(l->getUserData());
+  if (ud) {
+    switch (ud->type) {
+    case FGAICarrierHardware::Wire:
+      gp->type = FGInterface::Wire;
+      gp->wire_id = ud->id;
+      break;
+    case FGAICarrierHardware::Catapult:
+      gp->type = FGInterface::Catapult;
+      break;
+    default:
+      gp->type = FGInterface::Solid;
+      break;
+    }
+
+    // Copy the velocity from the carrier class.
+    ud->carrier->getVelocityWrtEarth( gp->vel );
+  }
+
+  else {
 
     // Initialize velocity field.
     sgSetVec3( gp->vel, 0.0, 0.0, 0.0 );
-//   }
+  }
   
   // Get the texture name and decide what ground type we have.
   ssgState *st = l->getState();