From 928789a0d5cf516b3a28320daaef8795adf4a45b Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Fri, 23 Sep 2011 23:22:19 +0200 Subject: [PATCH 1/2] Local Weather 1.35 by Thorsten Renk --- Environment/local-weather-defaults.xml | 2 + Nasal/local_weather/cloud_definitions.nas | 1233 +++++++++++++++++ Nasal/local_weather/compat_layer.nas | 99 +- Nasal/local_weather/local_weather.nas | 1095 +++++++-------- Nasal/local_weather/weather_dynamics.nas | 26 + .../local_weather/weather_tile_management.nas | 127 +- Nasal/local_weather/weather_tiles.nas | 320 ++--- gui/dialogs/local_weather_tiles.xml | 76 +- 8 files changed, 2234 insertions(+), 744 deletions(-) create mode 100644 Nasal/local_weather/cloud_definitions.nas diff --git a/Environment/local-weather-defaults.xml b/Environment/local-weather-defaults.xml index 6c26c3b60..88a232232 100644 --- a/Environment/local-weather-defaults.xml +++ b/Environment/local-weather-defaults.xml @@ -16,6 +16,8 @@ 0 0 0 + 0 + 0 1 1 0 diff --git a/Nasal/local_weather/cloud_definitions.nas b/Nasal/local_weather/cloud_definitions.nas new file mode 100644 index 000000000..c85db3a3c --- /dev/null +++ b/Nasal/local_weather/cloud_definitions.nas @@ -0,0 +1,1233 @@ + +######################################################## +# routines to set up, transform and manage local weather +# Thorsten Renk, August 2011 +######################################################## + +# function purpose +# +# select_cloud_model to define the cloud parameters, given the cloud type and subtype + + +########################################################### +# define various cloud models +########################################################### + +var select_cloud_model = func(type, subtype) { + +var rn = rand(); +var path="Models/Weather/blank.ac"; + +if (type == "Cumulus"){ + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/cumulus_small_shader1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulus_small_shader2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulus_small_shader3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulus_small_shader4.xml";} + else {path = "Models/Weather/cumulus_small_shader5.xml";} + } + else if (subtype == "large") { + if (rn > 0.83) {path = "Models/Weather/cumulus_shader1.xml";} + else if (rn > 0.664) {path = "Models/Weather/cumulus_shader2.xml";} + else if (rn > 0.498) {path = "Models/Weather/cumulus_shader3.xml";} + else if (rn > 0.332) {path = "Models/Weather/cumulus_shader4.xml";} + else if (rn > 0.166) {path = "Models/Weather/cumulus_shader5.xml";} + else {path = "Models/Weather/cumulus_shader6.xml";} + } + } +else if (type == "Cumulus (cloudlet)"){ + + + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet2.rgb"; + cloudAssembly.n_sprites = 10; + cloudAssembly.min_width = 500.0; + cloudAssembly.max_width = 700.0; + cloudAssembly.min_height = 500.0; + cloudAssembly.max_height = 700.0; + cloudAssembly.min_cloud_width = 1300; + cloudAssembly.min_cloud_height = 700; + cloudAssembly.bottom_shade = 0.7; + } + else + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet1.rgb"; + cloudAssembly.n_sprites = 5; + cloudAssembly.min_width = 600.0; + cloudAssembly.max_width = 900.0; + cloudAssembly.min_height = 600.0; + cloudAssembly.max_height = 900.0; + cloudAssembly.min_cloud_width = 1300; + cloudAssembly.min_cloud_height = 700; + cloudAssembly.bottom_shade = 0.4; + } + + + # characterize the basic texture sheet + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.z_scale = 1.0; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.875) {path = "Models/Weather/cumulus_small_sl1.xml";} + else if (rn > 0.750) {path = "Models/Weather/cumulus_small_sl2.xml";} + else if (rn > 0.625) {path = "Models/Weather/cumulus_small_sl3.xml";} + else if (rn > 0.500) {path = "Models/Weather/cumulus_small_sl4.xml";} + else if (rn > 0.375) {path = "Models/Weather/cumulus_small_sl5.xml";} + else if (rn > 0.250) {path = "Models/Weather/cumulus_small_sl6.xml";} + else if (rn > 0.125) {path = "Models/Weather/cumulus_small_sl7.xml";} + else {path = "Models/Weather/cumulus_small_sl8.xml";} + } + else if (subtype == "large") { + if (rn > 0.9) {path = "Models/Weather/cumulus_sl1.xml";} + else if (rn > 0.8) {path = "Models/Weather/cumulus_sl2.xml";} + else if (rn > 0.7) {path = "Models/Weather/cumulus_sl3.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulus_sl4.xml";} + else if (rn > 0.5) {path = "Models/Weather/cumulus_sl5.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulus_sl6.xml";} + else if (rn > 0.3) {path = "Models/Weather/cumulus_sl7.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulus_sl8.xml";} + else if (rn > 0.1) {path = "Models/Weather/cumulus_sl9.xml";} + else {path = "Models/Weather/cumulus_sl10.xml";} + } + + } + + } + +else if (type == "Cu (volume)"){ + + + + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet2.rgb"; + cloudAssembly.n_sprites = 5; + cloudAssembly.min_width = 400.0; + cloudAssembly.max_width = 700.0; + cloudAssembly.min_height = 400.0; + cloudAssembly.max_height = 700.0; + cloudAssembly.min_cloud_width = 1000; + cloudAssembly.min_cloud_height = 1000; + cloudAssembly.bottom_shade = 0.7; + } + else + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet1.rgb"; + cloudAssembly.n_sprites = 5; + cloudAssembly.min_width = 800.0; + cloudAssembly.max_width = 1100.0; + cloudAssembly.min_height = 800.0; + cloudAssembly.max_height = 1100.0; + cloudAssembly.min_cloud_width = 1500; + cloudAssembly.min_cloud_height = 1000; + cloudAssembly.bottom_shade = 0.4; + } + + + # characterize the basic texture sheet + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.z_scale = 1.0; + + #signal that new routines are used + path = "new"; + } + + +else if (type == "Congestus"){ + + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + cloudAssembly.n_sprites = 5; + cloudAssembly.min_width = 600.0; + cloudAssembly.max_width = 900.0; + cloudAssembly.min_height = 600.0; + cloudAssembly.max_height = 900.0; + cloudAssembly.min_cloud_width = 1300; + cloudAssembly.min_cloud_height = 1000; + cloudAssembly.bottom_shade = 0.4; + } + else + { + + if (rand() > 0.5) + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 3; + cloudAssembly.min_width = 1300.0; + cloudAssembly.max_width = 2000.0; + cloudAssembly.min_height = 600.0; + cloudAssembly.max_height = 900.0; + } + else + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet2.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 2; + cloudAssembly.min_width = 1200.0; + cloudAssembly.max_width = 1800.0; + cloudAssembly.min_height = 700.0; + cloudAssembly.max_height = 1000.0; + } + + + cloudAssembly.n_sprites = 3; + cloudAssembly.min_cloud_width = 2200.0; + cloudAssembly.min_cloud_height = 1200.0; + cloudAssembly.bottom_shade = 0.4; + + } + cloudAssembly.z_scale = 1.0; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.9) {path = "Models/Weather/cumulus_sl1.xml";} + else if (rn > 0.8) {path = "Models/Weather/cumulus_sl2.xml";} + else if (rn > 0.7) {path = "Models/Weather/cumulus_sl3.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulus_sl4.xml";} + else if (rn > 0.5) {path = "Models/Weather/cumulus_sl5.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulus_small_sl4.xml";} + else if (rn > 0.3) {path = "Models/Weather/cumulus_small_sl5.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulus_small_sl6.xml";} + else if (rn > 0.1) {path = "Models/Weather/cumulus_small_sl7.xml";} + else {path = "Models/Weather/cumulus_small_sl8.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/congestus_sl1.xml";} + else if (rn > 0.6) {path = "Models/Weather/congestus_sl2.xml";} + else if (rn > 0.4) {path = "Models/Weather/congestus_sl3.xml";} + else if (rn > 0.2) {path = "Models/Weather/congestus_sl4.xml";} + else {path = "Models/Weather/congestus_sl5.xml";} + } + } + } +else if (type == "Stratocumulus"){ + +# new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + cloudAssembly.n_sprites = 7; + cloudAssembly.min_width = 600.0; + cloudAssembly.max_width = 900.0; + cloudAssembly.min_height = 600.0; + cloudAssembly.max_height = 900.0; + cloudAssembly.min_cloud_width = 1300; + cloudAssembly.min_cloud_height = 1300; + cloudAssembly.bottom_shade = 0.6; + } + else + { + if (rand() > 0.66) + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 3; + cloudAssembly.min_width = 1900.0; + cloudAssembly.max_width = 2100.0; + cloudAssembly.min_height = 1000.0; + cloudAssembly.max_height = 1100.0; + cloudAssembly.n_sprites = 3; + cloudAssembly.bottom_shade = 0.5; + cloudAssembly.min_cloud_width = 3500.0; + cloudAssembly.min_cloud_height = 1600.0; + } + else if (rand() > 0.33) + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet2.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 2; + cloudAssembly.min_width = 1900.0; + cloudAssembly.max_width = 2000.0; + cloudAssembly.min_height = 1000.0; + cloudAssembly.max_height = 1100.0; + cloudAssembly.n_sprites = 3; + cloudAssembly.bottom_shade = 0.5; + cloudAssembly.min_cloud_width = 3500.0; + cloudAssembly.min_cloud_height = 1600.0; + } + else + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + cloudAssembly.min_width = 800.0; + cloudAssembly.max_width = 1000.0; + cloudAssembly.min_height = 800.0; + cloudAssembly.max_height = 1000.0; + cloudAssembly.n_sprites = 5; + cloudAssembly.bottom_shade = 0.6; + cloudAssembly.min_cloud_width = 3000.0; + cloudAssembly.min_cloud_height = 1100.0; + } + + + + + + + } + + + cloudAssembly.z_scale = 1.0; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/stratocumulus_small1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratocumulus_small2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratocumulus_small3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratocumulus_small4.xml";} + else {path = "Models/Weather/stratocumulus_small5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/stratocumulus_sl1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratocumulus_sl2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratocumulus_sl3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratocumulus_sl4.xml";} + else {path = "Models/Weather/stratocumulus_sl5.xml";} + } + } + + } +else if (type == "Cumulus (whisp)"){ + +# new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + mult = 1.0; + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/altocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.9; + cloudAssembly.n_sprites = 4; + cloudAssembly.min_width = 400.0 * mult; + cloudAssembly.max_width = 600.0 * mult; + cloudAssembly.min_height = 400.0 * mult; + cloudAssembly.max_height = 600.0 * mult; + cloudAssembly.min_cloud_width = 800 * mult * mult; + cloudAssembly.min_cloud_height = 800 * mult * mult; + cloudAssembly.z_scale = 1.0; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/cumulus_whisp1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulus_whisp2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulus_whisp3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulus_whisp4.xml";} + else {path = "Models/Weather/cumulus_whisp5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/cumulus_whisp1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulus_whisp2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulus_whisp3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulus_whisp4.xml";} + else {path = "Models/Weather/cumulus_whisp5.xml";} + } + + } + + } +else if (type == "Cumulus bottom"){ + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + mult = 1.0; + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_bottom_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 1; + + #characterize the cloud + cloudAssembly.bottom_shade = 1.0; + cloudAssembly.n_sprites = 4; + cloudAssembly.min_width = 600.0 * mult; + cloudAssembly.max_width = 800.0 * mult; + cloudAssembly.min_height = 600.0 * mult; + cloudAssembly.max_height = 800.0 * mult; + cloudAssembly.min_cloud_width = 1200 * mult * mult; + cloudAssembly.min_cloud_height = 800 * mult * mult; + cloudAssembly.z_scale = 0.6; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.0) {path = "Models/Weather/cumulus_bottom1.xml";} + } + else if (subtype == "large") { + if (rn > 0.0) {path = "Models/Weather/cumulus_bottom1.xml";} + } + } + + } +else if (type == "Congestus bottom"){ + + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + mult = 1.0; + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_bottom_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 1; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.7; + cloudAssembly.n_sprites = 4; + cloudAssembly.min_width = 1100.0 * mult; + cloudAssembly.max_width = 1400.0 * mult; + cloudAssembly.min_height = 1100.0 * mult; + cloudAssembly.max_height = 1400.0 * mult; + cloudAssembly.min_cloud_width = 1600 * mult * mult; + cloudAssembly.min_cloud_height = 1200 * mult * mult; + cloudAssembly.z_scale = 0.4; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.0) {path = "Models/Weather/congestus_bottom1.xml";} + } + else if (subtype == "large") { + if (rn > 0.0) {path = "Models/Weather/congestus_bottom1.xml";} + } + } + + } +else if (type == "Stratocumulus bottom"){ + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + mult = 1.0; + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_bottom_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 1; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.7; + cloudAssembly.n_sprites = 3; + cloudAssembly.min_width = 1200.0; + cloudAssembly.max_width = 1600.0; + cloudAssembly.min_height = 1200.0 ; + cloudAssembly.max_height = 1600.0; + cloudAssembly.min_cloud_width = 2000 ; + cloudAssembly.min_cloud_height = 1700; + cloudAssembly.z_scale = 0.4; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.0) {path = "Models/Weather/stratocumulus_bottom1.xml";} + } + else if (subtype == "large") { + if (rn > 0.0) {path = "Models/Weather/stratocumulus_bottom1.xml";} + } + } + + } +else if (type == "Cumulonimbus (cloudlet)"){ + if (subtype == "small") { + if (rn > 0.875) {path = "Models/Weather/cumulonimbus_sl1.xml";} + else if (rn > 0.75) {path = "Models/Weather/cumulonimbus_sl2.xml";} + else if (rn > 0.625) {path = "Models/Weather/cumulonimbus_sl3.xml";} + else if (rn > 0.5) {path = "Models/Weather/cumulonimbus_sl4.xml";} + else if (rn > 0.375) {path = "Models/Weather/cumulonimbus_sl5.xml";} + else if (rn > 0.25) {path = "Models/Weather/cumulonimbus_sl6.xml";} + else if (rn > 0.125) {path = "Models/Weather/cumulonimbus_sl7.xml";} + else {path = "Models/Weather/cumulonimbus_sl8.xml";} + } + else if (subtype == "large") { + if (rn > 0.875) {path = "Models/Weather/cumulonimbus_sl1.xml";} + else if (rn > 0.75) {path = "Models/Weather/cumulonimbus_sl2.xml";} + else if (rn > 0.625) {path = "Models/Weather/cumulonimbus_sl3.xml";} + else if (rn > 0.5) {path = "Models/Weather/cumulonimbus_sl4.xml";} + else if (rn > 0.375) {path = "Models/Weather/cumulonimbus_sl5.xml";} + else if (rn > 0.25) {path = "Models/Weather/cumulonimbus_sl6.xml";} + else if (rn > 0.125) {path = "Models/Weather/cumulonimbus_sl7.xml";} + else {path = "Models/Weather/cumulonimbus_sl8.xml";} + } + + } + +else if (type == "Altocumulus"){ + + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/altocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.8; + cloudAssembly.n_sprites = 10; + cloudAssembly.min_width = 400.0 * mult; + cloudAssembly.max_width = 700.0 * mult; + cloudAssembly.min_height = 400.0 * mult; + cloudAssembly.max_height = 700.0 * mult; + cloudAssembly.min_cloud_width = 1200 * mult * mult; + cloudAssembly.min_cloud_height = 1200 * mult * mult; + cloudAssembly.z_scale = 0.8; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_shader6.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_shader7.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_shader8.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_shader9.xml";} + else {path = "Models/Weather/altocumulus_shader10.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_shader1.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_shader2.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_shader3.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_shader4.xml";} + else {path = "Models/Weather/altocumulus_shader5.xml";} + } + } + } + +else if (type == "Stratus (structured)"){ + + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/altocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.4; + cloudAssembly.n_sprites = 25; + cloudAssembly.min_width = 1700.0 * mult; + cloudAssembly.max_width = 2500.0 * mult; + cloudAssembly.min_height = 1700.0 * mult; + cloudAssembly.max_height = 2500.0 * mult; + cloudAssembly.min_cloud_width = 3200.0 * mult * mult; + cloudAssembly.min_cloud_height = 500.0 * mult * mult + cloudAssembly.max_height; + cloudAssembly.z_scale = 0.3; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_layer6.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_layer7.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_layer8.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_layer9.xml";} + else {path = "Models/Weather/altocumulus_layer10.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_layer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_layer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_layer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_layer4.xml";} + else {path = "Models/Weather/altocumulus_layer5.xml";} + } + + } + } +else if (type == "Altocumulus perlucidus"){ + + # new code + + if (local_weather.hardcoded_clouds_flag == 1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/altocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.8; + cloudAssembly.n_sprites = 25; + cloudAssembly.min_width = 1700.0 * mult; + cloudAssembly.max_width = 2500.0 * mult; + cloudAssembly.min_height = 1700.0 * mult; + cloudAssembly.max_height = 2500.0 * mult; + cloudAssembly.min_cloud_width = 3200.0 * mult * mult; + cloudAssembly.min_cloud_height = 500.0 * mult * mult + cloudAssembly.max_height; + cloudAssembly.z_scale = 0.2; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_thinlayer6.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_thinlayer7.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_thinlayer8.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_thinlayer9.xml";} + else {path = "Models/Weather/altocumulus_thinlayer10.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/altocumulus_thinlayer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/altocumulus_thinlayer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/altocumulus_thinlayer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/altocumulus_thinlayer4.xml";} + else {path = "Models/Weather/altocumulus_thinlayer5.xml";} + } + } + } +else if ((type == "Cumulonimbus") or (type == "Cumulonimbus (rain)")) { + if (subtype == "small") { + if (rn > 0.5) {path = "Models/Weather/cumulonimbus_small1.xml";} + else {path = "Models/Weather/cumulonimbus_small2.xml";} + } + else if (subtype == "large") { + if (rn > 0.5) {path = "Models/Weather/cumulonimbus_small1.xml";} + else {path = "Models/Weather/cumulonimbus_small2.xml";} + } + } +else if (type == "Cirrus") { + if (subtype == "large") { + if (rn > 0.916) {path = "Models/Weather/cirrus1.xml";} + else if (rn > 0.833) {path = "Models/Weather/cirrus2.xml";} + else if (rn > 0.75) {path = "Models/Weather/cirrus3.xml";} + else if (rn > 0.666) {path = "Models/Weather/cirrus4.xml";} + else if (rn > 0.583) {path = "Models/Weather/cirrus5.xml";} + else if (rn > 0.500) {path = "Models/Weather/cirrus6.xml";} + else if (rn > 0.416) {path = "Models/Weather/cirrus7.xml";} + else if (rn > 0.333) {path = "Models/Weather/cirrus8.xml";} + else if (rn > 0.250) {path = "Models/Weather/cirrus9.xml";} + else if (rn > 0.166) {path = "Models/Weather/cirrus10.xml";} + else if (rn > 0.083) {path = "Models/Weather/cirrus11.xml";} + else {path = "Models/Weather/cirrus12.xml";} + } + else if (subtype == "small") { + if (rn > 0.75) {path = "Models/Weather/cirrus_amorphous1.xml";} + else if (rn > 0.5) {path = "Models/Weather/cirrus_amorphous2.xml";} + else if (rn > 0.25) {path = "Models/Weather/cirrus_amorphous3.xml";} + else {path = "Models/Weather/cirrus_amorphous4.xml";} + } + } +else if (type == "Cirrocumulus") { + if (subtype == "small") { + if (rn > 0.5) {path = "Models/Weather/cirrocumulus1.xml";} + else {path = "Models/Weather/cirrocumulus2.xml";} + } + else if (subtype == "large") { + if (rn > 0.875) {path = "Models/Weather/cirrocumulus1.xml";} + else if (rn > 0.750){path = "Models/Weather/cirrocumulus4.xml";} + else if (rn > 0.625){path = "Models/Weather/cirrocumulus5.xml";} + else if (rn > 0.500){path = "Models/Weather/cirrocumulus6.xml";} + else if (rn > 0.385){path = "Models/Weather/cirrocumulus7.xml";} + else if (rn > 0.250){path = "Models/Weather/cirrocumulus8.xml";} + else if (rn > 0.125){path = "Models/Weather/cirrocumulus9.xml";} + else {path = "Models/Weather/cirrocumulus10.xml";} + } + } +else if (type == "Cirrocumulus (cloudlet)") { + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.6;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cirrocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 1.0; + cloudAssembly.n_sprites = 8; + cloudAssembly.min_width = 700.0 * mult; + cloudAssembly.max_width = 1200.0 * mult; + cloudAssembly.min_height = 700.0 * mult; + cloudAssembly.max_height = 1200.0 * mult; + cloudAssembly.min_cloud_width = 1500.0; + cloudAssembly.min_cloud_height = 100.0 * mult; + cloudAssembly.z_scale = 0.3; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/cirrocumulus_cloudlet6.xml";} + else if (rn > 0.6) {path = "Models/Weather/cirrocumulus_cloudlet7.xml";} + else if (rn > 0.4) {path = "Models/Weather/cirrocumulus_cloudlet8.xml";} + else if (rn > 0.2) {path = "Models/Weather/cirrocumulus_cloudlet9.xml";} + else {path = "Models/Weather/cirrocumulus_cloudlet10.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/cirrocumulus_cloudlet1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cirrocumulus_cloudlet2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cirrocumulus_cloudlet3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cirrocumulus_cloudlet4.xml";} + else {path = "Models/Weather/cirrocumulus_cloudlet5.xml";} + } + } + } +else if (type == "Cirrocumulus (new)") { + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cirrocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 1.0; + cloudAssembly.n_sprites = 2; + cloudAssembly.min_width = 200.0 * mult; + cloudAssembly.max_width = 300.0 * mult; + cloudAssembly.min_height = 200.0 * mult; + cloudAssembly.max_height = 300.0 * mult; + cloudAssembly.min_cloud_width = 400.0 * mult; + cloudAssembly.min_cloud_height = 400.0 * mult; + cloudAssembly.z_scale = 0.5; + + #signal that new routines are used + path = "new"; + } + } + +else if (type == "Nimbus") { + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/nimbus_sheet1.rgb"; + cloudAssembly.num_tex_x = 2; + cloudAssembly.num_tex_y = 3; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.8; + cloudAssembly.n_sprites = 10; + cloudAssembly.min_width = 2700.0 * mult; + cloudAssembly.max_width = 3000.0 * mult; + cloudAssembly.min_height = 2700.0 * mult; + cloudAssembly.max_height = 3000.0 * mult; + cloudAssembly.min_cloud_width = 3500.0 * mult * mult * mult; + cloudAssembly.min_cloud_height = 100.0 * mult * mult * mult + cloudAssembly.min_height; + cloudAssembly.z_scale = 0.4; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/nimbus_sls1.xml";} + else if (rn > 0.6) {path = "Models/Weather/nimbus_sls2.xml";} + else if (rn > 0.4) {path = "Models/Weather/nimbus_sls3.xml";} + else if (rn > 0.2) {path = "Models/Weather/nimbus_sls4.xml";} + else {path = "Models/Weather/nimbus_sls5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/nimbus_sl1.xml";} + else if (rn > 0.6) {path = "Models/Weather/nimbus_sl2.xml";} + else if (rn > 0.4) {path = "Models/Weather/nimbus_sl3.xml";} + else if (rn > 0.2) {path = "Models/Weather/nimbus_sl4.xml";} + else {path = "Models/Weather/nimbus_sl5.xml";} + } + + } + } +else if (type == "Stratus") { + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.8;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/stratus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 2; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.4; + cloudAssembly.n_sprites = 20; + cloudAssembly.min_width = 1900.0 * mult; + cloudAssembly.max_width = 2400.0 * mult; + cloudAssembly.min_height = 1900.0 * mult; + cloudAssembly.max_height = 2400.0 * mult; + cloudAssembly.min_cloud_width = 5000.0 * mult; + cloudAssembly.min_cloud_height = 1.1 * cloudAssembly.max_height; + cloudAssembly.z_scale = 0.4; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/stratus_layer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_layer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_layer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_layer4.xml";} + else {path = "Models/Weather/stratus_layer5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/stratus_layer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_layer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_layer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_layer4.xml";} + else {path = "Models/Weather/stratus_layer5.xml";} + } + } + } +else if (type == "Stratus (thin)") { + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") + { + var mult = 0.5; + cloudAssembly.texture_sheet = "/Models/Weather/cirrocumulus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 3; + cloudAssembly.n_sprites = 20; + cloudAssembly.z_scale = 0.4; + } + else + { + var mult = 1.0; + cloudAssembly.texture_sheet = "/Models/Weather/stratus_sheet1.rgb"; + cloudAssembly.num_tex_x = 3; + cloudAssembly.num_tex_y = 2; + cloudAssembly.n_sprites = 10; + cloudAssembly.z_scale = 0.3; + } + + + + #characterize the cloud + cloudAssembly.bottom_shade = 0.8; + cloudAssembly.min_width = 1500.0 * mult; + cloudAssembly.max_width = 2000.0 * mult; + cloudAssembly.min_height = 1500.0 * mult; + cloudAssembly.max_height = 2000.0 * mult; + cloudAssembly.min_cloud_width = 2500.0; + cloudAssembly.min_cloud_height = 50.0; + + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/stratus_tlayer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_tlayer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_tlayer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_tlayer4.xml";} + else {path = "Models/Weather/stratus_tlayer5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/stratus_tlayer1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_tlayer2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_tlayer3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_tlayer4.xml";} + else {path = "Models/Weather/stratus_tlayer5.xml";} + } + + } + } +else if (type == "Cirrostratus") { + + # new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "small") {var mult = 0.7;} + else {var mult = 1.0;} + + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cirrostratus_sheet1.rgb"; + cloudAssembly.num_tex_x = 2; + cloudAssembly.num_tex_y = 2; + + #characterize the cloud + cloudAssembly.bottom_shade = 1.0; + cloudAssembly.n_sprites = 4; + cloudAssembly.min_width = 3500.0 * mult; + cloudAssembly.max_width = 4000.0 * mult; + cloudAssembly.min_height = 3500.0 * mult; + cloudAssembly.max_height = 4000.0 * mult; + cloudAssembly.min_cloud_width = 8000.0; + cloudAssembly.min_cloud_height = 50.0; + cloudAssembly.z_scale = 0.3; + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + if (subtype == "small") { + if (rn > 0.75) {path = "Models/Weather/cirrostratus1.xml";} + else if (rn > 0.5) {path = "Models/Weather/cirrostratus2.xml";} + else if (rn > 0.25) {path = "Models/Weather/cirrostratus3.xml";} + else {path = "Models/Weather/cirrostratus4.xml";} + } + else if (subtype == "large") { + if (rn > 0.75) {path = "Models/Weather/cirrostratus1.xml";} + else if (rn > 0.5) {path = "Models/Weather/cirrostratus2.xml";} + else if (rn > 0.25) {path = "Models/Weather/cirrostratus3.xml";} + else {path = "Models/Weather/cirrostratus4.xml";} + } + } + } +else if (type == "Fog (thin)") { + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/stratus_thin1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_thin2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_thin3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_thin4.xml";} + else {path = "Models/Weather/stratus_thin5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/stratus_thin1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_thin2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_thin3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_thin4.xml";} + else {path = "Models/Weather/stratus_thin5.xml";} + } + } +else if (type == "Fog (thick)") { + if (subtype == "small") { + if (rn > 0.8) {path = "Models/Weather/stratus_thick1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_thick2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_thick3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_thick4.xml";} + else {path = "Models/Weather/stratus_thick5.xml";} + } + else if (subtype == "large") { + if (rn > 0.8) {path = "Models/Weather/stratus_thick1.xml";} + else if (rn > 0.6) {path = "Models/Weather/stratus_thick2.xml";} + else if (rn > 0.4) {path = "Models/Weather/stratus_thick3.xml";} + else if (rn > 0.2) {path = "Models/Weather/stratus_thick4.xml";} + else {path = "Models/Weather/stratus_thick5.xml";} + } + } +else if (type == "Test") {path="Models/Weather/single_cloud.xml";} +else if (type == "Box_test") { + if (subtype == "standard") { + if (rn > 0.8) {path = "Models/Weather/cloudbox1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cloudbox2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cloudbox3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cloudbox4.xml";} + else {path = "Models/Weather/cloudbox5.xml";} + } + else if (subtype == "core") { + if (rn > 0.8) {path = "Models/Weather/cloudbox_core1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cloudbox_core2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cloudbox_core3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cloudbox_core4.xml";} + else {path = "Models/Weather/cloudbox_core5.xml";} + } + else if (subtype == "bottom") { + if (rn > 0.66) {path = "Models/Weather/cloudbox_bottom1.xml";} + else if (rn > 0.33) {path = "Models/Weather/cloudbox_bottom2.xml";} + else if (rn > 0.0) {path = "Models/Weather/cloudbox_bottom3.xml";} + } + } +else if (type == "Cb_box") { + +# new code + + if (local_weather.hardcoded_clouds_flag ==1) + { + cloudAssembly = local_weather.cloud.new(type, subtype); + + if (subtype == "standard") + { + if (rand() > 0.5) # use a Congestus texture + { + + if (rand() > 0.5) + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 3; + cloudAssembly.min_width = 1300.0; + cloudAssembly.max_width = 2000.0; + cloudAssembly.min_height = 600.0; + cloudAssembly.max_height = 900.0; + } + else + { + cloudAssembly.texture_sheet = "/Models/Weather/congestus_sheet2.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 2; + cloudAssembly.min_width = 1200.0; + cloudAssembly.max_width = 1800.0; + cloudAssembly.min_height = 700.0; + cloudAssembly.max_height = 1000.0; + } + + cloudAssembly.n_sprites = 3; + cloudAssembly.min_cloud_width = 2200.0; + cloudAssembly.min_cloud_height = 1200.0; + cloudAssembly.bottom_shade = 0.4; + cloudAssembly.z_scale = 1.0; + } + else + { + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cumulonimbus_sheet2.rgb"; + cloudAssembly.num_tex_x = 2; + cloudAssembly.num_tex_y = 2; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.6; + cloudAssembly.n_sprites = 6; + cloudAssembly.min_width = 800.0; + cloudAssembly.max_width = 1100.0; + cloudAssembly.min_height = 800.0; + cloudAssembly.max_height = 1100.0; + cloudAssembly.min_cloud_width = 3000.0; + cloudAssembly.min_cloud_height = 1500.0; + cloudAssembly.z_scale = 1.0; + + + } + } + else if (subtype == "core") + { + # characterize the basic texture sheet + cloudAssembly.texture_sheet = "/Models/Weather/cumulonimbus_sheet1.rgb"; + cloudAssembly.num_tex_x = 2; + cloudAssembly.num_tex_y = 2; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.6; + cloudAssembly.n_sprites = 10; + cloudAssembly.min_width = 1000.0; + cloudAssembly.max_width = 1500.0; + cloudAssembly.min_height = 1000.0; + cloudAssembly.max_height = 1500.0 ; + cloudAssembly.min_cloud_width = 3500.0; + cloudAssembly.min_cloud_height = 2000.0; + cloudAssembly.z_scale = 1.0; + } + else if (subtype == "bottom") + { + cloudAssembly.texture_sheet = "/Models/Weather/cumulus_bottom_sheet1.rgb"; + cloudAssembly.num_tex_x = 1; + cloudAssembly.num_tex_y = 1; + + #characterize the cloud + cloudAssembly.bottom_shade = 0.5; + cloudAssembly.n_sprites = 4; + cloudAssembly.min_width = 1100.0; + cloudAssembly.max_width = 1400.0; + cloudAssembly.min_height = 1100.0; + cloudAssembly.max_height = 1400.0; + cloudAssembly.min_cloud_width = 1600; + cloudAssembly.min_cloud_height = 1200; + cloudAssembly.z_scale = 0.4; + + } + + #signal that new routines are used + path = "new"; + } + + else # old code + { + + + + if (subtype == "standard") { + if (rn > 0.833) {path = "Models/Weather/cumulonimbus_sl6.xml";} + else if (rn > 0.666) {path = "Models/Weather/cumulonimbus_sl7.xml";} + else if (rn > 0.5) {path = "Models/Weather/cumulonimbus_sl8.xml";} + else if (rn > 0.333) {path = "Models/Weather/congestus_sl1.xml";} + else if (rn > 0.166) {path = "Models/Weather/congestus_sl2.xml";} + else {path = "Models/Weather/congestus_sl3.xml";} + } + else if (subtype == "core") { + if (rn > 0.8) {path = "Models/Weather/cumulonimbus_sl1.xml";} + else if (rn > 0.6) {path = "Models/Weather/cumulonimbus_sl2.xml";} + else if (rn > 0.4) {path = "Models/Weather/cumulonimbus_sl3.xml";} + else if (rn > 0.2) {path = "Models/Weather/cumulonimbus_sl4.xml";} + else {path = "Models/Weather/cumulonimbus_sl5.xml";} + } + else if (subtype == "bottom") { + if (rn > 0.0) {path = "Models/Weather/congestus_bottom1.xml";} + } + + } + } + + +else {print("Cloud type ", type, " subtype ",subtype, " not available!");} + +return path; +} + +# hash for assembling hard-coded clouds + +var cloudAssembly = {}; + diff --git a/Nasal/local_weather/compat_layer.nas b/Nasal/local_weather/compat_layer.nas index 718aef02b..1df26b60b 100644 --- a/Nasal/local_weather/compat_layer.nas +++ b/Nasal/local_weather/compat_layer.nas @@ -83,6 +83,8 @@ weather_tiles = local_weather; var result = "yes"; +if (1==0) # no compatibility tests for 2.4 binary, it has the required features + { print("Compatibility layer: testing for hard coded support"); if (props.globals.getNode("/rendering/scene/saturation", 0) == nil) @@ -119,6 +121,21 @@ print("* can disable global weather: "~result); print("Compatibility layer: tests done."); + } + + +# features of a 2.4 binary + +features.can_set_light = 1; +features.can_set_scattering = 1; +features.terrain_presampling = 1; +features.terrain_presampling_active = 1; +features.can_disable_environment = 1; + +# features of a current GIT binary + +features.fast_geodinfo = 1; + # do actual startup() local_weather.updateMenu(); @@ -128,6 +145,8 @@ local_weather.startup(); + + var setDefaultCloudsOff = func { if (features.can_disable_environment == 1) @@ -149,6 +168,16 @@ else } } +if (local_weather.hardcoded_clouds_flag == 1) + { + # we store that information ourselves, so this should be zero + setprop("/environment/clouds/layer[0]/elevation-ft",0.0); + + # layer wrapping off + setprop("/sim/rendering/clouds3d-wrap",0); + + } + } @@ -226,7 +255,9 @@ settimer( func {visibility_loop(); },0); #################################### var setLift = func (lift) { - setprop("/environment/local-weather-lift-fps",lift); + +setprop("/environment/local-weather-lift-fps",lift); + } #################################### @@ -655,8 +686,7 @@ model.getNode("tile-index",1).setValue(tile_counter); model.getNode("load", 1).remove(); -# sort the model node into a vector for easy deletion -# append(weather_tile_management.modelArrays[tile_counter-1],model); + # sort the cloud into the cloud hash array @@ -699,6 +729,64 @@ if (local_weather.dynamics_flag == 1) } +########################################################### +# place a single cloud using hard-coded system +########################################################### + +var create_cloud_new = func(c) { + + + +var tile_counter = getprop(lw~"tiles/tile-counter"); +cloud_index = cloud_index + 1; + +c.index = tile_counter; +c.cloud_index = cloud_index; + +# write the actual cloud into the scenery + + +var p = props.Node.new({ "layer" : 0, + "index": cloud_index, + "lat-deg": c.lat, + "lon-deg": c.lon, + "min-sprite-width-m": c.min_width, + "max-sprite-width-m": c.max_width, + "min-sprite-height-m": c.min_height, + "max-sprite-height-m": c.max_height, + "num-sprites": c.n_sprites, + "bottom-shade": c.bottom_shade, + "texture": c.texture_sheet, + "num-textures-x": c.num_tex_x, + "num-textures-y": c.num_tex_y, + "min-cloud-width-m": c.min_cloud_width, + "max-cloud-width-m": c.min_cloud_width, + "min-cloud-height-m": c.min_cloud_height, + "max-cloud-height-m": c.min_cloud_height, + "z-scale": c.z_scale, + "height-map-texture": 0, + "alt-ft" : c.alt}); +fgcommand("add-cloud", p); + +# print("alt: ", c.alt); + +# add other management properties to the hash if dynamics is on + +if (local_weather.dynamics_flag == 1) + { + c.timestamp = weather_dynamics.time_lw; + } + + +# add cloud to array + +append(weather_tile_management.cloudArray,c); + + +} + + + ########################################################### # place a cloud layer from arrays, split across frames ########################################################### @@ -736,6 +824,7 @@ for (var k = 0; k < k_max; k = k+1) cloud_evolution_timestamp = local_weather.clouds_evolution_timestamp[s-k-1]; } create_cloud(clouds_path[s-k-1], clouds_lat[s-k-1], clouds_lon[s-k-1], clouds_alt[s-k-1], clouds_orientation[s-k-1]); + #create_cloud_new(clouds_path[s-k-1], clouds_lat[s-k-1], clouds_lon[s-k-1], clouds_alt[s-k-1], clouds_orientation[s-k-1]); } setsize(clouds_path,s-k_max); @@ -838,3 +927,7 @@ var buffered_tile_index = 0; var cloud_mean_altitude = 0.0; var cloud_flt = 0.0; var cloud_evolution_timestamp = 0.0; + +# globals to handle new cloud indexing + +var cloud_index = 0; diff --git a/Nasal/local_weather/local_weather.nas b/Nasal/local_weather/local_weather.nas index bde539ad6..d6f7e31e5 100644 --- a/Nasal/local_weather/local_weather.nas +++ b/Nasal/local_weather/local_weather.nas @@ -29,7 +29,6 @@ # calcLift_max to calculate the maximal available thermal lift for given altitude # calcLift to calculate the thermal lift at aircraft position # calcWaveLift to calculate wave lift at aircraft position -# select_cloud_model to select a path to the cloud model, given the cloud type and subtype # create_cloud_vec to place a single cloud into an array to be written later # clear_all to remove all clouds, effect volumes and weather stations and stop loops # create_detailed_cumulus_cloud to place multiple cloudlets into a box based on a size parameter @@ -82,6 +81,9 @@ # thermalLift to store thermal info and provide methods to move and time-evolve a thermal # waveLift to store wave info + + + ################################### # geospatial helper functions ################################### @@ -603,6 +605,10 @@ var inc2 = 0.9 * (vis_aloft - vis)/1500.0; var inc3 = (vis_ovcst - vis_aloft)/(ovcst_alt_high - vis_alt1+1500); var inc4 = 0.5; + +if (realistic_visibility_flag == 1) + {inc4 = inc4 * 8.0;} + # compute the visibility if (altitude < alt1) @@ -620,6 +626,11 @@ else if (altitude > ovcst_alt_high) vis = vis + inc1 * alt1 + inc2 * (alt2-alt1) + inc3 * (ovcst_alt_high - alt2) + inc4 * (altitude - ovcst_alt_high); } +# limit visibility (otherwise memory consumption is very bad...) + +if (vis > 140000.0) + {vis = 140000.0;} + # compute the horizon shading if (altitude < scatt_alt_low) @@ -855,6 +866,10 @@ if (getprop(lw~"interpolation-loop-flag") ==1) {settimer(interpolation_loop, int var thermal_lift_start = func (ev) { + +# if another lift loop is already running, do nothing +if (getprop(lw~"lift-loop-flag") == 1) {return;} + # copy the properties from effect volume to the lift object l = thermalLift.new(ev.lat, ev.lon, ev.radius, ev.height, ev.cn, ev.sh, ev.max_lift, ev.f_lift_radius); @@ -887,8 +902,9 @@ if (debug_output_flag == 1) # and start the lift loop, unless another one is already running # so we block overlapping calls -if (getprop(lw~"lift-loop-flag") == 0) -{setprop(lw~"lift-loop-flag",1); settimer(thermal_lift_loop,0);} + +setprop(lw~"lift-loop-flag",1); +settimer(thermal_lift_loop,0); } @@ -1397,390 +1413,6 @@ return lift; } -########################################################### -# select a cloud model -########################################################### - -var select_cloud_model = func(type, subtype) { - -var rn = rand(); -var path="Models/Weather/blank.ac"; - -if (type == "Cumulus"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/cumulus_small_shader1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulus_small_shader2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulus_small_shader3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulus_small_shader4.xml";} - else {path = "Models/Weather/cumulus_small_shader5.xml";} - } - else if (subtype == "large") { - if (rn > 0.83) {path = "Models/Weather/cumulus_shader1.xml";} - else if (rn > 0.664) {path = "Models/Weather/cumulus_shader2.xml";} - else if (rn > 0.498) {path = "Models/Weather/cumulus_shader3.xml";} - else if (rn > 0.332) {path = "Models/Weather/cumulus_shader4.xml";} - else if (rn > 0.166) {path = "Models/Weather/cumulus_shader5.xml";} - else {path = "Models/Weather/cumulus_shader6.xml";} - } - } -else if (type == "Cumulus (cloudlet)"){ - if (subtype == "small") { - if (rn > 0.875) {path = "Models/Weather/cumulus_small_sl1.xml";} - else if (rn > 0.750) {path = "Models/Weather/cumulus_small_sl2.xml";} - else if (rn > 0.625) {path = "Models/Weather/cumulus_small_sl3.xml";} - else if (rn > 0.500) {path = "Models/Weather/cumulus_small_sl4.xml";} - else if (rn > 0.375) {path = "Models/Weather/cumulus_small_sl5.xml";} - else if (rn > 0.250) {path = "Models/Weather/cumulus_small_sl6.xml";} - else if (rn > 0.125) {path = "Models/Weather/cumulus_small_sl7.xml";} - else {path = "Models/Weather/cumulus_small_sl8.xml";} - } - else if (subtype == "large") { - if (rn > 0.9) {path = "Models/Weather/cumulus_sl1.xml";} - else if (rn > 0.8) {path = "Models/Weather/cumulus_sl2.xml";} - else if (rn > 0.7) {path = "Models/Weather/cumulus_sl3.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulus_sl4.xml";} - else if (rn > 0.5) {path = "Models/Weather/cumulus_sl5.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulus_sl6.xml";} - else if (rn > 0.3) {path = "Models/Weather/cumulus_sl7.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulus_sl8.xml";} - else if (rn > 0.1) {path = "Models/Weather/cumulus_sl9.xml";} - else {path = "Models/Weather/cumulus_sl10.xml";} - } - - } -else if (type == "Congestus"){ - if (subtype == "small") { - if (rn > 0.9) {path = "Models/Weather/cumulus_sl1.xml";} - else if (rn > 0.8) {path = "Models/Weather/cumulus_sl2.xml";} - else if (rn > 0.7) {path = "Models/Weather/cumulus_sl3.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulus_sl4.xml";} - else if (rn > 0.5) {path = "Models/Weather/cumulus_sl5.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulus_small_sl4.xml";} - else if (rn > 0.3) {path = "Models/Weather/cumulus_small_sl5.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulus_small_sl6.xml";} - else if (rn > 0.1) {path = "Models/Weather/cumulus_small_sl7.xml";} - else {path = "Models/Weather/cumulus_small_sl8.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/congestus_sl1.xml";} - else if (rn > 0.6) {path = "Models/Weather/congestus_sl2.xml";} - else if (rn > 0.4) {path = "Models/Weather/congestus_sl3.xml";} - else if (rn > 0.2) {path = "Models/Weather/congestus_sl4.xml";} - else {path = "Models/Weather/congestus_sl5.xml";} - } - - } -else if (type == "Stratocumulus"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/stratocumulus_small1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratocumulus_small2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratocumulus_small3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratocumulus_small4.xml";} - else {path = "Models/Weather/stratocumulus_small5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/stratocumulus_sl1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratocumulus_sl2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratocumulus_sl3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratocumulus_sl4.xml";} - else {path = "Models/Weather/stratocumulus_sl5.xml";} - } - - } -else if (type == "Cumulus (whisp)"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/cumulus_whisp1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulus_whisp2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulus_whisp3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulus_whisp4.xml";} - else {path = "Models/Weather/cumulus_whisp5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/cumulus_whisp1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulus_whisp2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulus_whisp3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulus_whisp4.xml";} - else {path = "Models/Weather/cumulus_whisp5.xml";} - } - - } -else if (type == "Cumulus bottom"){ - if (subtype == "small") { - if (rn > 0.0) {path = "Models/Weather/cumulus_bottom1.xml";} - } - else if (subtype == "large") { - if (rn > 0.0) {path = "Models/Weather/cumulus_bottom1.xml";} - } - - } -else if (type == "Congestus bottom"){ - if (subtype == "small") { - if (rn > 0.0) {path = "Models/Weather/congestus_bottom1.xml";} - } - else if (subtype == "large") { - if (rn > 0.0) {path = "Models/Weather/congestus_bottom1.xml";} - } - - } -else if (type == "Stratocumulus bottom"){ - if (subtype == "small") { - if (rn > 0.0) {path = "Models/Weather/stratocumulus_bottom1.xml";} - } - else if (subtype == "large") { - if (rn > 0.0) {path = "Models/Weather/stratocumulus_bottom1.xml";} - } - - } -else if (type == "Cumulonimbus (cloudlet)"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/cumulonimbus_sl1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulonimbus_sl2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulonimbus_sl3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulonimbus_sl4.xml";} - else {path = "Models/Weather/cumulonimbus_sl5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/cumulonimbus_sl1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cumulonimbus_sl2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cumulonimbus_sl3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cumulonimbus_sl4.xml";} - else {path = "Models/Weather/cumulonimbus_sl5.xml";} - } - - } - -else if (type == "Altocumulus"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_shader6.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_shader7.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_shader8.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_shader9.xml";} - else {path = "Models/Weather/altocumulus_shader10.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_shader1.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_shader2.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_shader3.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_shader4.xml";} - else {path = "Models/Weather/altocumulus_shader5.xml";} - } - } - -else if (type == "Stratus (structured)"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_layer6.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_layer7.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_layer8.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_layer9.xml";} - else {path = "Models/Weather/altocumulus_layer10.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_layer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_layer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_layer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_layer4.xml";} - else {path = "Models/Weather/altocumulus_layer5.xml";} - } - } -else if (type == "Altocumulus perlucidus"){ - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_thinlayer6.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_thinlayer7.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_thinlayer8.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_thinlayer9.xml";} - else {path = "Models/Weather/altocumulus_thinlayer10.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/altocumulus_thinlayer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/altocumulus_thinlayer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/altocumulus_thinlayer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/altocumulus_thinlayer4.xml";} - else {path = "Models/Weather/altocumulus_thinlayer5.xml";} - } - } -else if ((type == "Cumulonimbus") or (type == "Cumulonimbus (rain)")) { - if (subtype == "small") { - if (rn > 0.5) {path = "Models/Weather/cumulonimbus_small1.xml";} - else {path = "Models/Weather/cumulonimbus_small2.xml";} - } - else if (subtype == "large") { - if (rn > 0.5) {path = "Models/Weather/cumulonimbus_small1.xml";} - else {path = "Models/Weather/cumulonimbus_small2.xml";} - } - } -else if (type == "Cirrus") { - if (subtype == "large") { - if (rn > 0.888) {path = "Models/Weather/cirrus1.xml";} - else if (rn > 0.777) {path = "Models/Weather/cirrus2.xml";} - else if (rn > 0.666) {path = "Models/Weather/cirrus3.xml";} - else if (rn > 0.555) {path = "Models/Weather/cirrus4.xml";} - else if (rn > 0.444) {path = "Models/Weather/cirrus5.xml";} - else if (rn > 0.333) {path = "Models/Weather/cirrus6.xml";} - else if (rn > 0.222) {path = "Models/Weather/cirrus7.xml";} - else if (rn > 0.111) {path = "Models/Weather/cirrus8.xml";} - else {path = "Models/Weather/cirrus9.xml";} - } - else if (subtype == "small") { - if (rn > 0.75) {path = "Models/Weather/cirrus_amorphous1.xml";} - else if (rn > 0.5) {path = "Models/Weather/cirrus_amorphous2.xml";} - else if (rn > 0.25) {path = "Models/Weather/cirrus_amorphous3.xml";} - else {path = "Models/Weather/cirrus_amorphous4.xml";} - } - } -else if (type == "Cirrocumulus") { - if (subtype == "small") { - if (rn > 0.5) {path = "Models/Weather/cirrocumulus1.xml";} - else {path = "Models/Weather/cirrocumulus2.xml";} - } - else if (subtype == "large") { - if (rn > 0.875) {path = "Models/Weather/cirrocumulus1.xml";} - else if (rn > 0.750){path = "Models/Weather/cirrocumulus4.xml";} - else if (rn > 0.625){path = "Models/Weather/cirrocumulus5.xml";} - else if (rn > 0.500){path = "Models/Weather/cirrocumulus6.xml";} - else if (rn > 0.385){path = "Models/Weather/cirrocumulus7.xml";} - else if (rn > 0.250){path = "Models/Weather/cirrocumulus8.xml";} - else if (rn > 0.125){path = "Models/Weather/cirrocumulus9.xml";} - else {path = "Models/Weather/cirrocumulus10.xml";} - } - } -else if (type == "Cirrocumulus (cloudlet)") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/cirrocumulus_cloudlet6.xml";} - else if (rn > 0.6) {path = "Models/Weather/cirrocumulus_cloudlet7.xml";} - else if (rn > 0.4) {path = "Models/Weather/cirrocumulus_cloudlet8.xml";} - else if (rn > 0.2) {path = "Models/Weather/cirrocumulus_cloudlet9.xml";} - else {path = "Models/Weather/cirrocumulus_cloudlet10.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/cirrocumulus_cloudlet1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cirrocumulus_cloudlet2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cirrocumulus_cloudlet3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cirrocumulus_cloudlet4.xml";} - else {path = "Models/Weather/cirrocumulus_cloudlet5.xml";} - } - } -else if (type == "Nimbus") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/nimbus_sls1.xml";} - else if (rn > 0.6) {path = "Models/Weather/nimbus_sls2.xml";} - else if (rn > 0.4) {path = "Models/Weather/nimbus_sls3.xml";} - else if (rn > 0.2) {path = "Models/Weather/nimbus_sls4.xml";} - else {path = "Models/Weather/nimbus_sls5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/nimbus_sl1.xml";} - else if (rn > 0.6) {path = "Models/Weather/nimbus_sl2.xml";} - else if (rn > 0.4) {path = "Models/Weather/nimbus_sl3.xml";} - else if (rn > 0.2) {path = "Models/Weather/nimbus_sl4.xml";} - else {path = "Models/Weather/nimbus_sl5.xml";} - } - } -else if (type == "Stratus") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/stratus_layer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_layer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_layer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_layer4.xml";} - else {path = "Models/Weather/stratus_layer5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/stratus_layer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_layer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_layer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_layer4.xml";} - else {path = "Models/Weather/stratus_layer5.xml";} - } - } -else if (type == "Stratus (thin)") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/stratus_tlayer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_tlayer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_tlayer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_tlayer4.xml";} - else {path = "Models/Weather/stratus_tlayer5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/stratus_tlayer1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_tlayer2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_tlayer3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_tlayer4.xml";} - else {path = "Models/Weather/stratus_tlayer5.xml";} - } - } -else if (type == "Cirrostratus") { - if (subtype == "small") { - if (rn > 0.75) {path = "Models/Weather/cirrostratus1.xml";} - else if (rn > 0.5) {path = "Models/Weather/cirrostratus2.xml";} - else if (rn > 0.25) {path = "Models/Weather/cirrostratus3.xml";} - else {path = "Models/Weather/cirrostratus4.xml";} - } - else if (subtype == "large") { - if (rn > 0.75) {path = "Models/Weather/cirrostratus1.xml";} - else if (rn > 0.5) {path = "Models/Weather/cirrostratus2.xml";} - else if (rn > 0.25) {path = "Models/Weather/cirrostratus3.xml";} - else {path = "Models/Weather/cirrostratus4.xml";} - } - } -else if (type == "Fog (thin)") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/stratus_thin1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_thin2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_thin3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_thin4.xml";} - else {path = "Models/Weather/stratus_thin5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/stratus_thin1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_thin2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_thin3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_thin4.xml";} - else {path = "Models/Weather/stratus_thin5.xml";} - } - } -else if (type == "Fog (thick)") { - if (subtype == "small") { - if (rn > 0.8) {path = "Models/Weather/stratus_thick1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_thick2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_thick3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_thick4.xml";} - else {path = "Models/Weather/stratus_thick5.xml";} - } - else if (subtype == "large") { - if (rn > 0.8) {path = "Models/Weather/stratus_thick1.xml";} - else if (rn > 0.6) {path = "Models/Weather/stratus_thick2.xml";} - else if (rn > 0.4) {path = "Models/Weather/stratus_thick3.xml";} - else if (rn > 0.2) {path = "Models/Weather/stratus_thick4.xml";} - else {path = "Models/Weather/stratus_thick5.xml";} - } - } -else if (type == "Test") {path="Models/Weather/single_cloud.xml";} -else if (type == "Box_test") { - if (subtype == "standard") { - if (rn > 0.8) {path = "Models/Weather/cloudbox1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cloudbox2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cloudbox3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cloudbox4.xml";} - else {path = "Models/Weather/cloudbox5.xml";} - } - else if (subtype == "core") { - if (rn > 0.8) {path = "Models/Weather/cloudbox_core1.xml";} - else if (rn > 0.6) {path = "Models/Weather/cloudbox_core2.xml";} - else if (rn > 0.4) {path = "Models/Weather/cloudbox_core3.xml";} - else if (rn > 0.2) {path = "Models/Weather/cloudbox_core4.xml";} - else {path = "Models/Weather/cloudbox_core5.xml";} - } - else if (subtype == "bottom") { - if (rn > 0.66) {path = "Models/Weather/cloudbox_bottom1.xml";} - else if (rn > 0.33) {path = "Models/Weather/cloudbox_bottom2.xml";} - else if (rn > 0.0) {path = "Models/Weather/cloudbox_bottom3.xml";} - } - } - - -else {print("Cloud type ", type, " subtype ",subtype, " not available!");} - -return path; -} @@ -1792,6 +1424,24 @@ return path; var create_cloud_vec = func(path, lat, long, alt, heading) { +if (path == "new") # we have to switch to new cloud generating routines + { + local_weather.cloudAssembly.lat = lat; + local_weather.cloudAssembly.lon = long; + local_weather.cloudAssembly.alt = alt; + + if (dynamics_flag == 1) + { + local_weather.cloudAssembly.mean_alt = cloud_mean_altitude; + local_weather.cloudAssembly.flt = cloud_fractional_lifetime; + local_weather.cloudAssembly.evolution_timestamp = cloud_evolution_timestamp; + local_weather.cloudAssembly.rel_alt = c.alt - c.mean_alt; + } + compat_layer.create_cloud_new(local_weather.cloudAssembly); + + return; + } + append(clouds_path,path); append(clouds_lat,lat); append(clouds_lon,long); @@ -1831,6 +1481,14 @@ foreach (var m; modelNode) } +# remove the hard-coded clouds + +foreach (c; weather_tile_management.cloudArray) + { + c.remove(); + } +setsize(weather_tile_management.cloudArray,0); + # reset pressure continuity weather_tiles.last_pressure = 0.0; @@ -1885,6 +1543,8 @@ settimer ( func { setsize(weather_tile_management.cloudSceneryArray,0); setsize(alt_20_array,0); setsize(alt_50_array,0); + setsize(alt_min_array,0); + setsize(alt_mean_array,0); setsize(weather_dynamics.tile_convective_altitude,0); setsize(weather_dynamics.tile_convective_strength,0); setsize(weatherStationArray,0); @@ -1897,7 +1557,7 @@ settimer ( func { compat_layer.setOvercast(0.0); setprop(lwi~"ipoint-number",0); setprop(lwi~"atmosphere-ipoint-number", 0); - },1.1); + },0.1); setprop(lw~"tmp/presampling-status", "idle"); @@ -1905,6 +1565,10 @@ setprop(lw~"tmp/presampling-status", "idle"); weather_tiles.rnd_store = rand(); +# default 3d clouds layer wrapping back on, just in case + +setprop("/sim/rendering/clouds3d-wrap",1); + # indicate that we are no longer running @@ -1925,80 +1589,198 @@ var edge_bias = convective_texture_mix; size = size + convective_size_bias; -if (size > 2.0) + +if (hardcoded_clouds_flag == 0) { - if (rand() > (size - 2.0)) - {create_cumulonimbus_cloud(lat, lon, alt, size); } - else - {create_cumulonimbus_cloud_rain(lat, lon, alt, size, 0.1 + 0.2* rand());} - return; + if (size > 2.0) + { + if (rand() > (size - 2.0)) + {create_cumulonimbus_cloud(lat, lon, alt, size); } + else + {create_cumulonimbus_cloud_rain(lat, lon, alt, size, 0.1 + 0.2* rand());} + return; + } + + else if (size>1.5) + { + var type = "Congestus"; + var btype = "Congestus bottom"; + var height = 400; + var n = 8; + var n_b = 4; + var x = 1000.0; + var y = 300.0; + var edge = 0.3; + } + + else if (size>1.1) + { + var type = "Cumulus (cloudlet)"; + var btype = "Cumulus bottom"; + var height = 200; + var n = 8; + var n_b = 1; + var x = 400.0; + var y = 200.0; + var edge = 0.3; + } + else if (size>0.8) + { + var type = "Cumulus (cloudlet)"; + var btype = "Cumulus bottom"; + var height = 150; + var n = 6; + var x = 300.0; + var y = 200.0; + var edge = 0.3; + } + else if (size>0.4) + { + var type = "Cumulus (cloudlet)"; + var btype = "Cumulus bottom"; + var height = 100; + var n = 4; + var x = 200.0; + var y = 200.0; + var edge = 1.0; + } + else + { + var type = "Cumulus (whisp)"; + var btype = "Cumulus bottom"; + var height = 100; + var n = 1; + var x = 100.0; + var y = 100.0; + var edge = 1.0; + } + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + create_streak(type,lat,lon, alt+ 0.5* (height +cloud_vertical_size_map["Cumulus"] * ft_to_m), height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + + # for large clouds, add a bottom + + if ((size > 1.1) and (edge < 0.4)) + { + + create_streak(btype,lat,lon, alt, 100.0,n_b,0.0,edge,0.3*x,1,0.0,0.0,0.3*y,alpha,1.0); + } + + + + } +else + { + if (size > 2.0) + { + if (rand() > (size - 2.0)) + {create_cumulonimbus_cloud(lat, lon, alt, size); } + else + {create_cumulonimbus_cloud_rain(lat, lon, alt, size, 0.1 + 0.2* rand());} + return; + } + + else if (size>1.5) + { + var type = "Congestus"; + + var height = 400; + var n = 3; + var x = 700.0; + var y = 200.0; + var edge = 0.2; + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + + var type = "Cu (volume)"; + var height = 400; + var n = 10; + var x = 1400.0; + var y = 400.0; + var edge = 0.2; + + edge = edge + edge_bias; + + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + + var btype = "Congestus bottom"; + var n_b = 6; + + create_streak(btype,lat,lon, alt - 1100.0, 100.0,n_b,0.0,edge,0.3*x,1,0.0,0.0,0.3*y,alpha,1.0); + + } + else if (size>1.1) + { + var type = "Cumulus (cloudlet)"; + var btype = "Cumulus bottom"; + var height = 200; + var n = 6; + var n_b = 2; + var x = 900.0; + var y = 200.0; + var edge = 0.2; + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + + create_streak(btype,lat,lon, alt -600.0, 100.0,n_b,0.0,edge,0.3*x,1,0.0,0.0,0.3*y,alpha,1.0); + + } + else if (size>0.8) + { + var type = "Cumulus (cloudlet)"; + var height = 150; + var n = 4; + var x = 300.0; + var y = 300.0; + var edge = 0.3; + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + + n = 2; + x = 700.0; + y = 200.0; + edge = 1.0; + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + } + + else if (size>0.4) + { + var type = "Cumulus (cloudlet)"; + var height = 100; + var n = 2; + var x = 600.0; + var y = 100.0; + var edge = 1.0; + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + create_streak(type,lat,lon, alt+ 0.3* (height)-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + } + else + { + var type = "Cumulus (whisp)"; + var height = 100; + var n = 1; + var x = 100.0; + var y = 100.0; + var edge = 1.0; + + var alpha = rand() * 180.0; + edge = edge + edge_bias; + create_streak(type,lat,lon, alt+ 0.3* (height )-600.0, height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); + } + } -else if (size>1.5) - { - var type = "Congestus"; - var btype = "Congestus bottom"; - var height = 400; - var n = 8; - var n_b = 4; - var x = 1000.0; - var y = 300.0; - var edge = 0.3; - } -else if (size>1.1) - { - var type = "Cumulus (cloudlet)"; - var btype = "Cumulus bottom"; - var height = 200; - var n = 8; - var n_b = 1; - var x = 400.0; - var y = 200.0; - var edge = 0.3; - } -else if (size>0.8) - { - var type = "Cumulus (cloudlet)"; - var height = 150; - var n = 6; - var x = 300.0; - var y = 200.0; - var edge = 0.3; - } -else if (size>0.4) - { - var type = "Cumulus (cloudlet)"; - var btype = "Cumulus bottom"; - var height = 100; - var n = 4; - var x = 200.0; - var y = 200.0; - var edge = 1.0; - } -else - { - var type = "Cumulus (whisp)"; - var btype = "Cumulus bottom"; - var height = 100; - var n = 1; - var x = 100.0; - var y = 100.0; - var edge = 1.0; - } - -var alpha = rand() * 180.0; - -edge = edge + edge_bias; - -create_streak(type,lat,lon, alt+ 0.5* (height +cloud_vertical_size_map["Cumulus"] * ft_to_m), height,n,0.0,edge,x,1,0.0,0.0,y,alpha,1.0); - -# for large clouds, add a bottom - -if ((size > 1.1) and (edge < 0.4)) - { - create_streak(btype,lat,lon, alt, 100.0,n_b,0.0,edge,0.3*x,1,0.0,0.0,0.3*y,alpha,1.0); - } } @@ -2008,14 +1790,12 @@ if ((size > 1.1) and (edge < 0.4)) var create_cumulonimbus_cloud = func(lat, lon, alt, size) { -var height = 3000.0; -var alpha = rand() * 180.0; +if (hardcoded_clouds_flag == 1) + {create_cloudbox("Cb_box", lat, lon, alt, 2500.0,2000.0, 1000.0,14, 0.2, 0.1, 3.4, 8, 0.9, 0.2, 8);} +else + {create_cloudbox("Cb_box", lat, lon, alt, 2500.0,2000.0, 1000.0,14, 0.2, 0.1, 1.4, 4, 0.9, 0.2, 8);} -create_streak("Cumulonimbus",lat,lon, alt+ 700, 0,2,0.0,0.0,1600.0,1,0.0,0.0,800.0,alpha,1.0); -create_streak("Cumulonimbus",lat,lon, alt+ 0.5* height + 700, height,6,0.0,0.0,1600.0,1,0.0,0.0,800.0,alpha,1.0); -create_streak("Congestus bottom",lat,lon, alt, 100.0,6,0.0,1.0,0.7*1600,1,0.0,0.0,0.7*800,alpha,1.0); -create_streak("Congestus bottom",lat,lon, alt + 700, 100.0,6,0.0,1.0,0.7*1600,1,0.0,0.0,0.7*800,alpha,1.0); } @@ -2025,14 +1805,11 @@ create_streak("Congestus bottom",lat,lon, alt + 700, 100.0,6,0.0,1.0,0.7*1600,1, var create_cumulonimbus_cloud_rain = func(lat, lon, alt, size, rain) { -var height = 3000.0; -var alpha = rand() * 180.0; +if (hardcoded_clouds_flag == 1) + {create_cloudbox("Cb_box", lat, lon, alt, 2500.0,2000.0, 1000.0,14, 0.2, 0.1, 3.4, 8, 0.9, 0.2, 8);} +else + {create_cloudbox("Cb_box", lat, lon, alt, 2500.0,2000.0, 1000.0,14, 0.2, 0.1, 1.4, 4, 0.9, 0.2, 8);} -create_streak("Cumulonimbus",lat,lon, alt+ 700, 0,2,0.0,0.0,1600.0,1,0.0,0.0,800.0,alpha,1.0); -create_streak("Cumulonimbus",lat,lon, alt+ 0.5* height + 700, height,6,0.0,0.0,1600.0,1,0.0,0.0,800.0,alpha,1.0); - -create_streak("Congestus bottom",lat,lon, alt, 100.0,6,0.0,1.0,0.7*1600,1,0.0,0.0,0.7*800,alpha,1.0); -create_streak("Congestus bottom",lat,lon, alt + 700, 100.0,6,0.0,1.0,0.7*1600,1,0.0,0.0,0.7*800,alpha,1.0); # place a rain texture @@ -2082,7 +1859,10 @@ var cumulus_loop = func (blat, blon, balt, nc, size) { if (local_weather_running_flag == 0) {return;} -var n = int(25/cumulus_efficiency_factor); +if (local_weather.features.fast_geodinfo == 0) + {var n = int(25/cumulus_efficiency_factor);} +else + {var n = int(200/cumulus_efficiency_factor);} if (nc < 0) { @@ -2119,9 +1899,15 @@ var alpha = getprop(lw~"tmp/tile-orientation-deg") * math.pi/180.0; # the tile o if (detailed_terrain_interaction_flag == 1) { - var alt_min = getprop(lw~"tmp/tile-alt-min-ft"); - var alt_mean = getprop(lw~"tmp/tile-alt-mean-ft"); - var alt_var = alt_mean - alt_min; + var tile_index = getprop(lw~"tiles/tile-counter"); + #var alt_min = alt_min_array[tile_index-1]; + #var alt_mean = alt_mean_array[tile_index -1]; + #var alt_median = alt_50_array[tile_index -1]; + #var alt_base = alt_20_array[tile-index -1]; + #var alt_min = getprop(lw~"tmp/tile-alt-min-ft"); + #var alt_mean = getprop(lw~"tmp/tile-alt-mean-ft"); + #var alt_median = getprop(lw~"tmp/tile-alt-median-ft"); + #var alt_base = getprop(lw~"tmp/tile-alt-offset-ft"); } var sec_to_rad = 2.0 * math.pi/86400; # conversion factor for sinusoidal dependence on daytime @@ -2181,15 +1967,13 @@ while (i < nc) { # apply some optional corrections, biases clouds towards higher elevations var terrain_altitude_factor = 1.0; + var terrain_strength_factor = 1.0; if (detailed_terrain_interaction_flag == 1) { - var elevation_enhancement = (elevation - alt_mean) / 1000.0; - - if (elevation_enhancement > 0.7) {elevation_enhancement = 0.7;} - if (elevation_enhancement < -0.7) {elevation_enhancement = -0.7;} - - terrain_altitude_factor = 1.0 + elevation_enhancement; + + terrain_altitude_factor = get_terrain_altitude_factor(tile_index, balt, elevation); + terrain_strength_factor = get_terrain_strength_factor(terrain_altitude_factor); } @@ -2198,7 +1982,40 @@ while (i < nc) { if (rand() < (p * cumulus_efficiency_factor * terrain_altitude_factor)) # we decide to place a cloud at this spot { - strength = (1.5 * rand() + (2.0 * p)) * t_factor2; # the strength of thermal activity at the spot + + + # check if we have a terrain elevation analysis available and can use a + # detailed placement altitude correction + + if (presampling_flag == 1) + { + + if (detailed_terrain_interaction_flag == 1) + { + var grad = get_terrain_gradient(lat, lon, elevation, alpha, 1000.0); + } + else + {var grad = 0.0;} + + + var place_alt = get_convective_altitude(balt, elevation, getprop(lw~"tiles/tile-counter"), grad); + } + else {var place_alt = balt;} + + # no cloud placement into the ground + if (place_alt < elevation) {continue;} + + # if we're in a lee, we may not want to place the cloud + + if (detailed_terrain_interaction_flag == 1) + { + var p_lee_suppression = get_lee_bias(grad); + if (rand() > p_lee_suppression) {continue;} + } + + + # now decide on the strength of the thermal + strength = (1.5 * rand() + (2.0 * p * terrain_strength_factor)) * t_factor2; # the strength of thermal activity at the spot if (strength > 1.0) { # we place a large cloud, and we generate lift @@ -2206,15 +2023,8 @@ while (i < nc) { } else {path = select_cloud_model("Cumulus","small");} - # check if we have a terrain elevation analysis available and can use a - # detailed placement altitude correction + - if (presampling_flag == 1) - { - var place_alt = get_convective_altitude(balt, elevation, getprop(lw~"tiles/tile-counter")); - } - else {var place_alt = balt;} - cloud_mean_altitude = place_alt; cloud_fractional_lifetime = rand(); cloud_evolution_timestamp = weather_dynamics.time_lw; @@ -2253,7 +2063,7 @@ while (i < nc) { var lift = (3.0 + 10.0 * (strength -1.0))/thermal_conditions; var radius = (500 + 500 * rand())*thermal_conditions; - create_effect_volume(1, lat, lon, 1.1*radius, 1.1*radius, 0.0, 0.0, place_alt*1.15, -1, -1, -1, lift*0.04, lift, -2,-1); + create_effect_volume(1, lat, lon, 1.1*radius, 1.1*radius, 0.0, 0.0, place_alt*1.15, -1, -1, -1, lift*0.03, lift, -2,-1); } # end if place_lift_flag } # end if generate-thermal-lift-flag @@ -2348,15 +2158,30 @@ while (i < nc) { }} else {continue;} + + # apply some optional corrections, biases clouds towards higher elevations + + var terrain_altitude_factor = 1.0; + var terrain_strength_factor = 1.0; + + if (detailed_terrain_interaction_flag == 1) + { + terrain_altitude_factor = get_terrain_altitude_factor(tile_index, balt, elevation); + terrain_strength_factor = get_terrain_strength_factor(terrain_altitude_factor); + } + + + + # check if to place a cloud with weight sqrt(p), the lifetime gets another sqrt(p) factor - if (rand() > math.sqrt(p * cumulus_efficiency_factor)) + if (rand() > math.sqrt(p * cumulus_efficiency_factor * terrain_altitude_factor)) {i=i+1; continue;} # then calculate the strength of the updraft - strength = (1.5 * rand() + (2.0 * p)) * t_factor2; # the strength of thermal activity at the spot + strength = (1.5 * rand() + (2.0 * p * terrain_strength_factor)) * t_factor2; # the strength of thermal activity at the spot if (strength > 1.0) { path = select_cloud_model("Cumulus","large"); place_lift_flag = 1; @@ -2365,9 +2190,21 @@ while (i < nc) { if (presampling_flag == 1) { - var place_alt = get_convective_altitude(balt, elevation, tile_index); + var place_alt = get_convective_altitude(balt, elevation, tile_index,0.0); } else {var place_alt = balt;} + + + # no cloud placement into the ground + if (place_alt < elevation) {continue;} + + # if we're in a lee, we may not want to place the cloud + + if (detailed_terrain_interaction_flag == 1) + { + var p_lee_suppression = get_lee_bias(grad); + if (rand() > math.sqrt(p_lee_suppression)) {continue;} + } cloud_mean_altitude = place_alt; cloud_fractional_lifetime = 0.0; @@ -2409,7 +2246,7 @@ while (i < nc) { var lift = (3.0 + 10.0 * (strength -1.0))/thermal_conditions; var radius = (500 + 500 * rand())*thermal_conditions; - create_effect_volume(1, lat, lon, 1.1*radius, 1.1*radius, 0.0, 0.0, place_alt*1.15, -1, -1, -1, lift*0.04, lift, -2,-1); + create_effect_volume(1, lat, lon, 1.1*radius, 1.1*radius, 0.0, 0.0, place_alt*1.15, -1, -1, -1, lift*0.03, lift, -2,-1); } # end if place_lift_flag } # end if generate-thermal-lift-flag @@ -2873,10 +2710,8 @@ for (var i=0; i 0.2) # we have below 20 fps - {n = 5;} -else if (dt > 0.1) # we have below 10 fps - {n = 10;} -else if (dt > 0.05) # we have below 5 fps - {n = 15;} + var dt = getprop("/sim/time/delta-sec"); + if (dt > 0.2) # we have below 20 fps + {n = 5;} + else if (dt > 0.1) # we have below 10 fps + {n = 10;} + else if (dt > 0.05) # we have below 5 fps + {n = 15;} + } +else + { + n = 250; n_out = 250; + } if (nc <= 0) # we're done and may analyze the result { @@ -3135,6 +2975,8 @@ setprop(lw~"tmp/tile-alt-layered-ft",0.5 * (alt_min + alt_20)); append(alt_50_array, alt_med); append(alt_20_array, alt_20); +append(alt_min_array, alt_min); +append(alt_mean_array, alt_mean); } @@ -3174,7 +3016,7 @@ for (var i=0; i alt_variation) {alt_diff = alt_variation;} # maximal shift is given by alt_variation +# print("balt: ", balt, " new alt: ", balt + shift_strength * alt_diff * fraction); + return balt + shift_strength * alt_diff * fraction; } + +########################################################### +# detailed terrain gradient determination in wind direction +########################################################### + + +var get_terrain_gradient = func (lat, lon, elevation1, phi, dist) { + + +# get the first elevation +# var elevation1 = compat_layer.get_elevation(lat,lon); + +# look upwind to learn about the history of the cloud +var elevation2 = compat_layer.get_elevation(lat+weather_tiles.get_lat(0.0,dist,phi), lon+weather_tiles.get_lon(0.0,dist,phi)); + +return (elevation2 - elevation1)/(dist * m_to_ft); +} + +########################################################### +# enhancement of the placement altitude due to terrain +########################################################### + +var get_gradient_factor = func (grad) { + +if (grad > 0.0) + {return 1.0;} +else + { + return 1.0 -2.0 * grad; + } +} + + +########################################################### +# suppression of placement in lee terrain +########################################################### + +var get_lee_bias = func (grad) { + + +if ((local_weather.wind_model_flag == 1) or (local_weather.wind_model_flag == 3)) + { + var windspeed = tile_wind_speed[0]; + } + else if ((local_weather.wind_model_flag ==2) or (local_weather.wind_model_flag == 4) or (local_weather.wind_model_flag == 5)) + { + var windspeed = tile_wind_speed[tile_index-1]; + } + + +if (grad < 0.0) + {return 1.0;} +else + { + var lee_bias = 1.0 - (grad * 0.2 * windspeed); + } +if (lee_bias < 0.2) {lee_bias = 0.2;} + +return lee_bias; +} + +########################################################### +# enhancement of Cumulus in above average altitude +########################################################### + + +var get_terrain_altitude_factor = func (tile_index, balt, elevation) { + + +var alt_mean = alt_mean_array[tile_index -1]; +var alt_base = alt_20_array[tile_index -1]; + +var alt_layer = balt - alt_base; +var alt_above_terrain = balt - elevation; +var alt_above_mean = balt - alt_mean; + +# the cloud may still be above terrain even if the layer altitude is negative, but we want to avoid neg. factors here + +if (alt_above_terrain < 0.0) {alt_above_terrain = 0.0;} + +var norm_alt_diff = (alt_above_mean - alt_above_terrain)/alt_layer; + +if (norm_alt_diff > 0.0) + { + var terrain_altitude_factor = 1.0 + 2.0 * norm_alt_diff; + } + else + { + var terrain_altitude_factor = 1.0/(1.0 - 5.0 * norm_alt_diff); + } + +if (terrain_altitude_factor > 3.0) {terrain_altitude_factor = 3.0;} +if (terrain_altitude_factor < 0.1) {terrain_altitude_factor = 0.1;} + +return terrain_altitude_factor; +} + + +var get_terrain_strength_factor = func (terrain_altitude_factor) { + +return 1.0+ (0.5 * (terrain_altitude_factor-1.0)); + +} + + ########################################################### # terrain presampling listener dispatcher ########################################################### @@ -3500,6 +3477,8 @@ detailed_clouds_flag = getprop(lw~"config/detailed-clouds-flag"); dynamical_convection_flag = getprop(lw~"config/dynamical-convection-flag"); debug_output_flag = getprop(lw~"config/debug-output-flag"); fps_control_flag = getprop(lw~"config/fps-control-flag"); +realistic_visibility_flag = getprop(lw~"config/realistic-visibility-flag"); +detailed_terrain_interaction_flag = getprop(lw~"config/detailed-terrain-interaction-flag"); } @@ -3663,7 +3642,6 @@ var n_bottom = getprop(lw~"tmp/box-bottom-n"); var type = "Box_test"; -#create_cloudbox(type,subtype,lat, lon, alt, x,y,z,n); create_cloudbox(type, lat, lon, alt, x,y,z,n, f_core, r_core, h_core, n_core, f_bottom, h_bottom, n_bottom); @@ -3772,7 +3750,7 @@ if (compat_layer.features.can_disable_environment ==1) # switch off normal 3d clouds -compat_layer.setDefaultCloudsOff(); +local_weather.setDefaultCloudsOff(); # now see if we need to presample the terrain @@ -4021,12 +3999,13 @@ if (dynamics_flag ==1) # and start the buffer loop and housekeeping loop if needed -if (getprop(lw~"config/buffer-flag") ==1) +#if (getprop(lw~"config/buffer-flag") ==1) +if (buffer_flag == 1) { if (getprop(lw~"buffer-loop-flag") == 0) { setprop(lw~"buffer-loop-flag",1); weather_tile_management.buffer_loop(0); - setprop(lw~"housekeeping-loop-flag",1); weather_tile_management.housekeeping_loop(0); + setprop(lw~"housekeeping-loop-flag",1); weather_tile_management.housekeeping_loop(0,0); } } @@ -4136,9 +4115,29 @@ var test = func { var lat = getprop("position/latitude-deg"); var lon = getprop("position/longitude-deg"); +thread_flag = 0; +dynamics_flag = 0; +presampling_flag = 0; + + +#if (compat_layer.features.can_disable_environment ==1) +# { +# props.globals.getNode("/environment/config/enabled").setBoolValue(0); +# props.globals.getNode("/environment/params/metar-updates-environment").setBoolValue(0); +# } +# +#compat_layer.setDefaultCloudsOff(); + +#var array = []; +#append(weather_tile_management.modelArrays,array); +#setprop(lw~"tiles/tile-counter",getprop(lw~"tiles/tile-counter")+1); + + #var pos = geo.aircraft_position(); -debug.dump(geodinfo(lat, lon)); +#debug.dump(geodinfo(lat, lon)); + +#create_cumulonimbus_cloud(lat, lon, 6000.0, 2.5); # geo.put_model("Models/Astro/Earth.ac",lat, lon); @@ -4147,10 +4146,26 @@ debug.dump(geodinfo(lat, lon)); #setprop("/environment/terrain/area[0]/output/valid", 0 ); +elttest(); + } +var elttest = func { +var lat_uncertainty = 0.001; +var lon_uncertainty = 0.001; + +#var lat = getprop("/position/latitude-deg") + lat_uncertainty * 0.5 - rand(); +#var lon = getprop("/position/longitude-deg") + lon_uncertainty * 0.5 - rand(); +var lat = getprop("/position/latitude-string"); +var lon = getprop("/position/longitude-string"); +var aircraft = getprop("sim/description"); +var callsign = getprop("sim/multiplay/callsign"); +var help_string = "ELT AutoMessage: " ~ aircraft ~ " " ~ callsign ~ " " ~lat~" LAT "~lon~" LON, requesting SAR service"; + +setprop("/sim/multiplay/chat", help_string); +} ################################################################# @@ -4292,7 +4307,7 @@ var effectVolume = { correct_altitude: func { var convective_alt = weather_dynamics.tile_convective_altitude[me.index-1] + alt_20_array[me.index-1]; var elevation = compat_layer.get_elevation(me.lat, me.lon); - me.alt_high = local_weather.get_convective_altitude(convective_alt, elevation, me.index) *1.15; + me.alt_high = local_weather.get_convective_altitude(convective_alt, elevation, me.index,0.0) *1.15; me.height = me.alt_high * 0.87; }, correct_altitude_and_age: func { @@ -4309,7 +4324,7 @@ var effectVolume = { else {p_cover = 0.2;} } } - me.alt_high = get_convective_altitude(convective_alt, elevation, me.index) * 1.15; + me.alt_high = get_convective_altitude(convective_alt, elevation, me.index,0.0) * 1.15; me.height = me.alt_high * 0.87; var current_lifetime = math.sqrt(p_cover)/math.sqrt(0.35) * weather_dynamics.cloud_convective_lifetime_s; var fractional_increase = (weather_dynamics.time_lw - me.evolution_timestamp)/current_lifetime; @@ -4347,7 +4362,7 @@ var thermalLift = { correct_altitude: func { var convective_alt = weather_dynamics.tile_convective_altitude[me.index-1] + alt_20_array[me.index-1]; var elevation = compat_layer.get_elevation(me.lat, me.lon); - me.height = local_weather.get_convective_altitude(convective_alt, elevation, me.index); + me.height = local_weather.get_convective_altitude(convective_alt, elevation, me.index,0.0); }, correct_altitude_and_age: func { var convective_alt = weather_dynamics.tile_convective_altitude[me.index-1] + local_weather.alt_20_array[me.index-1]; @@ -4363,7 +4378,7 @@ var thermalLift = { else {p_cover = 0.2;} } } - me.height = get_convective_altitude(convective_alt, elevation, me.index); + me.height = get_convective_altitude(convective_alt, elevation, me.index,0.0); var current_lifetime = math.sqrt(p_cover)/math.sqrt(0.35) * weather_dynamics.cloud_convective_lifetime_s; var fractional_increase = (weather_dynamics.time_lw - me.evolution_timestamp)/current_lifetime; me.flt = me.flt + fractional_increase; @@ -4412,11 +4427,11 @@ var ec = "/environment/config/"; # a hash map of the strength for convection associated with terrain types -var landcover_map = {BuiltUpCover: 0.35, Town: 0.35, Freeway:0.35, BarrenCover:0.3, HerbTundraCover: 0.25, GrassCover: 0.2, CropGrassCover: 0.2, EvergreenBroadCover: 0.2, EvergreenNeedleCover: 0.2, Sand: 0.25, Grass: 0.2, Ocean: 0.01, Marsh: 0.05, Lake: 0.01, ShrubCover: 0.15, Landmass: 0.2, CropWoodCover: 0.15, MixedForestCover: 0.1, DryCropPastureCover: 0.25, MixedCropPastureCover: 0.2, IrrCropPastureCover: 0.15, DeciduousBroadCover: 0.1, DeciduousNeedleCover: 0.1, Bog: 0.05, pa_taxiway : 0.35, pa_tiedown: 0.35, pc_taxiway: 0.35, pc_tiedown: 0.35, Glacier: 0.01, DryLake: 0.3, IntermittentStream: 0.2, DryCrop: 0.2, Lava: 0.3}; +var landcover_map = {BuiltUpCover: 0.35, Town: 0.35, Freeway:0.35, BarrenCover:0.3, HerbTundraCover: 0.25, GrassCover: 0.2, CropGrassCover: 0.2, EvergreenBroadCover: 0.2, EvergreenNeedleCover: 0.2, Sand: 0.25, Grass: 0.2, Ocean: 0.01, Marsh: 0.05, Lake: 0.01, ShrubCover: 0.15, Landmass: 0.2, CropWoodCover: 0.15, MixedForestCover: 0.15, DryCropPastureCover: 0.25, MixedCropPastureCover: 0.2, IrrCropPastureCover: 0.15, DeciduousBroadCover: 0.1, DeciduousNeedleCover: 0.1, Bog: 0.05, pa_taxiway : 0.35, pa_tiedown: 0.35, pc_taxiway: 0.35, pc_tiedown: 0.35, Glacier: 0.03, DryLake: 0.3, IntermittentStream: 0.2, DryCrop: 0.2, Lava: 0.3, GolfCourse: 0.2}; # a hash map of average vertical cloud model sizes -var cloud_vertical_size_map = {Altocumulus: 700.0, Cumulus: 600.0, Nimbus: 1000.0, Stratus: 800.0, Stratus_structured: 600.0, Stratus_thin: 400.0, Cirrocumulus: 200.0}; +var cloud_vertical_size_map = {Altocumulus: 700.0, Cumulus: 600.0, Congestus: 2000.0, Nimbus: 1000.0, Stratus: 800.0, Stratus_structured: 600.0, Stratus_thin: 400.0, Cirrocumulus: 200.0, Cb_box: 2000.0}; # the array of aloft wind interpolation altitudes @@ -4430,6 +4445,13 @@ var clouds_lon = []; var clouds_alt = []; var clouds_orientation = []; + + + +# storage array for assembled clouds + +var cloudAssemblyArray = []; + # additional info needed for dynamical clouds: the base altitude around which cloudlets are distributed # and the fractional lifetime @@ -4443,6 +4465,8 @@ var clouds_evolution_timestamp = []; var terrain_n = []; var alt_50_array = []; var alt_20_array = []; +var alt_min_array = []; +var alt_mean_array = []; # array of currently existing effect volumes @@ -4455,6 +4479,8 @@ var thermal = {}; var wave = {}; + + # arrays of currently existing weather stations, wind interpolation and atmospheric condition points var weatherStationArray = []; @@ -4497,7 +4523,10 @@ var metar_flag = 0; var local_weather_running_flag = 0; var local_weather_startup_flag = 0; var fps_control_flag = 0; -var detailed_terrain_interaction_flag = 0; +var buffer_flag = 1; +var detailed_terrain_interaction_flag = 1; +var hardcoded_clouds_flag = 0; +var realistic_visibility_flag = 0; # globals for framerate controlled cloud management @@ -4524,26 +4553,6 @@ setprop(lw~"tmp/ipoint-latitude-deg",getprop("position/latitude-deg")); setprop(lw~"tmp/ipoint-longitude-deg",getprop("position/longitude-deg")); -# set config values - -# setprop(lw~"config/distance-to-load-tile-m",39000.0); -# setprop(lw~"config/distance-to-remove-tile-m",39500.0); -# setprop(lw~"config/detailed-clouds-flag",1); -# setprop(lw~"config/dynamics-flag",0); -# setprop(lw~"config/thermal-properties",1.0); -# setprop(lw~"config/wind-model","constant"); -# setprop(lw~"config/buffer-flag",1); -# setprop(lw~"config/asymmetric-reduction",0.7); -# setprop(lw~"config/clouds-visible-range-m",30000.0); -# setprop(lw~"config/asymmetric-buffering-flag",0); -# setprop(lw~"config/asymmetric-buffering-reduction",0.3); -# setprop(lw~"config/asymmetric-buffering-angle-deg",90.0); -# setprop(lw~"config/clouds-in-dynamics-loop",250); -# setprop(lw~"config/debug-output-flag",0); -# setprop(lw~"config/generate-thermal-lift-flag", 0); -# setprop(lw~"config/dynamical-convection-flag", 0); -# setprop(lw~"config/thread-flag", 1); -# setprop(lw~"config/presampling-flag", 1); # set the default loop flags to loops inactive diff --git a/Nasal/local_weather/weather_dynamics.nas b/Nasal/local_weather/weather_dynamics.nas index 87b5b36db..8adc598de 100644 --- a/Nasal/local_weather/weather_dynamics.nas +++ b/Nasal/local_weather/weather_dynamics.nas @@ -54,6 +54,32 @@ return windfield; } +var get_wind_direction = func (tile_index) { + +if ((local_weather.wind_model_flag == 1) or (local_weather.wind_model_flag == 3)) + { + return tile_wind_direction[0]; + } +else if ((local_weather.wind_model_flag ==2) or (local_weather.wind_model_flag == 4) or (local_weather.wind_model_flag == 5)) + { + return tile_wind_direction[tile_index-1]; + } + +} + +var get_wind_speed = func (tile_index) { + +if ((local_weather.wind_model_flag == 1) or (local_weather.wind_model_flag == 3)) + { + return tile_wind_speed[0]; + } +else if ((local_weather.wind_model_flag ==2) or (local_weather.wind_model_flag == 4) or (local_weather.wind_model_flag == 5)) + { + return tile_wind_speed[tile_index-1]; + } + +} + ######################################################## # timing loop # this gets the accurate time since the start of weather dynamics diff --git a/Nasal/local_weather/weather_tile_management.nas b/Nasal/local_weather/weather_tile_management.nas index 9cddc8310..db4483961 100644 --- a/Nasal/local_weather/weather_tile_management.nas +++ b/Nasal/local_weather/weather_tile_management.nas @@ -1228,7 +1228,7 @@ if (getprop(lw~"buffer-loop-flag") ==1) {settimer( func {buffer_loop(i)}, 0);} # housekeeping loop ############################### -var housekeeping_loop = func (index) { +var housekeeping_loop = func (index, index1) { if (local_weather.local_weather_running_flag == 0) {return;} @@ -1237,12 +1237,14 @@ var n_max = size(cloudSceneryArray); n_cloudSceneryArray = n_max; var s = size(active_tile_list); -setprop(lw~"clouds/cloud-scenery-count",n_max); +var m_max = size(cloudArray); + +setprop(lw~"clouds/cloud-scenery-count",n_max+m_max); # don't do anything as long as the array is empty -if (n_max == 0) # nothing to do, loop over - {if (getprop(lw~"housekeeping-loop-flag") ==1) {settimer( func {housekeeping_loop(index)}, 0);} return;} +if ((n_max == 0) and (m_max == 0)) # nothing to do, loop over + {if (getprop(lw~"housekeeping-loop-flag") ==1) {settimer( func {housekeeping_loop(index, index1)}, 0);} return;} # parse the flags @@ -1255,7 +1257,7 @@ if (asymmetric_buffering_flag ==1) var current_heading = getprop("orientation/heading-deg"); } -# now process the array +# now process the Scenery array if (index > n_max-1) {index = 0;} @@ -1310,7 +1312,34 @@ for (var i = index; i < i_max; i = i+1) } -if (getprop(lw~"housekeeping-loop-flag") ==1) {settimer( func {housekeeping_loop(i)}, 0);} +# now process the hard coded cloud array and see a tile has been removed + +if (index1 > m_max-1) {index1 = 0;} + +var j_max = index1 + n; +if (j_max > m_max) {j_max = m_max;} + +for (var j = index1; j < j_max; j = j+1) + { + var c = cloudArray[j]; + + var flag = 0; + + for (var k = 0; k < s; k = k+1) + { + if (active_tile_list[k] == c.index) {flag = 1; break;} + } + + if (flag == 0) + { + c.remove(); + cloudArray = delete_from_vector(cloudArray,j); + j = j -1; j_max = j_max - 1; m_max = m_max - 1; + continue; + } + } + +if (getprop(lw~"housekeeping-loop-flag") ==1) {settimer( func {housekeeping_loop(i,j)}, 0);} } @@ -1555,11 +1584,20 @@ var cloudScenery = { return me.calt.getValue(); }, correct_altitude: func { - var lat = me.clat.getValue(); - var lon = me.clon.getValue(); + var lat = me.lat; + var lon = me.lon; var convective_alt = weather_dynamics.tile_convective_altitude[me.index-1] + local_weather.alt_20_array[me.index-1]; var elevation = compat_layer.get_elevation(lat, lon); - var alt_new = local_weather.get_convective_altitude(convective_alt, elevation, me.index); + + if (local_weather.detailed_terrain_interaction_flag == 1) + { + var phi = local_weather.get_wind_direction(me.index) * math.pi/180.0; + var grad = local_weather.get_terrain_gradient(lat, lon, elevation, phi, 1000.0); + } + else + {var grad = 0.0;} + + var alt_new = local_weather.get_convective_altitude(convective_alt, elevation, me.index, grad); me.target_alt = alt_new + me.rel_alt; }, correct_altitude_and_age: func { @@ -1582,13 +1620,25 @@ var cloudScenery = { } } - + if (local_weather.detailed_terrain_interaction_flag == 1) + { + var phi = local_weather.get_wind_direction(me.index) * math.pi/180.0; + var grad = local_weather.get_terrain_gradient(lat, lon, elevation, phi, 1000.0); + var lee_bias = local_weather.get_lee_bias(grad); + } + else + { + var grad = 0.0; + var lee_bias = 1.0; + } + # correct the altitude - var alt_new = local_weather.get_convective_altitude(convective_alt, elevation, me.index); + var alt_new = local_weather.get_convective_altitude(convective_alt, elevation, me.index, grad); me.target_alt = alt_new + me.rel_alt; # correct fractional lifetime based on terrain below - var current_lifetime = math.sqrt(p_cover)/math.sqrt(0.35) * weather_dynamics.cloud_convective_lifetime_s; + + var current_lifetime = math.sqrt(p_cover * lee_bias)/math.sqrt(0.35) * weather_dynamics.cloud_convective_lifetime_s; var fractional_increase = (weather_dynamics.time_lw - me.evolution_timestamp)/current_lifetime; me.flt = me.flt + fractional_increase; me.evolution_timestamp = weather_dynamics.time_lw; @@ -1641,6 +1691,59 @@ var cloudScenery = { }, }; +var cloudArray = []; + +var cloud = { + new: func(type, subtype) { + var c = { parents: [cloud] }; + c.type = type; + c.subtype = subtype; + + return c; + }, + remove: func { + var p = props.Node.new({ "layer" : 0, + "index": me.cloud_index }); + fgcommand("del-cloud", p); + }, + move: func { + # this doesn't move a cloud in the scenery, but updates its position in internal space + var windfield = local_weather.windfield; + var dt = local_weather.time_lw - me.timestamp; + + me.lat = me.lat + windfield[1] * dt * local_weather.m_to_lat; + me.lon = me.lon + windfield[0] * dt * local_weather.m_to_lon; + me.timestamp = weather_dynamics.time_lw; + + }, + correct_altitude: func { + var convective_alt = weather_dynamics.tile_convective_altitude[me.index-1] + local_weather.alt_20_array[me.index-1]; + var elevation = compat_layer.get_elevation(me.lat, me.lon); + + if (local_weather.detailed_terrain_interaction_flag == 1) + { + var phi = local_weather.get_wind_direction(me.index) * math.pi/180.0; + var grad = local_weather.get_terrain_gradient(me.lat, me.lon, elevation, phi, 1000.0); + } + else + {var grad = 0.0;} + + var alt_new = local_weather.get_convective_altitude(convective_alt, elevation, me.index, grad); + var target_alt = alt_new + me.rel_alt; + + var p = props.Node.new({ "layer" : 0, + "index": me.cloud_index, + "lat-deg": me.lat, + "lon-deg": me.lon, + "alt-ft": target_alt + }); + fgcommand("move-cloud",p); + + me.alt = target_alt; + }, +}; + + ################### # helper functions ################### diff --git a/Nasal/local_weather/weather_tiles.nas b/Nasal/local_weather/weather_tiles.nas index 216b4dc6e..b7dea927b 100644 --- a/Nasal/local_weather/weather_tiles.nas +++ b/Nasal/local_weather/weather_tiles.nas @@ -98,27 +98,30 @@ calc_geo(blat); local_weather.set_weather_station(blat, blon, alt_offset, 20000.0, 14.0, 12.0, 29.78); -# create_8_8_nimbus_var3(blat, blon, 2000.0 + alt_offset+local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft, 0.0); +#strength = 0.5; +#local_weather.create_cumosys(blat,blon, 3000.0, get_n(strength), 20000.0); -#create_2_8_sstratus_streak(blat, blon,5000.0,0.0); +#create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ; +#create_2_8_altocumulus_streaks(blat, blon, 12000+alt_offset, alpha) ; +#create_6_8_stratus(blat, blon, 3000+alt_offset, alpha) ; +#create_4_8_tstratus_patches(blat, blon, 5000+alt_offset, alpha) ; +#create_4_8_sstratus_patches(blat, blon, 12000+alt_offset, alpha) ; +#create_4_8_cirrostratus_patches(blat, blon, 20000+alt_offset, alpha) ; -#create_4_8_cirrocumulus_bank(blat, blon, 6000.0, 0.0); +#create_4_8_cirrocumulus_streaks(blat, blon, 10000.0 + alt_offset, alpha); +create_4_8_alttstratus_streaks(blat, blon, 5000+alt_offset, alpha) ; +#create_2_8_cirrocumulus_patches(blat, blon, 13000+alt_offset, alpha) ; +#create_8_8_nimbus_rain(blat, blon, 5000+alt_offset, alpha, 0.3) ; -#create_4_8_cirrocumulus_streaks(blat, blon, 6000.0, 0.0); +#create_4_8_altocumulus_perlucidus(blat, blon, 5000+alt_offset, alpha) ; -# create_2_8_cirrocumulus(blat, blon, 6000.0, 0.0); +#create_detailed_stratocumulus_bank(blat, blon, 4000+alt_offset,alpha); -# create_detailed_small_stratocumulus_bank(blat, blon,3000.0+alt_offset,0.0); +#store convective altitude and strength -create_4_8_altocumulus_perlucidus(blat, blon, 10000.0, 0.0); -#local_weather.create_effect_volume(3, blat, blon, 20000.0, 7000.0, alpha, 0.0, 80000.0, -1, -1, -1, -1, 15.0, -3,-1); -create_1_8_contrails(blat, blon, 30000.0, 0.0); - -# store convective altitude and strength - -local_weather.set_atmosphere_ipoint(blat, blon, 45000.0, 10000.0, 45000.0, 0.2, 25000.0, 30000.0, 0.7, 10000.0, 11000.0); +local_weather.set_atmosphere_ipoint(blat, blon, 45000.0, 10000.0, 45000.0, 0.0, 25000.0, 30000.0, 0.9, 10000.0, 11000.0); append(weather_dynamics.tile_convective_altitude,3000.0); @@ -159,7 +162,7 @@ calc_geo(blat); var vis = 30000.0 + rand() * 15000.0; var T = 20.0 + rand() * 10.0; -var spread = 5.0 + 3.0 * rand(); +var spread = 14.0 + 8.0 * rand(); var D = T - spread; var p = 1025.0 + rand() * 6.0; p = adjust_p(p); @@ -168,7 +171,7 @@ local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_i -var alt = spread * 1000; +var alt = spread * 400; var strength = 0.0; @@ -297,7 +300,7 @@ calc_geo(blat); var vis = 25000.0 + rand() * 15000.0; var T = 15.0 + rand() * 10.0; -var spread = 4.0 + 2.0 * rand(); +var spread = 10.0 + 4.0 * rand(); var D = T - spread; var p = 1019.0 + rand() * 6.0; p = adjust_p(p); @@ -305,10 +308,11 @@ var p = 1019.0 + rand() * 6.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); -var alt = spread * 1000; +var alt = spread * 400; var strength = 0.0; +# print("alt: ",alt, "spread: ", spread, "offset: ", alt_offset); var rn = rand(); @@ -443,7 +447,7 @@ calc_geo(blat); var vis = 20000.0 + rand() * 12000.0; var T = 12.0 + rand() * 10.0; -var spread = 3.0 + 2.0 * rand(); +var spread = 7.0 + 4.0 * rand(); var D = T - spread; var p = 1013.0 + rand() * 6.0; p = adjust_p(p); @@ -453,7 +457,7 @@ local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_i # now a random selection of different possible cloud configuration scenarios -var alt = spread * 1000; +var alt = spread * 400; var strength = 0.0; var rn = rand(); @@ -651,7 +655,7 @@ calc_geo(blat); var vis = 12000.0 + rand() * 9000.0; var T = 10.0 + rand() * 10.0; -var spread = 2.0 + 2.0 * rand(); +var spread = 6.0 + 2.0 * rand(); var D = T - spread; var p = 1007.0 + rand() * 6.0; p = adjust_p(p); @@ -659,7 +663,7 @@ var p = 1007.0 + rand() * 6.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; # bias Cumulus clouds towards larger sizes due to lots of water vapour @@ -813,7 +817,7 @@ calc_geo(blat); var vis = 9000.0 + rand() * 10000.0; var T = 5.0 + rand() * 10.0; -var spread = 2.0 + 2.5 * rand(); +var spread = 5.0 + 2.0 * rand(); var D = T - spread; var p = 1001.0 + rand() * 6.0; p = adjust_p(p); @@ -823,7 +827,7 @@ var p = 1001.0 + rand() * 6.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; var rn = rand(); @@ -963,7 +967,7 @@ calc_geo(blat); var vis = 5000.0 + rand() * 5000.0; var T = 3.0 + rand() * 7.0; -var spread = 1.5 + 1.5 * rand(); +var spread = 4.5 + 1.0 * rand(); var D = T - spread; var p = 995.0 + rand() * 6.0; p = adjust_p(p); @@ -973,7 +977,7 @@ local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_i # set a closed Nimbostratus layer -var alt = spread * 1000.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; +var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; var strength = 0.0; @@ -1032,9 +1036,9 @@ calc_geo(blat); # get probabilistic values for the weather parameters -var vis = 35000.0 + rand() * 20000.0; +var vis = 45000.0 + rand() * 20000.0; var T = 8.0 + rand() * 8.0; -var spread = 3.0 + 2.0 * rand(); +var spread = 7.0 + 3.0 * rand(); var D = T - spread; var p = 1005.0 + rand() * 10.0; p = adjust_p(p); @@ -1042,7 +1046,7 @@ var p = 1005.0 + rand() * 10.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; var rn = rand(); @@ -1129,7 +1133,7 @@ calc_geo(blat); var vis = 12000.0 + rand() * 10000.0; var T = 16.0 + rand() * 10.0; -var spread = 2.0 + 2.0 * rand(); +var spread = 6.0 + 3.0 * rand(); var D = T - spread; var p = 1005.0 + rand() * 10.0; p = adjust_p(p); @@ -1137,7 +1141,7 @@ var p = 1005.0 + rand() * 10.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; # bias Cumulus clouds towards larger sizes due to lots of water vapour @@ -1265,7 +1269,7 @@ calc_geo(blat); var vis = 9000.0 + rand() * 10000.0; var T = 20.0 + rand() * 15.0; -var spread = 3.0 + 2.0 * rand(); +var spread = 8.0 + 2.0 * rand(); var D = T - spread; var p = 970 + rand() * 10.0; p = adjust_p(p); @@ -1274,7 +1278,7 @@ var p = 970 + rand() * 10.0; p = adjust_p(p); local_weather.set_weather_station(blat, blon, alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; # bias Cumulus clouds towards larger sizes due to lots of water vapour @@ -1402,7 +1406,7 @@ calc_geo(blat); var vis = 20000.0 + rand() * 10000.0; var T = 20.0 + rand() * 8.0; -var spread = 3.0 + 2.0 * rand(); +var spread = 8.0 + 2.0 * rand(); var D = T - spread; var p = 1005 + rand() * 10.0; p = adjust_p(p); @@ -1425,7 +1429,7 @@ x = -15000.0; y = -15000.0; local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis*0.7, T+3.0, D+3.0, (p-2.0) * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; # thunderstorms first @@ -1536,7 +1540,7 @@ calc_geo(blat); var vis = 20000.0 + rand() * 5000.0; var T = 10.0 + rand() * 8.0; -var spread = 3.0 + 3.0 * rand(); +var spread = 9.0 + 4.0 * rand(); var D = T - spread; var p = 1005 + rand() * 10.0; p = adjust_p(p); @@ -1559,7 +1563,7 @@ x = -15000.0; y = -15000.0; local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; # some weak Cumulus development @@ -1636,7 +1640,7 @@ calc_geo(blat); var vis = 15000.0 + rand() * 5000.0; var T = 13.0 + rand() * 8.0; -var spread = 2.5 + 2.5 * rand(); +var spread = 8.0 + 2.0 * rand(); var D = T - spread; var p = 1005 + rand() * 10.0; p = adjust_p(p); @@ -1659,7 +1663,7 @@ x = -15000.0; y = -15000.0; local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0; +var alt = spread * 400.0; var strength = 0.0; # followed by random patches of Cirrostratus @@ -1753,7 +1757,7 @@ calc_geo(blat); var vis = 12000.0 + rand() * 3000.0; var T = 15.0 + rand() * 7.0; -var spread = 2.5 + 1.5 * rand(); +var spread = 7.0 + 2.0 * rand(); var D = T - spread; var p = 1005 + rand() * 10.0; p = adjust_p(p); @@ -1776,7 +1780,7 @@ x = -15000.0; y = -15000.0; local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; +var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; var strength = 0.0; # closed Stratus layer @@ -1860,7 +1864,7 @@ calc_geo(blat); var vis = 12000.0 + rand() * 3000.0; var T = 17.0 + rand() * 6.0; -var spread = 2.0 + 1.0 * rand(); +var spread = 5.0 + 2.0 * rand(); var D = T - spread; var p = 1005 + rand() * 10.0; p = adjust_p(p); @@ -1883,7 +1887,7 @@ x = -15000.0; y = -15000.0; local_weather.set_weather_station(blat +get_lat(x,y,phi), blon + get_lon(x,y,phi), alt_offset, vis, T, D, p * hp_to_inhg); # altitude for the lowest layer -var alt = spread * 1000.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; +var alt = spread * 400.0 + local_weather.cloud_vertical_size_map["Nimbus"] * 0.5 * m_to_ft; var strength = 0.0; # low Nimbostratus layer @@ -1927,120 +1931,6 @@ tile_finished(); - - - - - - -#################################### -# Glider's sky -#################################### - -var set_gliders_sky_tile = func { - -setprop(lw~"tiles/code","gliders_sky"); - -tile_start(); - -var x = 0.0; -var y = 0.0; -var lat = 0.0; -var lon = 0.0; - -var alpha = getprop(lw~"tmp/tile-orientation-deg"); -var phi = alpha * math.pi/180.0; -var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft"); - -# get tile center coordinates - -var blat = getprop(lw~"tiles/tmp/latitude-deg"); -var blon = getprop(lw~"tiles/tmp/longitude-deg"); -calc_geo(blat); - -# first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure) -local_weather.set_weather_station(blat, blon, alt_offset, 35000.0, 20.0, 16.0, 1018 * hp_to_inhg); - - - -var alt = 3000.0; - -# add convective clouds - -var strength = 0.5; -var n = int(4000 * strength); # calculate the number of placement tries from tile size 20x20km and strength -local_weather.create_cumosys(blat,blon, alt+alt_offset,n, 20000.0); - -# store convective altitude and strength - -append(weather_dynamics.tile_convective_altitude,alt); -append(weather_dynamics.tile_convective_strength,strength); - -tile_finished(); - - -} - -#################################### -# Blue thermals -#################################### - -var set_blue_thermals_tile = func { - -setprop(lw~"tiles/code","blue_thermals"); - -tile_start(); - -var x = 0.0; -var y = 0.0; -var lat = 0.0; -var lon = 0.0; - -var alpha = getprop(lw~"tmp/tile-orientation-deg"); -var phi = alpha * math.pi/180.0; -var alt_offset = getprop(lw~"tmp/tile-alt-offset-ft"); - -# get tile center coordinates - -var blat = getprop(lw~"tiles/tmp/latitude-deg"); -var blon = getprop(lw~"tiles/tmp/longitude-deg"); -calc_geo(blat); - -# first weather info for tile center (lat, lon, visibility, temperature, dew point, pressure) -local_weather.set_weather_station(blat, blon, alt_offset, 45000.0, 20.0, 15.0, 1018 * hp_to_inhg); - -local_weather.generate_thermal_lift_flag = 3; - -var alt = 5000.0; - -# add convective clouds - -# set flag to blue thermal generation -if (local_weather.generate_thermal_lift_flag !=0) - {local_weather.generate_thermal_lift_flag = 3;} - -var strength = 0.9; -var n = int(4000 * strength); # calculate the number of placement tries from tile size 20x20km and strength -local_weather.create_cumosys(blat,blon, 5000.0+alt_offset,n, 20000.0); - -# set flag back to normal thermal generation -if (local_weather.generate_thermal_lift_flag !=0) - {local_weather.generate_thermal_lift_flag = 0;} - -# store convective altitude and strength - -append(weather_dynamics.tile_convective_altitude,alt); -append(weather_dynamics.tile_convective_strength,strength); - -tile_finished(); - - -} - - - - - #################################### # METAR #################################### @@ -2497,23 +2387,31 @@ var set_METAR_weather_station = func { var create_8_8_stratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + local_weather.create_streak("Stratus",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0); } var create_8_8_tstratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 650.0;} + local_weather.create_streak("Stratus (thin)",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0); } var create_8_8_cirrostratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,30,1250.0,0.0,400.0,30,1250.0,0.0,400.0,alpha,1.0); } var create_8_8_nimbus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0); @@ -2556,6 +2454,7 @@ var create_8_8_nimbus_var3 = func (lat, lon, alt, alpha) { var phi = alpha * math.pi/180.0; + local_weather.create_streak("Nimbus",lat, lon, alt,500.0,35,1111.0,0.0,200.0,35,1111.0,0.0,200.0,alpha,1.0); for (var i=0; i<6; i=i+1) @@ -2575,6 +2474,8 @@ for (var i=0; i<6; i=i+1) var create_8_8_nimbus_rain = func (lat, lon, alt, alpha, rain) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 3000.0;} + if (local_weather.detailed_clouds_flag == 0) {local_weather.create_streak("Nimbus",lat, lon, alt,500.0,32,1250.0,0.0,200.0,32,1250.0,0.0,200.0,alpha,1.0);} else @@ -2601,6 +2502,8 @@ else var create_8_8_stratus_rain = func (lat, lon, alt, alpha, rain) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + local_weather.create_streak("Stratus",lat, lon, alt,500.0,32,1250.0,0.0,400.0,32,1250.0,0.0,400.0,alpha,1.0); if (rain > 0.1) @@ -2617,6 +2520,8 @@ else var create_6_8_stratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + local_weather.create_streak("Stratus",lat, lon, alt,500.0,20,0.0,0.2,20000.0,20,0.0,0.2,20000.0,alpha,1.0); } @@ -2627,6 +2532,7 @@ var create_6_8_nimbus_rain = func (lat, lon, alt, alpha, rain) { var phi = alpha * math.pi/180.0; +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 3000.0;} for (var i = 0; i < 3; i = i + 1) { @@ -2656,6 +2562,7 @@ var create_6_8_stratus_rain = func (lat, lon, alt, alpha, rain) { var phi = alpha * math.pi/180.0; +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} for (var i = 0; i < 3; i = i + 1) { @@ -2682,16 +2589,22 @@ for (var i = 0; i < 3; i = i + 1) var create_6_8_stratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + local_weather.create_undulatus("Stratus",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0); } var create_6_8_tstratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 650.0;} + local_weather.create_undulatus("Stratus (thin)",lat, lon, alt,300.0,10,4000.0,0.1,400.0,50,800.0,0.1,100.0, 1000.0, alpha,1.0); } var create_6_8_cirrostratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + local_weather.create_streak("Cirrostratus",lat,lon,alt,500.0,24,1500.0,0.0,900.0,24,1500.0,0.0,900.0,alpha,1.0); } @@ -2720,6 +2633,8 @@ else var create_4_8_stratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 15000; var y = 2.0 * (rand()-0.5) * 15000; @@ -2747,6 +2662,8 @@ var create_4_8_stratus_patches = func (lat, lon, alt, alpha) { var phi = alpha * math.pi/180.0; +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + for (var i=0; i<16; i=i+1) { var x = 2.0 * (rand()-0.5) * 18000; @@ -2762,6 +2679,8 @@ var create_4_8_tstratus_patches = func (lat, lon, alt, alpha) { var phi = alpha * math.pi/180.0; +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 650.0;} + for (var i=0; i<22; i=i+1) { var x = 2.0 * (rand()-0.5) * 18000; @@ -2782,6 +2701,8 @@ var create_4_8_sstratus_patches = func (lat, lon, alt, alpha) { var phi = alpha * math.pi/180.0; +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 800.0;} + for (var i=0; i<22; i=i+1) { var x = 2.0 * (rand()-0.5) * 18000; @@ -2798,6 +2719,8 @@ for (var i=0; i<22; i=i+1) var create_4_8_cirrostratus_patches = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<6; i=i+1) @@ -2813,12 +2736,16 @@ for (var i=0; i<6; i=i+1) var create_4_8_cirrostratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + local_weather.create_undulatus("Cirrostratus",lat, lon, alt,300.0,5,8000.0,0.1,400.0,40,1000.0,0.1,100.0, 1500.0, alpha,1.0); } var create_4_8_stratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 5000; var y = 2.0 * (rand()-0.5) * 5000; @@ -2833,6 +2760,8 @@ local_weather.create_streak("Stratus",lat+get_lat(x,y-4000,phi), lon+get_lon(x,y var create_4_8_tstratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 650.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 5000; var y = 2.0 * (rand()-0.5) * 5000; @@ -2847,6 +2776,8 @@ local_weather.create_streak("Stratus (thin)",lat+get_lat(x,y-4000,phi), lon+get_ var create_4_8_sstratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 800.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 5000; var y = 2.0 * (rand()-0.5) * 5000; @@ -2860,6 +2791,8 @@ local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get var create_4_8_cirrocumulus_bank = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 5000; var y = 2.0 * (rand()-0.5) * 5000; @@ -2873,6 +2806,8 @@ local_weather.create_streak("Cirrocumulus (cloudlet)",lat+get_lat(x,y,phi), lon+ var create_4_8_cirrocumulus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 5000; var y = 2.0 * (rand()-0.5) * 5000; @@ -2886,6 +2821,8 @@ local_weather.create_streak("Cirrocumulus (cloudlet)",lat+get_lat(x,y,phi), lon+ var create_4_8_cirrocumulus_streaks = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; var beta = 90.0 + (rand() -0.5) * 30.0; @@ -2904,6 +2841,8 @@ for (var i=0; i<2; i=i+1) var create_4_8_altocumulus_perlucidus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<20; i=i+1) @@ -2919,6 +2858,8 @@ for (var i=0; i<20; i=i+1) var create_4_8_alttstratus_streaks = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<10; i=i+1) @@ -2937,6 +2878,8 @@ for (var i=0; i<10; i=i+1) var create_4_8_alttstratus_patches = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<14; i=i+1) @@ -2966,6 +2909,8 @@ else var create_2_8_stratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1500.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<8; i=i+1) @@ -2981,6 +2926,8 @@ for (var i=0; i<8; i=i+1) var create_2_8_tstratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 650.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<8; i=i+1) @@ -2997,6 +2944,8 @@ for (var i=0; i<8; i=i+1) var create_2_8_sstratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 800.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<8; i=i+1) @@ -3018,6 +2967,8 @@ for (var i=0; i<8; i=i+1) var create_2_8_sstratus_streak = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 800.0;} + var phi = alpha * math.pi/180.0; var x = 2.0 * (rand()-0.5) * 6000; @@ -3030,6 +2981,8 @@ local_weather.create_streak("Stratus (structured)",lat+get_lat(x,y,phi), lon+get var create_2_8_cirrostratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<3; i=i+1) @@ -3045,6 +2998,8 @@ for (var i=0; i<3; i=i+1) var create_2_8_cirrocumulus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<25; i=i+1) @@ -3072,6 +3027,8 @@ local_weather.create_streak("Cirrus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), var create_2_8_alttstratus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} + var phi = alpha * math.pi/180.0; for (var i=0; i<4; i=i+1) @@ -3100,6 +3057,9 @@ for (var i=0; i<2; i=i+1) } + + + var create_1_8_altocumulus_scattered = func (lat, lon, alt, alpha) { var phi = alpha * math.pi/180.0; @@ -3153,12 +3113,15 @@ local_weather.create_streak("Cirrus",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), var create_1_8_cirrostratus_undulatus = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 1800.0;} + local_weather.create_undulatus("Cirrostratus",lat, lon, alt,300.0,1,8000.0,0.0,400.0,40,1000.0,0.1,100.0, 1500.0, alpha,1.0); } var create_1_8_contrails = func (lat, lon, alt, alpha) { +if (local_weather.hardcoded_clouds_flag == 1) {alt = alt - 300.0;} var phi = alpha * math.pi/180.0; @@ -3239,14 +3202,29 @@ var n = int(9 + rand() * 7); var alt_offset = 0.5 * local_weather.cloud_vertical_size_map["Cumulus"] * ft_to_m; -local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+90.0+beta,tri); +if (local_weather.hardcoded_clouds_flag == 0) + { + local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+90.0+beta,tri); -local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+270.0+beta,tri); + local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt + alt_offset,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+270.0+beta,tri); -local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+5250,phi), lon+get_lon(x,y+5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+90.0+beta,tri); + local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+5250,phi), lon+get_lon(x,y+5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+90.0+beta,tri); -local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-5250,phi), lon+get_lon(x,y-5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+270.0+beta,tri); + local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-5250,phi), lon+get_lon(x,y-5250,phi), alt,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+270.0+beta,tri); + } +else + { + local_weather.create_streak("Stratocumulus",lat+get_lat(x,y+7500,phi), lon+get_lon(x,y+7500,phi), alt-1000.0 ,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+90.0+beta,tri); + + local_weather.create_streak("Stratocumulus",lat+get_lat(x,y-7500,phi), lon+get_lon(x,y-7500,phi), alt-1000.0 ,500.0,m,1100.0,0.1,400.0,n,1100.0,0.1,400.0,alpha+270.0+beta,tri); + + + local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y+5250,phi), lon+get_lon(x,y+5250,phi), alt-1000.0,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+90.0+beta,tri); + + local_weather.create_streak("Stratocumulus bottom",lat+get_lat(x,y-5250,phi), lon+get_lon(x,y-5250,phi), alt-1000.0,0.0,m+1,700.0,0.2,400.0,n+1,700.0,0.0,400.0,alpha+270.0+beta,tri); + + } } @@ -3354,6 +3332,28 @@ local_weather.create_effect_volume(1, lat, lon, 7500.0 * 0.7 * scale, 7500.0 * 0 } +# spectacular, but not useful in practice + + +var create_2_8_cirrocumulus_patches = func (lat, lon, alt, alpha) { + +var phi = alpha * math.pi/180.0; + +for (var i=0; i<2; i=i+1) + { + var x = 2.0 * (rand()-0.5) * 10000; + var y = 2.0 * (rand()-0.5) * 10000; + var tri = 1.5 + rand(); + var beta = rand() * math.pi; + + #local_weather.create_streak("Cirrocumulus (new)",lat+get_lat(x,y,phi), lon+get_lon(x,y,phi), alt,0.0,50,150.0,0.2,50.0,50,150.0,0.2,50.0,alpha ,tri); + + local_weather.create_layer("Cirrocumulus (new)", lat+get_lat(x,y,phi), lon+get_lat(x,y,phi), alt, 0.0, 8500.0, 5000.0, beta, 15.0, 0.25, 0, 0.0); + + } +} + + ################### # helper functions ################### diff --git a/gui/dialogs/local_weather_tiles.xml b/gui/dialogs/local_weather_tiles.xml index de1e571e8..aacc2d387 100644 --- a/gui/dialogs/local_weather_tiles.xml +++ b/gui/dialogs/local_weather_tiles.xml @@ -6,20 +6,20 @@ local_weather_tiles 310 - 360 + 385 false 5 - 330 + 355 10 - 305 + 330 280 25 true @@ -35,7 +35,7 @@ Coldfront Warmfront Tropical - + Test tile dialog-apply @@ -51,13 +51,13 @@ 5 - 270 + 295 67 - 270 + 295 40 25 /local-weather/tmp/tile-orientation-deg @@ -65,13 +65,13 @@ 105 - 270 + 295 125 - 270 + 295 30 25 /local-weather/tmp/windspeed-kt @@ -79,7 +79,7 @@ 155 - 270 + 295 @@ -87,7 +87,7 @@ 240 - 270 + 295 50 25 /local-weather/tmp/tile-alt-offset-ft @@ -96,7 +96,7 @@ 5 - 240 + 265 @@ -104,7 +104,7 @@ 65 - 240 + 265 50 20 0.0 @@ -119,14 +119,14 @@ 112 - 240 + 265 167 - 240 + 265 50 20 0.0 @@ -139,14 +139,14 @@ 215 - 240 + 265 240 - 240 + 265 50 20 0.0 @@ -162,14 +162,14 @@ 5 - 210 + 235 150 - 210 + 235 140 25 true @@ -187,13 +187,13 @@ 5 - 180 + 205 150 - 180 + 205 140 25 true @@ -209,7 +209,7 @@ 10 - 150 + 175 15 15 @@ -221,7 +221,7 @@ 150 - 150 + 175 15 15 @@ -233,7 +233,7 @@ 10 - 125 + 150 15 15 @@ -245,7 +245,7 @@ 150 - 125 + 150 15 15 @@ -257,7 +257,7 @@ 10 - 100 + 125 15 15 @@ -269,7 +269,7 @@ 150 - 100 + 125 15 15 @@ -279,6 +279,30 @@ + + 10 + 100 + 15 + 15 + + /local-weather/config/detailed-terrain-interaction-flag + + dialog-apply + + + + + 150 + 100 + 15 + 15 + + /local-weather/config/realistic-visibility-flag + + dialog-apply + + + 10 75 From a2b26f8d59933750aadc7329b9c0098865679e09 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Fri, 23 Sep 2011 23:25:15 +0200 Subject: [PATCH 2/2] Local Weather 1.36 by Thorsten Renk --- Nasal/local_weather/compat_layer.nas | 12 ++++ Nasal/local_weather/local_weather.nas | 99 +++++++++++++++++++-------- Shaders/road.frag | 6 ++ Shaders/road.geom | 30 ++++++++ Shaders/road.vert | 11 +++ Shaders/skydome.frag | 31 ++++++++- Shaders/skydome.vert | 25 ++++--- 7 files changed, 177 insertions(+), 37 deletions(-) create mode 100644 Shaders/road.frag create mode 100644 Shaders/road.geom create mode 100644 Shaders/road.vert diff --git a/Nasal/local_weather/compat_layer.nas b/Nasal/local_weather/compat_layer.nas index 1df26b60b..4038a9a0e 100644 --- a/Nasal/local_weather/compat_layer.nas +++ b/Nasal/local_weather/compat_layer.nas @@ -479,6 +479,18 @@ if (features.can_set_scattering == 1) } +#################################### +# set skydome scattering parameters +#################################### + +var setSkydomeShader = func (r, m, d) { + +setprop("/sim/rendering/rayleigh", r); +setprop("/sim/rendering/mie", m); +setprop("/sim/rendering/dome-density",d); + +} + ########################################################### # set wind to given direction and speed ########################################################### diff --git a/Nasal/local_weather/local_weather.nas b/Nasal/local_weather/local_weather.nas index d6f7e31e5..185945f77 100644 --- a/Nasal/local_weather/local_weather.nas +++ b/Nasal/local_weather/local_weather.nas @@ -594,12 +594,14 @@ var alt1 = vis_alt1; var alt2 = alt1 + 1500.0; -#var inc1 = 0.15; -#var inc2 = 5.0; -#var inc3 = 0.7; - # compute the visibility gradients +if (realistic_visibility_flag == 1) + { + vis_aloft = vis_aloft * 2.0; + vis_ovcst = vis_ovcst * 3.0; + } + var inc1 = 0.1 * (vis_aloft - vis)/(vis_alt1 - ialt); var inc2 = 0.9 * (vis_aloft - vis)/1500.0; var inc3 = (vis_ovcst - vis_aloft)/(ovcst_alt_high - vis_alt1+1500); @@ -607,7 +609,7 @@ var inc4 = 0.5; if (realistic_visibility_flag == 1) - {inc4 = inc4 * 8.0;} + {inc4 = inc4 * 3.0;} # compute the visibility @@ -628,35 +630,67 @@ else if (altitude > ovcst_alt_high) # limit visibility (otherwise memory consumption is very bad...) -if (vis > 140000.0) - {vis = 140000.0;} +if (vis > 120000.0) + {vis = 120000.0;} -# compute the horizon shading +# determine scattering shader parameters if scattering shader is on -if (altitude < scatt_alt_low) +if (scattering_shader_flag == 1) { - var scatt = scatt_max; - } -else if (altitude < scatt_alt_high) - { - var scatt = scatt_max + (0.95 - scatt_max) * (altitude - scatt_alt_low)/(scatt_alt_high-scatt_alt_low); + var rayleigh = 0.0003 ; + var mie = 0.003; + var density = 0.3; + + if (altitude < 30000.0) + { + rayleigh = 0.0004 - altitude/30000.0 * 0.0001; + mie = 0.004 - altitude/30000.0 * 0.001; + } + else if (altitude < 60000.0) + { + rayleigh = 0.0003 - (altitude-30000.0)/30000.0 * 0.0001; + mie = 0.003 - (altitude-30000.0)/30000.0 * 0.001; + } + else if (altitude < 85000.0) + { + rayleigh = 0.0002 - (altitude-60000.0)/25000.0 * 0.0001; + mie = 0.002; + } + else + {rayleigh = 0.0001; mie = 0.002;} } +# otherwise compute normal skydome shader parameters else - {var scatt = 0.95;} + { + + # compute the horizon shading + + if (altitude < scatt_alt_low) + { + var scatt = scatt_max; + } + else if (altitude < scatt_alt_high) + { + var scatt = scatt_max + (0.95 - scatt_max) * (altitude - scatt_alt_low)/(scatt_alt_high-scatt_alt_low); + } + else + {var scatt = 0.95;} # compute the overcast haze -if (altitude < ovcst_alt_low) - { - var ovcst = ovcst_max; + if (altitude < ovcst_alt_low) + { + var ovcst = ovcst_max; + } + else if (altitude < ovcst_alt_high) + { + var ovcst = ovcst_max - ovcst_max * (altitude - ovcst_alt_low)/(ovcst_alt_high-ovcst_alt_low); + } + else + {var ovcst = 0.0;} + } -else if (altitude < ovcst_alt_high) - { - var ovcst = ovcst_max - ovcst_max * (altitude - ovcst_alt_low)/(ovcst_alt_high-ovcst_alt_low); - } -else - {var ovcst = 0.0;} # limit relative changes of the visibility, will make for gradual transitions @@ -678,8 +712,16 @@ setprop(lwi~"dewpoint-degc",D); if (p > 10.0) {setprop(lwi~"pressure-sea-level-inhg",p);} setprop(lwi~"turbulence",0.0); -compat_layer.setScattering(scatt); -compat_layer.setOvercast(ovcst); + +if (scattering_shader_flag == 1) + { + local_weather.setSkydomeShader(rayleigh, mie, density); + } +else + { + local_weather.setScattering(scatt); + local_weather.setOvercast(ovcst); + } # now check if an effect volume writes the property and set only if not @@ -3479,6 +3521,7 @@ debug_output_flag = getprop(lw~"config/debug-output-flag"); fps_control_flag = getprop(lw~"config/fps-control-flag"); realistic_visibility_flag = getprop(lw~"config/realistic-visibility-flag"); detailed_terrain_interaction_flag = getprop(lw~"config/detailed-terrain-interaction-flag"); +scattering_shader_flag = getprop("/sim/rendering/scattering-shader"); } @@ -4103,6 +4146,7 @@ setlistener(lw~"config/target-framerate", func {target_framerate = getprop(lw~"c setlistener(lw~"config/small-scale-persistence", func {weather_tiles.small_scale_persistence = getprop(lw~"config/small-scale-persistence");}); +setlistener("/sim/rendering/scattering-shader", func {scattering_shader_flag = getprop("/sim/rendering/scattering-shader"); }); } @@ -4525,8 +4569,9 @@ var local_weather_startup_flag = 0; var fps_control_flag = 0; var buffer_flag = 1; var detailed_terrain_interaction_flag = 1; -var hardcoded_clouds_flag = 0; +var hardcoded_clouds_flag = 1; var realistic_visibility_flag = 0; +var scattering_shader_flag = 0; # globals for framerate controlled cloud management diff --git a/Shaders/road.frag b/Shaders/road.frag new file mode 100644 index 000000000..0b60098e3 --- /dev/null +++ b/Shaders/road.frag @@ -0,0 +1,6 @@ +#version 120 + +uniform sampler2d BaseTex; + +void main() { +} diff --git a/Shaders/road.geom b/Shaders/road.geom new file mode 100644 index 000000000..ba686d0aa --- /dev/null +++ b/Shaders/road.geom @@ -0,0 +1,30 @@ +#version 120 +#extension GL_EXT_geometry_shader4 : enable + +varying in vec4 ecPositionIn[]; +varying in vec3 ecNormalIn[]; + +varying out vec4 ecPosition; +varying out vec3 ecNormal; + +void main() { + gl_Position = gl_PositionIn[0]; + gl_TexCoord[0] = gl_TexCoordIn[0][0]; + ecPosition = ecPositionIn[0]; + ecNormal = ecNormalIn[0]; + EmitVertex(); + + gl_Position = gl_PositionIn[1]; + gl_TexCoord[0] = gl_TexCoordIn[1][0]; + ecPosition = ecPositionIn[1]; + ecNormal = ecNormalIn[1]; + EmitVertex(); + + gl_Position = gl_PositionIn[2]; + gl_TexCoord[0] = gl_TexCoordIn[2][0]; + ecPosition = ecPositionIn[2]; + ecNormal = ecNormalIn[2]; + EmitVertex(); + + EndPrimitive(); +} diff --git a/Shaders/road.vert b/Shaders/road.vert new file mode 100644 index 000000000..8783af590 --- /dev/null +++ b/Shaders/road.vert @@ -0,0 +1,11 @@ +#version 120 + +varying vec4 ecPositionIn; +varying vec3 ecNormalIn; + +void main() { + ecPositionIn = gl_ModelViewMatrix * gl_Vertex; + ecNormalIn = gl_NormalMatrix * gl_Normal; + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + gl_Position = ftransform(); +} diff --git a/Shaders/skydome.frag b/Shaders/skydome.frag index a120eb2aa..c50309fc5 100644 --- a/Shaders/skydome.frag +++ b/Shaders/skydome.frag @@ -6,7 +6,8 @@ varying vec3 rayleigh; varying vec3 mie; -varying vec3 eye; +varying vec3 eye; +varying float ct; float miePhase(in float cosTheta, in float g) { @@ -30,9 +31,35 @@ float rayleighPhase(in float cosTheta) void main() { float cosTheta = dot(normalize(eye), gl_LightSource[0].position.xyz); - + + vec3 color = rayleigh * rayleighPhase(cosTheta); color += mie * miePhase(cosTheta, -0.8); + + vec3 white = vec3(1.0,1.0,1.0); + + + //float scale = dot(normalize(white),normalize(color)); + //float scale1 = 1.0 - exp(-5.0 * length(color)); + //float scale2 = length(color)/length(white); + + //if (scale1>1.0) color = color/scale1; + + //color = color/scale1; + + + + if (color.x > 0.8) color.x = 0.8 + 0.8* log(color.x/0.8); + if (color.y > 0.8) color.y = 0.8 + 0.8* log(color.y/0.8); + if (color.z > 0.8) color.z = 0.8 + 0.8* log(color.z/0.8); + + vec3 fogColor = vec3 (gl_Fog.color.x, gl_Fog.color.y, gl_Fog.color.z); + + + if (ct > -0.03) color = mix(color, fogColor ,smoothstep(0.2, -0.2, ct)); + else color = mix (color, fogColor, smoothstep(0.2,-0.2,-0.03)); + + gl_FragColor = vec4(color, 1.0); gl_FragDepth = 0.1; diff --git a/Shaders/skydome.vert b/Shaders/skydome.vert index 917aba508..5c3505f01 100644 --- a/Shaders/skydome.vert +++ b/Shaders/skydome.vert @@ -10,7 +10,8 @@ uniform mat4 osg_ViewMatrixInverse; varying vec3 rayleigh; varying vec3 mie; -varying vec3 eye; +varying vec3 eye; +varying float ct; // Dome parameters from FG and screen const float domeSize = 80000.0; @@ -48,7 +49,10 @@ float intersection (in float cheight, in vec3 ray, in float rad2) // Return the scale function at height = 0 for different thetas float outscatterscale(in float costheta) -{ +{ + + if (costheta < -0.12) costheta = -0.12 - 4.0* (costheta+0.12) ; + float x = 1.0 - costheta; float a = 1.16941; @@ -98,7 +102,8 @@ void main() // We are in space, calculate correct positiondelta! relativePosition -= space * normalize(relativePosition); } - + + vec3 positionDelta = relativePosition / fSamples; float deltaLength = length(positionDelta); // Should multiply by something? @@ -111,7 +116,9 @@ void main() // If sample is above camera, reverse ray direction if(positionDelta.z < 0.0) cameraCosTheta = -positionDelta.z / deltaLength; else cameraCosTheta = positionDelta.z / deltaLength; - + + float cameraCosTheta1 = -positionDelta.z / deltaLength; + // Total attenuation from camera to skydome float totalCameraScatter = outscatter(cameraCosTheta, scaledAltitude); @@ -135,7 +142,8 @@ void main() // Again, reverse the direction if vertex is over the camera float cameraScatter; if(relativePosition.z < 0.0) { // Vertex is over the camera - cameraCosTheta = -dot(normalize(positionDelta), normalize(sample)); + cameraCosTheta = -dot(normalize(positionDelta), normalize(sample)); + cameraScatter = totalCameraScatter - outscatter(cameraCosTheta, sampleAltitude); } else { // Vertex is below camera cameraCosTheta = dot(normalize(positionDelta), normalize(sample)); @@ -151,12 +159,13 @@ void main() sample += positionDelta; } - color *= sunIntensity; - + color *= sunIntensity; + ct = cameraCosTheta1; rayleigh = rayleighK * color; mie = mieK * color; eye = gl_NormalMatrix * positionDelta; - + + // We need to move the camera so that the dome appears to be centered around earth