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";
// Constructor
FGTileEntry::FGTileEntry ( void )
: ncount(0),
- state(Unused)
+ state(Unused),
+ vtlist(NULL),
+ vnlist(NULL),
+ tclist(NULL)
{
nodes.clear();
}
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
FG_LOG( FG_TERRAIN, FG_ALERT,
"Parent count is zero for an ssg tile! Dying" );
exit(-1);
- }
+ }
}
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:
}
+// 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;
fgFRAGMENT *frag_ptr;
FGMaterialSlot *mtl_ptr;
int i;
- int tile_diameter;
int index;
int culled = 0;
int drawn = 0;
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:
// 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
// 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();
}
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 );
};