]> git.mxchange.org Git - flightgear.git/commitdiff
Started laying out the infrastructure for handling lighting.
authorcurt <curt>
Mon, 4 Dec 2000 05:24:38 +0000 (05:24 +0000)
committercurt <curt>
Mon, 4 Dec 2000 05:24:38 +0000 (05:24 +0000)
Started experimenting with ground lighting.

src/Scenery/newcache.cxx
src/Scenery/tileentry.cxx
src/Scenery/tileentry.hxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

index e9b848f13f62120c49c820bd649904d192e3db9e..742e1a9ab03bae747b7ae49c4a3853173105ecd4 100644 (file)
 
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/debug/logstream.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/math/sg_random.h>
 #include <simgear/misc/fgstream.hxx>
 #include <simgear/misc/fgpath.hxx>
 
 #include <Main/globals.hxx>
+#include <Objects/matlib.hxx>
+#include <Objects/newmat.hxx>
 #include <Objects/obj.hxx>
 #include <Scenery/scenery.hxx>  // for scenery.center
 
 #include "newcache.hxx"
 #include "tileentry.hxx"
+#include "tilemgr.hxx"         // temp, need to delete later
 
 FG_USING_NAMESPACE(std);
 
 // a cheesy hack (to be fixed later)
 extern ssgBranch *terrain;
-extern ssgEntity *penguin;
+extern ssgBranch *ground;
 
 
 // the tile cache
@@ -128,6 +133,70 @@ static void print_refs( ssgSelector *sel, ssgTransform *trans,
 #endif
 
 
+static ssgLeaf *gen_lights( const FGBucket &b ) {
+
+    FGTileEntry *t = global_tile_cache.get_tile( b );
+    Point3D center = t->get_offset() + scenery.center;
+
+    double lon, lat, elev;
+    double w = b.get_width();
+    double h = b.get_height();
+
+    double area = b.get_width_m() * b.get_height_m();
+    int num = (int)(area / 1000000); // number of point lights to create
+    cout << "generating " << num << " lights" << endl;
+
+    if ( num <= 0 ) {
+       return NULL;
+    }
+
+    // Allocate ssg structure
+    ssgVertexArray   *vl = new ssgVertexArray( num );
+    ssgNormalArray   *nl = NULL;
+    ssgTexCoordArray *tl = NULL;
+    ssgColourArray   *cl = new ssgColourArray( 1 );
+
+    // default to white lights for now
+    sgVec4 color;
+    sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
+    cl->add( color );
+
+    for ( int i = 0; i < num; ++i ) {
+       lon = b.get_center_lon() - w * 0.5 + sg_random() * w;
+       lat = b.get_center_lat() - h * 0.5 + sg_random() * h;
+
+       Point3D geod = Point3D( lon * DEG_TO_RAD, lat * DEG_TO_RAD, 0.0);
+       Point3D tmp = sgGeodToCart( geod );
+       sgdVec3 cart;
+       sgdSetVec3( cart, tmp.x(), tmp.y(), tmp.z() );
+
+       if ( ! global_tile_mgr.current_elev_ssg( cart, &elev ) ) {
+           elev = 0.0;
+       }
+       // cout << " lon = " << lon << "  lat = " << lat << "  elev = " << elev 
+       //      << endl;
+
+       geod.setz( elev + 8.0 + sg_random() * 4);
+       tmp = sgGeodToCart( geod ) - center;
+       sgVec3 p;
+       sgSetVec3( p, tmp.x(), tmp.y(), tmp.z() );
+       // cout << " x = " << cart[0] << "  y = " << cart[1]
+       //      << "  z = " << cart[2] << endl;
+       vl->add( p );
+    }
+
+    // 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;
+}
+
+
 // Fill in a tile cache entry with real data for the specified bucket
 void FGNewCache::fill_in( const FGBucket& b ) {
     FG_LOG( FG_TERRAIN, FG_INFO, "FILL IN CACHE ENTRY = " << b.gen_index() );
@@ -151,9 +220,10 @@ void FGNewCache::fill_in( const FGBucket& b ) {
        exit(-1);
     }
 
-    e->select_ptr = new ssgSelector;
-    e->transform_ptr = new ssgTransform;
-    e->range_ptr = new ssgRangeSelector;
+    e->terra_transform = new ssgTransform;
+    e->terra_range = new ssgRangeSelector;
+    e->lights_transform = new ssgTransform;
+    e->lights_range = new ssgRangeSelector;
     e->tile_bucket = b;
 
     FGPath tile_path;
@@ -171,7 +241,7 @@ void FGNewCache::fill_in( const FGBucket& b ) {
     ssgBranch *new_tile = fgObjLoad( tile_base.str(), e, true );
 
     if ( new_tile != NULL ) {
-       e->range_ptr->addKid( new_tile );
+       e->terra_range->addKid( new_tile );
     }
   
     // load custom objects
@@ -207,7 +277,7 @@ void FGNewCache::fill_in( const FGBucket& b ) {
        }
     }
 
-    e->transform_ptr->addKid( e->range_ptr );
+    e->terra_transform->addKid( e->terra_range );
 
     // calculate initial tile offset
     e->SetOffset( scenery.center );
@@ -215,12 +285,19 @@ void FGNewCache::fill_in( const FGBucket& b ) {
     sgSetCoord( &sgcoord,
                e->offset.x(), e->offset.y(), e->offset.z(),
                0.0, 0.0, 0.0 );
-    e->transform_ptr->setTransform( &sgcoord );
-
-    e->select_ptr->addKid( e->transform_ptr );
-    terrain->addKid( e->select_ptr );
-
-    e->select_ptr->select(1);
+    e->terra_transform->setTransform( &sgcoord );
+    terrain->addKid( e->terra_transform );
+
+    e->lights_transform = NULL;
+    /* uncomment this section for testing ground lights
+    ssgLeaf *lights = gen_lights( b );
+    if ( lights ) {
+       e->lights_range->addKid( lights );
+       e->lights_transform->addKid( e->lights_range );
+       e->lights_transform->setTransform( &sgcoord );
+       ground->addKid( e->lights_transform );
+    }
+    */
 }
 
 
index 973b918d07f3ee33006a713af8bd8bb0fc8b7a3b..2765868d20f1bb7b0ee91f10d0c1664c7c9db468 100644 (file)
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/debug/logstream.hxx>
 
+#include <Aircraft/aircraft.hxx>
+#include <Main/globals.hxx>
+#include <Scenery/scenery.hxx>
+
 #include "tileentry.hxx"
 
 FG_USING_STD(for_each);
@@ -44,7 +48,6 @@ FGTileEntry::FGTileEntry ()
     : ncount(0)
 {
     nodes.clear();
-    select_ptr = NULL;
 }
 
 
@@ -112,16 +115,15 @@ void FGTileEntry::free_tile() {
     }
     index_ptrs.clear();
 
-    // delete the ssg branch
-
-    int pcount = select_ptr->getNumParents();
+    // delete the terrain branch
+    int pcount = terra_transform->getNumParents();
     if ( pcount > 0 ) {
        // find the first parent (should only be one)
-       ssgBranch *parent = select_ptr->getParent( 0 ) ;
+       ssgBranch *parent = terra_transform->getParent( 0 ) ;
        if( parent ) {
            // my_remove_branch( select_ptr );
-           parent->removeKid( select_ptr );
-           select_ptr = NULL;
+           parent->removeKid( terra_transform );
+           terra_transform = NULL;
        } else {
            FG_LOG( FG_TERRAIN, FG_ALERT,
                    "parent pointer is NULL!  Dying" );
@@ -132,12 +134,77 @@ void FGTileEntry::free_tile() {
                "Parent count is zero for an ssg tile!  Dying" );
        exit(-1);
     }
+
+    if ( lights_transform ) {
+       // delete the terrain lighting branch
+       pcount = lights_transform->getNumParents();
+       if ( pcount > 0 ) {
+           // find the first parent (should only be one)
+           ssgBranch *parent = lights_transform->getParent( 0 ) ;
+           if( parent ) {
+               parent->removeKid( lights_transform );
+               lights_transform = NULL;
+           } else {
+               FG_LOG( FG_TERRAIN, FG_ALERT,
+                       "parent pointer is NULL!  Dying" );
+               exit(-1);
+           }
+       } else {
+           FG_LOG( FG_TERRAIN, FG_ALERT,
+                   "Parent count is zero for an ssg light tile!  Dying" );
+           exit(-1);
+       }
+    }
 }
 
 
-// when a tile is still in the cache, but not in the immediate draw
-// list, it can still remain in the scene graph, but we use a range
-// selector to disable it from ever being drawn.
-void FGTileEntry::ssg_disable() {
-    select_ptr->select(0);
+// Update the ssg transform node for this tile so it can be
+// properly drawn relative to our (0,0,0) point
+void FGTileEntry::prep_ssg_node( const Point3D& p, float vis) {
+    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 + bounding_radius );
+#else
+    float ranges[2];
+    ranges[0] = SG_ZERO;
+    ranges[1] = vis + bounding_radius;
+    terra_range->setRanges( ranges, 2 );
+    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() * 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 );
+
+       sgScaleVec3( up, agl / 20.0 + dist / 10000 );
+       sgAddVec3( sgTrans, up );
+       lights_transform->setTransform( sgTrans );
+    }
 }
index 95048b07988362805ba48baecaf88c7dbad365cc..230b1ecdc3735a7491d089d46d4bc13edd8043ab 100644 (file)
@@ -93,7 +93,6 @@ public:
     // ssg tree structure for this tile is as follows:
     // ssgRoot(scene)
     //     - ssgBranch(terrain)
-    //      - ssgSelector(tile)
     //        - ssgTransform(tile)
     //           - ssgRangeSelector(tile)
     //              - ssgEntity(tile)
@@ -102,14 +101,13 @@ public:
     //                   ...
     //                 - kidn(fan)
 
-    // selector (turn tile on/off)
-    ssgSelector *select_ptr;
-
     // pointer to ssg transform for this tile
-    ssgTransform *transform_ptr;
+    ssgTransform *terra_transform;
+    ssgTransform *lights_transform;
 
     // pointer to ssg range selector for this tile
-    ssgRangeSelector *range_ptr;
+    ssgRangeSelector *terra_range;
+    ssgRangeSelector *lights_range;
 
 public:
 
@@ -134,28 +132,7 @@ public:
 
     // Update the ssg transform node for this tile so it can be
     // properly drawn relative to our (0,0,0) point
-    inline void prep_ssg_node( const Point3D& p, float vis) {
-        SetOffset( p );
-
-// #define USE_UP_AND_COMING_PLIB_FEATURE
-#ifdef USE_UP_AND_COMING_PLIB_FEATURE
-        range_ptr->setRange( 0, SG_ZERO );
-        range_ptr->setRange( 1, vis + bounding_radius );
-#else
-        float ranges[2];
-        ranges[0] = SG_ZERO;
-        ranges[1] = vis + bounding_radius;
-        range_ptr->setRanges( ranges, 2 );
-#endif
-        sgVec3 sgTrans;
-        sgSetVec3( sgTrans, offset.x(), offset.y(), offset.z() );
-        transform_ptr->setTransform( sgTrans );
-    }
-
-    // when a tile is still in the cache, but not in the immediate
-    // draw l ist, it can still remain in the scene graph, but we use
-    // a range selector to disable it from ever being drawn.
-    void ssg_disable();
+    void prep_ssg_node( const Point3D& p, float vis);
 };
 
 
index b9af69eb64ab7eea9dc198f0117ca0283dc9c021..1b45d3a466ef36c5a3c50a9ed8ff355d07a296a9 100644 (file)
@@ -30,7 +30,8 @@
 #endif
 
 #include <GL/glut.h>
-#include <simgear/xgl/xgl.h>
+
+#include <plib/ssg.h>
 
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
@@ -70,7 +71,8 @@ static inline Point3D operator + (const Point3D& a, const sgdVec3 b)
 
 // Constructor
 FGTileMgr::FGTileMgr():
-    state( Start )
+    state( Start ),
+    vis( 16000 )
 {
 }
 
@@ -113,11 +115,7 @@ void FGTileMgr::sched_tile( const FGBucket& b ) {
     // see if tile already exists in the cache
     FGTileEntry *t = global_tile_cache.get_tile( b );
 
-    if ( t != NULL ) {
-        // tile exists in cache, reenable it.
-        // cout << "REENABLING DISABLED TILE" << endl;
-        t->select_ptr->select( 1 );
-    } else {
+    if ( t == NULL ) {
         // register a load request
         load_queue.push_back( b );
     }
@@ -132,6 +130,8 @@ void FGTileMgr::load_tile( const FGBucket& b ) {
     if ( t == NULL ) {
        FG_LOG( FG_TERRAIN, FG_DEBUG, "Loading tile " << b );
        global_tile_cache.fill_in( b );
+       FGTileEntry *t = global_tile_cache.get_tile( b );
+       t->prep_ssg_node( scenery.center, vis);
     } else {
        FG_LOG( FG_TERRAIN, FG_DEBUG, "Tile already in cache " << b );
     }
@@ -153,11 +153,14 @@ static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) {
 // explicitely.  lat & lon are in radians.  view_pos in current world
 // coordinate translated near (0,0,0) (in meters.)  Returns result in
 // meters.
-bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, sgVec3 view_pos,
-                                 double *terrain_elev ) {
-    sgdVec3 orig, dir;
+bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev ) {
+    sgdVec3 view_pos;
+    sgdVec3 sc;
+    sgdSetVec3( sc, scenery.center.x(), scenery.center.y(), scenery.center.z());
+    sgdSubVec3( view_pos, abs_view_pos, sc );
 
-    sgdSetVec3(orig, view_pos );
+    sgdVec3 orig, dir;
+    sgdCopyVec3(orig, view_pos );
     sgdCopyVec3(dir, abs_view_pos );
 
     hit_list.Intersect( terrain, orig, dir );
@@ -201,8 +204,6 @@ bool FGTileMgr::current_elev_ssg( sgdVec3 abs_view_pos, sgVec3 view_pos,
 
 // schedule a needed buckets for loading
 void FGTileMgr::schedule_needed() {
-    double vis;
-
 #ifndef FG_OLD_WEATHER
     if ( WeatherDatabase != NULL ) {
        vis = WeatherDatabase->getWeatherVisibility();
@@ -214,31 +215,8 @@ void FGTileMgr::schedule_needed() {
 #endif
     cout << "visibility = " << vis << endl;
 
-    double clat = (int)current_bucket.get_center_lat();
-    if ( clat > 0 ) {
-       clat = (int)clat + 0.5;
-    } else {
-       clat = (int)clat - 0.5;
-    }
-    double clat_rad = clat * DEG_TO_RAD;
-    double cos_lat = cos( clat_rad );
-    double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
-    double local_perimeter = 2.0 * local_radius * FG_PI;
-    double degree_width = local_perimeter / 360.0;
-
-    // cout << "clat = " << clat << endl;
-    // cout << "clat (radians) = " << clat_rad << endl;
-    // cout << "cos(lat) = " << cos_lat << endl;
-    // cout << "local_radius = " << local_radius << endl;
-    // cout << "local_perimeter = " << local_perimeter << endl;
-    cout << "degree_width = " << degree_width << endl;
-
-    double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
-    double degree_height = perimeter / 360.0;
-    cout << "degree_height = " << degree_height << endl;
-
-    double tile_width = current_bucket.get_width() * degree_width;
-    double tile_height = current_bucket.get_height() * degree_height;
+    double tile_width = current_bucket.get_width_m();
+    double tile_height = current_bucket.get_height_m();
     cout << "tile width = " << tile_width << "  tile_height = " << tile_height
         << endl;
 
@@ -371,7 +349,7 @@ int FGTileMgr::update( double lon, double lat ) {
        prep_ssg_nodes();
        sgSetVec3( tmp_view_pos, 0.0, 0.0, 0.0 );
        double tmp_elev;
-       if ( current_elev_ssg(tmp_abs_view_pos, tmp_view_pos, &tmp_elev) ) {
+       if ( current_elev_ssg(tmp_abs_view_pos, &tmp_elev) ) {
            scenery.cur_elev = tmp_elev;
        } else {
            scenery.cur_elev = 0.0;
@@ -381,7 +359,6 @@ int FGTileMgr::update( double lon, double lat ) {
        //      << " view pos = " << current_view.view_pos << endl;
        double tmp_elev;
        if ( current_elev_ssg(globals->get_current_view()->get_abs_view_pos(),
-                             globals->get_current_view()->get_view_pos(),
                              &tmp_elev) )
        {
            scenery.cur_elev = tmp_elev;
@@ -418,13 +395,12 @@ void FGTileMgr::prep_ssg_nodes() {
     // selector and transform
 
     FGTileEntry *e;
-    Point3D p = scenery.center;
     global_tile_cache.reset_traversal();
 
     while ( ! global_tile_cache.at_end() ) {
         // cout << "processing a tile" << endl;
         if ( (e = global_tile_cache.get_current()) ) {
-           e->prep_ssg_node( p, vis);
+           e->prep_ssg_node( scenery.center, vis);
         } else {
             cout << "warning ... empty tile in cache" << endl;
         }
index b90c2df846ea944c8807e3c30c57b9f577f7285a..7be5fe52c583a155ce08db2f8fec2dd40c001b72 100644 (file)
@@ -102,6 +102,7 @@ private:
     FGTileEntry *current_tile;
        
     // x and y distance of tiles to load/draw
+    float vis;
     int xrange, yrange;
        
     // current longitude latitude
@@ -137,9 +138,7 @@ public:
                     const sgdVec3 p, const sgdVec3 dir,
                     FGHitList *list );
 
-    bool current_elev_ssg( sgdVec3 abs_view_pos, 
-                          sgVec3 view_pos,
-                          double *terrain_elev );
+    bool current_elev_ssg( sgdVec3 abs_view_pos, double *terrain_elev );
        
     // Prepare the ssg nodes ... for each tile, set it's proper
     // transform and update it's range selector based on current