X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScenery%2Ftileentry.cxx;h=b87da6b1d6fbca5a418d3c5746004004f23cf905;hb=4a79d82ba62fa4e5be759fa0fc4b20220e8da303;hp=7845bd0325772897c3de8c9b744ce76399c373a7;hpb=ec5ea9f3449f9298d43ec7610c80f3b0a77f9e00;p=flightgear.git diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index 7845bd032..b87da6b1d 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -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,63 +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 ) { +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; } @@ -253,39 +214,39 @@ 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 ) { + 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 ) { + 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 ) { + 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 ) { + 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 ) { + if ( fgPartialFreeSSGtree( taxi_lights_selector.get(), delete_size ) == 0 ) { taxi_lights_selector = 0; free_tracker |= TAXI_LIGHTS; } @@ -309,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. @@ -329,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(); @@ -340,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); + gnd_lights_brightness->setSingleChildOn(0); } else { - gnd_lights_brightness->select(0x00); + gnd_lights_brightness->setAllChildrenOff(); } } - 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 ); - } 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 ); - 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 @@ -634,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 ) ) @@ -782,32 +562,29 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) // obj_load() will generate ground lighting for us ... - ssgVertexArray *light_pts = new ssgVertexArray( 100 ); - ssgBranch* new_tile = new ssgBranch; + osg::ref_ptr light_pts = new osg::Vec3Array; + osg::Group* new_tile = new osg::Group; if (found_tile_base) { // load tile if found ... - ssgSharedPtr geometry = new ssgBranch; - if ( obj_load( object_base.str(), geometry, - NULL, NULL, NULL, light_pts, true ) ) { - geometry->getKid( 0 )->setTravCallback(SSG_CALLBACK_PRETRAV, - &FGTileMgr::tile_filter_cb); - - new_tile -> addKid( geometry ); + 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"); - ssgSharedPtr geometry = new ssgBranch; + 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 { SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: failed to generate ocean tile!" ); @@ -823,30 +600,27 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) SGPath custom_path = obj->path; custom_path.append( obj->name ); - ssgSharedPtr geometry = new ssgBranch; - ssgSharedPtr vasi_lights = new ssgBranch; - ssgSharedPtr rwy_lights = new ssgBranch; - ssgSharedPtr taxi_lights = new ssgBranch; + 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, 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 ); + 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 -> getNumKids() > 0 ) - vasi_lights_transform -> addKid( vasi_lights ); + if ( vasi_lights -> getNumChildren() > 0 ) + vasi_lights_transform -> addChild( vasi_lights.get() ); - if ( rwy_lights -> getNumKids() > 0 ) - rwy_lights_transform -> addKid( rwy_lights ); + if ( rwy_lights -> getNumChildren() > 0 ) + rwy_lights_transform -> addChild( rwy_lights.get() ); - if ( taxi_lights -> getNumKids() > 0 ) - taxi_lights_transform -> addKid( taxi_lights ); + if ( taxi_lights -> getNumChildren() > 0 ) + taxi_lights_transform -> addChild( taxi_lights.get() ); } @@ -861,14 +635,14 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) } custom_path.append( obj->name ); - sgCoord obj_pos; - WorldCoordinate( &obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); + osg::Matrix obj_pos; + WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); - ssgTransform *obj_trans = new ssgTransform; - obj_trans->setTransform( &obj_pos ); + 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->addKid( obj_trans ); + new_tile->addChild( obj_trans ); pending_models++; // push an entry onto the model load queue @@ -882,27 +656,27 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) } else if (obj->type == OBJECT_SIGN || obj->type == OBJECT_RUNWAY_SIGN) { - ssgBranch *(*make_sign)(SGMaterialLib *, const string, const string); - make_sign = obj->type == OBJECT_SIGN ? sgMakeSign : sgMakeRunwaySign; - // load the object itself SGPath custom_path = obj->path; custom_path.append( obj->name ); - sgCoord obj_pos; - WorldCoordinate( &obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); + osg::Matrix obj_pos; + WorldCoordinate( obj_pos, center, obj->lat, obj->lon, obj->elev, obj->hdg ); - ssgTransform *obj_trans = new ssgTransform; - obj_trans->setTransform( &obj_pos ); + osg::MatrixTransform *obj_trans = new osg::MatrixTransform; + obj_trans->setMatrix( obj_pos ); - ssgBranch *custom_obj - = (*make_sign)(globals->get_matlib(), custom_path.str(), obj->name); + 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 -> addKid( custom_obj ); + obj_trans -> addChild( custom_obj ); } - new_tile->addKid( obj_trans ); + new_tile->addChild( obj_trans ); } delete obj; @@ -910,125 +684,102 @@ FGTileEntry::load( const string_list &path_list, bool is_base ) 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 ); } - - delete light_pts; -} - -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 - - 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_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->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->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->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; @@ -1043,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" ); @@ -1070,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" ); @@ -1094,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" ); @@ -1118,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" ); @@ -1142,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" );