-void FGTileEntry::prep_ssg_node( const Point3D& p, float vis) {
- if ( !loaded ) return;
-
- SetOffset( p );
-
-// #define USE_UP_AND_COMING_PLIB_FEATURE
-#ifdef USE_UP_AND_COMING_PLIB_FEATURE
- terra_range->setRange( 0, SG_ZERO );
- terra_range->setRange( 1, vis + bounding_radius );
- lights_range->setRange( 0, SG_ZERO );
- lights_range->setRange( 1, vis * 1.5 + bounding_radius );
-#else
- float ranges[2];
- ranges[0] = SG_ZERO;
- ranges[1] = vis + bounding_radius;
- terra_range->setRanges( ranges, 2 );
- if ( lights_range ) {
- ranges[1] = vis * 1.5 + bounding_radius;
- lights_range->setRanges( ranges, 2 );
- }
-#endif
- sgVec3 sgTrans;
- sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
- terra_transform->setTransform( sgTrans );
-
- if ( 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 up;
- sgCopyVec3( up, globals->get_current_view()->get_world_up() );
-
- double agl;
- if ( current_aircraft.fdm_state ) {
- agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
- - scenery.cur_elev;
- } else {
- agl = 0.0;
- }
-
- // 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 );
-
- if ( general.get_glDepthBits() > 16 ) {
- sgScaleVec3( up, 10.0 + agl / 100.0 + dist / 10000 );
- } else {
- sgScaleVec3( up, 10.0 + agl / 20.0 + dist / 5000 );
- }
- sgAddVec3( sgTrans, up );
- lights_transform->setTransform( sgTrans );
-
- // select which set of lights based on sun angle
- float sun_angle = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
- if ( sun_angle > 95 ) {
- lights_brightness->select(0x04);
- } else if ( sun_angle > 92 ) {
- lights_brightness->select(0x02);
- } else if ( sun_angle > 89 ) {
- lights_brightness->select(0x01);
- } else {
- lights_brightness->select(0x00);
- }
- }
-
- // ADA
- // Transform & Render runway lights - 23 Mar 2001
- sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
- if ( lightmaps_transform ) {
- static unsigned int selectnode = 0;
- // Run-time extension check.
- if (!glutExtensionSupported("GL_EXT_point_parameters")) {
- //use lightmaps on billboarded polygons
- } else {
- // using GL_EXT_point_parameters
-
- // This part is same as ground-lights code above by Curt
- sgVec3 up1;
- sgCopyVec3( up1, globals->get_current_view()->get_world_up() );
-
- double agl1;
- if ( current_aircraft.fdm_state ) {
- agl1 = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
- - scenery.cur_elev;
- } else {
- agl1 = 0.0;
- }
-
- // 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 to1;
- sgCopyVec3( to1, sgTrans );
- double dist1 = sgLengthVec3( to1 );
-
- if ( general.get_glDepthBits() > 16 ) {
- sgScaleVec3( up1, 0.0 + agl1 / 2000.0 + dist1 / 10000 );
- } else {
- sgScaleVec3( up1, 0.0 + agl1 / 20.0 + dist1 / 5000 );
- }
- sgAddVec3( sgTrans, up1 );
- lightmaps_transform->setTransform( sgTrans );
-
- float sun_angle1 = cur_light_params.sun_angle * SGD_RADIANS_TO_DEGREES;
- if ( (sun_angle1 > 89) ) {
- lightmaps_brightness->select(0x01);
- selectnode *=2;
- selectnode = selectnode | 0x000001;
- if (selectnode > 0xFFFFFF) selectnode = 1;
- lightmaps_sequence->select(selectnode);
- } else {
- lightmaps_brightness->select(0x00);
- lightmaps_sequence->select(0x000000);
- }
- } // end of GL_EXT_point_parameters section
-
- } // end of runway lights section
- // ADA
-
-}
-
-
-ssgLeaf* FGTileEntry::gen_lights( ssgVertexArray *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;
-
- // Allocate ssg structure
- ssgVertexArray *vl = new ssgVertexArray( size + 1 );
- ssgNormalArray *nl = NULL;
- ssgTexCoordArray *tl = NULL;
- ssgColourArray *cl = new ssgColourArray( size + 1 );
-
- sgVec4 color;
- for ( int i = 0; i < lights->getNum(); ++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) );
-
- // factor = sg_random() ^ 2, range = 0 .. 1 concentrated towards 0
- float factor = sg_random();
- factor *= factor;
-
- if ( zombie > 0.5 ) {
- // 50% chance of yellowish
- sgSetVec4( color, 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 );
- } else if ( zombie > 0.05 ) {
- // 10% chance of orangish
- sgSetVec4( color, 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 );
- }
- cl->add( color );
- }
- }
-
- // create ssg leaf
- ssgLeaf *leaf =
- new ssgVtxTable ( GL_POINTS, vl, nl, tl, cl );
-
- // assign state
- FGNewMat *newmat = material_lib.find( "LIGHTS" );
- leaf->setState( newmat->get_state() );
-
- return leaf;
-}
-
-
-ssgBranch*
-FGTileEntry::obj_load( const std::string& path,
- ssgVertexArray* lights, bool is_base )
-{
- ssgBranch* result = 0;
-
- // try loading binary format
- result = fgBinObjLoad( path, this, lights, is_base );
- if ( result == NULL ) {
- // next try the older ascii format
- result = fgAsciiObjLoad( path, this, lights, is_base );
- if ( result == NULL ) {
- // default to an ocean tile
- result = fgGenTile( path, this );
- }
- }
-
- return result;
-}
-
-
-void
-FGTileEntry::load( const SGPath& base, bool is_base )
-{
- cout << "load() base = " << base.str() << endl;
-
- // Generate names for later use
- string index_str = tile_bucket.gen_index_str();
-
- SGPath tile_path = base;
- 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() );
-
-#define FG_MAX_LIGHTS 1000
-
- // obj_load() will generate ground lighting for us ...
- ssgVertexArray *light_pts = new ssgVertexArray( 100 );
-
- // ADA
- ssgVertexArray *lights_rway = new ssgVertexArray( 100 );
- ssgVertexArray *lights_dir = new ssgVertexArray( 100 );
- ssgVertexArray *lights_normal = new ssgVertexArray( 100 );
- int lights_type[FG_MAX_LIGHTS];
- // ADA
-
- ssgBranch* new_tile = new ssgBranch;
-
- // 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() ) {
- string token, name;
-
- while ( ! in.eof() ) {
- in >> token;
-
- if ( token == "OBJECT_BASE" ) {
- in >> name >> ::skipws;
- SG_LOG( SG_TERRAIN, SG_INFO, "token = " << token
- << " name = " << name );
-
- SGPath custom_path = tile_path;
- custom_path.append( name );
-
- ssgBranch *custom_obj
- = obj_load( custom_path.str(), light_pts, true );
-
- if ( custom_obj != NULL ) {
- new_tile -> addKid( custom_obj );
- }
- } else if ( token == "OBJECT" ) {
- in >> name >> ::skipws;
- SG_LOG( SG_TERRAIN, SG_DEBUG, "token = " << token
- << " name = " << name );
-
- SGPath custom_path = tile_path;
- custom_path.append( name );
- ssgBranch *custom_obj
- = obj_load( custom_path.str(), NULL, false );
- if ( custom_obj != NULL ) {
- new_tile -> addKid( custom_obj );
- }
- } else if ( token == "OBJECT_STATIC" ) {
- // 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 = 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 );
-
- // 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(),
- this, obj_trans );
- FGTileMgr::model_ready( dm );
- } 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
- = gen_taxi_sign( custom_path.str(), name );
-
- // wire the pieces together
- if ( custom_obj != NULL ) {
- obj_trans -> addKid( custom_obj );
- }
- new_tile->addKid( obj_trans );
- } 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
- = gen_runway_sign( custom_path.str(), name );
-
- // wire the pieces together
- if ( custom_obj != NULL ) {
- obj_trans -> addKid( custom_obj );
- }
- new_tile->addKid( obj_trans );
- } 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_ALERT,
- "Unknown token " << token << " in "
- << stg_name.str() );
- in >> ::skipws;
- }
- }
- } else {
- // no .stg file so this must be old scenery
-
- new_tile = obj_load( basename.str(), light_pts, true );
-
- // load custom objects
- SG_LOG( SG_TERRAIN, SG_DEBUG, "Checking for custom objects ..." );
-
- SGPath index_path = tile_path;
- index_path.append( index_str );
- index_path.concat( ".ind" );
-
- SG_LOG( SG_TERRAIN, SG_DEBUG, "Looking in " << index_path.str() );
-
- sg_gzifstream in( index_path.str() );
-
- if ( in.is_open() ) {
- string token, name;
-
- while ( ! in.eof() ) {
- in >> token;
-
- if ( token == "OBJECT" ) {
- in >> name >> ::skipws;
- SG_LOG( SG_TERRAIN, SG_DEBUG, "token = " << token
- << " name = " << name );
-
- SGPath custom_path = tile_path;
- custom_path.append( name );
- ssgBranch *custom_obj
- = obj_load( custom_path.str(), NULL, false );
- if ( (new_tile != NULL) && (custom_obj != NULL) ) {
- new_tile -> addKid( custom_obj );
- }
- } else if ( token == "OBJECT_STATIC" ) {
- // 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 = 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 );
-
- // 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(),
- this, obj_trans );
- FGTileMgr::model_ready( dm );
- } 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
- = gen_taxi_sign( custom_path.str(), name );
-
- // wire the pieces together
- if ( (new_tile != NULL) && (custom_obj != NULL) ) {
- obj_trans -> addKid( custom_obj );
- }
- new_tile->addKid( obj_trans );
- } 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
- = gen_runway_sign( custom_path.str(), name );
-
- // wire the pieces together
- if ( (new_tile != NULL) && (custom_obj != NULL) ) {
- obj_trans -> addKid( custom_obj );
- }
- new_tile->addKid( obj_trans );
- } else {
- SG_LOG( SG_TERRAIN, SG_ALERT,
- "Unknown token " << token << " in "
- << index_path.str() );
- in >> ::skipws;
- }
- }
- }
- }
-
- if ( new_tile != NULL ) {
- terra_range->addKid( new_tile );
- }
-
- terra_transform->addKid( terra_range );
-
- // calculate initial tile offset
- SetOffset( scenery.center );
- sgCoord sgcoord;
- sgSetCoord( &sgcoord,
- offset.x(), offset.y(), offset.z(),
- 0.0, 0.0, 0.0 );
- terra_transform->setTransform( &sgcoord );
- // terrain->addKid( terra_transform );
-
- lights_transform = NULL;
- lights_range = NULL;
- /* uncomment this section for testing ground lights */
- if ( light_pts->getNum() ) {
- SG_LOG( SG_TERRAIN, SG_DEBUG, "generating lights" );
- lights_transform = new ssgTransform;
- lights_range = new ssgRangeSelector;
- lights_brightness = new ssgSelector;
- ssgLeaf *lights;
-
- lights = gen_lights( light_pts, 4, 0.7 );
- lights_brightness->addKid( lights );
-
- lights = gen_lights( light_pts, 2, 0.85 );
- lights_brightness->addKid( lights );
-
- lights = gen_lights( light_pts, 1, 1.0 );
- lights_brightness->addKid( lights );
-
- lights_range->addKid( lights_brightness );
- lights_transform->addKid( lights_range );
- lights_transform->setTransform( &sgcoord );
- // ground->addKid( lights_transform );
- }
- /* end of ground light section */
-
- // ADA
- // Create runway lights - 23 Mar 2001
- lightmaps_transform = NULL;
- lightmaps_sequence = NULL;
- ols_transform = NULL;
- // lightmaps_range = NULL;
-
- if ( lights_rway->getNum() ) {
- SG_LOG( SG_TERRAIN, SG_DEBUG, "generating airport lights" );
- lightmaps_transform = new ssgTransform;
- // lightmaps_range = new ssgRangeSelector;
- lightmaps_brightness = new ssgSelector;
- lightmaps_sequence = new ssgSelector;
- ols_transform = new ssgTransform;
- ssgBranch *lightmaps_branch;
-
- // call function to generate the runway lights
- lightmaps_branch = gen_runway_lights( lights_rway,
- lights_normal, lights_dir, lights_type);
- lightmaps_brightness->addKid( lightmaps_branch );
-
- // build the runway lights' scene
- // lightmaps_range->addKid( lightmaps_brightness ); //dont know why this doesnt work !!
- // lightmaps_transform->addKid( lightmaps_range ); //dont know why this doesnt work !!
- lightmaps_transform->addKid( lightmaps_brightness );
- lightmaps_sequence->setTraversalMaskBits( SSGTRAV_HOT );
- lightmaps_transform->addKid( lightmaps_sequence );
- lightmaps_transform->setTransform( &sgcoord );
- }
- // ADA