Index: ../../SimGear/source/simgear/environment/visual_enviro.cxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/environment/visual_enviro.cxx,v
retrieving revision 1.14
diff -u -p -r1.14 visual_enviro.cxx
--- ../../SimGear/source/simgear/environment/visual_enviro.cxx	8 Mar 2006 18:16:08 -0000	1.14
+++ ../../SimGear/source/simgear/environment/visual_enviro.cxx	21 Mar 2006 17:26:09 -0000
@@ -34,6 +34,7 @@
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/scene/sky/cloudfield.hxx>
 #include <simgear/scene/sky/newcloud.hxx>
+#include <simgear/props/props.hxx>
 #include "visual_enviro.hxx"
 
 #include <vector>
@@ -51,6 +52,85 @@ typedef struct {
 static float rainpos[MAX_RAIN_SLICE];
 #define MAX_LT_TREE_SEG	400
 
+#define DFL_MIN_LIGHT 0.35
+sgVec3 SGEnviro::min_light = {DFL_MIN_LIGHT, DFL_MIN_LIGHT, DFL_MIN_LIGHT};
+#define DFL_STREAK_BRIGHT_NEARMOST_LAYER 0.9
+SGfloat SGEnviro::streak_bright_nearmost_layer = DFL_STREAK_BRIGHT_NEARMOST_LAYER;
+#define DFL_STREAK_BRIGHT_FARMOST_LAYER 0.5
+SGfloat SGEnviro::streak_bright_farmost_layer = DFL_STREAK_BRIGHT_FARMOST_LAYER; 
+#define DFL_STREAK_PERIOD_MAX 2.5
+SGfloat SGEnviro::streak_period_max = DFL_STREAK_PERIOD_MAX; 
+#define DFL_STREAK_PERIOD_CHANGE_PER_KT 0.005
+SGfloat SGEnviro::streak_period_change_per_kt = DFL_STREAK_PERIOD_CHANGE_PER_KT;
+#define DFL_STREAK_PERIOD_MIN 1.0
+SGfloat SGEnviro::streak_period_min = DFL_STREAK_PERIOD_MIN;
+#define DFL_STREAK_LENGTH_MIN 0.03
+SGfloat SGEnviro::streak_length_min = DFL_STREAK_LENGTH_MIN;
+#define DFL_STREAK_LENGTH_CHANGE_PER_KT 0.0005
+SGfloat SGEnviro::streak_length_change_per_kt = DFL_STREAK_LENGTH_CHANGE_PER_KT;
+#define DFL_STREAK_LENGTH_MAX 0.1
+SGfloat SGEnviro::streak_length_max = DFL_STREAK_LENGTH_MAX;
+#define DFL_STREAK_COUNT_MIN 40
+int SGEnviro::streak_count_min = DFL_STREAK_COUNT_MIN;
+#define DFL_STREAK_COUNT_MAX 190
+#if (DFL_STREAK_COUNT_MAX > MAX_RAIN_SLICE)
+#error "Bad default!"
+#endif
+int SGEnviro::streak_count_max = DFL_STREAK_COUNT_MAX;
+#define DFL_CONE_BASE_RADIUS 15.0
+SGfloat SGEnviro::cone_base_radius = DFL_CONE_BASE_RADIUS;
+#define DFL_CONE_HEIGHT 30.0
+SGfloat SGEnviro::cone_height = DFL_CONE_HEIGHT;
+
+void SGEnviro::config(const SGPropertyNode* n)
+{
+	if (!n) return;
+
+	{
+	const float ml = n->getFloatValue("/min-light", DFL_MIN_LIGHT);
+	sgSetVec3(min_light, ml, ml, ml);
+	}
+
+	streak_bright_nearmost_layer = n->getFloatValue(
+			"/streak-brightness-nearmost-layer", 
+			DFL_STREAK_BRIGHT_NEARMOST_LAYER);
+	streak_bright_farmost_layer = n->getFloatValue(
+			"/streak-brightness-farmost-layer",
+			DFL_STREAK_BRIGHT_FARMOST_LAYER);
+
+	streak_period_max = n->getFloatValue(
+			"/streak-period-max",
+			DFL_STREAK_PERIOD_MAX);
+	streak_period_min = n->getFloatValue(
+			"/streak-period-min",
+			DFL_STREAK_PERIOD_MIN);
+	streak_period_change_per_kt = n->getFloatValue(
+			"/streak-period-change-per-kt",
+			DFL_STREAK_PERIOD_CHANGE_PER_KT);
+
+	streak_length_max = n->getFloatValue(
+			"/streak-length-max",
+			DFL_STREAK_LENGTH_MAX);
+	streak_length_min = n->getFloatValue(
+			"/streak-length-min",
+			DFL_STREAK_LENGTH_MIN);
+	streak_length_change_per_kt = n->getFloatValue(
+			"/streak-length-change-per-kt",
+			DFL_STREAK_LENGTH_CHANGE_PER_KT);
+
+	streak_count_min = n->getIntValue(
+			"/streak-count-min", DFL_STREAK_COUNT_MIN);
+	streak_count_max = n->getIntValue(
+			"/streak-count-max", DFL_STREAK_COUNT_MAX);
+	if (streak_count_max > MAX_RAIN_SLICE)
+		streak_count_max = MAX_RAIN_SLICE;
+
+	cone_base_radius = n->getFloatValue(
+			"/cone-base-radius", DFL_CONE_BASE_RADIUS);
+	cone_height = n->getFloatValue("/cone_height", DFL_CONE_HEIGHT);
+}
+
+
 /**
  * A class to render lightnings.
  */
@@ -85,7 +165,7 @@ static list_of_lightning lightnings;
 
 SGEnviro sgEnviro;
 
-SGEnviro::SGEnviro(void) :
+SGEnviro::SGEnviro() :
 	view_in_cloud(false),
 	precipitation_enable_state(true),
 	precipitation_density(100.0),
@@ -246,7 +326,7 @@ void SGEnviro::setLight(sgVec4 adj_fog_c
 	}
 }
 
-void SGEnviro::callback_cloud(float heading, float alt, float radius, int familly, float dist, int cloudId) {
+void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
 	// send data to wx radar
 	// compute turbulence
 	// draw precipitation
@@ -256,7 +336,7 @@ void SGEnviro::callback_cloud(float head
 	// http://www.pilotfriend.com/flight_training/weather/THUNDERSTORM%20HAZARDS1.htm
 	double turbulence = 0.0;
 	if( dist < radius * radius * 2.25f ) {
-		switch(familly) {
+		switch(family) {
 			case SGNewCloud::CLFamilly_st:
 				turbulence = 0.2;
 				break;
@@ -291,7 +371,7 @@ void SGEnviro::callback_cloud(float head
 	// convert to LWC for radar (experimental)
 	// http://www-das.uwyo.edu/~geerts/cwx/notes/chap08/moist_cloud.html
 	double LWC = 0.0;
-	switch(familly) {
+	switch(family) {
 		case SGNewCloud::CLFamilly_st:
 			LWC = 0.29;
 			break;
@@ -325,7 +405,7 @@ void SGEnviro::callback_cloud(float head
 	// NB:data valid only from cockpit view
 
 	// spawn a new lightning
-	if(lightning_enable_state && min_time_before_lt <= 0.0 && (familly == SGNewCloud::CLFamilly_cb) &&
+	if(lightning_enable_state && min_time_before_lt <= 0.0 && (family == SGNewCloud::CLFamilly_cb) &&
 		dist < 15000.0 * 15000.0 && sg_random() > 0.9f) {
 		double lat, lon;
 		Point3D orig, dest;
@@ -344,7 +424,7 @@ void SGEnviro::callback_cloud(float head
 //		min_time_before_lt = 5.0;
 	}
 	if( (alt - radius * 0.1) > precipitation_max_alt )
-		switch(familly) {
+		switch(family) {
 			case SGNewCloud::CLFamilly_st:
 			case SGNewCloud::CLFamilly_cu:
 			case SGNewCloud::CLFamilly_cb:
@@ -361,26 +441,25 @@ list_of_SGWxRadarEcho *SGEnviro::get_rad
 
 // precipitation rendering code
 void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
-
 	sgVec3 light;
-	sgVec3 min_light = {0.35, 0.35, 0.35};
 	sgAddVec3( light, fog_color, min_light );
 	float da = SG_PI * 2.0f / (float) slices;
 	// low number = faster
-	float speedf = 2.5f - speed / 200.0;
-	if( speedf < 1.0f )
-		speedf = 1.0f;
-	float lenf = 0.03f + speed / 2000.0;
-	if( lenf > 0.10f )
-		lenf = 0.10f;
+	float speedf = streak_period_max - speed * streak_period_change_per_kt;
+	if( speedf < streak_period_min )
+		speedf = streak_period_min;
+	float lenf = streak_length_min + speed * streak_length_change_per_kt;
+	if( lenf > streak_length_max )
+		lenf = streak_length_max;
     float t = fmod((float) elapsed_time, speedf) / speedf;
 //	t = 0.1f;
 	if( !down )
 		t = 1.0f - t;
 	float angle = 0.0f;
-	glColor4f(1.0f, 0.7f, 0.7f, 0.9f);
+	//glColor4f(1.0f, 0.7f, 0.7f, 0.9f); // XXX unneeded? overriden below
 	glBegin(GL_LINES);
-	int rainpos_indice = 0;
+	if (slices >  MAX_RAIN_SLICE)
+		slices = MAX_RAIN_SLICE; // should never happen
 	for( int i = 0 ; i < slices ; i++ ) {
 		float x = cos(angle) * baseRadius;
 		float y = sin(angle) * baseRadius;
@@ -388,12 +467,14 @@ void SGEnviro::DrawCone2(float baseRadiu
 		sgVec3 dir = {x, -height, y};
 
 		// rain drops at 2 different speed to simulate depth
-		float t1 = (i & 1 ? t : t + t) + rainpos[rainpos_indice];
+		float t1 = (i & 1 ? t : t + t) + rainpos[i];
 		if(t1 > 1.0f)	t1 -= 1.0f;
 		if(t1 > 1.0f)	t1 -= 1.0f;
 
 		// distant raindrops are more transparent
-		float c = (i & 1 ? t1 * 0.5f : t1 * 0.9f);
+		float c = t1 * (i & 1 ? 
+				streak_bright_farmost_layer 
+				: streak_bright_nearmost_layer);
 		glColor4f(c * light[0], c * light[1], c * light[2], c);
 		sgVec3 p1, p2;
 		sgScaleVec3(p1, dir, t1);
@@ -403,13 +484,28 @@ void SGEnviro::DrawCone2(float baseRadiu
 
 		glVertex3f(p1[0], p1[1] + height, p1[2]);
 		glVertex3f(p2[0], p2[1] + height, p2[2]);
-		if( ++rainpos_indice >= MAX_RAIN_SLICE )
-			rainpos_indice = 0;
 	}
 	glEnd();
 }
 
-void SGEnviro::drawRain(double pitch, double roll, double heading, double speed, double rain_norm) {
+void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
+
+#if 0
+	static int debug_period = 0;
+	if (debug_period++ == 50) {
+		debug_period = 0;
+		cout << "drawRain(" 
+			<< pitch << ", " 
+			<< roll  << ", " 
+			<< heading << ", " 
+			<< hspeed << ", " 
+			<< rain_norm << ");"
+			//" angle = " << angle 
+			//<< " raindrop(KTS) = " << raindrop_speed_kts
+			<< endl;
+	}
+#endif
+
 
 	glBindTexture(GL_TEXTURE_2D, 0);
 
@@ -421,7 +517,8 @@ void SGEnviro::drawRain(double pitch, do
 	glDisable(GL_LIGHTING);
 
 	int slice_count = static_cast<int>(
-				(40.0 + rain_norm*150.0)* precipitation_density / 100.0);
+			(streak_count_min + rain_norm*(streak_count_max-streak_count_min))
+				* precipitation_density / 100.0);
 
 	// www.wonderquest.com/falling-raindrops.htm says that
 	// Raindrop terminal velocity is 5 to 20mph
@@ -431,21 +528,21 @@ void SGEnviro::drawRain(double pitch, do
 	double raindrop_speed_kts 
 		= (5.0 + rain_norm*15.0) * SG_MPH_TO_MPS * SG_MPS_TO_KT;
 
-	float angle = atanf(speed / raindrop_speed_kts) * SG_RADIANS_TO_DEGREES;
-	// We assume that the speed is HORIZONTAL airspeed here!!! XXX
-	// DOCUMENT THE CHANGE IN THE PARAMETER speed MEANING BY RENAMING IT!!!
+	float angle = atanf(hspeed / raindrop_speed_kts) * SG_RADIANS_TO_DEGREES;
 	glPushMatrix();
-		// the cone rotate with speed
+		// the cone rotate with hspeed
 		angle = -pitch - angle;
-		glRotatef(heading, 0.0, 1.0, 0.0);
 		glRotatef(roll, 0.0, 0.0, 1.0);
+		glRotatef(heading, 0.0, 1.0, 0.0);
 		glRotatef(angle, 1.0, 0.0, 0.0);
 
 		// up cone
-		DrawCone2(15.0, 30.0, slice_count, true, rain_norm, speed);
+		DrawCone2(cone_base_radius, cone_height, 
+				slice_count, true, rain_norm, hspeed);
 		// down cone (usually not visible)
 		if(angle > 0.0 || heading != 0.0)
-			DrawCone2(15.0, -30.0, slice_count, false, rain_norm, speed);
+			DrawCone2(cone_base_radius, -cone_height, 
+					slice_count, false, rain_norm, hspeed);
 
 	glPopMatrix();
 
@@ -460,10 +557,10 @@ void SGEnviro::set_soundMgr(SGSoundMgr *
 	soundMgr = mgr;
 }
 
-void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double speed) {
+void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
 	if( precipitation_enable_state && rain_norm > 0.0)
 	  if( precipitation_max_alt >= last_alt )
-		drawRain(pitch, roll, heading, speed, rain_norm);
+		drawRain(pitch, roll, heading, hspeed, rain_norm);
 }
 
 
Index: ../../SimGear/source/simgear/environment/visual_enviro.hxx
===================================================================
RCS file: /var/cvs/SimGear-0.3/source/simgear/environment/visual_enviro.hxx,v
retrieving revision 1.11
diff -u -p -r1.11 visual_enviro.hxx
--- ../../SimGear/source/simgear/environment/visual_enviro.hxx	8 Mar 2006 18:16:08 -0000	1.11
+++ ../../SimGear/source/simgear/environment/visual_enviro.hxx	21 Mar 2006 17:26:10 -0000
@@ -90,11 +90,31 @@ private:
 
 	/** a list of all the radar echo. */
 	list_of_SGWxRadarEcho radarEcho;
+	static sgVec3 min_light;
+	static SGfloat streak_bright_nearmost_layer,
+				   streak_bright_farmost_layer, 
+				   streak_period_max, 
+				   streak_period_change_per_kt,
+				   streak_period_min,
+				   streak_length_min,
+				   streak_length_change_per_kt,
+				   streak_length_max;
+	static int streak_count_min, streak_count_max;
+	static SGfloat cone_base_radius,
+				   cone_height;
 
 public:
 	SGEnviro();
 	~SGEnviro();
 
+	/** Read the config from the precipitation rendering config properties.
+	 * @param precip_rendering_cfgNode "/sim/rendering/precipitation" in fg
+	 * Set from whatever info present in the
+	 * subnodes passed, substituting hardwired defaults for missing fields.
+	 * If NULL is given, do nothing.
+	 */
+	void config(const class SGPropertyNode* precip_rendering_cfgNode);
+
     /**
      * Forward a few states used for renderings.
      */
@@ -107,12 +127,12 @@ public:
      * @param heading direction of cloud in radians
      * @param alt asl of cloud in meters
      * @param radius radius of cloud in meters
-     * @param familly cloud familly
+     * @param family cloud family
      * @param dist  squared dist to cloud in meters
      */
-	void callback_cloud(float heading, float alt, float radius, int familly, float dist, int cloudId);
+	void callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId);
 
-	void drawRain(double pitch, double roll, double heading, double speed, double rain_norm);
+	void drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm);
     /**
      * Draw rain or snow precipitation around the viewer.
      * @param rain_norm rain normalized intensity given by metar class
@@ -120,10 +140,10 @@ public:
      * @param hail_norm hail normalized intensity given by metar class
      * @param pitch pitch rotation of viewer
      * @param roll roll rotation of viewer
-     * @param speed moving speed of viewer in kt
+     * @param hspeed moving horizontal speed of viewer in kt
      */
 	void drawPrecipitation(double rain_norm, double snow_norm, double hail_norm,
-							double pitch, double roll, double heading, double speed);
+							double pitch, double roll, double heading, double hspeed);
 
     /**
      * Draw the lightnings spawned by cumulo nimbus.
@@ -186,6 +206,12 @@ public:
 	float get_precipitation_density(void) const;
 	bool get_precipitation_enable_state(void) const;
 
+	/** 
+	 * Decrease the precipitation density to the given percentage.
+	 * (Only show the given percentage of rain streaks etc.)
+	 * Default precipitation density upon construction is 100.0.
+	 * @param density 0.0 to 100.0
+	 */
 	void set_precipitation_density(float density);
     /**
      * Enable or disable the rendering of precipitation around the viewer.
Index: ../../FlightGear/source/src/Environment/environment_mgr.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/Environment/environment_mgr.cxx,v
retrieving revision 1.21
diff -u -p -r1.21 environment_mgr.cxx
--- ../../FlightGear/source/src/Environment/environment_mgr.cxx	21 Feb 2006 01:16:10 -0000	1.21
+++ ../../FlightGear/source/src/Environment/environment_mgr.cxx	21 Mar 2006 17:26:53 -0000
@@ -189,6 +189,7 @@ FGEnvironmentMgr::bind ()
   fgTie("/environment/turbulence/use-cloud-turbulence", &sgEnviro,
       &SGEnviro::get_turbulence_enable_state,
       &SGEnviro::set_turbulence_enable_state);
+  sgEnviro.config(fgGetNode("/sim/rendering/precipitation"));
 }
 
 void
Index: ../../FlightGear/data/preferences.xml
===================================================================
RCS file: /var/cvs/FlightGear-0.9/data/preferences.xml,v
retrieving revision 1.210
diff -u -p -r1.210 preferences.xml
--- ../../FlightGear/data/preferences.xml	17 Mar 2006 12:28:28 -0000	1.210
+++ ../../FlightGear/data/preferences.xml	21 Mar 2006 17:26:55 -0000
@@ -55,6 +55,32 @@ Started September 2000 by David Megginso
    <enhanced-lighting type="bool" userarchive="y">false</enhanced-lighting>
    <distance-attenuation type="bool" userarchive="y">false</distance-attenuation>
    <precipitation-enable type="bool" userarchive="y">false</precipitation-enable>
+   <precipitation>
+	<!-- streaks coloring and transparency -->
+   	<min-light type="float">0.35</min-light>
+	<streak-brightness-nearmost-layer type="float">0.9</streak-brightness-nearmost-layer>
+	<streak-brightness-farmost-layer type="float">0.5</streak-brightness-farmost-layer>
+
+	<!-- streak period as a function of the speed, decreases with speed -->
+	<streak-period-max type="float">2.5</streak-period-max>
+	<streak-period-change-per-kt type="float">0.005</streak-period-change-per-kt>
+	<streak-period-min type="float">1.0</streak-period-min>
+
+	<!-- streak length as a function of the speed, increases with speed -->
+	<streak-length-min type="float">0.03</streak-length-min>
+	<streak-length-change-per-kt type="float">0.0005</streak-length-change-per-kt>
+	<streak-length-max type="float">0.1</streak-length-max>
+
+	<!-- # of rain streaks at the 100.0% precipitation density -->
+	<streak-count-min type="int">40</streak-count-min><!-- lightest rain -->
+	<streak-count-max type="int">190</streak-count-max><!-- heaviest rain -->
+	<!-- numbers over MAX_RAIN_SLICE in simgear/environment/visual_enviro.cxx
+	  will be ignored in the current implementation.  -->
+
+	<!-- the precipitation cone geometry -->
+	<cone-base-radius type="float">15.0</cone-base-radius>
+	<cone-height type="float">30.0</cone-height>
+   </precipitation>
    <lightning-enable type="bool" userarchive="y">false</lightning-enable>
    <bump-mapping type="bool" userarchive="y">false</bump-mapping>
    <clouds3d-enable type="bool" userarchive="y">false</clouds3d-enable>
