X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FEnvironment%2Ffgclouds.cxx;h=10f4887e53450b3e108e1d11ee597ce3147b078c;hb=cef9eb3d73e16efca914a353c0c1e83e049ccb17;hp=5d172348d64dbc1a083d2b0da60c2152a2e7b013;hpb=084ba158b7b58a3f2470a04dd8261caecc0403a6;p=flightgear.git diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 5d172348d..10f4887e5 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -48,25 +48,27 @@ extern SGSky *thesky; FGClouds::FGClouds(FGEnvironmentCtrl * controller) : - station_elevation_ft(0.0), - _controller( controller ), - snd_lightning(NULL), - rebuild_required(true), + snd_lightning(0), + _controller(controller), + station_elevation_ft(0.0), + clouds_3d_enabled(false), last_scenario( "unset" ), - last_env_config( new SGPropertyNode() ), - last_env_clouds( new SGPropertyNode() ) + last_env_config( new SGPropertyNode ), + last_env_clouds( new SGPropertyNode ) { update_event = 0; } + FGClouds::~FGClouds() { } int FGClouds::get_update_event(void) const { return update_event; } + void FGClouds::set_update_event(int count) { update_event = count; - build(); + buildCloudLayers(); } void FGClouds::init(void) { @@ -78,8 +80,6 @@ void FGClouds::init(void) { soundMgr->add( snd_lightning, "thunder" ); sgEnviro.set_soundMgr( soundMgr ); } - - rebuild_required = true; } void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer) { @@ -157,23 +157,22 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov int CloudVarietyCount = 0; double totalCount = 0.0; - if (! clouds_3d_enabled) return; - 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 || box_def_root == NULL) + // If we don't have the required properties, then render the cloud in 2D + if ((! clouds_3d_enabled) || coverage == 0.0 || + layer_def_root == NULL || cloud_def_root == NULL || box_def_root == NULL) + { + thesky->get_cloud_layer(iLayer)->set_enable3dClouds(false); return; - + } + + // If we can't find a definition for this cloud type, then render the cloud in 2D SGPropertyNode *layer_def=NULL; - layer_def = layer_def_root->getChild(name.c_str()); if( !layer_def ) { if( name[2] == '-' ) { @@ -181,9 +180,15 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov layer_def = layer_def_root->getChild(base_name.c_str()); } if( !layer_def ) - return; + { + thesky->get_cloud_layer(iLayer)->set_enable3dClouds(false); + return; + } } + // At this point, we know we've got some 3D clouds to generate. + thesky->get_cloud_layer(iLayer)->set_enable3dClouds(true); + 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); @@ -217,30 +222,38 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov 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 = grid_z_rand * (sg_random() - 0.5); - double choice = sg_random(); - - for(int i = 0; i < CloudVarietyCount ; i ++) { - choice -= tCloudVariety[i].count * totalCount; - if( choice <= 0.0 ) { - sgVec3 pos={x,z,y}; - buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, pos, layer); - break; - } - } + + if (sg_random() < coverage) + { + double choice = sg_random(); + + for(int i = 0; i < CloudVarietyCount ; i ++) { + choice -= tCloudVariety[i].count * totalCount; + if( choice <= 0.0 ) { + sgVec3 pos={x,z,y}; + + buildCloud(cloud_def_root, + box_def_root, + tCloudVariety[i].name, + pos, + layer); + break; + } + } + } } } // Now we've built any clouds, enable them and set the density (coverage) - layer->setCoverage(coverage); - layer->applyCoverage(); + //layer->setCoverage(coverage); + //layer->applyCoverage(); thesky->get_cloud_layer(iLayer)->set_enable3dClouds(clouds_3d_enabled); } -// TODO:call this after real metar updates void FGClouds::buildCloudLayers(void) { SGPropertyNode *metar_root = fgGetNode("/environment", true); - - double wind_speed_kt = metar_root->getDoubleValue("wind-speed-kt"); + + //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"); double pressure_mb = metar_root->getDoubleValue("pressure-sea-level-inhg") * SG_INHG_TO_PA / 100.0; @@ -253,8 +266,6 @@ void FGClouds::buildCloudLayers(void) { double cumulus_base = 122.0 * (temperature_degc - dewpoint_degc); double stratus_base = 100.0 * (100.0 - rel_humidity) * SG_FEET_TO_METER; - bool cu_seen = false; - for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) { SGPropertyNode *cloud_root = fgGetNode("/environment/clouds/layer", iLayer, true); @@ -282,7 +293,7 @@ void FGClouds::buildCloudLayers(void) { } else if( alt_ft > 6500 ) { // layer_type = "as|ac|ns"; layer_type = "ac"; - if( pressure_mb < 1005.0 && coverage_norm >= 5.5 ) + if( pressure_mb < 1005.0 && coverage_norm >= 0.5 ) layer_type = "ns"; } else { // layer_type = "st|cu|cb|sc"; @@ -294,7 +305,7 @@ void FGClouds::buildCloudLayers(void) { layer_type = "st"; } else { // above formulae is far from perfect - if ( alt_ft < 2000 ) + if ( alt_ft < 2000 ) layer_type = "st"; else if( alt_ft < 4500 ) layer_type = "cu"; @@ -302,7 +313,7 @@ void FGClouds::buildCloudLayers(void) { layer_type = "sc"; } } - + buildLayer(iLayer, layer_type, alt_m, coverage_norm); } } @@ -312,9 +323,6 @@ void FGClouds::update_metar_properties( const FGMetar *m ) { int i; - int j; - double d; - char s[128]; fgSetString("/environment/metar/station-id", m->getId()); fgSetDouble("/environment/metar/min-visibility-m", @@ -322,17 +330,15 @@ FGClouds::update_metar_properties( const FGMetar *m ) fgSetDouble("/environment/metar/max-visibility-m", m->getMaxVisibility().getVisibility_m() ); + SGPropertyNode *metar = fgGetNode("/environment/metar", true); const SGMetarVisibility *dirvis = m->getDirVisibility(); - for (i = 0; i < 8; i++, dirvis++) { - const char *min = "/environment/metar/visibility[%d]/min-m"; - const char *max = "/environment/metar/visibility[%d]/max-m"; - d = dirvis->getVisibility_m(); + for (i = 0; i < 8; i++, dirvis++) { + SGPropertyNode *vis = metar->getChild("visibility", i, true); + double v = dirvis->getVisibility_m(); - snprintf(s, 128, min, i); - fgSetDouble(s, d); - snprintf(s, 128, max, i); - fgSetDouble(s, d); + vis->setDoubleValue("min-m", v); + vis->setDoubleValue("max-m", v); } fgSetInt("/environment/metar/base-wind-range-from", @@ -353,57 +359,41 @@ FGClouds::update_metar_properties( const FGMetar *m ) m->getPressure_inHg() ); vector cv = m->getClouds(); - vector::const_iterator cloud; + vector::const_iterator cloud, cloud_end = cv.end(); // Load into both the METAR and environment properties to stop interpolation - const char *cl[] = {"/environment/metar/clouds/layer[%i]", - "/environment/clouds/layer[%i]"}; - - for (j = 0; j < 2; j++) - { - for (i = 0, cloud = cv.begin(); cloud != cv.end(); cloud++, i++) { - const char *coverage_string[5] = - { "clear", "few", "scattered", "broken", "overcast" }; - const double thickness[5] = { 0, 65, 600,750, 1000}; - int q; - - snprintf(s, 128, cl[j], i); - strncat(s, "/coverage", 128); - q = cloud->getCoverage(); - fgSetString(s, coverage_string[q] ); - - snprintf(s, 128, cl[j], i); - strncat(s, "/elevation-ft", 128); - fgSetDouble(s, cloud->getAltitude_ft() + station_elevation_ft); - - snprintf(s, 128, cl[j], i); - strncat(s, "/thickness-ft", 128); - fgSetDouble(s, thickness[q]); - - snprintf(s, 128, cl[j], i); - strncat(s, "/span-m", 128); - fgSetDouble(s, 40000.0); - } - - for (; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) { - - - snprintf(s, 128, cl[j], i); - strncat(s, "/coverage", 128); - fgSetString(s, "clear"); - - snprintf(s, 128, cl[j], i); - strncat(s, "/elevation-ft", 128); - fgSetDouble(s, -9999); - - snprintf(s, 128, cl[j], i); - strncat(s, "/thickness-ft", 128); - fgSetDouble(s, 0); - - snprintf(s, 128, cl[j], i); - strncat(s, "/span-m", 128); - fgSetDouble(s, 40000.0); + SGPropertyNode *metar_clouds = fgGetNode("/environment/metar/clouds", true); + SGPropertyNode *clouds = fgGetNode("/environment/clouds", true); + + for (i = 0, cloud = cv.begin(); i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) { + const char *coverage_string[5] = { "clear", "few", "scattered", "broken", "overcast" }; + const double thickness_value[5] = { 0, 65, 600, 750, 1000 }; + + const char *coverage = "clear"; + double elevation = -9999.0; + double thickness = 0.0; + const double span = 40000.0; + + if (cloud != cloud_end) { + int c = cloud->getCoverage(); + coverage = coverage_string[c]; + elevation = cloud->getAltitude_ft() + station_elevation_ft; + thickness = thickness_value[c]; + ++cloud; } + + SGPropertyNode *layer; + layer = metar_clouds->getChild("layer", i, true); + layer->setStringValue("coverage", coverage); + layer->setDoubleValue("elevation-ft", elevation); + layer->setDoubleValue("thickness-ft", thickness); + layer->setDoubleValue("span-m", span); + + layer = clouds->getChild("layer", i, true); + layer->setStringValue("coverage", coverage); + layer->setDoubleValue("elevation-ft", elevation); + layer->setDoubleValue("thickness-ft", thickness); + layer->setDoubleValue("span-m", span); } fgSetDouble("/environment/metar/rain-norm", m->getRain()); @@ -432,7 +422,6 @@ FGClouds::update_env_config () fgGetDouble("/environment/metar/pressure-inhg") ); } - void FGClouds::setLayer( int iLayer, float alt_ft, const string& coverage, const string& layer_type ) { double coverage_norm = 0.0; if( coverage == "few" ) @@ -453,9 +442,9 @@ void FGClouds::buildScenario( const string& scenario ) { // fetch station elevation if exists if( station == "XXXX" ) - station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0); + station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0) * SG_METER_TO_FEET; else { - const FGAirport* a = globals->get_airports()->search( station ); + const FGAirport* a = FGAirport::findByIdent(station); station_elevation_ft = (a ? a->getElevation() : 0.0); } @@ -467,7 +456,7 @@ void FGClouds::buildScenario( const string& scenario ) { station += " 011000Z "; if( scenario == "Fair weather" ) { - fakeMetar = "15003KT 12SM SCT033 FEW200 20/08 Q1015 NOSIG"; + fakeMetar = "15003KT 12SM SCT041 FEW200 20/08 Q1015 NOSIG"; //setLayer(0, 3300.0, "scattered", "cu"); } else if( scenario == "Thunderstorm" ) { fakeMetar = "15012KT 08SM TSRA SCT040 BKN070 20/12 Q0995"; @@ -488,12 +477,12 @@ void FGClouds::buildScenario( const string& scenario ) { } } +void FGClouds::set_scenario(const char * sc) { -void FGClouds::build() { - string scenario = fgGetString("/environment/weather-scenario", "METAR"); - - if(!rebuild_required && (scenario == last_scenario)) - return; + scenario = string(sc); + +// if(!rebuild_required && (scenario == last_scenario)) +// return; if( last_scenario == "none" ) { // save clouds and weather conditions @@ -504,6 +493,8 @@ void FGClouds::build() { } if( scenario == "METAR" ) { + // needed here to compute station_elevation_ft + buildScenario( scenario ); string realMetar = fgGetString("/environment/metar/real-metar", ""); if( realMetar != "" ) { @@ -536,29 +527,21 @@ void FGClouds::build() { } last_scenario = scenario; - rebuild_required = false; if( snd_lightning == NULL ) init(); } +const char * FGClouds::get_scenario(void) const +{ + return scenario.c_str(); +} + void FGClouds::set_3dClouds(bool enable) { if (enable != clouds_3d_enabled) { clouds_3d_enabled = enable; - - for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) { - thesky->get_cloud_layer(iLayer)->set_enable3dClouds(enable); - - if (!enable) { - thesky->get_cloud_layer(iLayer)->get_layer3D()->clear(); - } - } - - if (enable) { - rebuild_required = true; - build(); - } + buildCloudLayers(); } }