# include <config.h>
#endif
-#include <plib/ssg.h> // plib include
+#include <plib/sg.h>
+#include <plib/ssg.h>
-#include <simgear/constants.h>
#include <simgear/math/fg_random.h>
#include "sky.hxx"
puff_progression = 0;
ramp_up = 0.15;
ramp_down = 0.15;
+ // ramp_up = 4.0;
+ // ramp_down = 4.0;
}
pre_root->addKid( pre_selector );
post_root->addKid( post_selector );
+
+ // add the cloud ssgStates to the material lib
+ FGPath cloud_path;
+
+ cloud_path.set( tex_path.str() );
+ 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_mats[SG_CLOUD_MOSTLY_CLOUDY] = SGCloudMakeState( cloud_path.str() );
+
+ cloud_path.set( tex_path.str() );
+ cloud_path.append( "mostlysunny.rgba" );
+ cloud_mats[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState( cloud_path.str() );
+
+ cloud_path.set( tex_path.str() );
+ cloud_path.append( "cirrus.rgba" );
+ cloud_mats[SG_CLOUD_CIRRUS] = SGCloudMakeState( cloud_path.str() );
}
{
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 );
}
-// 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
+
+ // 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 ( effective_visibility < 4000.0 ) {
- // bail and don't draw clouds
- return;
+ 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
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 ) {
+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);
+ layer->build( span, asl, thickness, transition, state );
layer_list_iterator current = cloud_layers.begin();
layer_list_iterator last = cloud_layers.end();
}
+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 ) {
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;
// (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()
}
}
- // 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