diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index ce3968b90..8a618ab2d 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -69,6 +69,9 @@ FGAIBase::FGAIBase() } FGAIBase::~FGAIBase() { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(aip.getTransform()); + globals->get_scenery()->get_scene_graph()->removeKid(aip.getSceneGraph()); // unbind(); SGPropertyNode *root = globals->get_props()->getNode("ai/models", true); @@ -146,6 +149,8 @@ bool FGAIBase::init() { aip.setVisible(true); invisible = false; globals->get_scenery()->get_scene_graph()->addKid(aip.getSceneGraph()); + // Register that one at the scenery manager + globals->get_scenery()->register_placement_transform(aip.getTransform()); } else { if (model_path != "") { SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model."); diff --git a/src/ATC/AIEntity.cxx b/src/ATC/AIEntity.cxx index 9dccebea0..79d10a6a2 100644 --- a/src/ATC/AIEntity.cxx +++ b/src/ATC/AIEntity.cxx @@ -48,6 +48,9 @@ FGAIEntity::~FGAIEntity() { _model->deRef(); // Ought to check valid? //cout << "Removing model from scene graph..." << endl; globals->get_scenery()->get_scene_graph()->removeKid(_aip.getSceneGraph()); + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(_aip.getTransform()); + //cout << "Done!" << endl; } @@ -57,6 +60,9 @@ void FGAIEntity::SetModel(ssgBranch* model) { _aip.init(_model); _aip.setVisible(false); globals->get_scenery()->get_scene_graph()->addKid(_aip.getSceneGraph()); + // Register that one at the scenery manager + globals->get_scenery()->register_placement_transform(_aip.getTransform()); + } void FGAIEntity::Update(double dt) { diff --git a/src/FDM/groundcache.cxx b/src/FDM/groundcache.cxx index 3a944a42b..5c4be473f 100644 --- a/src/FDM/groundcache.cxx +++ b/src/FDM/groundcache.cxx @@ -342,6 +342,10 @@ bool FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3], double rad) { + Point3D old_cntr = globals->get_scenery()->get_center(); + Point3D cntr(pt[0], pt[1], pt[2]); + globals->get_scenery()->set_center( cntr ); + // Empty cache. cache_root.removeAllKids(); ground_radius = 0.0; @@ -379,7 +383,7 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3], // We need the offset to the scenery scenery center. sgdVec3 doffset; - Point3D psc = globals->get_tile_mgr()->get_current_center(); + Point3D psc = globals->get_scenery()->get_center(); sgdSetVec3(doffset, psc[0], psc[1], psc[2]); sgdSubVec3(doffset, doffset, pt); @@ -396,7 +400,7 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3], sgMakeTransMat4(xform, offset); - // Walk the terrain branch for now. + // Walk the scene graph and extract solid ground triangles and carrier data. ssgBranch *terrain = globals->get_scenery()->get_scene_graph(); cache_fill(terrain, xform, &acSphere, down, &wireSphere); @@ -412,6 +416,8 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3], SG_LOG(SG_FLIGHT, SG_WARN, "prepare_ground_cache(): trying to build cache " "without any scenery below the aircraft" ); + globals->get_scenery()->set_center( old_cntr ); + return found_ground; } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index f1bb31746..e3f255f6b 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -500,6 +500,28 @@ static void fgMainLoop( void ) { double visibility_meters = fgGetDouble("/environment/visibility-m"); FGViewer *current_view = globals->get_current_view(); + // Let the scenery center follow the current view position with + // 30m increments. + // + // Having the scenery center near the view position will eliminate + // jitter of objects which are placed very near the view position + // and haveing it's center near that view position. + // So the 3d insruments of the aircraft will not jitter with this. + // + // Following the view position exactly would introduce jitter of + // the scenery tiles (they would be from their center up to 10000m + // to the view and this will introduce roundoff too). By stepping + // at 30m incements the roundoff error of the scenery tiles is + // still present, but we will make exactly the same roundoff error + // at each frame until the center is switched to a new + // position. This roundoff is still visible but you will most + // propably not notice. + double *vp = globals->get_current_view()->get_absolute_view_pos(); + Point3D cntr(vp[0], vp[1], vp[2]); + if (30.0*30.0 < cntr.distance3Dsquared(globals->get_scenery()->get_center())) { + globals->get_scenery()->set_next_center( cntr ); + } + // get the location data for the primary FDM (now hardcoded to ac model)... SGLocation *acmodel_loc = NULL; acmodel_loc = (SGLocation *)globals-> @@ -517,6 +539,8 @@ static void fgMainLoop( void ) { acmodel_loc-> get_absolute_view_pos(globals-> get_scenery()->get_center()) ); + globals->get_scenery()->set_center( cntr ); + // save results of update in SGLocation for fdm... if ( globals->get_scenery()->get_cur_elev() > -9990 ) { acmodel_loc-> @@ -539,6 +563,7 @@ static void fgMainLoop( void ) { SGLocation *view_location = globals->get_current_view()->getSGLocation(); globals->get_tile_mgr()->update( view_location, visibility_meters, current_view->get_absolute_view_pos() ); + globals->get_scenery()->set_center( cntr ); // save results of update in SGLocation for fdm... if ( globals->get_scenery()->get_cur_elev() > -9990 ) { current_view->getSGLocation()-> diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index f1fa952d3..b3102774b 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -306,7 +306,9 @@ FGRenderer::update( bool refresh_camera_settings ) { FGViewer *current__view = globals->get_current_view(); // calculate our current position in cartesian space - globals->get_scenery()->set_center( globals->get_scenery()->get_next_center() ); + Point3D cntr = globals->get_scenery()->get_next_center(); + globals->get_scenery()->set_center(cntr); + current__view->set_scenery_center(cntr); if ( refresh_camera_settings ) { // update view port diff --git a/src/Main/viewer.cxx b/src/Main/viewer.cxx index 74f25e834..6615f78b0 100644 --- a/src/Main/viewer.cxx +++ b/src/Main/viewer.cxx @@ -542,14 +542,15 @@ FGViewer::getZeroElevViewPos () void FGViewer::updateFromModelLocation (SGLocation * location) { - sgCopyMat4(LOCAL, location->getCachedTransformMatrix()); + Point3D center = globals->get_scenery()->get_next_center(); + sgCopyMat4(LOCAL, location->getTransformMatrix(center)); } void FGViewer::updateAtModelLocation (SGLocation * location) { - sgCopyMat4(ATLOCAL, - location->getCachedTransformMatrix()); + Point3D center = globals->get_scenery()->get_next_center(); + sgCopyMat4(ATLOCAL, location->getTransformMatrix(center)); } void @@ -560,8 +561,20 @@ FGViewer::recalcOurOwnLocation (SGLocation * location, double lon_deg, double la dampEyeData(roll_deg, pitch_deg, heading_deg); location->setPosition( lon_deg, lat_deg, alt_ft ); location->setOrientation( roll_deg, pitch_deg, heading_deg ); - sgCopyMat4(LOCAL, - location->getTransformMatrix(globals->get_scenery()->get_center())); + Point3D center = globals->get_scenery()->get_next_center(); + sgCopyMat4(LOCAL, location->getTransformMatrix(center)); +} + +void +FGViewer::set_scenery_center(const Point3D& center) +{ + _location->set_tile_center(center); + _location->getTransformMatrix(center); + if (_type == FG_LOOKAT) { + _target_location->set_tile_center(center); + _target_location->getTransformMatrix(center); + } + set_dirty(); } // recalc() is done every time one of the setters is called (making the @@ -670,10 +683,11 @@ FGViewer::recalcLookAt () _target_roll_deg, _target_pitch_deg, _target_heading_deg ); } // calculate the "at" target object positon relative to eye or view's tile center... + Point3D center = globals->get_scenery()->get_next_center(); sgdVec3 dVec3; - sgdSetVec3(dVec3, _location->get_tile_center()[0], _location->get_tile_center()[1], _location->get_tile_center()[2]); + sgdSetVec3(dVec3, center[0], center[1], center[2]); sgdSubVec3(dVec3, - _target_location->get_absolute_view_pos(globals->get_scenery()->get_center()), + _target_location->get_absolute_view_pos(center), dVec3 ); sgSetVec3(at_pos, dVec3[0], dVec3[1], dVec3[2]); @@ -739,10 +753,10 @@ void FGViewer::copyLocationData() { // Get our friendly vectors from the eye location... + sgdCopyVec3(_absolute_view_pos, + _location->get_absolute_view_pos(globals->get_scenery()->get_next_center())); sgCopyVec3(_zero_elev_view_pos, _location->get_zero_elev()); sgCopyVec3(_relative_view_pos, _location->get_view_pos()); - sgdCopyVec3(_absolute_view_pos, - _location->get_absolute_view_pos(globals->get_scenery()->get_center())); sgCopyMat4(UP, _location->getCachedUpMatrix()); sgCopyVec3(_world_up, _location->get_world_up()); // these are the vectors that the sun and moon code like to get... diff --git a/src/Main/viewer.hxx b/src/Main/viewer.hxx index 5907997e9..4a319edc3 100644 --- a/src/Main/viewer.hxx +++ b/src/Main/viewer.hxx @@ -258,6 +258,8 @@ public: _ground_level_nearplane_m = near_m; } + void set_scenery_center(const Point3D& center); + ////////////////////////////////////////////////////////////////////// // Part 5: misc setters and getters ////////////////////////////////////////////////////////////////////// diff --git a/src/Main/viewmgr.cxx b/src/Main/viewmgr.cxx index bc1c54521..33fe8f7cb 100644 --- a/src/Main/viewmgr.cxx +++ b/src/Main/viewmgr.cxx @@ -24,6 +24,11 @@ #include // strcmp #include +#include + +#include + +#include #include "viewmgr.hxx" #include "fg_props.hxx" @@ -724,6 +729,12 @@ FGViewMgr::setView (int newview ) set_view( newview ); // copy in view data copyToCurrent (); + + // Copy the fdm's position into the SGLocation which is shared with + // some views ... + globals->get_aircraft_model()->update(0); + // Do the update ... + update(0); } diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index eff9d67ff..922d3561c 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -90,18 +90,11 @@ public: return views[i]; } inline FGViewer *next_view() { - ++current; - if ( current >= (int)views.size() ) { - current = 0; - } - copyToCurrent(); + setView((current+1 < (int)views.size()) ? (current + 1) : 0); return views[current]; } inline FGViewer *prev_view() { - --current; - if ( current < 0 ) { - current = views.size() - 1; - } + setView((0 < current) ? (current - 1) : (views.size() - 1)); return views[current]; } diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index 6bcba3913..662a4a4b8 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -46,6 +46,10 @@ FGAircraftModel::FGAircraftModel () FGAircraftModel::~FGAircraftModel () { + // Unregister that one at the scenery manager + if (_aircraft) + globals->get_scenery()->unregister_placement_transform(_aircraft->getTransform()); + delete _aircraft; delete _scene; // SSG will delete it @@ -75,6 +79,9 @@ FGAircraftModel::init () _scene->addKid(_aircraft->getSceneGraph()); _selector->addKid(_aircraft->getSceneGraph()); globals->get_scenery()->get_aircraft_branch()->addKid(_selector); + + // Register that one at the scenery manager + globals->get_scenery()->register_placement_transform(_aircraft->getTransform()); } void diff --git a/src/Model/acmodel.hxx b/src/Model/acmodel.hxx index a59bd954a..e15705374 100644 --- a/src/Model/acmodel.hxx +++ b/src/Model/acmodel.hxx @@ -11,6 +11,7 @@ #endif #include +#include SG_USING_STD(string); SG_USING_STD(vector); diff --git a/src/Model/modelmgr.cxx b/src/Model/modelmgr.cxx index 4175f65bf..01743325f 100644 --- a/src/Model/modelmgr.cxx +++ b/src/Model/modelmgr.cxx @@ -101,6 +101,10 @@ FGModelMgr::init () // Add this model to the global scene graph globals->get_scenery()->get_scene_graph()->addKid(model->getSceneGraph()); + // Register that one at the scenery manager + globals->get_scenery()->register_placement_transform(model->getTransform()); + + // Save this instance for updating add_instance(instance); } @@ -188,6 +192,9 @@ FGModelMgr::Instance::Instance () FGModelMgr::Instance::~Instance () { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(model->getTransform()); + delete model; } diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 51b598c74..8e0f361c1 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -30,6 +30,7 @@ #include #include +#include #include
@@ -100,3 +101,33 @@ void FGScenery::bind() { void FGScenery::unbind() { fgUntie("/environment/ground-elevation-m"); } + +void FGScenery::set_center( Point3D p ) { + center = p; + sgdVec3 c; + sgdSetVec3(c, p.x(), p.y(), p.z()); + placement_list_type::iterator it = _placement_list.begin(); + while (it != _placement_list.end()) { + (*it)->setSceneryCenter(c); + ++it; + } +} + +void FGScenery::register_placement_transform(ssgPlacementTransform *trans) { + trans->ref(); + _placement_list.push_back(trans); + sgdVec3 c; + sgdSetVec3(c, center.x(), center.y(), center.z()); + trans->setSceneryCenter(c); +} + +void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) { + placement_list_type::iterator it = _placement_list.begin(); + while (it != _placement_list.end()) { + if ((*it) == trans) { + (*it)->deRef(); + it = _placement_list.erase(it); + } else + ++it; + } +} diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index 3c753e1d1..d96660cee 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -29,15 +29,19 @@ # error This library requires C++ #endif +#include #include +#include #include #include +SG_USING_STD(list); class ssgRoot; class ssgBranch; +class ssgPlacementTransform; // Define a structure containing global scenery parameters @@ -72,6 +76,10 @@ class FGScenery : public SGSubsystem { ssgBranch *models_branch; ssgBranch *aircraft_branch; + // list of all placement transform, used to move the scenery center on the fly. + typedef list placement_list_type; + placement_list_type _placement_list; + public: FGScenery(); @@ -87,7 +95,7 @@ public: inline void set_cur_elev( double e ) { cur_elev = e; } inline Point3D get_center() const { return center; } - inline void set_center( Point3D p ) { center = p; } + void set_center( Point3D p ); inline Point3D get_next_center() const { return next_center; } inline void set_next_center( Point3D p ) { next_center = p; } @@ -142,6 +150,9 @@ public: inline void set_aircraft_branch (ssgBranch *t) { aircraft_branch = t; } + + void register_placement_transform(ssgPlacementTransform *trans); + void unregister_placement_transform(ssgPlacementTransform *trans); }; diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index e294e9f01..57b92d646 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -62,10 +63,10 @@ SG_USING_STD(string); FGTileEntry::FGTileEntry ( const SGBucket& b ) : center( Point3D( 0.0 ) ), tile_bucket( b ), - terra_transform( new ssgTransform ), - vasi_lights_transform( new ssgTransform ), - rwy_lights_transform( new ssgTransform ), - taxi_lights_transform( new ssgTransform ), + terra_transform( new ssgPlacementTransform ), + vasi_lights_transform( new ssgPlacementTransform ), + rwy_lights_transform( new ssgPlacementTransform ), + taxi_lights_transform( new ssgPlacementTransform ), terra_range( new ssgRangeSelector ), vasi_lights_selector( new ssgSelector ), rwy_lights_selector( new ssgSelector ), @@ -316,8 +317,6 @@ bool FGTileEntry::free_tile() { void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { if ( !loaded ) return; - SetOffset( p ); - // visibility can change from frame to frame so we update the // range selector cutoff's each time. terra_range->setRange( 0, SG_ZERO ); @@ -328,9 +327,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { gnd_lights_range->setRange( 1, vis * 1.5 + bounding_radius ); } - sgVec3 sgTrans; - sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() ); - terra_transform->setTransform( sgTrans ); + sgdVec3 sgdTrans; + sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() ); FGLight *l = (FGLight *)(globals->get_subsystem("lighting")); if ( gnd_lights_transform ) { @@ -348,12 +346,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { agl = globals->get_current_view()->getAltitudeASL_ft() * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev(); - // sgTrans just happens to be the - // vector from scenery center to the center of this tile which - // is what we want to calculate the distance of - sgVec3 to; - sgCopyVec3( to, sgTrans ); - double dist = sgLengthVec3( to ); + // Compute the distance of the scenery center from the view position. + double dist = center.distance3D(p); if ( general.get_glDepthBits() > 16 ) { sgScaleVec3( lift_vec, 10.0 + agl / 100.0 + dist / 10000 ); @@ -361,11 +355,12 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { sgScaleVec3( lift_vec, 10.0 + agl / 20.0 + dist / 5000 ); } - sgVec3 lt_trans; - sgCopyVec3( lt_trans, sgTrans ); - - sgAddVec3( lt_trans, lift_vec ); - gnd_lights_transform->setTransform( lt_trans ); + sgdVec3 dlt_trans; + sgdCopyVec3( dlt_trans, sgdTrans ); + sgdVec3 dlift_vec; + sgdSetVec3( dlift_vec, lift_vec ); + sgdAddVec3( dlt_trans, dlift_vec ); + gnd_lights_transform->setTransform( dlt_trans ); // select which set of lights based on sun angle float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; @@ -404,11 +399,12 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); } - sgVec3 lt_trans; - sgCopyVec3( lt_trans, sgTrans ); - - sgAddVec3( lt_trans, lift_vec ); - vasi_lights_transform->setTransform( lt_trans ); + sgdVec3 dlt_trans; + sgdCopyVec3( dlt_trans, sgdTrans ); + sgdVec3 dlift_vec; + sgdSetVec3( dlift_vec, lift_vec ); + sgdAddVec3( dlt_trans, dlift_vec ); + vasi_lights_transform->setTransform( dlt_trans ); // generally, vasi lights are always on vasi_lights_selector->select(0x01); @@ -438,11 +434,12 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); } - sgVec3 lt_trans; - sgCopyVec3( lt_trans, sgTrans ); - - sgAddVec3( lt_trans, lift_vec ); - rwy_lights_transform->setTransform( lt_trans ); + sgdVec3 dlt_trans; + sgdCopyVec3( dlt_trans, sgdTrans ); + sgdVec3 dlift_vec; + sgdSetVec3( dlift_vec, lift_vec ); + sgdAddVec3( dlt_trans, dlift_vec ); + rwy_lights_transform->setTransform( dlt_trans ); // turn runway lights on/off based on sun angle and visibility float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; @@ -478,11 +475,12 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); } - sgVec3 lt_trans; - sgCopyVec3( lt_trans, sgTrans ); - - sgAddVec3( lt_trans, lift_vec ); - taxi_lights_transform->setTransform( lt_trans ); + sgdVec3 dlt_trans; + sgdCopyVec3( dlt_trans, sgdTrans ); + sgdVec3 dlift_vec; + sgdSetVec3( dlift_vec, lift_vec ); + sgdAddVec3( dlt_trans, dlift_vec ); + taxi_lights_transform->setTransform( dlt_trans ); // turn taxi lights on/off based on sun angle and visibility float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; @@ -938,12 +936,16 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) terra_transform->addKid( terra_range ); // calculate initial tile offset - SetOffset( globals->get_scenery()->get_center() ); - sgCoord sgcoord; - sgSetCoord( &sgcoord, - offset.x(), offset.y(), offset.z(), - 0.0, 0.0, 0.0 ); - terra_transform->setTransform( &sgcoord ); + sgdVec3 sgdTrans; + sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() ); + terra_transform->setTransform( sgdTrans ); + + sgdVec3 sgdCenter; + Point3D p = globals->get_scenery()->get_center(); + sgdSetVec3( sgdCenter, p.x(), p.y(), p.z() ); + terra_transform->setSceneryCenter( sgdCenter ); + globals->get_scenery()->register_placement_transform(terra_transform); + // terrain->addKid( terra_transform ); // Add ground lights to scene graph if any exist @@ -951,7 +953,7 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) gnd_lights_range = NULL; if ( light_pts->getNum() ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "generating lights" ); - gnd_lights_transform = new ssgTransform; + gnd_lights_transform = new ssgPlacementTransform; gnd_lights_range = new ssgRangeSelector; gnd_lights_brightness = new ssgSelector; ssgLeaf *lights; @@ -967,22 +969,30 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) gnd_lights_range->addKid( gnd_lights_brightness ); gnd_lights_transform->addKid( gnd_lights_range ); - gnd_lights_transform->setTransform( &sgcoord ); + gnd_lights_transform->setTransform( sgdTrans ); + gnd_lights_transform->setSceneryCenter( sgdCenter ); + globals->get_scenery()->register_placement_transform(gnd_lights_transform); } // Update vasi lights transform if ( vasi_lights_transform->getNumKids() > 0 ) { - vasi_lights_transform->setTransform( &sgcoord ); + vasi_lights_transform->setTransform( sgdTrans ); + vasi_lights_transform->setSceneryCenter( sgdCenter ); + globals->get_scenery()->register_placement_transform(vasi_lights_transform); } // Update runway lights transform if ( rwy_lights_transform->getNumKids() > 0 ) { - rwy_lights_transform->setTransform( &sgcoord ); + rwy_lights_transform->setTransform( sgdTrans ); + rwy_lights_transform->setSceneryCenter( sgdCenter ); + globals->get_scenery()->register_placement_transform(rwy_lights_transform); } // Update taxi lights transform if ( taxi_lights_transform->getNumKids() > 0 ) { - taxi_lights_transform->setTransform( &sgcoord ); + taxi_lights_transform->setTransform( sgdTrans ); + taxi_lights_transform->setSceneryCenter( sgdCenter ); + globals->get_scenery()->register_placement_transform(taxi_lights_transform); } } @@ -1070,6 +1080,9 @@ FGTileEntry::disconnect_ssg_nodes() SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile! terra_transform = " << terra_transform ); } + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(terra_transform); + // find the terrain branch parent int pcount = terra_transform->getNumParents(); if ( pcount > 0 ) { @@ -1092,6 +1105,8 @@ FGTileEntry::disconnect_ssg_nodes() // find the ground lighting branch if ( gnd_lights_transform ) { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(gnd_lights_transform); pcount = gnd_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) @@ -1114,6 +1129,8 @@ FGTileEntry::disconnect_ssg_nodes() // find the vasi lighting branch if ( vasi_lights_transform ) { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(vasi_lights_transform); pcount = vasi_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) @@ -1136,6 +1153,8 @@ FGTileEntry::disconnect_ssg_nodes() // find the runway lighting branch if ( rwy_lights_transform ) { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(rwy_lights_transform); pcount = rwy_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) @@ -1158,6 +1177,8 @@ FGTileEntry::disconnect_ssg_nodes() // find the taxi lighting branch if ( taxi_lights_transform ) { + // Unregister that one at the scenery manager + globals->get_scenery()->unregister_placement_transform(taxi_lights_transform); pcount = taxi_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index bcc669c47..90471243b 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -58,6 +58,7 @@ typedef point_list::const_iterator const_point_list_iterator; class ssgLeaf; class ssgBranch; class ssgTransform; +class ssgPlacementTransform; class ssgSelector; class ssgRangeSelector; class ssgVertexArray; @@ -109,7 +110,6 @@ public: // global tile culling data Point3D center; double bounding_radius; - Point3D offset; // this tile's official location in the world SGBucket tile_bucket; @@ -128,11 +128,11 @@ private: // - kidn(fan) // pointer to ssg transform for this tile - ssgTransform *terra_transform; - ssgTransform *vasi_lights_transform; - ssgTransform *rwy_lights_transform; - ssgTransform *taxi_lights_transform; - ssgTransform *gnd_lights_transform; + ssgPlacementTransform *terra_transform; + ssgPlacementTransform *vasi_lights_transform; + ssgPlacementTransform *rwy_lights_transform; + ssgPlacementTransform *taxi_lights_transform; + ssgPlacementTransform *gnd_lights_transform; // pointer to ssg range selector for this tile ssgRangeSelector *terra_range; @@ -218,15 +218,6 @@ public: // completely freed. bool free_tile(); - // Calculate this tile's offset - void SetOffset( const Point3D& p) - { - offset = center - p; - } - - // Return this tile's offset - inline Point3D get_offset() const { return offset; } - // Update the ssg transform node for this tile so it can be // properly drawn relative to our (0,0,0) point void prep_ssg_node( const Point3D& p, sgVec3 up, float vis); @@ -283,7 +274,7 @@ public: /** * return the SSG Transform node for the terrain */ - inline ssgTransform *get_terra_transform() { return terra_transform; } + inline ssgPlacementTransform *get_terra_transform() { return terra_transform; } inline double get_timestamp() const { return timestamp; } inline void set_timestamp( double time_ms ) { timestamp = time_ms; } diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index b53b7d8cf..c0676ad70 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -410,15 +410,6 @@ int FGTileMgr::update( SGLocation *location, double visibility_meters, // << current_bucket ); fgSetInt( "/environment/current-tile-id", current_bucket.gen_index() ); - // set global scenery center from current tile center - current_tile = tile_cache.get_tile( current_bucket ); - if ( current_tile != NULL ) { - globals->get_scenery()->set_next_center( current_tile->center ); - } else { - SG_LOG( SG_TERRAIN, SG_WARN, "Tile not found (Ok if initializing)" ); - globals->get_scenery()->set_next_center( Point3D(0.0) ); - } - // do tile load scheduling. // Note that we need keep track of both viewer buckets and fdm buckets. if ( state == Running ) { @@ -517,7 +508,6 @@ void FGTileMgr::prep_ssg_nodes( SGLocation *location, float vis ) { Point3D center = location->get_tile_center(); if (center == Point3D(0.0)) return; - current_center = center; float *up = location->get_world_up(); FGTileEntry *e; diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 4b2405f1f..6e4b30f34 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -103,10 +103,6 @@ private: * tile cache */ FGNewCache tile_cache; - /** - * and its center - */ - Point3D current_center; /** * Queue tiles for loading. @@ -192,7 +188,6 @@ public: // based on current visibilty void prep_ssg_nodes( float // visibility_meters ); void prep_ssg_nodes( SGLocation *location, float visibility_meters ); - const Point3D get_current_center(void) const { return current_center; } // Set flag with event manager so that non-moving view refreshes // tiles...