diff --git a/src/Scenery/tilecache.cxx b/src/Scenery/tilecache.cxx index 188aa3e8d..c996087f2 100644 --- a/src/Scenery/tilecache.cxx +++ b/src/Scenery/tilecache.cxx @@ -137,10 +137,13 @@ FGTileCache::fill_in( int index, const FGBucket& p ) tile_cache[index].mark_loaded(); tile_cache[index].tile_bucket = p; - ssgBranch *new_tile = fgObjLoad( tile_path.str(), &tile_cache[index] ); tile_cache[index].branch_ptr = new ssgTransform; - tile_cache[index].branch_ptr->addKid( new_tile ); - // tile_cache[index].branch_ptr->addKid( penguin ); + tile_cache[index].range_ptr = new ssgRangeSelector; + ssgBranch *new_tile = fgObjLoad( tile_path.str(), &tile_cache[index] ); + if ( new_tile != NULL ) { + tile_cache[index].range_ptr->addKid( new_tile ); + } + tile_cache[index].branch_ptr->addKid( tile_cache[index].range_ptr ); terrain->addKid( tile_cache[index].branch_ptr ); // cout << " ncount before = " << tile_cache[index].ncount << "\n"; diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index 3c66667d5..1af8fb4c7 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -42,7 +42,10 @@ FG_USING_STD(mem_fun_ref); // Constructor FGTileEntry::FGTileEntry ( void ) : ncount(0), - state(Unused) + state(Unused), + vtlist(NULL), + vnlist(NULL), + tclist(NULL) { nodes.clear(); } @@ -73,9 +76,15 @@ FGTileEntry::free_tile() fragment_list.erase( begin(), end() ); // delete the ssg used structures - delete vtlist; - delete vnlist; - delete tclist; + if ( vtlist != NULL ) { + delete vtlist; + } + if ( vnlist != NULL ) { + delete vnlist; + } + if ( tclist != NULL ) { + delete tclist; + } // delete the ssg branch @@ -105,7 +114,7 @@ FGTileEntry::free_tile() FG_LOG( FG_TERRAIN, FG_ALERT, "Parent count is zero for an ssg tile! Dying" ); exit(-1); - } + } } diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 1a80f53c7..81f67b639 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -109,7 +109,21 @@ public: sgVec3 *vnlist; sgVec2 *tclist; - // pointer to ssg branch; + // ssg tree structure for this tile is as follows: + // ssgRoot(scene) + // - ssgBranch(terrain) + // - ssgTransform(tile) + // - ssgRangeSelector(tile) + // - ssgEntity(tile) + // - kid1(fan) + // - kid2(fan) + // ... + // - kidn(fan) + + // pointer to ssg range selector for this tile + ssgRangeSelector *range_ptr; + + // pointer to ssg transform for this tile ssgTransform *branch_ptr; public: diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 3b9b2854f..f303f8218 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -734,6 +734,42 @@ update_tile_geometry( FGTileEntry *t, GLdouble *MODEL_VIEW) } +// Prepare the ssg nodes ... for each tile, set it's proper +// transform and update it's range selector based on current +// visibilty +void FGTileMgr::prep_ssg_nodes( void ) { + FGTileEntry *t; + + int tile_diameter = current_options.get_tile_diameter(); + + float ranges[2]; + ranges[0] = 0.0f; + ranges[1] = current_weather.get_visibility(); + + // traverse the potentially viewable tile list and update range + // selector and transform + for ( int i = 0; i < (tile_diameter * tile_diameter); i++ ) { + int index = tiles[i]; + t = global_tile_cache.get_tile(index); + + if ( t->is_loaded() ) { + // set range selector (LOD trick) + t->range_ptr->setRanges( ranges, 2 ); + + // calculate tile offset + t->SetOffset( scenery.center ); + + // calculate ssg transform + sgCoord sgcoord; + sgSetCoord( &sgcoord, + t->offset.x(), t->offset.y(), t->offset.z(), + 0.0, 0.0, 0.0 ); + t->branch_ptr->setTransform( &sgcoord ); + } + } +} + + // Render the local tiles void FGTileMgr::render( void ) { FGInterface *f; @@ -744,7 +780,6 @@ void FGTileMgr::render( void ) { fgFRAGMENT *frag_ptr; FGMaterialSlot *mtl_ptr; int i; - int tile_diameter; int index; int culled = 0; int drawn = 0; @@ -753,7 +788,7 @@ void FGTileMgr::render( void ) { f = current_aircraft.fdm_state; v = ¤t_view; - tile_diameter = current_options.get_tile_diameter(); + int tile_diameter = current_options.get_tile_diameter(); // moved to fgTileMgrUpdate, right after we check if we need to // load additional tiles: @@ -775,13 +810,6 @@ void FGTileMgr::render( void ) { // calculate tile offset t->SetOffset( scenery.center ); - // calculate ssg transform - sgCoord sgcoord; - sgSetCoord( &sgcoord, - t->offset.x(), t->offset.y(), t->offset.z(), - 0.0, 0.0, 0.0 ); - t->branch_ptr->setTransform( &sgcoord ); - // Course (tile based) culling if ( viewable(t->offset, t->bounding_radius) ) { // at least a portion of this tile could be viewable @@ -854,6 +882,6 @@ void FGTileMgr::render( void ) { // traverse the transient per-material fragment lists and render // out all fragments for each material property. xglPushMatrix(); - // material_mgr.render_fragments(); + material_mgr.render_fragments(); xglPopMatrix(); } diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 7c1740e8b..0f7ee3815 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -108,6 +108,11 @@ public: double current_elev_new( const FGBucket& p ); double current_elev( double lon, double lat, const Point3D& abs_view_pos ); + // Prepare the ssg nodes ... for each tile, set it's proper + // transform and update it's range selector based on current + // visibilty + void prep_ssg_nodes( void ); + // Render the local tiles --- hack, hack, hack void render( void ); };