]> git.mxchange.org Git - flightgear.git/commitdiff
3D clouds from Stuart Buchanan. Need a recent driver update, --enable-clouds3d option...
authorfredb <fredb>
Sun, 26 Oct 2008 09:38:21 +0000 (09:38 +0000)
committerfredb <fredb>
Sun, 26 Oct 2008 09:38:21 +0000 (09:38 +0000)
src/Environment/environment_mgr.cxx
src/Environment/fgclouds.cxx
src/Environment/fgclouds.hxx

index b24d8acb490a173e0044bcd5d943b756b3314cc3..243671932d4019e4cd03553443bbfdf101357980 100644 (file)
@@ -182,21 +182,12 @@ FGEnvironmentMgr::bind ()
          &FGEnvironmentMgr::set_cloud_layer_coverage);
     fgSetArchivable(buf);
   }
-  fgTie("/sim/rendering/clouds3d-enable", &sgEnviro,
-         &SGEnviro::get_clouds_enable_state,
-         &SGEnviro::set_clouds_enable_state);
-  fgTie("/sim/rendering/clouds3d-vis-range", &sgEnviro,
-         &SGEnviro::get_clouds_visibility,
-         &SGEnviro::set_clouds_visibility);
-  fgTie("/sim/rendering/clouds3d-density", &sgEnviro,
-         &SGEnviro::get_clouds_density,
-         &SGEnviro::set_clouds_density);
-  fgTie("/sim/rendering/clouds3d-cache-size", &sgEnviro,
-         &SGEnviro::get_clouds_CacheSize,
-         &SGEnviro::set_clouds_CacheSize);
-  fgTie("/sim/rendering/clouds3d-cache-resolution", &sgEnviro,
-         &SGEnviro::get_CacheResolution,
-         &SGEnviro::set_CacheResolution);
+  fgTie("/sim/rendering/clouds3d-enable", thesky,
+         &SGSky::get_3dClouds,
+         &SGSky::set_3dClouds);
+  fgTie("/sim/rendering/clouds3d-density", thesky,
+         &SGSky::get_3dCloudDensity,
+         &SGSky::set_3dCloudDensity);
   fgTie("/sim/rendering/precipitation-enable", &sgEnviro,
          &SGEnviro::get_precipitation_enable_state,
          &SGEnviro::set_precipitation_enable_state);
index 5129c08d8421d1c6347119cdf763cb36140b569b..2248ac9e1a3fe0f8772e023093e426839837430b 100644 (file)
@@ -80,55 +80,92 @@ void FGClouds::init(void) {
        }
 }
 
-SGNewCloud *FGClouds::buildCloud(SGPropertyNode *cloud_def_root, const string& name) {
-       SGPropertyNode *cld_def=NULL;
-
-       cld_def = cloud_def_root->getChild(name.c_str());
+void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode  *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer) {
+       SGPropertyNode *box_def=NULL;
+        SGPropertyNode *cld_def=NULL;
+        
+        SGPath texture_root = globals->get_fg_root();
+        texture_root.append("Textures");
+        texture_root.append("Sky");
+
+       box_def = box_def_root->getChild(name.c_str());
+  
        string base_name = name.substr(0,2);
-       if( !cld_def ) {
+       if( !box_def ) {
                if( name[2] == '-' ) {
-                       cld_def = cloud_def_root->getChild(base_name.c_str());
+                       box_def = box_def_root->getChild(base_name.c_str());
                }
-               if( !cld_def )
-                       return NULL;
+               if( !box_def )
+                       return;
        }
-       string familly = cld_def->getStringValue("familly", base_name.c_str());
-       SGNewCloud *cld = new SGNewCloud(familly);
-       for(int i = 0; i < cld_def->nChildren() ; i++) {
-               SGPropertyNode *abox = cld_def->getChild(i);
+        
+       for(int i = 0; i < box_def->nChildren() ; i++) {
+               SGPropertyNode *abox = box_def->getChild(i);
                if( strcmp(abox->getName(), "box") == 0) {
-                       double x = abox->getDoubleValue("x");
-                       double y = abox->getDoubleValue("y");
-                       double z = abox->getDoubleValue("z");
-                       double size = abox->getDoubleValue("size");
-                       int type = abox->getIntValue("type", SGNewCloud::CLbox_standard);
-                       cld->addContainer(x, y, z, size, (SGNewCloud::CLbox_type) type);
+                       double x = abox->getDoubleValue("x") + pos[0];
+                       double y = abox->getDoubleValue("y") + pos[1];
+                       double z = abox->getDoubleValue("z") + pos[2];
+                        SGVec3f newpos = SGVec3f(x, z, y);
+                        
+                        string type = abox->getStringValue("type", "cu-small");
+                               
+                        cld_def = cloud_def_root->getChild(type.c_str());
+                        if ( !cld_def ) return;
+                        
+                        double min_width = cld_def->getDoubleValue("min-cloud-width-m", 500.0);
+                        double max_width = cld_def->getDoubleValue("max-cloud-width-m", 1000.0);
+                        double min_height = cld_def->getDoubleValue("min-cloud-height-m", min_width);
+                        double max_height = cld_def->getDoubleValue("max-cloud-height-m", max_width);
+                        double min_sprite_width = cld_def->getDoubleValue("min-sprite-width-m", 200.0);
+                        double max_sprite_width = cld_def->getDoubleValue("max-sprite-width-m", min_sprite_width);
+                        double min_sprite_height = cld_def->getDoubleValue("min-sprite-height-m", min_sprite_width);
+                        double max_sprite_height = cld_def->getDoubleValue("max-sprite-height-m", max_sprite_width);
+                        int num_sprites = cld_def->getIntValue("num-sprites", 20);
+                        int num_textures_x = cld_def->getIntValue("num-textures-x", 1);
+                        int num_textures_y = cld_def->getIntValue("num-textures-y", 1);
+                        double bottom_shade = cld_def->getDoubleValue("bottom-shade", 1.0);
+                        string texture = cld_def->getStringValue("texture", "cl_cumulus.rgb");
+          
+                        SGNewCloud *cld = 
+                                new SGNewCloud(texture_root, 
+                                               texture, 
+                                               min_width, 
+                                               max_width, 
+                                               min_height,
+                                               max_height,
+                                               min_sprite_width,
+                                               max_sprite_width,
+                                               min_sprite_height,
+                                               max_sprite_height,
+                                               bottom_shade,
+                                               num_sprites,
+                                               num_textures_x,
+                                               num_textures_y);
+                        layer->addCloud(newpos, cld);
                }
        }
-       cld->genSprites();
-       return cld;
 }
 
-void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, double coverage) {
+void FGClouds::buildLayer(int iLayer, const string& name, double alt, double coverage) {
        struct {
                string name;
                double count;
        } tCloudVariety[20];
        int CloudVarietyCount = 0;
        double totalCount = 0.0;
-
+        
        SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false);
+       SGPropertyNode *box_def_root   = fgGetNode("/environment/cloudlayers/boxes", false);
        SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false);
+        SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D();
 
        layer->clear();
        // when we don't generate clouds the layer is rendered in 2D
        if( coverage == 0.0 )
                return;
-       if( layer_def_root == NULL || cloud_def_root == NULL)
-               return;
-       if( name == "ci" || name == "sc" || name == "st")
+       if( layer_def_root == NULL || cloud_def_root == NULL || box_def_root == NULL)
                return;
-
+       
        SGPropertyNode *layer_def=NULL;
 
        layer_def = layer_def_root->getChild(name.c_str());
@@ -140,7 +177,7 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
                if( !layer_def )
                        return;
        }
-
+        
        double grid_x_size = layer_def->getDoubleValue("grid-x-size", 1000.0);
        double grid_y_size = layer_def->getDoubleValue("grid-y-size", 1000.0);
        double grid_x_rand = layer_def->getDoubleValue("grid-x-rand", grid_x_size);
@@ -160,7 +197,7 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
                        do {
                                variety++;
                                snprintf(variety_name, sizeof(variety_name), cloud_name.c_str(), variety);
-                       } while( cloud_def_root->getChild(variety_name, 0, false) );
+                       } while( box_def_root->getChild(variety_name, 0, false) );
 
                        totalCount += count;
                        if( CloudVarietyCount < 20 )
@@ -172,8 +209,8 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
 
        for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) {
                for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) {
-                       double x = px + grid_x_rand * (sg_random() - 0.5);
-                       double y = py + grid_y_rand * (sg_random() - 0.5);
+                       double x = px + grid_x_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
+                       double y = py + grid_y_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
                        double z = alt + grid_z_rand * (sg_random() - 0.5);
                        double choice = sg_random();
                        currCoverage += coverage;
@@ -184,23 +221,23 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
                        for(int i = 0; i < CloudVarietyCount ; i ++) {
                                choice -= tCloudVariety[i].count * totalCount;
                                if( choice <= 0.0 ) {
-                                       SGNewCloud *cld = buildCloud(cloud_def_root, tCloudVariety[i].name);
                                        sgVec3 pos={x,z,y};
-                                       if( cld )
-                                               layer->addCloud(pos, cld);
 
+                                        buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, pos, layer);
                                        break;
                                }
                        }
                }
        }
 
+        // Now we've built any clouds, enable them
+        thesky->get_cloud_layer(iLayer)->set_enable3dClouds(thesky->get_3dClouds());
 }
 
 // TODO:call this after real metar updates
 void FGClouds::buildMETAR(void) {
        SGPropertyNode *metar_root = fgGetNode("/environment", true);
-
+        
        double wind_speed_kt     = metar_root->getDoubleValue("wind-speed-kt");
        double temperature_degc  = metar_root->getDoubleValue("temperature-sea-level-degc");
        double dewpoint_degc     = metar_root->getDoubleValue("dewpoint-sea-level-degc");
@@ -262,8 +299,7 @@ void FGClouds::buildMETAR(void) {
                        }
                }
 
-               SGCloudField *layer3D = thesky->get_cloud_layer(iLayer)->get_layer3D();
-               buildLayer(layer3D, layer_type, alt_m, coverage_norm);
+               buildLayer(iLayer, layer_type, alt_m, coverage_norm);
        }
 }
 
@@ -395,8 +431,7 @@ void FGClouds::setLayer( int iLayer, float alt_ft, const string& coverage, const
        else if( coverage == "overcast" )
                coverage_norm = 8.0/8.0;        // 8
 
-       SGCloudField *layer3D = thesky->get_cloud_layer(iLayer)->get_layer3D();
-       buildLayer(layer3D, layer_type, station_elevation_ft + alt_ft * SG_FEET_TO_METER, coverage_norm);
+       buildLayer(iLayer, layer_type, station_elevation_ft + alt_ft * SG_FEET_TO_METER, coverage_norm);
 }
 
 void FGClouds::buildScenario( const string& scenario ) {
index 71fc0ecbcd05ab93e314a326f47fc0fddf61055b..71e92b7aee753cc98d5ecf432ca284f671ae6b39 100644 (file)
@@ -42,8 +42,8 @@ class FGEnvironmentCtrl;
 class FGClouds {
 
 private:
-       SGNewCloud *buildCloud(SGPropertyNode *cloud_def_root, const string& name);
-       void buildLayer(SGCloudField *layer, const string& name, double alt, double coverage);
+void buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer);
+       void buildLayer(int iLayer, const string& name, double alt, double coverage);
 
        void buildMETAR(void);