From 7b547acbf9586c0569a36864e6efe98c8b4c5bb0 Mon Sep 17 00:00:00 2001 From: fredb Date: Thu, 6 Nov 2008 21:58:50 +0000 Subject: [PATCH] Stuart Buchanan : It fixes the following issues (to a greater or lesser extent): 1) Performance. Quad trees used to improve culling, and the sprites are placed on the surface of a sphere rather than randomly throughout the cloud, requiring fewer textures. This saves about 5-10fps on my machine. 2) Disabled 3D clouds have no performance impact. Previously they were still in the scenegraph. Now they are removed. 3) Clouds are now loaded on start-up, and don't require the scenario to be changed, they also work with METAR. 4) The cloud field is shifted as you travel. There's a small bug in that the clouds "jump" as you reach the edge of the field. 5) Iterative sorting of sprites. This doesn't appear to solve the alpha blending problem completely, but may help a bit. --- src/Environment/environment_mgr.cxx | 8 +- src/Environment/fgclouds.cxx | 109 +++++++++++++++++++--------- src/Environment/fgclouds.hxx | 9 ++- 3 files changed, 83 insertions(+), 43 deletions(-) diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx index 243671932..30ac8ef54 100644 --- a/src/Environment/environment_mgr.cxx +++ b/src/Environment/environment_mgr.cxx @@ -182,14 +182,14 @@ FGEnvironmentMgr::bind () &FGEnvironmentMgr::set_cloud_layer_coverage); fgSetArchivable(buf); } - fgTie("/sim/rendering/clouds3d-enable", thesky, - &SGSky::get_3dClouds, - &SGSky::set_3dClouds); + fgTie("/sim/rendering/clouds3d-enable", fgClouds, + &FGClouds::get_3dClouds, + &FGClouds::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::get_precipitation_enable_state, &SGEnviro::set_precipitation_enable_state); fgTie("/environment/rebuild-layers", fgClouds, &FGClouds::get_update_event, diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 2248ac9e1..7865e9e0b 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -51,6 +51,7 @@ FGClouds::FGClouds(FGEnvironmentCtrl * controller) : station_elevation_ft(0.0), _controller( controller ), snd_lightning(NULL), + rebuild_required(true), last_scenario( "none" ), last_env_config( new SGPropertyNode() ), last_env_clouds( new SGPropertyNode() ) @@ -78,6 +79,8 @@ 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) { @@ -154,6 +157,8 @@ 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); @@ -231,7 +236,7 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov } // Now we've built any clouds, enable them - thesky->get_cloud_layer(iLayer)->set_enable3dClouds(thesky->get_3dClouds()); + thesky->get_cloud_layer(iLayer)->set_enable3dClouds(clouds_3d_enabled); } // TODO:call this after real metar updates @@ -476,48 +481,80 @@ void FGClouds::buildScenario( const string& scenario ) { } -void FGClouds::build(void) { +void FGClouds::build() { string scenario = fgGetString("/environment/weather-scenario", "METAR"); - if( scenario == last_scenario) - return; - if( last_scenario == "none" ) { + if(!rebuild_required && (scenario == last_scenario)) + return; + + + + if( last_scenario == "none" ) { // save clouds and weather conditions - SGPropertyNode *param = fgGetNode("/environment/config", true); - copyProperties( param, last_env_config ); - param = fgGetNode("/environment/clouds", true); - copyProperties( param, last_env_clouds ); - } - if( scenario == "METAR" ) { - string realMetar = fgGetString("/environment/metar/real-metar", ""); - if( realMetar != "" ) { - fgSetString("/environment/metar/last-metar", realMetar.c_str()); - FGMetar *m = new FGMetar( realMetar ); - update_metar_properties( m ); - update_env_config(); + SGPropertyNode *param = fgGetNode("/environment/config", true); + copyProperties( param, last_env_config ); + param = fgGetNode("/environment/clouds", true); + copyProperties( param, last_env_clouds ); + } + if( scenario == "METAR" ) { + string realMetar = fgGetString("/environment/metar/real-metar", ""); + if( realMetar != "" ) { + fgSetString("/environment/metar/last-metar", realMetar.c_str()); + FGMetar *m = new FGMetar( realMetar ); + update_metar_properties( m ); + update_env_config(); // propagate aloft tables - _controller->reinit(); - } - buildMETAR(); - } - else if( scenario == "none" ) { + _controller->reinit(); + } + buildMETAR(); + } + else if( scenario == "none" ) { // restore clouds and weather conditions - SGPropertyNode *param = fgGetNode("/environment/config", true); - copyProperties( last_env_config, param ); - param = fgGetNode("/environment/clouds", true); - copyProperties( last_env_clouds, param ); - fgSetDouble("/environment/metar/rain-norm", 0.0); - fgSetDouble("/environment/metar/snow-norm", 0.0); + SGPropertyNode *param = fgGetNode("/environment/config", true); + copyProperties( last_env_config, param ); + param = fgGetNode("/environment/clouds", true); + copyProperties( last_env_clouds, param ); + fgSetDouble("/environment/metar/rain-norm", 0.0); + fgSetDouble("/environment/metar/snow-norm", 0.0); // update_env_config(); // propagate aloft tables - _controller->reinit(); - buildMETAR(); - } - else - buildScenario( scenario ); - last_scenario = scenario; + _controller->reinit(); + buildMETAR(); + } + else + buildScenario( scenario ); + + last_scenario = scenario; + rebuild_required = false; // ... - if( snd_lightning == NULL ) - init(); + if( snd_lightning == NULL ) + init(); } + +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(); + } + } +} + +bool FGClouds::get_3dClouds() const { + return clouds_3d_enabled; +} + diff --git a/src/Environment/fgclouds.hxx b/src/Environment/fgclouds.hxx index 71e92b7ae..9e8f7c92c 100644 --- a/src/Environment/fgclouds.hxx +++ b/src/Environment/fgclouds.hxx @@ -59,8 +59,10 @@ void buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, co SGSoundSample *snd_lightning; FGEnvironmentCtrl * _controller; float station_elevation_ft; - string last_scenario; - SGPropertyNode *last_env_config, *last_env_clouds; + bool clouds_3d_enabled; + bool rebuild_required; + string last_scenario; + SGPropertyNode *last_env_config, *last_env_clouds; public: FGClouds(FGEnvironmentCtrl * controller); @@ -72,7 +74,8 @@ public: int get_update_event(void) const; void set_update_event(int count); - + bool get_3dClouds() const; + void set_3dClouds(bool enable); }; #endif // _FGCLOUDS_HXX