]> git.mxchange.org Git - flightgear.git/commitdiff
Jim Wilson:
authorcurt <curt>
Mon, 20 May 2002 16:13:37 +0000 (16:13 +0000)
committercurt <curt>
Mon, 20 May 2002 16:13:37 +0000 (16:13 +0000)
This is a small fix for what turned out to be a major bug.  Ground elevation
was calculated incorrectly when distant from one of the view locations. This
resulted in several problems including bizarre gear trimming, mid air
"crashes" (as in thinking we hit the ground) and so on when close to or on the
ground.

Unfortunately it does require a second ssg traversal when in tower view
(only), but the increased load isn't all that noticable.  For the time being
this really is the best solution.  In a future update I will be eliminating
the unecessary per frame traversals for the static views (without having to
maintain multiple ssgRoots).

When we go to multiple FDM instances we will perhaps need to put the ssg
traversal and ground elevation queries for the FDMs into an event timer that
updates the FDMs ground elevation in a round robin fashion (maybe every 1/n
seconds where n is the number of FDM instances running).

src/Main/fg_commands.cxx
src/Main/location.cxx
src/Main/location.hxx
src/Main/main.cxx
src/Main/viewer.cxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

index b0f216ecab233f9574d65fb161293dd1528e486f..e86f7f849873674e86313d0dfc9699eecf3c8c24 100644 (file)
@@ -275,6 +275,7 @@ do_view_cycle (const SGPropertyNode * arg, SGCommandState ** state)
           globals->get_props()->setBoolValue( "/sim/hud/visibility", false );
       }
   }
+  global_tile_mgr.refresh_view_timestamps();
 //   fgReshape(fgGetInt("/sim/startup/xsize"), fgGetInt("/sim/startup/ysize"));
   return true;
 }
@@ -666,5 +667,4 @@ fgInitCommands ()
   }
 }
 
-// end of fg_commands.hxx
-
+// end of fg_commands.cxx
index 84f421822ee3080885baecdbad10da5f2fb48bd4..fcca883f7f51103626d3a8be68b9164f904318d9 100644 (file)
@@ -36,6 +36,7 @@
 #include <simgear/math/vector.hxx>
 
 #include <Scenery/scenery.hxx>
+
 #include "globals.hxx"
 
 #include "location.hxx"
@@ -112,7 +113,9 @@ FGLocation::FGLocation( void ):
     _alt_ft(0),
     _roll_deg(0),
     _pitch_deg(0),
-    _heading_deg(0)
+    _heading_deg(0),
+    _cur_elev_m(0),
+    _tile_center(0)
 {
     sgdZeroVec3(_absolute_view_pos);
 }
@@ -241,7 +244,7 @@ FGLocation::recalcPosition (double lon_deg, double lat_deg, double alt_ft) const
   Point3D p = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
                      lat_geoc_rad,
                      sea_level_radius_m);
-  Point3D tmp = sgPolarToCart3d(p) - globals->get_scenery()->get_next_center();
+  Point3D tmp = sgPolarToCart3d(p) - _tile_center;
   sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]);
 
                                // Calculate the absolute view position
@@ -254,11 +257,15 @@ FGLocation::recalcPosition (double lon_deg, double lat_deg, double alt_ft) const
                                // Calculate the relative view position
                                // from the scenery center.
                                 // aka Relative View Position
+
+  // FIXME: view position should ONLY be calculated in the viewer...
+  // Anything else should calculate their own positions relative to the 
+  // viewer's tile_center.
   sgdVec3 scenery_center;
   sgdSetVec3(scenery_center,
-            globals->get_scenery()->get_next_center().x(),
-            globals->get_scenery()->get_next_center().y(),
-            globals->get_scenery()->get_next_center().z());
+        globals->get_scenery()->get_center().x(),
+        globals->get_scenery()->get_center().y(),
+        globals->get_scenery()->get_center().z());
   sgdVec3 view_pos;
   sgdSubVec3(view_pos, _absolute_view_pos, scenery_center);
   sgSetVec3(_relative_view_pos, view_pos);
index ad7647a273b2159925b083e797df5b7e9ef3802e..b3aad326ea1462b4b1f0a9e5c34bfc18f151edea 100644 (file)
@@ -32,6 +32,7 @@
 #include <simgear/compiler.h>
 #include <simgear/constants.h>
 #include <simgear/bucket/newbucket.hxx>
+#include <simgear/math/point3d.hxx>
 
 #include <plib/sg.h>           // plib include
 
@@ -115,6 +116,8 @@ public:
     inline SGBucket get_current_bucket () { return _current_bucket; }
     void set_previous_bucket ( SGBucket previous_bucket ) { _previous_bucket = previous_bucket; }
     inline SGBucket get_previous_bucket () { return _previous_bucket; }
+    void set_tile_center ( Point3D tile_center ) { _tile_center = tile_center; }
+    inline Point3D get_tile_center () { return _tile_center; }
 
     // Matrices...
     virtual const sgVec4 * getTransformMatrix() { if ( _dirty ) { recalc(); }  return TRANS; }
@@ -150,6 +153,7 @@ private:
     // getting current elevation from tilemgr.
     SGBucket _previous_bucket;
     SGBucket _current_bucket;
+    Point3D _tile_center;
 
     // surface vector heading south
     sgVec3 _surface_south;
index 5877923a6a8b38f624c7624e5ba43af02ec440dd..59cd3bac8b06c479b4a89c6aa1ef53b022335007 100644 (file)
@@ -625,7 +625,9 @@ void fgRenderFrame() {
 # endif
 
        // position tile nodes and update range selectors
-       global_tile_mgr.prep_ssg_nodes(visibility_meters);
+
+        // this is done in the main loop now...
+        // global_tile_mgr.prep_ssg_nodes(visibility_meters);
 
        if ( fgGetBool("/sim/rendering/skyblend") ) {
            // draw the sky backdrop
@@ -1064,10 +1066,6 @@ static void fgMainLoop( void ) {
     }
 #endif
 
-    // redraw display
-    fgRenderFrame();
-
-
     //
     // Tile Manager updates - see if we need to load any new scenery tiles.
     //   this code ties together the fdm, viewer and scenery classes...
@@ -1080,12 +1078,16 @@ static void fgMainLoop( void ) {
     // ...only if location is different than the viewer (to avoid duplicating effort)
     if( acmodel_location != current_view->getFGLocation() ) {
       if( acmodel_location != 0 ) {
+        global_tile_mgr.prep_ssg_nodes(visibility_meters,
+               acmodel_location->get_world_up(),
+               acmodel_location->get_tile_center());
         global_tile_mgr.update( acmodel_location->getLongitude_deg(),
                            acmodel_location->getLatitude_deg(),
                             visibility_meters,
                             acmodel_location->get_absolute_view_pos(),
                             acmodel_location->get_current_bucket(),
-                            acmodel_location->get_previous_bucket()
+                            acmodel_location->get_previous_bucket(),
+                            acmodel_location->get_tile_center()
                             );
         // save results of update in FGLocation for fdm...
         if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
@@ -1093,9 +1095,13 @@ static void fgMainLoop( void ) {
         }
         acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
         acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+        acmodel_location->set_tile_center( globals->get_scenery()->get_next_center() );
       }
     }
 
+    global_tile_mgr.prep_ssg_nodes(visibility_meters,
+       current_view->getFGLocation()->get_world_up(),
+       current_view->getFGLocation()->get_tile_center());
     // update tile manager for view...
     // IMPORTANT!!! the tilemgr update for view location _must_ be done last 
     // after the FDM's until all of Flight Gear code references the viewer's location
@@ -1105,7 +1111,8 @@ static void fgMainLoop( void ) {
                             visibility_meters,
                             current_view->get_absolute_view_pos(),
                             current_view->getFGLocation()->get_current_bucket(),
-                            current_view->getFGLocation()->get_previous_bucket()
+                            current_view->getFGLocation()->get_previous_bucket(),
+                            current_view->getFGLocation()->get_tile_center()
                             );
     // save results of update in FGLocation for fdm...
     if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
@@ -1113,6 +1120,7 @@ static void fgMainLoop( void ) {
     }
     current_view->getFGLocation()->set_current_bucket( global_tile_mgr.get_current_bucket() );
     current_view->getFGLocation()->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+    current_view->getFGLocation()->set_tile_center( globals->get_scenery()->get_next_center() );
 
     // If fdm location is same as viewer's then we didn't do the update for fdm location 
     //   above so we need to save the viewer results in the fdm FGLocation as well...
@@ -1123,11 +1131,14 @@ static void fgMainLoop( void ) {
         }
         acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
         acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
+        acmodel_location->set_tile_center( globals->get_scenery()->get_next_center() );
       }
     }
 
     // END Tile Manager udpates
 
+    // redraw display
+    fgRenderFrame();
 
     SG_LOG( SG_ALL, SG_DEBUG, "" );
 }
index 1f6194826ca57d554b9b60224054350c4a0cc81d..4b77efb8cbd4c28a09797d020a140903d3c08ad7 100644 (file)
@@ -561,8 +561,11 @@ FGViewer::recalcLookAt ()
     recalcOurOwnLocation( _target_location, _target_lon_deg, _target_lat_deg, _target_alt_ft, 
           _target_roll_deg, _target_pitch_deg, _target_heading_deg );
   }
-  // save the "at" target object positon...
-  sgCopyVec3(at_pos,  _target_location->get_view_pos());
+  // calculate the "at" target object positon relative to eye or view's tile center...
+  sgdVec3 dVec3;
+  sgdSetVec3(dVec3,  _location->get_tile_center()[0], _location->get_tile_center()[1], _location->get_tile_center()[2]);
+  sgdSubVec3(dVec3, _target_location->get_absolute_view_pos(), dVec3 );
+  sgSetVec3(at_pos, dVec3[0], dVec3[1], dVec3[2]);
 
   // Update location data for eye...
   if ( _from_model ) {
index a9d7f78655748c8c6a0cd62cf8954005aca95c4f..53d2d6d4eb59e1a210e66305530fc786e1f5baec 100644 (file)
@@ -251,10 +251,14 @@ void FGTileMgr::initialize_queue()
 int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
        sgdVec3 abs_pos_vector;
         sgdCopyVec3(abs_pos_vector , globals->get_current_view()->get_absolute_view_pos());
-        return update( lon, lat, visibility_meters, abs_pos_vector, current_bucket, previous_bucket );
+        return update( lon, lat, visibility_meters, abs_pos_vector,
+                       current_bucket, previous_bucket,
+                       globals->get_scenery()->get_center() );
 }
 
-int FGTileMgr::update( double lon, double lat, double visibility_meters, sgdVec3 abs_pos_vector, SGBucket p_current, SGBucket p_previous ) {
+int FGTileMgr::update( double lon, double lat, double visibility_meters,
+                       sgdVec3 abs_pos_vector, SGBucket p_current,
+                       SGBucket p_previous, Point3D center ) {
     // SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update() for "
     //         << lon << " " << lat );
 
@@ -342,14 +346,14 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters, sgdVec3
     }
 
     // no reason to update this if we haven't moved...
-    if ( longitude != last_longitude || latitude == last_latitude ) {
+    if ( longitude != last_longitude || latitude != last_latitude ) {
       // update current elevation... 
-      updateCurrentElevAtPos(abs_pos_vector);
+      if (updateCurrentElevAtPos(abs_pos_vector, center)) {
+        last_longitude = longitude;
+        last_latitude = latitude;
+      }
     }
 
-    last_longitude = longitude;
-    last_latitude = latitude;
-
 #if 0
     }
 #endif
@@ -378,28 +382,25 @@ void FGTileMgr::setCurrentTile(double longitude, double latitude) {
     }
 }
 
-void FGTileMgr::updateCurrentElevAtPos(sgdVec3 abs_pos_vector) {
+int FGTileMgr::updateCurrentElevAtPos(sgdVec3 abs_pos_vector, Point3D center) {
 
   sgdVec3 sc;
+
   sgdSetVec3( sc,
-    globals->get_scenery()->get_center()[0],
-    globals->get_scenery()->get_center()[1],
-    globals->get_scenery()->get_center()[2] );
+    center[0],
+    center[1],
+    center[2]);
 
     // overridden with actual values if a terrain intersection is
     // found
     double hit_elev = -9999.0;
     double hit_radius = 0.0;
     sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
-
+    
     bool hit = false;
     if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) {
        // scenery center has been properly defined so any hit
        // should be valid (and not just luck)
-       sgdSetVec3( sc,
-         globals->get_scenery()->get_center()[0],
-         globals->get_scenery()->get_center()[1],
-         globals->get_scenery()->get_center()[2] );
        hit = fgCurrentElev(abs_pos_vector,
          sc,
          current_tile->get_terra_transform(),
@@ -418,13 +419,26 @@ void FGTileMgr::updateCurrentElevAtPos(sgdVec3 abs_pos_vector) {
           globals->get_scenery()->set_cur_radius( 0.0 );
           globals->get_scenery()->set_cur_normal( hit_normal );
     }
-
+    return hit;
 }
 
 void FGTileMgr::prep_ssg_nodes(float vis) {
-//    float vis = 0.0;
 
-//    vis = fgGetDouble("/environment/visibility-m");
+    // traverse the potentially viewable tile list and update range
+    // selector and transform
+
+    // just setup and call new function...
+
+    sgVec3 up;
+    sgCopyVec3( up, globals->get_current_view()->get_world_up() );
+
+    Point3D center;
+    center = globals->get_scenery()->get_center();
+    prep_ssg_nodes( vis, up, center );
+
+}
+
+void FGTileMgr::prep_ssg_nodes(float vis, sgVec3 up, Point3D center) {
 
     // traverse the potentially viewable tile list and update range
     // selector and transform
@@ -432,13 +446,10 @@ void FGTileMgr::prep_ssg_nodes(float vis) {
     FGTileEntry *e;
     tile_cache.reset_traversal();
 
-    sgVec3 up;
-    sgCopyVec3( up, globals->get_current_view()->get_world_up() );
-       
     while ( ! tile_cache.at_end() ) {
         // cout << "processing a tile" << endl;
        if ( (e = tile_cache.get_current()) ) {
-           e->prep_ssg_node( globals->get_scenery()->get_center(), up, vis);
+           e->prep_ssg_node( center, up, vis);
         } else {
            SG_LOG(SG_INPUT, SG_ALERT, "warning ... empty tile in cache");
         }
index 41a69669ec48283218bd8f8464943e872fd7c0b1..9eebc5dcb5af0c9166d9685320b455e0cfe40e85 100644 (file)
@@ -30,6 +30,7 @@
 #endif                                   
 
 #include <simgear/compiler.h>
+#include <simgear/math/point3d.hxx>
 
 #include <queue>
 
@@ -163,9 +164,9 @@ public:
     // local chunks.  If the chunk isn't already in the cache, then
     // read it from disk.
     int update( double lon, double lat, double visibility_meters );
-    int update( double lon, double lat, double visibility_meters, sgdVec3 abs_pos_vector, SGBucket p_current, SGBucket p_previous );
+    int update( double lon, double lat, double visibility_meters, sgdVec3 abs_pos_vector, SGBucket p_current, SGBucket p_previous, Point3D center );
     void setCurrentTile( double longitude, double latitude );
-    void updateCurrentElevAtPos(sgdVec3 abs_pos_vector);
+    int updateCurrentElevAtPos(sgdVec3 abs_pos_vector, Point3D center );
 
     // Determine scenery altitude.  Normally this just happens when we
     // render the scene, but we'd also like to be able to do this
@@ -182,6 +183,7 @@ public:
     // transform and update it's range selector based on current
     // visibilty
     void prep_ssg_nodes(float visibility_meters);
+    void prep_ssg_nodes(float visibility_meters, sgVec3 up, Point3D center);
 
     //
     // Set flag with event manager so that non-moving view refreshes tiles...