]> git.mxchange.org Git - flightgear.git/commitdiff
Make use of the ground material types
authorfrohlich <frohlich>
Thu, 8 Jun 2006 05:58:36 +0000 (05:58 +0000)
committerfrohlich <frohlich>
Thu, 8 Jun 2006 05:58:36 +0000 (05:58 +0000)
src/Scenery/hitlist.cxx
src/Scenery/hitlist.hxx
src/Scenery/scenery.cxx
src/Scenery/scenery.hxx

index 3a7a461590f30abe96e26ec5a7cab7a175557f87..264c6f9f8e98afd2493c19db5509c33fd5040820 100644 (file)
@@ -702,7 +702,8 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
                     sgdVec3 scenery_center,
                     ssgTransform *terra_transform,
                     FGHitList *hit_list,
-                    double *terrain_elev, double *radius, double *normal)
+                    double *terrain_elev, double *radius, double *normal,
+                   int & this_hit )
 {
     // SGTimeStamp start; start.stamp();
 
@@ -724,7 +725,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
     sgdSetMat4(xform,fxform);
     hit_list->Intersect( terra_transform, xform, orig, dir );
 
-    int this_hit = -1;
+    this_hit = -1;
     int max_hit = -1;
     double hit_elev = -9999;
     double max_elev = -9999;
index e1faaac3ddae629e89fac2b03317788d5771005a..0bb99c074044c64e1a07d2b17ac63bcfb1ab862f 100644 (file)
@@ -93,7 +93,8 @@ bool fgCurrentElev( sgdVec3 abs_view_pos,
                     FGHitList *hit_list,
                     double *terrain_elev,
                     double *radius,
-                    double *normal );
+                    double *normal,
+                   int & this_hit );
 
 bool fgCurrentElev( sgdVec3 abs_view_pos,
                     double max_alt_m,
index 4c82beae27ff12f5d9ae9a5bbc997826e6865b0d..0bbe2163e63056badd1ce59aec182af29d98026a 100644 (file)
@@ -32,6 +32,7 @@
 #include <simgear/scene/tgdb/userdata.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/scene/model/placementtrans.hxx>
+#include <simgear/scene/material/matlib.hxx>
 
 #include <Main/fg_props.hxx>
 
@@ -143,6 +144,17 @@ FGScenery::get_elevation_m(double lat, double lon, double max_alt,
   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);
+}
+
 bool
 FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
                                 double& alt, bool exact)
@@ -159,6 +171,52 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
 
   // 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 (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 };
   
@@ -176,7 +234,33 @@ FGScenery::get_cart_elevation_m(const sgdVec3& pos, double max_altoff,
     // 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);
+                        &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 (replaced_center)
index b24f63a35120952c796ec2249591335cc8c88b92..58690188fd559c25115c4f362cda0e98b6017bdd 100644 (file)
@@ -94,6 +94,8 @@ public:
     /// 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);
 
     /// Compute the elevation of the scenery beow the cartesian point pos.
     /// you the returned scenery altitude is not higher than the position
@@ -108,6 +110,8 @@ public:
     /// 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);
 
     /// Compute the nearest intersection point of the line starting from 
     /// start going in direction dir with the terrain.