X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScenery%2Ftileentry.cxx;h=b87da6b1d6fbca5a418d3c5746004004f23cf905;hb=4a79d82ba62fa4e5be759fa0fc4b20220e8da303;hp=b0639d5880745e6f3d3fad479940dc81f92acd16;hpb=7b824755ee96b8db4240ca9999570f3c7bacdad7;p=flightgear.git diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index b0639d588..b87da6b1d 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -16,7 +16,7 @@ // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ @@ -32,6 +32,14 @@ #include STL_STRING +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -42,7 +50,6 @@ #include #include #include -#include #include #include @@ -63,14 +70,14 @@ SG_USING_STD(string); FGTileEntry::FGTileEntry ( const SGBucket& b ) : center( Point3D( 0.0 ) ), tile_bucket( b ), - 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 ), - taxi_lights_selector( new ssgSelector ), + terra_transform( new SGPlacementTransform ), + vasi_lights_transform( new SGPlacementTransform ), + rwy_lights_transform( new SGPlacementTransform ), + taxi_lights_transform( new SGPlacementTransform ), + terra_range( new osg::LOD ), + vasi_lights_selector( new osg::Switch ), + rwy_lights_selector( new osg::Switch ), + taxi_lights_selector( new osg::Switch ), loaded(false), pending_models(0), is_inner_ring(false), @@ -92,47 +99,7 @@ FGTileEntry::~FGTileEntry () { // delete[] nodes; } - -#if 0 -// Please keep this for reference. We use Norman's optimized routine, -// but here is what the routine really is doing. -void -FGTileEntry::WorldCoordinate( sgCoord *obj_pos, Point3D center, - double lat, double lon, double elev, double hdg) -{ - // setup transforms - Point3D geod( lon * SGD_DEGREES_TO_RADIANS, - lat * SGD_DEGREES_TO_RADIANS, - elev ); - - Point3D world_pos = sgGeodToCart( geod ); - Point3D offset = world_pos - center; - - sgMat4 POS; - sgMakeTransMat4( POS, offset.x(), offset.y(), offset.z() ); - - sgVec3 obj_rt, obj_up; - sgSetVec3( obj_rt, 0.0, 1.0, 0.0); // Y axis - sgSetVec3( obj_up, 0.0, 0.0, 1.0); // Z axis - - sgMat4 ROT_lon, ROT_lat, ROT_hdg; - sgMakeRotMat4( ROT_lon, lon, obj_up ); - sgMakeRotMat4( ROT_lat, 90 - lat, obj_rt ); - sgMakeRotMat4( ROT_hdg, hdg, obj_up ); - - sgMat4 TUX; - sgCopyMat4( TUX, ROT_hdg ); - sgPostMultMat4( TUX, ROT_lat ); - sgPostMultMat4( TUX, ROT_lon ); - sgPostMultMat4( TUX, POS ); - - sgSetCoord( obj_pos, TUX ); -} -#endif - - -// Norman's 'fast hack' for above -static void WorldCoordinate( sgCoord *obj_pos, Point3D center, double lat, +static void WorldCoordinate( osg::Matrix& obj_pos, Point3D center, double lat, double lon, double elev, double hdg ) { double lon_rad = lon * SGD_DEGREES_TO_RADIANS; @@ -174,73 +141,57 @@ static void WorldCoordinate( sgCoord *obj_pos, Point3D center, double lat, mat[3][2] = offset.z(); mat[3][3] = SG_ONE ; - sgSetCoord( obj_pos, mat ); + for (unsigned i = 0; i < 4; ++i) + for (unsigned j = 0; j < 4; ++j) + obj_pos(i, j) = mat[i][j]; } -// recurse an ssg tree and call removeKid() on every node from the +// recurse an ssg tree and call removeChild() on every node from the // bottom up. Leaves the original branch in existance, but empty so // it can be removed by the calling routine. -static void my_remove_branch( ssgBranch * branch ) { - for ( ssgEntity *k = branch->getKid( 0 ); - k != NULL; - k = branch->getNextKid() ) - { - if ( k -> isAKindOf ( ssgTypeBranch() ) ) { - my_remove_branch( (ssgBranch *)k ); - branch -> removeKid ( k ); - } else if ( k -> isAKindOf ( ssgTypeLeaf() ) ) { - branch -> removeKid ( k ) ; - } - } -} +// static void my_remove_branch( osg::Group * branch ) { +// branch->removeChildren(0, branch->getNumChildren()); +// } // Free "n" leaf elements of an ssg tree. returns the number of // elements freed. An empty branch node is considered a leaf. This // is intended to spread the load of freeing a complex tile out over // several frames. -static int fgPartialFreeSSGtree( ssgBranch *b, int n ) { - -#if 0 - // for testing: we could call the following two lines and replace - // the functionality of this entire function and everything will - // get properly freed, but it will happen all at once and could - // cause a huge frame rate hit. - ssgDeRefDelete( b ); - return 0; -#endif - +static int fgPartialFreeSSGtree( osg::Group *b, int n ) { int num_deletes = 0; - if ( n > 0 ) { - // we still have some delete budget left - // if ( b->getNumKids() > 100 ) { - // cout << "large family = " << b->getNumKids() << endl; - // } - // deleting in reverse would help if my plib patch get's - // applied, but for now it will make things slower. - // for ( int i = b->getNumKids() - 1; i >= 0 ; --i ) { - for ( int i = 0; i < b->getNumKids(); ++i ) { - ssgEntity *kid = b->getKid(i); - if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) { - int result = fgPartialFreeSSGtree( (ssgBranch *)kid, n ); - num_deletes += result; - n -= result; - if ( n < 0 ) { - break; - } - } - // remove the kid if (a) it is now empty -or- (b) it's ref - // count is > zero at which point we don't care if it's - // empty, we don't want to touch it's contents. - if ( kid->getNumKids() == 0 || kid->getRef() > 1 ) { - b->removeKid( kid ); - num_deletes++; - n--; - } - } - } + b->removeChildren(0, b->getNumChildren()); + +// if ( n > 0 ) { +// // we still have some delete budget left +// // if ( b->getNumChilds() > 100 ) { +// // cout << "large family = " << b->getNumChilds() << endl; +// // } +// // deleting in reverse would help if my plib patch get's +// // applied, but for now it will make things slower. +// // for ( int i = b->getNumChilds() - 1; i >= 0 ; --i ) { +// for ( int i = 0; i < b->getNumChildren(); ++i ) { +// ssgEntity *kid = b->getChild(i); +// if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) { +// int result = fgPartialFreeSSGtree( (osg::Group *)kid, n ); +// num_deletes += result; +// n -= result; +// if ( n < 0 ) { +// break; +// } +// } +// // remove the kid if (a) it is now empty -or- (b) it's ref +// // count is > zero at which point we don't care if it's +// // empty, we don't want to touch it's contents. +// if ( kid->getNumChildren() == 0 || kid->getRef() > 1 ) { +// b->removeChild( kid ); +// num_deletes++; +// n--; +// } +// } +// } return num_deletes; } @@ -263,40 +214,40 @@ bool FGTileEntry::free_tile() { // delete the terrain branch (this should already have been // disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" ); - if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) { - ssgDeRefDelete( terra_transform ); + if ( fgPartialFreeSSGtree( terra_transform.get(), delete_size ) == 0 ) { + terra_transform = 0; free_tracker |= TERRA_NODE; } - } else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) { + } else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform.get() ) { // delete the terrain lighting branch (this should already have been // disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" ); - if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) { - ssgDeRefDelete( gnd_lights_transform ); + if ( fgPartialFreeSSGtree( gnd_lights_transform.get(), delete_size ) == 0 ) { + gnd_lights_transform = 0; free_tracker |= GROUND_LIGHTS; } - } else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector ) { + } else if ( !(free_tracker & VASI_LIGHTS) && vasi_lights_selector.get() ) { // delete the runway lighting branch (this should already have // been disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING vasi_lights_selector" ); - if ( fgPartialFreeSSGtree( vasi_lights_selector, delete_size ) == 0 ) { - ssgDeRefDelete( vasi_lights_selector ); + if ( fgPartialFreeSSGtree( vasi_lights_selector.get(), delete_size ) == 0 ) { + vasi_lights_selector = 0; free_tracker |= VASI_LIGHTS; } - } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector ) { + } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_selector.get() ) { // delete the runway lighting branch (this should already have // been disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_selector" ); - if ( fgPartialFreeSSGtree( rwy_lights_selector, delete_size ) == 0 ) { - ssgDeRefDelete( rwy_lights_selector ); + if ( fgPartialFreeSSGtree( rwy_lights_selector.get(), delete_size ) == 0 ) { + rwy_lights_selector = 0; free_tracker |= RWY_LIGHTS; } - } else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_selector ) { + } else if ( !(free_tracker & TAXI_LIGHTS) && taxi_lights_selector.get() ) { // delete the taxi lighting branch (this should already have been // disconnected from the scene graph) SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING taxi_lights_selector" ); - if ( fgPartialFreeSSGtree( taxi_lights_selector, delete_size ) == 0 ) { - ssgDeRefDelete( taxi_lights_selector ); + if ( fgPartialFreeSSGtree( taxi_lights_selector.get(), delete_size ) == 0 ) { + taxi_lights_selector = 0; free_tracker |= TAXI_LIGHTS; } } else if ( !(free_tracker & LIGHTMAPS) ) { @@ -319,19 +270,16 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // visibility can change from frame to frame so we update the // range selector cutoff's each time. - terra_range->setRange( 0, SG_ZERO ); - terra_range->setRange( 1, vis + bounding_radius ); + terra_range->setRange( 0, 0, vis + bounding_radius ); - if ( gnd_lights_range ) { - gnd_lights_range->setRange( 0, SG_ZERO ); - gnd_lights_range->setRange( 1, vis * 1.5 + bounding_radius ); + if ( gnd_lights_range.get() ) { + gnd_lights_range->setRange( 0, 0, vis * 1.5 + bounding_radius ); } - sgdVec3 sgdTrans; - sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() ); + SGVec3d lt_trans(center.x(), center.y(), center.z()); FGLight *l = (FGLight *)(globals->get_subsystem("lighting")); - if ( gnd_lights_transform ) { + if ( gnd_lights_transform.get() ) { // we need to lift the lights above the terrain to avoid // z-buffer fighting. We do this based on our altitude and // the distance this tile is away from scenery center. @@ -339,9 +287,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // we expect 'up' to be a unit vector coming in, but since we // modify the value of lift_vec, we need to create a local // copy. - sgVec3 lift_vec; - sgCopyVec3( lift_vec, up ); - + SGVec3f lift_vec(up); + double agl; agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER - globals->get_current_view()->getSGLocation()->get_cur_elev_m(); @@ -350,292 +297,115 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { double dist = center.distance3D(p); if ( general.get_glDepthBits() > 16 ) { - sgScaleVec3( lift_vec, 10.0 + agl / 100.0 + dist / 10000 ); + lift_vec *= 10.0 + agl / 100.0 + dist / 10000; } else { - sgScaleVec3( lift_vec, 10.0 + agl / 20.0 + dist / 5000 ); + lift_vec *= 10.0 + agl / 20.0 + dist / 5000; } - 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 ); + gnd_lights_transform->setTransform( lt_trans + toVec3d(lift_vec) ); // select which set of lights based on sun angle float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; if ( sun_angle > 95 ) { - gnd_lights_brightness->select(0x04); + gnd_lights_brightness->setSingleChildOn(2); } else if ( sun_angle > 92 ) { - gnd_lights_brightness->select(0x02); + gnd_lights_brightness->setSingleChildOn(1); } else if ( sun_angle > 89 ) { - gnd_lights_brightness->select(0x01); - } else { - gnd_lights_brightness->select(0x00); - } - } - - if ( vasi_lights_transform ) { - // we need to lift the lights above the terrain to avoid - // z-buffer fighting. We do this based on our altitude and - // the distance this tile is away from scenery center. - - sgVec3 lift_vec; - sgCopyVec3( lift_vec, up ); - - // we fudge agl by 30 meters so that the lifting function - // doesn't phase in until we are > 30m agl. - double agl; - agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER - - globals->get_current_view()->getSGLocation()->get_cur_elev_m() - - 30.0; - if ( agl < 0.0 ) { - agl = 0.0; - } - - if ( general.get_glDepthBits() > 16 ) { - sgScaleVec3( lift_vec, 0.25 + agl / 400.0 + agl*agl / 5000000.0 ); + gnd_lights_brightness->setSingleChildOn(0); } else { - sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); + gnd_lights_brightness->setAllChildrenOff(); } - - 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); } - if ( rwy_lights_transform ) { - // we need to lift the lights above the terrain to avoid - // z-buffer fighting. We do this based on our altitude and - // the distance this tile is away from scenery center. - - sgVec3 lift_vec; - sgCopyVec3( lift_vec, up ); - - // we fudge agl by 30 meters so that the lifting function - // doesn't phase in until we are > 30m agl. - double agl; - agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER - - globals->get_current_view()->getSGLocation()->get_cur_elev_m() - - 30.0; - if ( agl < 0.0 ) { - agl = 0.0; - } - - if ( general.get_glDepthBits() > 16 ) { - sgScaleVec3( lift_vec, 0.01 + agl / 400.0 + agl*agl / 5000000.0 ); - } else { - sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); - } - - 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 ); - + if ( rwy_lights_transform.get() ) { // turn runway lights on/off based on sun angle and visibility float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; if ( sun_angle > 85 || (fgGetDouble("/environment/visibility-m") < 5000.0) ) { - rwy_lights_selector->select(0x01); + rwy_lights_selector->setAllChildrenOn(); } else { - rwy_lights_selector->select(0x00); + rwy_lights_selector->setAllChildrenOff(); } } - if ( taxi_lights_transform ) { - // we need to lift the lights above the terrain to avoid - // z-buffer fighting. We do this based on our altitude and - // the distance this tile is away from scenery center. - - sgVec3 lift_vec; - sgCopyVec3( lift_vec, up ); - - // we fudge agl by 30 meters so that the lifting function - // doesn't phase in until we are > 30m agl. - double agl; - agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER - - globals->get_current_view()->getSGLocation()->get_cur_elev_m() - - 30.0; - if ( agl < 0.0 ) { - agl = 0.0; - } - - if ( general.get_glDepthBits() > 16 ) { - sgScaleVec3( lift_vec, 0.01 + agl / 400.0 + agl*agl / 5000000.0 ); - } else { - sgScaleVec3( lift_vec, 0.25 + agl / 150.0 ); - } - - 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 ); - + if ( taxi_lights_transform.get() ) { // turn taxi lights on/off based on sun angle and visibility float sun_angle = l->get_sun_angle() * SGD_RADIANS_TO_DEGREES; if ( sun_angle > 85 || (fgGetDouble("/environment/visibility-m") < 5000.0) ) { - taxi_lights_selector->select(0x01); + taxi_lights_selector->setAllChildrenOn(); } else { - taxi_lights_selector->select(0x00); - } - } - - if ( vasi_lights_transform && is_inner_ring ) { - // now we need to traverse the list of vasi lights and update - // their coloring (but only for the inner ring, no point in - // doing this extra work for tiles that are relatively far - // away.) - for ( int i = 0; i < vasi_lights_transform->getNumKids(); ++i ) { - // cout << "vasi root = " << i << endl; - ssgBranch *v = (ssgBranch *)vasi_lights_transform->getKid(i); - for ( int j = 0; j < v->getNumKids(); ++j ) { - // cout << " vasi branch = " << j << endl; - ssgTransform *kid = (ssgTransform *)v->getKid(j); - SGVASIUserData *vasi = (SGVASIUserData *)kid->getUserData(); - - if ( vasi != NULL ) { - sgdVec3 s; - sgdCopyVec3( s, vasi->get_abs_pos() ); - Point3D start(s[0], s[1], s[2]); - - sgdVec3 d; - sgdCopyVec3( d, globals->get_current_view()->get_absolute_view_pos() ); - - double dist = sgdDistanceVec3( s, d ); - - if ( dist < 10000 ) { - double cur_alt - = globals->get_current_view()->getAltitudeASL_ft() - * SG_FEET_TO_METER; - - double y = cur_alt - vasi->get_alt_m(); - - double angle; - if ( dist != 0 ) { - angle = asin( y / dist ); - } else { - angle = 0.0; - } - - vasi->set_color(angle * SG_RADIANS_TO_DEGREES); - } - // cout << " dist = " << dist - // << " angle = " << angle * SG_RADIANS_TO_DEGREES - // << endl; - } else { - SG_LOG( SG_TERRAIN, SG_ALERT, "no vasi data!" ); - } - } + taxi_lights_selector->setAllChildrenOff(); } } } -// Set up lights rendering call backs -static int fgLightsPredraw( ssgEntity *e ) { -#if 0 - if (glPointParameterIsSupported) { - static float quadratic[3] = {1.0, 0.01, 0.0001}; - glPointParameterfvProc(GL_DISTANCE_ATTENUATION_EXT, quadratic); - glPointParameterfProc(GL_POINT_SIZE_MIN_EXT, 1.0); - glPointSize(4.0); - } -#endif - return true; -} - -static int fgLightsPostdraw( ssgEntity *e ) { -#if 0 - if (glPointParameterIsSupported) { - static float default_attenuation[3] = {1.0, 0.0, 0.0}; - glPointParameterfvProc(GL_DISTANCE_ATTENUATION_EXT, - default_attenuation); - glPointSize(1.0); - } -#endif - return true; -} - - -ssgLeaf* FGTileEntry::gen_lights( SGMaterialLib *matlib, ssgVertexArray *lights, - int inc, float bright ) +osg::Node* +FGTileEntry::gen_lights( SGMaterialLib *matlib, osg::Vec3Array *lights, + int inc, float bright ) { // generate a repeatable random seed - float *p1 = lights->get( 0 ); - unsigned int *seed = (unsigned int *)p1; - sg_srandom( *seed ); - - int size = lights->getNum() / inc; + sg_srandom( (unsigned)(*lights)[0][0] ); // Allocate ssg structure - ssgVertexArray *vl = new ssgVertexArray( size + 1 ); - ssgNormalArray *nl = NULL; - ssgTexCoordArray *tl = NULL; - ssgColourArray *cl = new ssgColourArray( size + 1 ); + osg::Vec3Array *vl = new osg::Vec3Array; + osg::Vec4Array *cl = new osg::Vec4Array; - sgVec4 color; - for ( int i = 0; i < lights->getNum(); ++i ) { + for ( unsigned i = 0; i < lights->size(); ++i ) { // this loop is slightly less efficient than it otherwise // could be, but we want a red light to always be red, and a // yellow light to always be yellow, etc. so we are trying to // preserve the random sequence. float zombie = sg_random(); if ( i % inc == 0 ) { - vl->add( lights->get(i) ); + vl->push_back( (*lights)[i] ); // factor = sg_random() ^ 2, range = 0 .. 1 concentrated towards 0 float factor = sg_random(); factor *= factor; + osg::Vec4 color; if ( zombie > 0.5 ) { // 50% chance of yellowish - sgSetVec4( color, 0.9, 0.9, 0.3, bright - factor * 0.2 ); + color = osg::Vec4( 0.9, 0.9, 0.3, bright - factor * 0.2 ); } else if ( zombie > 0.15 ) { // 35% chance of whitish - sgSetVec4( color, 0.9, 0.9, 0.8, bright - factor * 0.2 ); + color = osg::Vec4( 0.9, 0.9, 0.8, bright - factor * 0.2 ); } else if ( zombie > 0.05 ) { // 10% chance of orangish - sgSetVec4( color, 0.9, 0.6, 0.2, bright - factor * 0.2 ); + color = osg::Vec4( 0.9, 0.6, 0.2, bright - factor * 0.2 ); } else { // 5% chance of redish - sgSetVec4( color, 0.9, 0.2, 0.2, bright - factor * 0.2 ); + color = osg::Vec4( 0.9, 0.2, 0.2, bright - factor * 0.2 ); } - cl->add( color ); + cl->push_back( color ); } } // create ssg leaf - ssgLeaf *leaf = - new ssgVtxTable ( GL_POINTS, vl, nl, tl, cl ); + osg::Geometry* geometry = new osg::Geometry; + geometry->setVertexArray(vl); + geometry->setColorArray(cl); + geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); + geometry->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, vl->size())); + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geometry); // assign state SGMaterial *mat = matlib->find( "GROUND_LIGHTS" ); - leaf->setState( mat->get_state() ); - leaf->setCallback( SSG_CALLBACK_PREDRAW, fgLightsPredraw ); - leaf->setCallback( SSG_CALLBACK_POSTDRAW, fgLightsPostdraw ); + geode->setStateSet(mat->get_state()); - return leaf; + return geode; } bool FGTileEntry::obj_load( const string& path, - ssgBranch *geometry, - ssgBranch *vasi_lights, - ssgBranch *rwy_lights, - ssgBranch *taxi_lights, - ssgVertexArray *ground_lights, bool is_base ) + osg::Group *geometry, + osg::Group *vasi_lights, + osg::Group *rwy_lights, + osg::Group *taxi_lights, + osg::Vec3Array *ground_lights, bool is_base ) { Point3D c; // returned center point double br; // returned bounding radius @@ -644,7 +414,7 @@ bool FGTileEntry::obj_load( const string& path, fgGetBool("/sim/rendering/random-objects", true); // try loading binary format - if ( sgBinObjLoad( path, is_base, + if ( SGBinObjLoad( path, is_base, &c, &br, globals->get_matlib(), use_random_objects, geometry, vasi_lights, rwy_lights, taxi_lights, ground_lights ) ) @@ -659,399 +429,357 @@ bool FGTileEntry::obj_load( const string& path, } +typedef enum { + OBJECT, + OBJECT_SHARED, + OBJECT_STATIC, + OBJECT_SIGN, + OBJECT_RUNWAY_SIGN +} object_type; + + +// storage class for deferred object processing in FGTileEntry::load() +struct Object { + Object(object_type t, const string& token, const SGPath& p, istream& in) + : type(t), path(p) + { + in >> name; + if (type != OBJECT) + in >> lon >> lat >> elev >> hdg; + in >> ::skipeol; + + if (type == OBJECT) + SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " " << name); + else + SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " " << name << " lon=" << + lon << " lat=" << lat << " elev=" << elev << " hdg=" << hdg); + } + object_type type; + string name; + SGPath path; + double lon, lat, elev, hdg; +}; + + void FGTileEntry::load( const string_list &path_list, bool is_base ) { bool found_tile_base = false; - // obj_load() will generate ground lighting for us ... - ssgVertexArray *light_pts = new ssgVertexArray( 100 ); - - ssgBranch* new_tile = new ssgBranch; - - unsigned int i = 0; - while ( i < path_list.size() ) { + SGPath object_base; + vector objects; + + string index_str = tile_bucket.gen_index_str(); + SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << index_str ); + + // scan and parse all files and store information + for (unsigned int i = 0; i < path_list.size(); i++) { + // If we found a terrain tile in Terrain/, we have to process the + // Objects/ dir in the same group, too, before we can stop scanning. + // FGGlobals::set_fg_scenery() inserts an empty string to path_list + // as marker. + if (path_list[i].empty()) { + if (found_tile_base) + break; + else + continue; + } bool has_base = false; - // Generate names for later use - string index_str = tile_bucket.gen_index_str(); - SGPath tile_path = path_list[i]; tile_path.append( tile_bucket.gen_base_path() ); SGPath basename = tile_path; basename.append( index_str ); - // string path = basename.str(); - SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << basename.str() ); + SG_LOG( SG_TERRAIN, SG_INFO, " Trying " << basename.str() ); -#define FG_MAX_LIGHTS 1000 // Check for master .stg (scene terra gear) file SGPath stg_name = basename; stg_name.concat( ".stg" ); sg_gzifstream in( stg_name.str() ); + if ( !in.is_open() ) + continue; - if ( in.is_open() ) { - string token, name; - - while ( ! in.eof() ) { - in >> token; + while ( ! in.eof() ) { + string token; + in >> token; - if ( token[0] == '#' ) { - in >> ::skipeol; - continue; - } - // Load only once (first found) - if ( token == "OBJECT_BASE" ) { - in >> name >> ::skipws; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " name = " << name ); - - if (!found_tile_base) { - found_tile_base = true; - has_base = true; - - SGPath custom_path = tile_path; - custom_path.append( name ); - - ssgBranch *geometry = new ssgBranch; - if ( obj_load( custom_path.str(), - geometry, NULL, NULL, NULL, light_pts, - true ) ) - { - geometry->getKid( 0 )->setTravCallback( - SSG_CALLBACK_PRETRAV, - &FGTileMgr::tile_filter_cb ); - new_tile -> addKid( geometry ); - } else { - delete geometry; - } - } else { - SG_LOG( SG_TERRAIN, SG_INFO, " (skipped)" ); - } - - // Load only if base is not in another file - } else if ( token == "OBJECT" ) { - if (!found_tile_base || has_base) { - in >> name >> ::skipws; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " name = " << name ); - - SGPath custom_path = tile_path; - custom_path.append( name ); - - ssgBranch *geometry = new ssgBranch; - ssgBranch *vasi_lights = new ssgBranch; - ssgBranch *rwy_lights = new ssgBranch; - ssgBranch *taxi_lights = new ssgBranch; - if ( obj_load( custom_path.str(), - geometry, vasi_lights, rwy_lights, - taxi_lights, NULL, false ) ) - { - if ( geometry -> getNumKids() > 0 ) { - geometry->getKid( 0 )->setTravCallback( - SSG_CALLBACK_PRETRAV, - &FGTileMgr::tile_filter_cb ); - new_tile -> addKid( geometry ); - } else { - delete geometry; - } - if ( vasi_lights -> getNumKids() > 0 ) { - vasi_lights_transform -> addKid( vasi_lights ); - } else { - delete vasi_lights; - } - if ( rwy_lights -> getNumKids() > 0 ) { - rwy_lights_transform -> addKid( rwy_lights ); - } else { - delete rwy_lights; - } - if ( taxi_lights -> getNumKids() > 0 ) { - taxi_lights_transform -> addKid( taxi_lights ); - } else { - delete taxi_lights; - } - } else { - delete geometry; - delete vasi_lights; - delete rwy_lights; - delete taxi_lights; - } - } - - // Always OK to load - } else if ( token == "OBJECT_STATIC" || - token == "OBJECT_SHARED" ) { - // load object info - double lon, lat, elev, hdg; - in >> name >> lon >> lat >> elev >> hdg >> ::skipws; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " name = " << name - << " pos = " << lon << ", " << lat - << " elevation = " << elev - << " heading = " << hdg ); - - // object loading is deferred to main render thread, - // but lets figure out the paths right now. - SGPath custom_path; - if ( token == "OBJECT_STATIC" ) { - custom_path= tile_path; - } else { - custom_path = globals->get_fg_root(); - } - custom_path.append( name ); - - sgCoord obj_pos; - WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg ); - - ssgTransform *obj_trans = new ssgTransform; - obj_trans->setTransform( &obj_pos ); - - // wire as much of the scene graph together as we can - new_tile->addKid( obj_trans ); - - // bump up the pending models count - pending_models++; - - // push an entry onto the model load queue - FGDeferredModel *dm - = new FGDeferredModel( custom_path.str(), - tile_path.str(), - tile_bucket, - this, obj_trans ); - FGTileMgr::model_ready( dm ); - - // Do we even use this one? - } else if ( token == "OBJECT_TAXI_SIGN" ) { - // load object info - double lon, lat, elev, hdg; - in >> name >> lon >> lat >> elev >> hdg >> ::skipws; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " name = " << name - << " pos = " << lon << ", " << lat - << " elevation = " << elev - << " heading = " << hdg ); - - // load the object itself - SGPath custom_path = tile_path; - custom_path.append( name ); - - sgCoord obj_pos; - WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg ); - - ssgTransform *obj_trans = new ssgTransform; - obj_trans->setTransform( &obj_pos ); - - ssgBranch *custom_obj - = sgMakeTaxiSign( globals->get_matlib(), - custom_path.str(), name ); - - // wire the pieces together - if ( custom_obj != NULL ) { - obj_trans -> addKid( custom_obj ); - } - new_tile->addKid( obj_trans ); - - // Do we even use this one? - } else if ( token == "OBJECT_RUNWAY_SIGN" ) { - // load object info - double lon, lat, elev, hdg; - in >> name >> lon >> lat >> elev >> hdg >> ::skipws; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " name = " << name - << " pos = " << lon << ", " << lat - << " elevation = " << elev - << " heading = " << hdg ); - - // load the object itself - SGPath custom_path = tile_path; - custom_path.append( name ); - - sgCoord obj_pos; - WorldCoordinate( &obj_pos, center, lat, lon, elev, hdg ); - - ssgTransform *obj_trans = new ssgTransform; - obj_trans->setTransform( &obj_pos ); - - ssgBranch *custom_obj - = sgMakeRunwaySign( globals->get_matlib(), - custom_path.str(), name ); - - // wire the pieces together - if ( custom_obj != NULL ) { - obj_trans -> addKid( custom_obj ); - } - new_tile->addKid( obj_trans ); - - // I don't think we use this, either - } else if ( token == "RWY_LIGHTS" ) { - double lon, lat, hdg, len, width; - string common, end1, end2; - in >> lon >> lat >> hdg >> len >> width - >> common >> end1 >> end2; - SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token - << " pos = " << lon << ", " << lat - << " hdg = " << hdg - << " size = " << len << ", " << width - << " codes = " << common << " " - << end1 << " " << end2 ); - } else { - SG_LOG( SG_TERRAIN, SG_DEBUG, - "Unknown token " << token << " in " - << stg_name.str() ); - in >> ::skipws; + if ( token[0] == '#' ) { + in >> ::skipeol; + continue; + } + // Load only once (first found) + if ( token == "OBJECT_BASE" ) { + string name; + in >> name >> ::skipws; + SG_LOG( SG_TERRAIN, SG_INFO, " " << token << " " << name ); + + if (!found_tile_base) { + found_tile_base = true; + has_base = true; + + object_base = tile_path; + object_base.append(name); + + } else + SG_LOG(SG_TERRAIN, SG_INFO, " (skipped)"); + + // Load only if base is not in another file + } else if ( token == "OBJECT" ) { + if (!found_tile_base || has_base) + objects.push_back(new Object(OBJECT, token, tile_path, in)); + else { + string name; + in >> name >> ::skipeol; + SG_LOG(SG_TERRAIN, SG_INFO, " " << token << " " + << name << " (skipped)"); } + + // Always OK to load + } else if ( token == "OBJECT_STATIC" ) { + objects.push_back(new Object(OBJECT_STATIC, token, tile_path, in)); + + } else if ( token == "OBJECT_SHARED" ) { + objects.push_back(new Object(OBJECT_SHARED, token, tile_path, in)); + + } else if ( token == "OBJECT_SIGN" ) { + objects.push_back(new Object(OBJECT_SIGN, token, tile_path, in)); + + } else if ( token == "OBJECT_RUNWAY_SIGN" ) { + objects.push_back(new Object(OBJECT_RUNWAY_SIGN, token, tile_path, in)); + + } else { + SG_LOG( SG_TERRAIN, SG_DEBUG, + "Unknown token '" << token << "' in " << stg_name.str() ); + in >> ::skipws; } } - - i++; } - if ( !found_tile_base ) { - // no tile base found, generate an ocean tile on the fly for - // this area - ssgBranch *geometry = new ssgBranch; + + // obj_load() will generate ground lighting for us ... + osg::ref_ptr light_pts = new osg::Vec3Array; + osg::Group* new_tile = new osg::Group; + + + if (found_tile_base) { + // load tile if found ... + osg::ref_ptr geometry = new osg::Group; + if ( obj_load( object_base.str(), geometry.get(), + NULL, NULL, NULL, light_pts.get(), true ) ) { + new_tile -> addChild( geometry.get() ); + } + + } else { + // ... or generate an ocean tile on the fly + SG_LOG(SG_TERRAIN, SG_INFO, " Generating ocean tile"); + osg::ref_ptr geometry = new osg::Group; Point3D c; double br; - if ( sgGenTile( path_list[0], tile_bucket, &c, &br, - globals->get_matlib(), geometry ) ) - { + if ( SGGenTile( path_list[0], tile_bucket, &c, &br, + globals->get_matlib(), geometry.get() ) ) { center = c; bounding_radius = br; - new_tile -> addKid( geometry ); + new_tile -> addChild( geometry.get() ); } else { - delete geometry; SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: failed to generate ocean tile!" ); } } + + // now that we have a valid center, process all the objects + for (unsigned int j = 0; j < objects.size(); j++) { + const Object *obj = objects[j]; + + if (obj->type == OBJECT) { + SGPath custom_path = obj->path; + custom_path.append( obj->name ); + + osg::ref_ptr geometry = new osg::Group; + osg::ref_ptr vasi_lights = new osg::Group; + osg::ref_ptr rwy_lights = new osg::Group; + osg::ref_ptr taxi_lights = new osg::Group; + + if ( obj_load( custom_path.str(), + geometry.get(), vasi_lights.get(), rwy_lights.get(), + taxi_lights.get(), NULL, false ) ) { + + if ( geometry -> getNumChildren() > 0 ) { + new_tile -> addChild( geometry.get() ); + } + + if ( vasi_lights -> getNumChildren() > 0 ) + vasi_lights_transform -> addChild( vasi_lights.get() ); + + if ( rwy_lights -> getNumChildren() > 0 ) + rwy_lights_transform -> addChild( rwy_lights.get() ); + + if ( taxi_lights -> getNumChildren() > 0 ) + taxi_lights_transform -> addChild( taxi_lights.get() ); + } + + + } else if (obj->type == OBJECT_SHARED || obj->type == OBJECT_STATIC) { + // object loading is deferred to main render thread, + // but lets figure out the paths right now. + SGPath custom_path; + if ( obj->type == OBJECT_STATIC ) { + custom_path = obj->path; + } else { + custom_path = globals->get_fg_root(); + } + custom_path.append( obj->name ); + + osg::Matrix obj_pos; + WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); + + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setMatrix( obj_pos ); + + // wire as much of the scene graph together as we can + new_tile->addChild( obj_trans ); + pending_models++; + + // push an entry onto the model load queue + FGDeferredModel *dm + = new FGDeferredModel( custom_path.str(), + obj->path.str(), + tile_bucket, + this, obj_trans, + obj->type == OBJECT_SHARED ); + FGTileMgr::model_ready( dm ); + + + } else if (obj->type == OBJECT_SIGN || obj->type == OBJECT_RUNWAY_SIGN) { + // load the object itself + SGPath custom_path = obj->path; + custom_path.append( obj->name ); + + osg::Matrix obj_pos; + WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); + + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setMatrix( obj_pos ); + + osg::Node *custom_obj = 0; + if (obj->type == OBJECT_SIGN) + custom_obj = SGMakeSign(globals->get_matlib(), custom_path.str(), obj->name); + else + custom_obj = SGMakeRunwaySign(globals->get_matlib(), custom_path.str(), obj->name); + + // wire the pieces together + if ( custom_obj != NULL ) { + obj_trans -> addChild( custom_obj ); + } + new_tile->addChild( obj_trans ); + + } + delete obj; + } + + if ( new_tile != NULL ) { - terra_range->addKid( new_tile ); + terra_range->addChild( new_tile ); } - terra_transform->addKid( terra_range ); + terra_transform->addChild( terra_range.get() ); // calculate initial tile offset - sgdVec3 sgdTrans; - sgdSetVec3( sgdTrans, center.x(), center.y(), center.z() ); + SGVec3d sgdTrans(center.x(), center.y(), center.z()); terra_transform->setTransform( sgdTrans ); // Add ground lights to scene graph if any exist gnd_lights_transform = NULL; gnd_lights_range = NULL; - if ( light_pts->getNum() ) { + if ( light_pts->size() ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "generating lights" ); - gnd_lights_transform = new ssgPlacementTransform; - gnd_lights_range = new ssgRangeSelector; - gnd_lights_brightness = new ssgSelector; - ssgLeaf *lights; + gnd_lights_transform = new SGPlacementTransform; + gnd_lights_range = new osg::LOD; + gnd_lights_brightness = new osg::Switch; + osg::Node *lights; - lights = gen_lights( globals->get_matlib(), light_pts, 4, 0.7 ); - gnd_lights_brightness->addKid( lights ); + lights = gen_lights( globals->get_matlib(), light_pts.get(), 4, 0.7 ); + gnd_lights_brightness->addChild( lights ); - lights = gen_lights( globals->get_matlib(), light_pts, 2, 0.85 ); - gnd_lights_brightness->addKid( lights ); + lights = gen_lights( globals->get_matlib(), light_pts.get(), 2, 0.85 ); + gnd_lights_brightness->addChild( lights ); - lights = gen_lights( globals->get_matlib(), light_pts, 1, 1.0 ); - gnd_lights_brightness->addKid( lights ); + lights = gen_lights( globals->get_matlib(), light_pts.get(), 1, 1.0 ); + gnd_lights_brightness->addChild( lights ); - gnd_lights_range->addKid( gnd_lights_brightness ); - gnd_lights_transform->addKid( gnd_lights_range ); + gnd_lights_range->addChild( gnd_lights_brightness.get() ); + gnd_lights_transform->addChild( gnd_lights_range.get() ); gnd_lights_transform->setTransform( sgdTrans ); } // Update vasi lights transform - if ( vasi_lights_transform->getNumKids() > 0 ) { + if ( vasi_lights_transform->getNumChildren() > 0 ) { vasi_lights_transform->setTransform( sgdTrans ); } // Update runway lights transform - if ( rwy_lights_transform->getNumKids() > 0 ) { + if ( rwy_lights_transform->getNumChildren() > 0 ) { rwy_lights_transform->setTransform( sgdTrans ); } // Update taxi lights transform - if ( taxi_lights_transform->getNumKids() > 0 ) { + if ( taxi_lights_transform->getNumChildren() > 0 ) { taxi_lights_transform->setTransform( sgdTrans ); } } void -FGTileEntry::makeDList( ssgBranch *b ) -{ - int nb = b->getNumKids(); - for (int i = 0; igetKid(i); - if (e->isAKindOf(ssgTypeLeaf())) { - ((ssgLeaf*)e)->makeDList(); - } else if (e->isAKindOf(ssgTypeBranch())) { - makeDList( (ssgBranch*)e ); - } - } -} - -void -FGTileEntry::add_ssg_nodes( ssgBranch *terrain_branch, - ssgBranch *gnd_lights_branch, - ssgBranch *vasi_lights_branch, - ssgBranch *rwy_lights_branch, - ssgBranch *taxi_lights_branch ) +FGTileEntry::add_ssg_nodes( osg::Group *terrain_branch, + osg::Group *gnd_lights_branch, + osg::Group *vasi_lights_branch, + osg::Group *rwy_lights_branch, + osg::Group *taxi_lights_branch ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. -#if PLIB_VERSION > 183 - if ( fgGetBool( "/sim/rendering/use-display-list", true ) ) { - makeDList( terra_transform ); - } -#endif - - terra_transform->ref(); - terrain_branch->addKid( terra_transform ); - globals->get_scenery()->register_placement_transform(terra_transform); + terrain_branch->addChild( terra_transform.get() ); + globals->get_scenery()->register_placement_transform(terra_transform.get()); SG_LOG( SG_TERRAIN, SG_DEBUG, "connected a tile into scene graph. terra_transform = " - << terra_transform ); + << terra_transform.get() ); SG_LOG( SG_TERRAIN, SG_DEBUG, "num parents now = " << terra_transform->getNumParents() ); - if ( gnd_lights_transform != NULL ) { + if ( gnd_lights_transform.get() != NULL ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. - gnd_lights_transform->ref(); - gnd_lights_branch->addKid( gnd_lights_transform ); - globals->get_scenery()->register_placement_transform(gnd_lights_transform); + gnd_lights_branch->addChild( gnd_lights_transform.get() ); + globals->get_scenery()->register_placement_transform(gnd_lights_transform.get()); } - if ( vasi_lights_transform != NULL ) { + if ( vasi_lights_transform.get() != NULL ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. - vasi_lights_selector->ref(); - vasi_lights_selector->addKid( vasi_lights_transform ); - globals->get_scenery()->register_placement_transform(vasi_lights_transform); - vasi_lights_branch->addKid( vasi_lights_selector ); + vasi_lights_selector->addChild( vasi_lights_transform.get() ); + globals->get_scenery()->register_placement_transform(vasi_lights_transform.get()); + vasi_lights_branch->addChild( vasi_lights_selector.get() ); } - if ( rwy_lights_transform != NULL ) { + if ( rwy_lights_transform.get() != NULL ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. - rwy_lights_selector->ref(); - rwy_lights_selector->addKid( rwy_lights_transform ); - globals->get_scenery()->register_placement_transform(rwy_lights_transform); - rwy_lights_branch->addKid( rwy_lights_selector ); + rwy_lights_selector->addChild( rwy_lights_transform.get() ); + globals->get_scenery()->register_placement_transform(rwy_lights_transform.get()); + rwy_lights_branch->addChild( rwy_lights_selector.get() ); } - if ( taxi_lights_transform != NULL ) { + if ( taxi_lights_transform.get() != NULL ) { // bump up the ref count so we can remove this later without // having ssg try to free the memory. - taxi_lights_selector->ref(); - taxi_lights_selector->addKid( taxi_lights_transform ); - globals->get_scenery()->register_placement_transform(taxi_lights_transform); - taxi_lights_branch->addKid( taxi_lights_selector ); + taxi_lights_selector->addChild( taxi_lights_transform.get() ); + globals->get_scenery()->register_placement_transform(taxi_lights_transform.get()); + taxi_lights_branch->addChild( taxi_lights_selector.get() ); } loaded = true; @@ -1066,21 +794,21 @@ FGTileEntry::disconnect_ssg_nodes() if ( ! loaded ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a not-fully loaded tile!" ); } else { - SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile! terra_transform = " << terra_transform ); + SG_LOG( SG_TERRAIN, SG_DEBUG, "removing a fully loaded tile! terra_transform = " << terra_transform.get() ); } // Unregister that one at the scenery manager - globals->get_scenery()->unregister_placement_transform(terra_transform); + globals->get_scenery()->unregister_placement_transform(terra_transform.get()); // find the terrain branch parent int pcount = terra_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) - ssgBranch *parent = terra_transform->getParent( 0 ) ; + osg::Group *parent = terra_transform->getParent( 0 ) ; if( parent ) { // disconnect the tile (we previously ref()'d it so it // won't get freed now) - parent->removeKid( terra_transform ); + parent->removeChild( terra_transform.get() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "parent pointer is NULL! Dying" ); @@ -1093,17 +821,17 @@ FGTileEntry::disconnect_ssg_nodes() } // find the ground lighting branch - if ( gnd_lights_transform ) { + if ( gnd_lights_transform.get() ) { // Unregister that one at the scenery manager - globals->get_scenery()->unregister_placement_transform(gnd_lights_transform); + globals->get_scenery()->unregister_placement_transform(gnd_lights_transform.get()); pcount = gnd_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) - ssgBranch *parent = gnd_lights_transform->getParent( 0 ) ; + osg::Group *parent = gnd_lights_transform->getParent( 0 ) ; if( parent ) { // disconnect the light branch (we previously ref()'d // it so it won't get freed now) - parent->removeKid( gnd_lights_transform ); + parent->removeChild( gnd_lights_transform.get() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "parent pointer is NULL! Dying" ); @@ -1117,17 +845,17 @@ FGTileEntry::disconnect_ssg_nodes() } // find the vasi lighting branch - if ( vasi_lights_transform ) { + if ( vasi_lights_transform.get() ) { // Unregister that one at the scenery manager - globals->get_scenery()->unregister_placement_transform(vasi_lights_transform); + globals->get_scenery()->unregister_placement_transform(vasi_lights_transform.get()); pcount = vasi_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) - ssgBranch *parent = vasi_lights_transform->getParent( 0 ) ; + osg::Group *parent = vasi_lights_transform->getParent( 0 ) ; if( parent ) { // disconnect the light branch (we previously ref()'d // it so it won't get freed now) - parent->removeKid( vasi_lights_transform ); + parent->removeChild( vasi_lights_transform.get() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "parent pointer is NULL! Dying" ); @@ -1141,17 +869,17 @@ FGTileEntry::disconnect_ssg_nodes() } // find the runway lighting branch - if ( rwy_lights_transform ) { + if ( rwy_lights_transform.get() ) { // Unregister that one at the scenery manager - globals->get_scenery()->unregister_placement_transform(rwy_lights_transform); + globals->get_scenery()->unregister_placement_transform(rwy_lights_transform.get()); pcount = rwy_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) - ssgBranch *parent = rwy_lights_transform->getParent( 0 ) ; + osg::Group *parent = rwy_lights_transform->getParent( 0 ) ; if( parent ) { // disconnect the light branch (we previously ref()'d // it so it won't get freed now) - parent->removeKid( rwy_lights_transform ); + parent->removeChild( rwy_lights_transform.get() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "parent pointer is NULL! Dying" ); @@ -1165,17 +893,17 @@ FGTileEntry::disconnect_ssg_nodes() } // find the taxi lighting branch - if ( taxi_lights_transform ) { + if ( taxi_lights_transform.get() ) { // Unregister that one at the scenery manager - globals->get_scenery()->unregister_placement_transform(taxi_lights_transform); + globals->get_scenery()->unregister_placement_transform(taxi_lights_transform.get()); pcount = taxi_lights_transform->getNumParents(); if ( pcount > 0 ) { // find the first parent (should only be one) - ssgBranch *parent = taxi_lights_transform->getParent( 0 ) ; + osg::Group *parent = taxi_lights_transform->getParent( 0 ) ; if( parent ) { // disconnect the light branch (we previously ref()'d // it so it won't get freed now) - parent->removeKid( taxi_lights_transform ); + parent->removeChild( taxi_lights_transform.get() ); } else { SG_LOG( SG_TERRAIN, SG_ALERT, "parent pointer is NULL! Dying" );