X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fsky%2Fsky.cxx;h=5cde898fb29e360e460a0c0f12b50326c597dd53;hb=6531b1ebbc5c82bed5f52869511e880afd05bfcf;hp=dc0627f18722036bf7098ef54c9fd5271c68a363;hpb=6cf271661519f849d83de23fdec47846e731d79f;p=simgear.git diff --git a/simgear/sky/sky.cxx b/simgear/sky/sky.cxx index dc0627f1..5cde898f 100644 --- a/simgear/sky/sky.cxx +++ b/simgear/sky/sky.cxx @@ -26,13 +26,11 @@ # include #endif -#include // plib include +#include +#include -#include #include -#include - #include "sky.hxx" @@ -46,6 +44,8 @@ SGSky::SGSky( void ) { puff_progression = 0; ramp_up = 0.15; ramp_down = 0.15; + // ramp_up = 4.0; + // ramp_down = 4.0; } @@ -98,27 +98,22 @@ void SGSky::build( double sun_size, double moon_size, // add the cloud ssgStates to the material lib FGPath cloud_path; - ssgSimpleState *cloud_state; cloud_path.set( tex_path.str() ); - cloud_path.append( "cirrus.rgba" ); - cloud_state = SGCloudMakeState( cloud_path.str() ); - material_lib.add_item( "CloudCirrus", cloud_state ); + cloud_path.append( "overcast.rgb" ); + cloud_mats[SG_CLOUD_OVERCAST] = SGCloudMakeState( cloud_path.str() ); cloud_path.set( tex_path.str() ); cloud_path.append( "mostlycloudy.rgba" ); - cloud_state = SGCloudMakeState( cloud_path.str() ); - material_lib.add_item( "CloudMostlyCloudy", cloud_state ); + cloud_mats[SG_CLOUD_MOSTLY_CLOUDY] = SGCloudMakeState( cloud_path.str() ); cloud_path.set( tex_path.str() ); cloud_path.append( "mostlysunny.rgba" ); - cloud_state = SGCloudMakeState( cloud_path.str() ); - material_lib.add_item( "CloudMostlySunny", cloud_state ); + cloud_mats[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState( cloud_path.str() ); cloud_path.set( tex_path.str() ); - cloud_path.append( "overcast.rgb" ); - cloud_state = SGCloudMakeState( cloud_path.str() ); - material_lib.add_item( "CloudOvercast", cloud_state ); + cloud_path.append( "cirrus.rgba" ); + cloud_mats[SG_CLOUD_CIRRUS] = SGCloudMakeState( cloud_path.str() ); } @@ -136,7 +131,7 @@ bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color, { if ( effective_visibility > 1000.0 ) { enable(); - dome->repaint( sky_color, fog_color, sun_angle ); + dome->repaint( sky_color, fog_color, sun_angle, effective_visibility ); oursun->repaint( sun_angle ); moon->repaint( moon_angle ); planets->repaint( sun_angle, nplanets, planet_data ); @@ -182,18 +177,36 @@ bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, } -// draw background portions of the sky -void SGSky::draw_background() { +// draw background portions of the sky ... do this before you draw the +// rest of your scene. +void SGSky::preDraw() { ssgCullAndDraw( pre_root ); } -// draw scenery elements of the sky -void SGSky::draw_scene( float alt ) { +// draw translucent clouds ... do this after you've drawn all the +// oapaque elements of your scene. +void SGSky::postDraw( float alt ) { + float slop = 5.0; // if we are closer than this to a cloud layer, + // don't draw clouds + + int in_cloud = -1; // cloud we are in - if ( effective_visibility < 4000.0 ) { - // bail and don't draw clouds - return; + // check where we are relative to the cloud layers + for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { + float asl = cloud_layers[i]->get_asl(); + float thickness = cloud_layers[i]->get_thickness(); + + if ( alt < asl - slop ) { + // below cloud layer + } else if ( alt < asl + thickness + slop ) { + // in cloud layer + + // bail now and don't draw any clouds + in_cloud = i; + } else { + // above cloud layer + } } // determine rendering order @@ -207,30 +220,39 @@ void SGSky::draw_scene( float alt ) { if ( pos == 0 ) { // we are below all the cloud layers, draw top to bottom for ( int i = cloud_layers.size() - 1; i >= 0; --i ) { - cloud_layers[i]->draw(); + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } } } else if ( pos >= (int)cloud_layers.size() ) { // we are above all the cloud layers, draw bottom to top for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { - cloud_layers[i]->draw(); + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } } } else { // we are between cloud layers, draw lower layers bottom to // top and upper layers top to bottom for ( int i = 0; i < pos; ++i ) { - cloud_layers[i]->draw(); + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } } for ( int i = cloud_layers.size() - 1; i >= pos; --i ) { - cloud_layers[i]->draw(); + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } } } } -void SGSky::add_cloud_layer( double asl, double thickness, double transition, - SGCloudType type ) { +void SGSky::add_cloud_layer( double asl, double thickness, + double transition, double span, + ssgSimpleState *state ) { SGCloudLayer *layer = new SGCloudLayer; - layer->build(tex_path, 40000.0f, asl, thickness, transition, type ); + layer->build( span, asl, thickness, transition, state ); layer_list_iterator current = cloud_layers.begin(); layer_list_iterator last = cloud_layers.end(); @@ -251,6 +273,23 @@ void SGSky::add_cloud_layer( double asl, double thickness, double transition, } +void SGSky::add_cloud_layer( double asl, double thickness, + double transition, double span, + const string &tex_path ) { + ssgSimpleState *state = SGCloudMakeState( tex_path ); + add_cloud_layer( asl, thickness, transition, span, state ); +} + + +void SGSky::add_cloud_layer( double asl, double thickness, + double transition, double span, + SGCloudType type ) { + if ( type > 0 && type < SG_MAX_CLOUD_TYPES ) { + add_cloud_layer( asl, thickness, transition, span, cloud_mats[type] ); + } +} + + // modify the current visibility based on cloud layers, thickness, // transition range, and simulated "puffs". void SGSky::modify_vis( float alt, float time_factor ) { @@ -290,25 +329,28 @@ void SGSky::modify_vis( float alt, float time_factor ) { double chance = rnd * rnd * rnd; if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) { in_puff = true; - do { - puff_length = fg_random() * 2.0; // up to 2 seconds - } while ( puff_length <= 0.0 ); + puff_length = fg_random() * 2.0; // up to 2 seconds puff_progression = 0.0; } } if ( in_puff ) { // modify actual_visibility based on puff envelope - + if ( puff_progression <= ramp_up ) { - double x = FG_PI_2 * puff_progression / ramp_up; + double x = 0.5 * SGD_PI * puff_progression / ramp_up; double factor = 1.0 - sin( x ); + // cout << "ramp up = " << puff_progression + // << " factor = " << factor << endl; effvis = effvis * factor; } else if ( puff_progression >= ramp_up + puff_length ) { - double x = FG_PI_2 * + double x = 0.5 * SGD_PI * (puff_progression - (ramp_up + puff_length)) / ramp_down; double factor = sin( x ); + // cout << "ramp down = " + // << puff_progression - (ramp_up + puff_length) + // << " factor = " << factor << endl; effvis = effvis * factor; } else { effvis = 0.0; @@ -325,6 +367,7 @@ void SGSky::modify_vis( float alt, float time_factor ) { // (double)current_options.get_model_hz(); puff_progression += time_factor; + // cout << "time factor = " << time_factor << endl; /* cout << "gml = " << global_multi_loop << " speed up = " << current_options.get_speed_up() @@ -336,9 +379,9 @@ void SGSky::modify_vis( float alt, float time_factor ) { } } - // never let visibility drop below zero - if ( effvis <= 0 ) { - effvis = 0.1; + // never let visibility drop below 25 meters + if ( effvis <= 25.0 ) { + effvis = 25.0; } } } // for