]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/hitlist.cxx
Make sure pu.h doesn't include glut by accident.
[flightgear.git] / src / Scenery / hitlist.cxx
index 266eb52c70644fca97e7c4087663079bf0230992..6d0182269f4628290376fc95d56f84807004c6b8 100644 (file)
@@ -17,6 +17,7 @@
 #include <simgear/math/point3d.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/math/vector.hxx>
+#include <simgear/timing/timestamp.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/viewer.hxx>
@@ -506,14 +507,14 @@ void FGHitList::Intersect( ssgBranch *scene, sgdMat4 m, sgdVec3 orig, sgdVec3 di
 
 // Determine scenery altitude via ssg.
 // returned results are in meters
-static double hitlist1_time = 0.0;
+// static double hitlist1_time = 0.0;
 
 bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
                     sgdVec3 scenery_center,
                     FGHitList *hit_list,
                     double *terrain_elev, double *radius, double *normal)
 {
-    SGTimeStamp start; start.stamp();
+    // SGTimeStamp start; start.stamp();
 
     bool result;
     sgdVec3 view_pos;
@@ -526,18 +527,21 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
     hit_list->Intersect( globals->get_scenery()->get_terrain_branch(),
                          orig, dir );
 
-    int this_hit=0;
+    int this_hit = -1;
+    int max_hit = -1;
     Point3D geoc;
     double hit_elev = -9999;
+    double max_elev = -9999;
     Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ;
 
     int hitcount = hit_list->num_hits();
     // cout << "hits = " << hitcount << endl;
     for ( int i = 0; i < hitcount; ++i ) {
-        geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
-        double lat_geod, alt, sea_level_r;
-        sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
-                     &alt, &sea_level_r);
+        // FIXME: sgCartToGeod is slow.  Call it just once for the
+        // "sc" point, and then handle the rest with a geodetic "up"
+        // vector approximation.  Across one tile, this will be
+        // acceptable.
+        double alt = sgCartToGeod( sc + hit_list->get_point(i) ).elev();
         // cout << "hit " << i << " lon = " << geoc.lon() << " lat = "
         //      << lat_geod << " alt = " << alt << "  max alt = " << max_alt_m
         //      << endl;
@@ -546,6 +550,16 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
             hit_elev = alt;
             this_hit = i;
         }
+        if ( alt > hit_elev ) {
+            max_elev = alt;
+            max_hit = i;
+        }
+    }
+
+    if ( this_hit < 0 ) {
+        // no hits below us, take the max hit 
+        this_hit = max_hit;
+        hit_elev = max_elev;
     }
 
     if ( hit_elev > -9000 ) {
@@ -568,15 +582,15 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
         result = false;
     }
 
-    SGTimeStamp finish; finish.stamp();
-    hitlist1_time = ( 29.0 * hitlist1_time + (finish - start) ) / 30.0;
+    // SGTimeStamp finish; finish.stamp();
+    // hitlist1_time = ( 29.0 * hitlist1_time + (finish - start) ) / 30.0;
     // cout << " time per call = " << hitlist1_time << endl;
 
     return result;
 }
 
 
-static double hitlist2_time = 0.0;
+// static double hitlist2_time = 0.0;
 
 // Determine scenery altitude via ssg.
 // returned results are in meters
@@ -586,7 +600,7 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
                     FGHitList *hit_list,
                     double *terrain_elev, double *radius, double *normal)
 {
-    SGTimeStamp start; start.stamp();
+    // SGTimeStamp start; start.stamp();
 
     bool result;
     sgdVec3 view_pos;
@@ -606,18 +620,21 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
     sgdSetMat4(xform,fxform);
     hit_list->Intersect( terra_transform, xform, orig, dir );
 
-    int this_hit=0;
+    int this_hit = -1;
+    int max_hit = -1;
     Point3D geoc;
     double hit_elev = -9999;
+    double max_elev = -9999;
     Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ;
 
     int hitcount = hit_list->num_hits();
     // cout << "hits = " << hitcount << endl;
     for ( int i = 0; i < hitcount; ++i ) {
-        geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
-        double lat_geod, alt, sea_level_r;
-        sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
-                     &alt, &sea_level_r);
+        // FIXME: sgCartToGeod is slow.  Call it just once for the
+        // "sc" point, and then handle the rest with a geodetic "up"
+        // vector approximation.  Across one tile, this will be
+        // acceptable.
+        double alt = sgCartToGeod( sc + hit_list->get_point(i) ).elev();
         // cout << "hit " << i << " lon = " << geoc.lon() << " lat = "
         //      << lat_geod << " alt = " << alt << "  max alt = " << max_alt_m
         //      << endl;
@@ -626,6 +643,16 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
             this_hit = i;
             // cout << "  it's a keeper" << endl;
         }
+        if ( alt > hit_elev ) {
+            max_elev = alt;
+            max_hit = i;
+        }
+    }
+
+    if ( this_hit < 0 ) {
+        // no hits below us, take the max hit 
+        this_hit = max_hit;
+        hit_elev = max_elev;
     }
 
     if ( hit_elev > -9000 ) {
@@ -646,9 +673,9 @@ bool fgCurrentElev( sgdVec3 abs_view_pos, double max_alt_m,
                                 hit_list, terrain_elev, radius, normal);
     }
 
-    SGTimeStamp finish; finish.stamp();
-    hitlist2_time = ( 29.0 * hitlist2_time + (finish - start) ) / 30.0;
-    cout << "time per call 2 = " << hitlist2_time << endl;
+    // SGTimeStamp finish; finish.stamp();
+    // hitlist2_time = ( 29.0 * hitlist2_time + (finish - start) ) / 30.0;
+    // cout << "time per call 2 = " << hitlist2_time << endl;
 
     return result;
 }