]> git.mxchange.org Git - flightgear.git/commitdiff
Shuffled around and restructured the terrain elevation interesection code
authorcurt <curt>
Wed, 11 Jul 2001 15:51:21 +0000 (15:51 +0000)
committercurt <curt>
Wed, 11 Jul 2001 15:51:21 +0000 (15:51 +0000)
to make it usable by the threaded tile loader for placing objects at ground
level at load time.

src/Scenery/hitlist.cxx
src/Scenery/hitlist.hxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

index 027b4b15b19c86d9a3a1db107243339f45f9ff34..b5abb780541af2209a2d75901e497a741520844b 100644 (file)
 
 #include <simgear/constants.h>
 #include <simgear/sg_inlines.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/math/point3d.hxx>
+#include <simgear/math/sg_geodesy.hxx>
 #include <simgear/math/vector.hxx>
 
+#include <Main/globals.hxx>
+
 #include "hitlist.hxx"
 
 
+extern ssgBranch *terrain;
+
+
 // check to see if the intersection point is
 // actually inside this face
 static bool sgdPointInTriangle( sgdVec3 point, sgdVec3 tri[3] )
@@ -304,3 +312,78 @@ void FGHitList::IntersectCachedLeaf( sgdMat4 m,
        }
     }
 }
+
+
+static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) {
+    sgVec3 tmp;
+    sgSetVec3(tmp, src[0], src[1], src[2] );
+    sgMat4 TMP;
+    sgTransposeNegateMat4 ( TMP, globals->get_current_view()->get_UP() ) ;
+    sgXformVec3(tmp, tmp, TMP);
+    sgSetVec3(dst, tmp[2], tmp[1], tmp[0] );
+}
+
+
+// a temporary hack until we get everything rewritten with sgdVec3
+static inline Point3D operator + (const Point3D& a, const sgdVec3 b)
+{
+    return Point3D(a.x()+b[0], a.y()+b[1], a.z()+b[2]);
+}
+
+
+// Determine scenery altitude via ssg.  Normally this just happens
+// when we render the scene, but we'd also like to be able to do this
+// explicitely.  lat & lon are in radians.  view_pos in current world
+// coordinate translated near (0,0,0) (in meters.)  Returns result in
+// meters.
+bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
+                   FGHitList *hit_list,
+                   double *terrain_elev, double *radius, double *normal)
+{
+    sgdVec3 view_pos;
+    sgdSubVec3( view_pos, abs_view_pos, scenery_center );
+
+    sgdVec3 orig, dir;
+    sgdCopyVec3(orig, view_pos );
+    sgdCopyVec3(dir, abs_view_pos );
+
+    hit_list->Intersect( terrain, orig, dir );
+
+    int this_hit=0;
+    Point3D geoc;
+    double result = -9999;
+    Point3D sc(scenery_center[0], scenery_center[1], scenery_center[2]) ;
+    
+    int hitcount = hit_list->num_hits();
+    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);
+       if ( alt > result && alt < 10000 ) {
+           result = alt;
+           this_hit = i;
+       }
+    }
+
+    if ( result > -9000 ) {
+       *terrain_elev = result;
+       *radius = geoc.radius();
+       sgVec3 tmp;
+       sgSetVec3(tmp, hit_list->get_normal(this_hit));
+       // cout << "cur_normal: " << tmp[0] << " " << tmp[1] << " "
+       //      << tmp[2] << endl;
+       /* ssgState *IntersectedLeafState =
+           ((ssgLeaf*)hit_list->get_entity(this_hit))->getState(); */
+       CurrentNormalInLocalPlane(tmp, tmp);
+       sgdSetVec3( normal, tmp );
+       // cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl;
+       return true;
+    } else {
+       SG_LOG( SG_TERRAIN, SG_INFO, "no terrain intersection" );
+       *terrain_elev = 0.0;
+       float *up = globals->get_current_view()->get_world_up();
+       sgdSetVec3(normal, up[0], up[1], up[2]);
+       return false;
+    }
+}
index 0fa5d74651a2074f91f80c56770a8c0e90bdac2d..709b23a205fb106b12b8d05f12aa986781561647 100644 (file)
@@ -93,4 +93,13 @@ inline void FGHitList::Intersect( ssgBranch *scene,
     }
 }
 
+
+// Associated function, assuming a wgs84 world with 0,0,0 at the
+// center, find the current terrain intersection elevation for the
+// point specified.
+bool fgCurrentElev( sgdVec3 abs_view_pos, sgdVec3 scenery_center,
+                   FGHitList *hit_list,
+                   double *terrain_elev, double *radius, double *normal );
+
+
 #endif // _HITLIST_HXX
index 3993368498619fce2f754b741a818585f13f7215..d162a00e42c35211700f796f277bd6c2bc5f251c 100644 (file)
@@ -63,12 +63,6 @@ extern ssgBranch *ground;
 FGTileMgr global_tile_mgr;
 
 
-// a temporary hack until we get everything rewritten with sgdVec3
-static inline Point3D operator + (const Point3D& a, const sgdVec3 b)
-{
-    return Point3D(a.x()+b[0], a.y()+b[1], a.z()+b[2]);
-}
-
 #ifdef ENABLE_THREADS
 SGLockedQueue<FGTileEntry *> FGTileMgr::attach_queue;
 SGLockedQueue<FGDeferredModel *> FGTileMgr::model_queue;
@@ -153,72 +147,6 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
 }
 
 
-static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) {
-    sgVec3 tmp;
-    sgSetVec3(tmp, src[0], src[1], src[2] );
-    sgMat4 TMP;
-    sgTransposeNegateMat4 ( TMP, globals->get_current_view()->get_UP() ) ;
-    sgXformVec3(tmp, tmp, TMP);
-    sgSetVec3(dst, tmp[2], tmp[1], tmp[0] );
-}
-
-
-// Determine scenery altitude via ssg.  Normally this just happens
-// when we render the scene, but we'd also like to be able to do this
-// explicitely.  lat & lon are in radians.  view_pos in current world
-// coordinate translated near (0,0,0) (in meters.)  Returns result in
-// meters.
-bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev ) {
-    sgdVec3 view_pos;
-    sgdVec3 sc;
-    sgdSetVec3( sc, scenery.center.x(), scenery.center.y(), scenery.center.z());
-    sgdSubVec3( view_pos, abs_view_pos, sc );
-
-    sgdVec3 orig, dir;
-    sgdCopyVec3(orig, view_pos );
-    sgdCopyVec3(dir, abs_view_pos );
-
-    hit_list.Intersect( terrain, orig, dir );
-
-    int this_hit=0;
-    Point3D geoc;
-    double result = -9999;
-
-    int hitcount = hit_list.num_hits();
-    for ( int i = 0; i < hitcount; ++i ) {
-       geoc = sgCartToPolar3d( scenery.center + hit_list.get_point(i) );      
-       double lat_geod, alt, sea_level_r;
-       sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod, 
-                    &alt, &sea_level_r);
-       if ( alt > result && alt < 10000 ) {
-           result = alt;
-           this_hit = i;
-       }
-    }
-
-    if ( result > -9000 ) {
-       *terrain_elev = result;
-       scenery.cur_radius = geoc.radius();
-       sgVec3 tmp;
-       sgSetVec3(tmp, hit_list.get_normal(this_hit));
-       // cout << "cur_normal: " << tmp[0] << " " << tmp[1] << " "
-       //      << tmp[2] << endl;
-       /* ssgState *IntersectedLeafState =
-           ((ssgLeaf*)hit_list.get_entity(this_hit))->getState(); */
-       CurrentNormalInLocalPlane(tmp, tmp);
-       sgdSetVec3( scenery.cur_normal, tmp );
-       // cout << "NED: " << tmp[0] << " " << tmp[1] << " " << tmp[2] << endl;
-       return true;
-    } else {
-       SG_LOG( SG_TERRAIN, SG_INFO, "no terrain intersection" );
-       *terrain_elev = 0.0;
-       float *up = globals->get_current_view()->get_world_up();
-       sgdSetVec3(scenery.cur_normal, up[0], up[1], up[2]);
-       return false;
-    }
-}
-
-
 // schedule a needed buckets for loading
 void FGTileMgr::schedule_needed() {
 #ifndef FG_OLD_WEATHER
@@ -401,6 +329,8 @@ int FGTileMgr::update( double lon, double lat ) {
        }
     }
     counter_hack = (counter_hack + 1) % 5;
+    sgdVec3 sc;
+    sgdSetVec3( sc, scenery.center[0], scenery.center[1], scenery.center[2] );
 
     if ( scenery.center == Point3D(0.0) ) {
        // initializing
@@ -419,7 +349,9 @@ int FGTileMgr::update( double lon, double lat ) {
        prep_ssg_nodes();
        sgSetVec3( tmp_view_pos, 0.0, 0.0, 0.0 );
        double tmp_elev;
-       if ( current_elev_ssg(tmp_abs_view_pos, &tmp_elev) ) {
+       if ( fgCurrentElev(tmp_abs_view_pos, sc, &hit_list,
+                          &tmp_elev, &scenery.cur_radius, scenery.cur_normal) )
+       {
            scenery.cur_elev = tmp_elev;
        } else {
            scenery.cur_elev = 0.0;
@@ -429,8 +361,9 @@ int FGTileMgr::update( double lon, double lat ) {
        // cout << "abs view pos = " << current_view.abs_view_pos
        //      << " view pos = " << current_view.view_pos << endl;
        double tmp_elev;
-       if ( current_elev_ssg(globals->get_current_view()->get_abs_view_pos(),
-                             &tmp_elev) )
+       if ( fgCurrentElev(globals->get_current_view()->get_abs_view_pos(),
+                          sc, &hit_list,
+                          &tmp_elev, &scenery.cur_radius, scenery.cur_normal) )
        {
            scenery.cur_elev = tmp_elev;
        } else {
index a6cfeb5b719280d9c34dff17abdd4b74b4bdde5e..fe9c6fd2f0a66d747931fc016106a0ba034983b2 100644 (file)
@@ -81,10 +81,6 @@ private:
     // see comment at prep_ssg_nodes()
     void prep_ssg_node( int idx );
        
-    // int hitcount;
-    // sgdVec3 hit_pts [ MAX_HITS ] ;
-
-    // ssgEntity *last_hit;
     FGHitList hit_list;
 
     SGBucket previous_bucket;
@@ -177,7 +173,6 @@ public:
                     const sgdVec3 p, const sgdVec3 dir,
                     FGHitList *list );
 
-    bool current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev );
        
     // Prepare the ssg nodes ... for each tile, set it's proper
     // transform and update it's range selector based on current