This provides the following enhancements & bug fixes
- Fix the chequer-board bug. - Add proper cloud coverage function - so scattered clouds are now truly scattered. - Add real-time control for visibility range. - Use a limited set of clouds rather than generating a completely new Geode for each cloud. This saves sorting and display time. - Add controls to Rendering dialog to allow fine-tuning of the number of sprites, cloud visibility and the number of different types of cloud. - Add some variance to the sort back-off to avoid all clouds being sorted at the same time. - Pack attributes into vectors for performance - Re-order the cloud type determination code so that if a cloud layer could either be stratus or cumulus, cumulus is used. - Lowered the cloud level in the standard cloud configuration slightly so a cumulus layer is generated rather than stratus. These last two mean that you should see some 3D cumuli if disabling real weather fetch. My thanks to Yon Uriarte for his help with performance work.
This commit is contained in:
parent
0cf9d58b76
commit
9721d7811f
2 changed files with 37 additions and 37 deletions
|
@ -188,6 +188,12 @@ FGEnvironmentMgr::bind ()
|
||||||
fgTie("/sim/rendering/clouds3d-density", thesky,
|
fgTie("/sim/rendering/clouds3d-density", thesky,
|
||||||
&SGSky::get_3dCloudDensity,
|
&SGSky::get_3dCloudDensity,
|
||||||
&SGSky::set_3dCloudDensity);
|
&SGSky::set_3dCloudDensity);
|
||||||
|
fgTie("/sim/rendering/clouds3d-vis-range", thesky,
|
||||||
|
&SGSky::get_3dCloudVisRange,
|
||||||
|
&SGSky::set_3dCloudVisRange);
|
||||||
|
fgTie("/sim/rendering/clouds3d-num-flavours", thesky,
|
||||||
|
&SGSky::get_3dCloudNumFlavours,
|
||||||
|
&SGSky::set_3dCloudNumFlavours);
|
||||||
fgTie("/sim/rendering/precipitation-enable", &sgEnviro,
|
fgTie("/sim/rendering/precipitation-enable", &sgEnviro,
|
||||||
&SGEnviro::get_precipitation_enable_state,
|
&SGEnviro::get_precipitation_enable_state,
|
||||||
&SGEnviro::set_precipitation_enable_state);
|
&SGEnviro::set_precipitation_enable_state);
|
||||||
|
@ -238,8 +244,7 @@ FGEnvironmentMgr::unbind ()
|
||||||
fgUntie("/sim/rendering/clouds3d-enable");
|
fgUntie("/sim/rendering/clouds3d-enable");
|
||||||
fgUntie("/sim/rendering/clouds3d-vis-range");
|
fgUntie("/sim/rendering/clouds3d-vis-range");
|
||||||
fgUntie("/sim/rendering/clouds3d-density");
|
fgUntie("/sim/rendering/clouds3d-density");
|
||||||
fgUntie("/sim/rendering/clouds3d-cache-size");
|
fgUntie("/sim/rendering/clouds3d-num-flavours");
|
||||||
fgUntie("/sim/rendering/clouds3d-cache-resolution");
|
|
||||||
fgUntie("/sim/rendering/precipitation-enable");
|
fgUntie("/sim/rendering/precipitation-enable");
|
||||||
fgUntie("/environment/rebuild-layers");
|
fgUntie("/environment/rebuild-layers");
|
||||||
fgUntie("/sim/rendering/lightning-enable");
|
fgUntie("/sim/rendering/lightning-enable");
|
||||||
|
|
|
@ -130,7 +130,8 @@ void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_d
|
||||||
string texture = cld_def->getStringValue("texture", "cl_cumulus.rgb");
|
string texture = cld_def->getStringValue("texture", "cl_cumulus.rgb");
|
||||||
|
|
||||||
SGNewCloud *cld =
|
SGNewCloud *cld =
|
||||||
new SGNewCloud(texture_root,
|
new SGNewCloud(type,
|
||||||
|
texture_root,
|
||||||
texture,
|
texture,
|
||||||
min_width,
|
min_width,
|
||||||
max_width,
|
max_width,
|
||||||
|
@ -165,6 +166,7 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
|
||||||
SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D();
|
SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D();
|
||||||
|
|
||||||
layer->clear();
|
layer->clear();
|
||||||
|
|
||||||
// when we don't generate clouds the layer is rendered in 2D
|
// when we don't generate clouds the layer is rendered in 2D
|
||||||
if( coverage == 0.0 )
|
if( coverage == 0.0 )
|
||||||
return;
|
return;
|
||||||
|
@ -210,7 +212,6 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalCount = 1.0 / totalCount;
|
totalCount = 1.0 / totalCount;
|
||||||
double currCoverage = 0.0;
|
|
||||||
|
|
||||||
for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) {
|
for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) {
|
||||||
for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) {
|
for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) {
|
||||||
|
@ -218,16 +219,11 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
|
||||||
double y = py + grid_y_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 z = alt + grid_z_rand * (sg_random() - 0.5);
|
||||||
double choice = sg_random();
|
double choice = sg_random();
|
||||||
currCoverage += coverage;
|
|
||||||
if( currCoverage < 1.0 )
|
|
||||||
continue;
|
|
||||||
currCoverage -= 1.0;
|
|
||||||
|
|
||||||
for(int i = 0; i < CloudVarietyCount ; i ++) {
|
for(int i = 0; i < CloudVarietyCount ; i ++) {
|
||||||
choice -= tCloudVariety[i].count * totalCount;
|
choice -= tCloudVariety[i].count * totalCount;
|
||||||
if( choice <= 0.0 ) {
|
if( choice <= 0.0 ) {
|
||||||
sgVec3 pos={x,z,y};
|
sgVec3 pos={x,z,y};
|
||||||
|
|
||||||
buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, pos, layer);
|
buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, pos, layer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +231,9 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we've built any clouds, enable them
|
// Now we've built any clouds, enable them and set the density (coverage)
|
||||||
|
layer->setCoverage(coverage);
|
||||||
|
layer->applyCoverage();
|
||||||
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(clouds_3d_enabled);
|
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(clouds_3d_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +261,8 @@ void FGClouds::buildMETAR(void) {
|
||||||
|
|
||||||
double alt_ft = cloud_root->getDoubleValue("elevation-ft");
|
double alt_ft = cloud_root->getDoubleValue("elevation-ft");
|
||||||
double alt_m = alt_ft * SG_FEET_TO_METER;
|
double alt_m = alt_ft * SG_FEET_TO_METER;
|
||||||
string coverage = cloud_root->getStringValue("coverage");
|
printf("Alt m: %.0f\n", alt_m);
|
||||||
|
string coverage = cloud_root->getStringValue("coverage");
|
||||||
double coverage_norm = 0.0;
|
double coverage_norm = 0.0;
|
||||||
if( coverage == "few" )
|
if( coverage == "few" )
|
||||||
coverage_norm = 2.0/8.0; // <1-2
|
coverage_norm = 2.0/8.0; // <1-2
|
||||||
|
@ -287,13 +286,13 @@ void FGClouds::buildMETAR(void) {
|
||||||
layer_type = "ns";
|
layer_type = "ns";
|
||||||
} else {
|
} else {
|
||||||
// layer_type = "st|cu|cb|sc";
|
// layer_type = "st|cu|cb|sc";
|
||||||
// +/- 20% from stratus probable base
|
if( cumulus_base * 0.80 < alt_m && cumulus_base * 1.20 > alt_m ) {
|
||||||
if( stratus_base * 0.80 < alt_m && stratus_base * 1.40 > alt_m )
|
// +/- 20% from cumulus probable base
|
||||||
layer_type = "st";
|
layer_type = "cu";
|
||||||
// +/- 20% from cumulus probable base
|
} else if( stratus_base * 0.80 < alt_m && stratus_base * 1.40 > alt_m ) {
|
||||||
else if( cumulus_base * 0.80 < alt_m && cumulus_base * 1.20 > alt_m )
|
// +/- 20% from stratus probable base
|
||||||
layer_type = "cu";
|
layer_type = "st";
|
||||||
else {
|
} else {
|
||||||
// above formulae is far from perfect
|
// above formulae is far from perfect
|
||||||
if ( alt_ft < 2000 )
|
if ( alt_ft < 2000 )
|
||||||
layer_type = "st";
|
layer_type = "st";
|
||||||
|
@ -444,12 +443,12 @@ void FGClouds::buildScenario( const string& scenario ) {
|
||||||
string station = fgGetString("/environment/metar/station-id", "XXXX");
|
string station = fgGetString("/environment/metar/station-id", "XXXX");
|
||||||
|
|
||||||
// fetch station elevation if exists
|
// fetch station elevation if exists
|
||||||
if( station == "XXXX" )
|
if( station == "XXXX" )
|
||||||
station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
|
station_elevation_ft = fgGetDouble("/position/ground-elev-m", 0.0);
|
||||||
else {
|
else {
|
||||||
const FGAirport* a = globals->get_airports()->search( station );
|
const FGAirport* a = globals->get_airports()->search( station );
|
||||||
station_elevation_ft = (a ? a->getElevation() : 0.0);
|
station_elevation_ft = (a ? a->getElevation() : 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
|
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
|
||||||
thesky->get_cloud_layer(iLayer)
|
thesky->get_cloud_layer(iLayer)
|
||||||
|
@ -461,7 +460,7 @@ void FGClouds::buildScenario( const string& scenario ) {
|
||||||
if( scenario == "Fair weather" ) {
|
if( scenario == "Fair weather" ) {
|
||||||
fakeMetar = "15003KT 12SM SCT033 FEW200 20/08 Q1015 NOSIG";
|
fakeMetar = "15003KT 12SM SCT033 FEW200 20/08 Q1015 NOSIG";
|
||||||
setLayer(0, 3300.0, "scattered", "cu");
|
setLayer(0, 3300.0, "scattered", "cu");
|
||||||
} else if( scenario == "Thunderstorm" ) {
|
} else if( scenario == "Thunderstorm" ) {
|
||||||
fakeMetar = "15012KT 08SM TSRA SCT040 BKN070 20/12 Q0995";
|
fakeMetar = "15012KT 08SM TSRA SCT040 BKN070 20/12 Q0995";
|
||||||
setLayer(0, 4000.0, "scattered", "cb");
|
setLayer(0, 4000.0, "scattered", "cb");
|
||||||
setLayer(1, 7000.0, "scattered", "ns");
|
setLayer(1, 7000.0, "scattered", "ns");
|
||||||
|
@ -487,8 +486,6 @@ void FGClouds::build() {
|
||||||
if(!rebuild_required && (scenario == last_scenario))
|
if(!rebuild_required && (scenario == last_scenario))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( last_scenario == "none" ) {
|
if( last_scenario == "none" ) {
|
||||||
// save clouds and weather conditions
|
// save clouds and weather conditions
|
||||||
SGPropertyNode *param = fgGetNode("/environment/config", true);
|
SGPropertyNode *param = fgGetNode("/environment/config", true);
|
||||||
|
@ -534,26 +531,24 @@ void FGClouds::build() {
|
||||||
|
|
||||||
void FGClouds::set_3dClouds(bool enable)
|
void FGClouds::set_3dClouds(bool enable)
|
||||||
{
|
{
|
||||||
if (enable != clouds_3d_enabled)
|
if (enable != clouds_3d_enabled) {
|
||||||
{
|
|
||||||
clouds_3d_enabled = enable;
|
clouds_3d_enabled = enable;
|
||||||
|
|
||||||
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
|
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
|
||||||
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(enable);
|
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(enable);
|
||||||
|
|
||||||
if (!enable) {
|
if (!enable) {
|
||||||
thesky->get_cloud_layer(iLayer)->get_layer3D()->clear();
|
thesky->get_cloud_layer(iLayer)->get_layer3D()->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable)
|
if (enable) {
|
||||||
{
|
|
||||||
rebuild_required = true;
|
rebuild_required = true;
|
||||||
build();
|
build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGClouds::get_3dClouds() const {
|
bool FGClouds::get_3dClouds() const {
|
||||||
return clouds_3d_enabled;
|
return clouds_3d_enabled;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue