1
0
Fork 0

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:
fredb 2008-12-04 20:56:40 +00:00
parent 0cf9d58b76
commit 9721d7811f
2 changed files with 37 additions and 37 deletions

View file

@ -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");

View file

@ -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;
} }