]> git.mxchange.org Git - flightgear.git/commitdiff
Modified Files:
authorfrohlich <frohlich>
Sun, 11 Jun 2006 13:34:18 +0000 (13:34 +0000)
committerfrohlich <frohlich>
Sun, 11 Jun 2006 13:34:18 +0000 (13:34 +0000)
src/AIModel/AIAircraft.cxx src/ATC/AILocalTraffic.cxx
src/FDM/flight.cxx src/FDM/flight.hxx src/FDM/groundcache.cxx
src/FDM/groundcache.hxx src/Main/fg_init.cxx src/Main/main.cxx
src/Scenery/hitlist.cxx src/Scenery/hitlist.hxx
src/Scenery/scenery.cxx src/Scenery/scenery.hxx
Make use of the attached SGMaterial reference userdata on scenegraph
leafs. Make the SGMaterial pointer available to the ground query
routines.

src/AIModel/AIAircraft.cxx
src/ATC/AILocalTraffic.cxx
src/FDM/flight.cxx
src/FDM/flight.hxx
src/FDM/groundcache.cxx
src/FDM/groundcache.hxx
src/Main/main.cxx
src/Scenery/hitlist.cxx
src/Scenery/hitlist.hxx
src/Scenery/scenery.cxx
src/Scenery/scenery.hxx

index fb7edf75161f2837cb3da961f07841ac75ce1326..5c560d9bcd4209b7b7a2cb07fcadd8b0d0d6ec19 100644 (file)
@@ -941,7 +941,7 @@ void FGAIAircraft::getGroundElev(double dt) {
 
         // FIXME: make sure the pos.lat/pos.lon values are in degrees ...
         double alt;
-        if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), 20000.0, alt))
+        if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), 20000.0, alt, 0))
             tgt_altitude = alt * SG_METER_TO_FEET;
 
         //cerr << "Target altitude : " << tgt_altitude << endl;
index 43d9b9485318541013fcbe50556bd8a1b59e5fbf..15eb6a3d3c1c7ccfc25d0041ab44e96eb5fabb66 100644 (file)
@@ -1590,7 +1590,7 @@ void FGAILocalTraffic::DoGroundElev() {
 
         // FIXME: make shure the pos.lat/pos.lon values are in degrees ...
         double alt;
-        if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt))
+        if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt, 0))
           _aip.getSGLocation()->set_cur_elev_m(alt);
 }
 
index d6e5366c9fea5d22fa35d9b942d2da5c34b87d61..fcb71deed25a7df37de7912ab2f3fbe6c3278d18 100644 (file)
@@ -32,6 +32,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/scene/model/placement.hxx>
+#include <simgear/scene/material/mat.hxx>
 #include <simgear/timing/timestamp.hxx>
 
 #include <Scenery/scenery.hxx>
@@ -836,16 +837,28 @@ FGInterface::get_cat_ft(double t, const double pt[3],
   return dist*SG_METER_TO_FEET;
 }
 
+// Legacy interface just kept because of JSBSim
 bool
 FGInterface::get_agl_m(double t, const double pt[3],
                        double contact[3], double normal[3], double vel[3],
                        int *type, double *loadCapacity,
                        double *frictionFactor, double *agl)
 {
-  return ground_cache.get_agl(t, pt, 2.0, contact, normal, vel, type,
-                              loadCapacity, frictionFactor, agl);
+  const SGMaterial* material;
+  bool ret = ground_cache.get_agl(t, pt, 2.0, contact, normal, vel, type,
+                                  &material, agl);
+  if (material) {
+    *loadCapacity = material->get_load_resistence();
+    *frictionFactor = material->get_friction_factor();
+
+  } else {
+    *loadCapacity = DBL_MAX;
+    *frictionFactor = 1.0;
+  }
+  return ret;
 }
 
+// Legacy interface just kept because of JSBSim
 bool
 FGInterface::get_agl_ft(double t, const double pt[3],
                         double contact[3], double normal[3], double vel[3],
@@ -855,45 +868,51 @@ FGInterface::get_agl_ft(double t, const double pt[3],
   // Convert units and do the real work.
   sgdVec3 pt_m;
   sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER );
+
+  const SGMaterial* material;
   bool ret = ground_cache.get_agl(t, pt_m, 2.0, contact, normal, vel,
-                                  type, loadCapacity, frictionFactor, agl);
+                                  type, &material, agl);
   // Convert units back ...
   sgdScaleVec3( contact, SG_METER_TO_FEET );
   sgdScaleVec3( vel, SG_METER_TO_FEET );
   *agl *= SG_METER_TO_FEET;
-  // FIXME: scale the load limit to something in the english unit system.
-  // Be careful with the DBL_MAX which is returned by default.
+
+  // return material properties if available
+  if (material) {
+    // FIXME: convert units?? now pascal to lbf/ft^2
+    *loadCapacity = 0.020885434*material->get_load_resistence();
+    *frictionFactor = material->get_friction_factor();
+  } else {
+    *loadCapacity = DBL_MAX;
+    *frictionFactor = 1.0;
+  }
   return ret;
 }
 
 bool
 FGInterface::get_agl_m(double t, const double pt[3], double max_altoff,
                        double contact[3], double normal[3], double vel[3],
-                       int *type, double *loadCapacity,
-                       double *frictionFactor, double *agl)
+                       int *type, const SGMaterial** material, double *agl)
 {
   return ground_cache.get_agl(t, pt, max_altoff, contact, normal, vel, type,
-                              loadCapacity, frictionFactor, agl);
+                              material, agl);
 }
 
 bool
 FGInterface::get_agl_ft(double t, const double pt[3], double max_altoff,
                         double contact[3], double normal[3], double vel[3],
-                        int *type, double *loadCapacity,
-                        double *frictionFactor, double *agl)
+                        int *type, const SGMaterial** material, double *agl)
 {
   // Convert units and do the real work.
   sgdVec3 pt_m;
   sgdScaleVec3( pt_m, pt, SG_FEET_TO_METER );
   bool ret = ground_cache.get_agl(t, pt_m, SG_FEET_TO_METER * max_altoff,
                                   contact, normal, vel,
-                                  type, loadCapacity, frictionFactor, agl);
+                                  type, material, agl);
   // Convert units back ...
   sgdScaleVec3( contact, SG_METER_TO_FEET );
   sgdScaleVec3( vel, SG_METER_TO_FEET );
   *agl *= SG_METER_TO_FEET;
-  // FIXME: scale the load limit to something in the english unit system.
-  // Be careful with the DBL_MAX which is returned by default.
   return ret;
 }
 
@@ -936,13 +955,13 @@ FGInterface::get_groundlevel_m(double lat, double lon, double alt)
     }
   }
   
-  double contact[3], normal[3], vel[3], lc, ff, agl;
+  double contact[3], normal[3], vel[3], agl;
   int type;
   // Ignore the return value here, since it just tells us if
   // the returns stem from the groundcache or from the coarse
   // computations below the groundcache. The contact point is still something
   // valid, the normals and the other returns just contain some defaults.
-  get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, &lc, &ff, &agl);
+  get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, 0, &agl);
   Point3D geodPos = sgCartToGeod(Point3D(contact[0], contact[1], contact[2]));
   return geodPos.elev();
 }
index f26824d15d6a58d42175a07d4a6d00e5620fe0a5..09d40bd323532761e2f9c61e6aa7f502af30b084 100644 (file)
@@ -1090,7 +1090,6 @@ public:
     enum GroundType {
       Unknown = 0, //??
       Solid, // Whatever we will roll on with infinite load factor.
-      Forest, // Ground unsuitable for taxiing.
       Water, // For the beaver ...
       Catapult, // Carrier cats.
       Wire // Carrier wires.
@@ -1133,14 +1132,17 @@ public:
                     double contact[3], double normal[3], double vel[3],
                     int *type, double *loadCapacity,
                     double *frictionFactor, double *agl);
+
+    // Return the altitude above ground below the wgs84 point pt
+    // Search for the nearest triangle to pt.
+    // Return ground properties like the ground type, a pointer to the
+    // material and finally the altitude above ground.
     bool get_agl_m(double t, const double pt[3], double max_altoff,
                    double contact[3], double normal[3], double vel[3],
-                   int *type, double *loadCapacity,
-                   double *frictionFactor, double *agl);
+                   int *type, const SGMaterial** material, double *agl);
     bool get_agl_ft(double t, const double pt[3], double max_altoff,
                     double contact[3], double normal[3], double vel[3],
-                    int *type, double *loadCapacity,
-                    double *frictionFactor, double *agl);
+                    int *type, const SGMaterial** material, double *agl);
     double get_groundlevel_m(double lat, double lon, double alt);
 
 
index ac0fa40acbe80919fe1f54126f4daf6d69cb985c..d4cfb80a9612a8b4a8de9b9b4b0f959dcea5ba70 100644 (file)
@@ -32,6 +32,8 @@
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/scene/material/mat.hxx>
+#include <simgear/scene/material/matlib.hxx>
 
 #include <Main/globals.hxx>
 #include <Scenery/scenery.hxx>
@@ -233,32 +235,15 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l )
   }
 
   else {
-
     // Initialize velocity field.
     sgdSetVec3( gp.vel, 0.0, 0.0, 0.0 );
     sgdSetVec3( gp.rot, 0.0, 0.0, 0.0 );
     sgdSetVec3( gp.pivot, 0.0, 0.0, 0.0 );
-  }
-  
-  // Get the texture name and decide what ground type we have.
-  ssgState *st = l->getState();
-  if (st != NULL && st->isAKindOf(ssgTypeSimpleState())) {
-    ssgSimpleState *ss = (ssgSimpleState*)st;
-    SGPath fullPath( ss->getTextureFilename() ? ss->getTextureFilename(): "" );
-    string file = fullPath.file();
-    SGPath dirPath(fullPath.dir());
-    string category = dirPath.file();
-    
-    if (category == "Runway")
-      gp.type = FGInterface::Solid;
-    else {
-      if (file == "asphault.rgb" || file == "airport.rgb")
-        gp.type = FGInterface::Solid;
-      else if (file == "water.rgb" || file == "water-lake.rgb")
-        gp.type = FGInterface::Water;
-      else if (file == "forest.rgb" || file == "cropwood.rgb")
-        gp.type = FGInterface::Forest;
-    }
+
+    // get some material information for use in the gear model
+    gp.material = globals->get_matlib()->findMaterial(l);
+    if (gp.material)
+      gp.type = gp.material->get_solid() ? FGInterface::Solid : FGInterface::Water;
   }
   
   return gp;
@@ -322,6 +307,7 @@ FGGroundCache::putSurfaceLeafIntoCache(const sgdSphere *sp,
   for (int i = 0; i < nt; ++i) {
     Triangle t;
     t.sphere.empty();
+    t.material = gp.material;
     short v[3];
     l->getTriangle(i, &v[0], &v[1], &v[2]);
     for (int k = 0; k < 3; ++k) {
@@ -395,6 +381,7 @@ FGGroundCache::velocityTransformTriangle(double dt,
   sgdCopyVec3(dst.rotation_pivot, src.rotation_pivot);
 
   dst.type = src.type;
+  dst.material = src.material;
 
   if (dt*sgdLengthSquaredVec3(src.velocity) != 0) {
     sgdVec3 pivotoff, vel;
@@ -621,15 +608,14 @@ FGGroundCache::get_cat(double t, const double dpt[3],
 bool
 FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
                        double contact[3], double normal[3], double vel[3],
-                       int *type, double *loadCapacity,
-                       double *frictionFactor, double *agl)
+                       int *type, const SGMaterial** material, double *agl)
 {
   bool ret = false;
 
   *type = FGInterface::Unknown;
 //   *agl = 0.0;
-  *loadCapacity = DBL_MAX;
-  *frictionFactor = 1.0;
+  if (material)
+    *material = 0;
   sgdSetVec3( vel, 0.0, 0.0, 0.0 );
   sgdSetVec3( contact, 0.0, 0.0, 0.0 );
   sgdSetVec3( normal, 0.0, 0.0, 0.0 );
@@ -683,11 +669,11 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
           sgdAddVec3(vel, triangle.velocity);
           // Save the ground type.
           *type = triangle.type;
-          // FIXME: figure out how to get that sign ...
-//           *agl = sqrt(sqdist);
-          *agl = sgdLengthVec3( dpt ) - sgdLengthVec3( contact );
-//           *loadCapacity = DBL_MAX;
-//           *frictionFactor = 1.0;
+          sgdVec3 dstToContact;
+          sgdSubVec3(dstToContact, contact, dpt);
+          *agl = sgdScalarProductVec3(dir, dstToContact);
+          if (material)
+            *material = triangle.material;
         }
       }
     }
@@ -708,10 +694,10 @@ FGGroundCache::get_agl(double t, const double dpt[3], double max_altoff,
   
   // The altitude is the distance of the requested point from the
   // contact point.
-  *agl = sgdLengthVec3( dpt ) - sgdLengthVec3( contact );
+  sgdVec3 dstToContact;
+  sgdSubVec3(dstToContact, contact, dpt);
+  *agl = sgdScalarProductVec3(dir, dstToContact);
   *type = FGInterface::Unknown;
-  *loadCapacity = DBL_MAX;
-  *frictionFactor = 1.0;
 
   return ret;
 }
index 0b90c0d8eeed1200ddc6fb7332c51fa00d1c3176..e91534a63f1ba532e7845e3e6392383fab6ee5dc 100644 (file)
@@ -28,6 +28,8 @@
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
 
+class SGMaterial;
+
 class FGGroundCache {
 public:
     FGGroundCache();
@@ -63,8 +65,7 @@ public:
     // and finally the altitude above ground.
     bool get_agl(double t, const double pt[3], double max_altoff,
                  double contact[3], double normal[3], double vel[3],
-                 int *type, double *loadCapacity,
-                 double *frictionFactor, double *agl);
+                 int *type, const SGMaterial** material, double *agl);
 
     // Return 1 if the hook intersects with a wire.
     // That test is done by checking if the quad spanned by the points pt*
@@ -82,6 +83,7 @@ public:
 
 private:
     struct Triangle {
+      Triangle() : material(0) {}
       // The edge vertices.
       sgdVec3 vertices[3];
       // The surface normal.
@@ -94,6 +96,8 @@ private:
       sgdVec3 rotation_pivot;
       // Ground type
       int type;
+      // the simgear material reference, contains friction coeficients ...
+      const SGMaterial* material;
     };
     struct Catapult {
       sgdVec3 start;
@@ -147,14 +151,13 @@ private:
 
     // Helper class to hold some properties of the ground triangle.
     struct GroundProperty {
-      GroundProperty() : type(0) {}
+      GroundProperty() : type(0), material(0) {}
       int type;
       int wire_id;
       sgdVec3 vel;
       sgdVec3 rot;
       sgdVec3 pivot;
-      // not yet implemented ...
-//       double loadCapacity;
+      const SGMaterial* material;
     };
 
     // compute the ground property of this leaf.
index b484917af4b6003f3ae067620277cdd39577d64a..f490eb06256d8b511cb5779272088a199a412529 100644 (file)
@@ -561,7 +561,7 @@ static void fgMainLoop( void ) {
       } else {
         // Do full intersection test.
         double lev;
-        if (globals->get_scenery()->get_elevation_m(lat, lon, alt+2, lev))
+        if (globals->get_scenery()->get_elevation_m(lat, lon, alt+2, lev, 0))
           view_location->set_cur_elev_m( lev );
         else
           view_location->set_cur_elev_m( -9999.0 );
index 264c6f9f8e98afd2493c19db5509c33fd5040820..afeb3bb1b68fa2b455755039552c29ef9f5ca672 100644 (file)
@@ -700,7 +700,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
 // returned results are in meters
 bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
                     sgdVec3 scenery_center,
-                    ssgTransform *terra_transform,
+                    ssgBranch *branch,
                     FGHitList *hit_list,
                     double *terrain_elev, double *radius, double *normal,
                    int & this_hit )
@@ -719,11 +719,11 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
 
     sgMat4 fxform;
     sgMakeIdentMat4 ( fxform ) ;
-    ssgGetEntityTransform( terra_transform, fxform );
+    ssgGetEntityTransform( branch, fxform );
 
     sgdMat4 xform;
     sgdSetMat4(xform,fxform);
-    hit_list->Intersect( terra_transform, xform, orig, dir );
+    hit_list->Intersect( branch, xform, orig, dir );
 
     this_hit = -1;
     int max_hit = -1;
index 0bb99c074044c64e1a07d2b17ac63bcfb1ab862f..cec41f967d72d7eb924a422c51d6384092725672 100644 (file)
@@ -89,7 +89,7 @@ public:
 bool fgCurrentElev( sgdVec3 abs_view_pos,
                     double max_alt_m,
                     sgdVec3 scenery_center,
-                    ssgTransform *terra_transform,
+                    ssgBranch *branch,
                     FGHitList *hit_list,
                     double *terrain_elev,
                     double *radius,
index 0bbe2163e63056badd1ce59aec182af29d98026a..39e21cd3766ef638ddc379ac5092c0467cad4ca3 100644 (file)
@@ -131,33 +131,19 @@ void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) {
 
 bool
 FGScenery::get_elevation_m(double lat, double lon, double max_alt,
-                           double& alt, bool exact)
+                           double& alt, const SGMaterial** material,
+                           bool exact)
 {
-//   std::cout << __PRETTY_FUNCTION__ << " "
-//             << lat << " "
-//             << lon << " "
-//             << max_alt
-//             << std::endl;
   sgdVec3 pos;
   sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS,
                max_alt, pos);
-  return get_cart_elevation_m(pos, 0, alt, exact);
-}
-
-bool
-FGScenery::get_material_m(double lat, double lon, double max_alt,
-                          double& alt, string & material, bool exact)
-{
-  sgdVec3 pos;
-  sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS,
-               max_alt, pos);
-
-  return get_cart_material_m(pos, 0, alt, material, exact);
+  return get_cart_elevation_m(pos, 0, alt, material, exact);
 }
 
 bool
 FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
-                                double& alt, bool exact)
+                                double& alt, const SGMaterial** material,
+                                bool exact)
 {
   Point3D saved_center = center;
   bool replaced_center = false;
@@ -188,78 +174,18 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
     // scenery center has been properly defined so any hit should
     // be valid (and not just luck)
     hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos),
-                        sc, (ssgTransform*)get_scene_graph(),
+                        sc, get_scene_graph(),
                         &hit_list, &alt, &hit_radius, hit_normal, this_hit);
-  }
 
-  if (replaced_center)
-    set_center( saved_center );
-  
-  return hit;
-}
-
-bool
-FGScenery::get_cart_material_m(const sgdVec3& pos, double max_altoff,
-                               double& alt, string& material, bool exact)
-{
-  Point3D saved_center = center;
-  bool replaced_center = false;
-  if (exact) {
-    Point3D ppos(pos[0], pos[1], pos[2]);
-    if (30.0*30.0 < ppos.distance3Dsquared(center)) {
-      set_center( ppos );
-      replaced_center = true;
-    }
-  }
-
-  material = "";
-
-  // overridden with actual values if a terrain intersection is
-  // found
-  int this_hit;
-  double hit_radius = 0.0;
-  sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
-  
-  bool hit = false;
-  if ( fabs(pos[0]) > 1.0 || fabs(pos[1]) > 1.0 || fabs(pos[2]) > 1.0 ) {
-    sgdVec3 sc;
-    sgdSetVec3(sc, center[0], center[1], center[2]);
-    
-    sgdVec3 ncpos;
-    sgdCopyVec3(ncpos, pos);
-    
-    FGHitList hit_list;
-    
-    // scenery center has been properly defined so any hit should
-    // be valid (and not just luck)
-    hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos),
-                        sc, (ssgTransform*)get_scene_graph(),
-                        &hit_list, &alt, &hit_radius, hit_normal,
-                       this_hit );
-
-    if( hit )
-    {
-       ssgEntity *entity = hit_list.get_entity( this_hit );
-
-       if( entity != NULL && entity->isAKindOf(ssgTypeLeaf()) )
-       {
-           ssgLeaf *leaf = (ssgLeaf*) hit_list.get_entity( this_hit );
-            ssgState *st = leaf->getState();
-
-           if( st != NULL && st->isAKindOf(ssgTypeSimpleState()) )
-           {
-               ssgSimpleState *ss = (ssgSimpleState *) st;
-
-               if( !globals->get_matlib()->find( ss, material ) )
-               {
-                   material = "not-in-matlib";
-               }
-           }
-       }
-    }
-    else
-    {
-       material = "no-hit";
+    if (material) {
+      *material = 0;
+      if (hit) {
+        ssgEntity *entity = hit_list.get_entity( this_hit );
+        if (entity && entity->isAKindOf(ssgTypeLeaf())) {
+          ssgLeaf* leaf = static_cast<ssgLeaf*>(entity);
+          *material = globals->get_matlib()->findMaterial(leaf);
+        }
+      }
     }
   }
 
@@ -269,7 +195,6 @@ FGScenery::get_cart_material_m(const sgdVec3& pos, double max_altoff,
   return hit;
 }
 
-
 bool
 FGScenery::get_cart_ground_intersection(const sgdVec3& pos,
                                         const sgdVec3& dir,
index 58690188fd559c25115c4f362cda0e98b6017bdd..84e12f8c35ff110bde80051ddbc2e7275a7af64d 100644 (file)
@@ -43,6 +43,7 @@ SG_USING_STD(list);
 
 class ssgRoot;
 class ssgBranch;
+class SGMaterial;
 
 
 // Define a structure containing global scenery parameters
@@ -93,9 +94,8 @@ public:
     /// value is undefined. 
     /// All values are meant to be in meters or degrees.
     bool get_elevation_m(double lat, double lon, double max_alt,
-                         double& alt, bool exact = false);
-    bool get_material_m(double lat, double lon, double max_alt,
-                        double& alt, string & material, bool exact = false);
+                         double& alt, const SGMaterial** material,
+                         bool exact = false);
 
     /// Compute the elevation of the scenery beow the cartesian point pos.
     /// you the returned scenery altitude is not higher than the position
@@ -109,9 +109,8 @@ public:
     /// value is undefined.
     /// All values are meant to be in meters.
     bool get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
-                              double& radius, bool exact = false);
-    bool get_cart_material_m(const sgdVec3& pos, double max_altoff,
-                             double& radius, string& material, bool exact = false);
+                              double& radius, const SGMaterial** material,
+                              bool exact = false);
 
     /// Compute the nearest intersection point of the line starting from 
     /// start going in direction dir with the terrain.