min_time_before_lt(0.0),
fov_width(55.0),
fov_height(55.0),
+ precipitation_max_alt(0.0),
precipitation_density(100.0)
{
for(int i = 0; i < MAX_RAIN_SLICE ; i++)
rainpos[i] = sg_random();
-
+ radarEcho.reserve(100);
}
SGEnviro::~SGEnviro(void) {
last_lon = lon;
last_lat = lat;
last_alt = alt;
+
+ radarEcho.clear();
+ precipitation_max_alt = 400.0;
}
void SGEnviro::endOfFrame(void) {
}
}
-void SGEnviro::callback_cloud(float heading, float alt, float radius, int familly, float dist) {
+void SGEnviro::callback_cloud(float heading, float alt, float radius, int familly, float dist, int cloudId) {
// send data to wx radar
// compute turbulence
// draw precipitation
LWC = 0.29*2.0;
break;
}
- // TODO:send data to radar antenna
+ // add to the list for the wxRadar instrument
+ if( LWC > 0.0 )
+ radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
+
// NB:data valid only from cockpit view
// spawn a new lightning
- if(min_time_before_lt <= 0.0 && (familly == SGNewCloud::CLFamilly_cb) &&
+ if(lightning_enable_state && min_time_before_lt <= 0.0 && (familly == SGNewCloud::CLFamilly_cb) &&
dist < 15000.0 * 15000.0 && sg_random() > 0.9f) {
double lat, lon;
Point3D orig, dest;
// reset timer
min_time_before_lt = 5.0 + sg_random() * 30;
// DEBUG only
-// min_time_before_lt = 1.0;
+// min_time_before_lt = 5.0;
}
+ if( (alt - radius * 0.1) > precipitation_max_alt )
+ switch(familly) {
+ case SGNewCloud::CLFamilly_st:
+ case SGNewCloud::CLFamilly_cu:
+ case SGNewCloud::CLFamilly_cb:
+ case SGNewCloud::CLFamilly_ns:
+ case SGNewCloud::CLFamilly_sc:
+ precipitation_max_alt = alt - radius * 0.1;
+ break;
+ }
+}
+
+list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
+ return &radarEcho;
}
// precipitation rendering code
glEnd();
}
-// TODO:check alt vs layer
void SGEnviro::drawRain(double pitch, double roll, double heading, double speed, double rain_norm) {
glBindTexture(GL_TEXTURE_2D, 0);
}
void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double speed) {
- // TODO:check alt with right layer (wich layer ?)
if( precipitation_enable_state && rain_norm > 0.0)
+ if( precipitation_max_alt >= last_alt )
drawRain(pitch, roll, heading, speed, rain_norm);
}
ay = sin(course) * dist;
glTranslatef( ax, ay, -sgEnviro.last_alt );
-// glTranslatef( ax, ay, 0 );
+
+ sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
for( int n = 0 ; n < nb_tree ; n++ ) {
if( lt_tree[n].prev < 0 )
class SGLightning;
class SGSoundMgr;
+/**
+ * Simulate some echo on a weather radar.
+ * Container class for the wx radar instrument.
+ */
+class SGWxRadarEcho {
+public:
+ SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist, double _LWC, bool _lightning, int _cloudId) :
+ heading( _heading ),
+ alt ( _alt ),
+ radius ( _radius ),
+ dist ( _dist ),
+ LWC ( _LWC ),
+ lightning ( _lightning ),
+ cloudId ( _cloudId )
+ {}
+
+ /** the heading in radian is versus north */
+ float heading;
+ float alt, radius, dist;
+ /** reflectivity converted to liquid water content. */
+ double LWC;
+ /** if true then this data is for a lightning else it is for water echo. */
+ bool lightning;
+ /** Unique identifier of cloud */
+ int cloudId;
+};
+
+typedef vector<SGWxRadarEcho> list_of_SGWxRadarEcho;
+
/**
* Visual environment helper class.
*/
bool view_in_cloud;
bool precipitation_enable_state;
float precipitation_density;
+ float precipitation_max_alt;
bool turbulence_enable_state;
double last_cloud_turbulence, cloud_turbulence;
bool lightning_enable_state;
float fov_width, fov_height;
+ /** a list of all the radar echo. */
+ list_of_SGWxRadarEcho radarEcho;
+
public:
SGEnviro();
~SGEnviro();
* @param familly cloud familly
* @param dist squared dist to cloud in meters
*/
- void callback_cloud(float heading, float alt, float radius, int familly, float dist);
+ void callback_cloud(float heading, float alt, float radius, int familly, float dist, int cloudId);
void drawRain(double pitch, double roll, double heading, double speed, double rain_norm);
/**
void setFOV( float w, float h );
void getFOV( float &w, float &h );
+ list_of_SGWxRadarEcho *get_radar_echo(void);
};
extern SGEnviro sgEnviro;
if( ! iCloud->visible )
continue;
sgSubVec3( dist, iCloud->pos, eyePos );
- sphere.setCenter(dist[0], dist[2], dist[1]);
+ sphere.setCenter(dist[0], dist[2], dist[1] + eyePos[1]);
float radius = iCloud->aCloud->getRadius();
sphere.setRadius(radius);
sphere.orthoXform(mat);
// cloud fields are tiled on the flat earth
// compute the position in the tile
- relx = fmod( deltax + relative_position[SG_X] + tmp[3][0], fieldSize );
- rely = fmod( deltay + relative_position[SG_Y] + tmp[3][1], fieldSize );
+ relx = fmod( deltax + relative_position[SG_X], fieldSize );
+ rely = fmod( deltay + relative_position[SG_Y], fieldSize );
relx = fmod( relx + fieldSize, fieldSize );
rely = fmod( rely + fieldSize, fieldSize );
sgSetVec3( eyePos, relx, alt, rely);
- sgCopyVec3( view_vec, tmp[1] );
- sgCopyVec3( view_X, tmp[0] );
- sgCopyVec3( view_Y, tmp[2] );
- tmp[3][2] = 0;
- tmp[3][0] = 0;
- tmp[3][1] = 0;
+ sgSetVec3( view_X, tmp[0][0], tmp[1][0], tmp[2][0] );
+ sgSetVec3( view_Y, tmp[0][1], tmp[1][1], tmp[2][1] );
+ sgSetVec3( view_vec, tmp[0][2], tmp[1][2], tmp[2][2] );
+
ssgLoadModelviewMatrix( tmp );
/* flat earth
// iCloud->aCloud->drawContainers();
iCloud->aCloud->Render(iCloud->eyePos);
sgEnviro.callback_cloud(iCloud->heading, iCloud->alt,
- iCloud->aCloud->getRadius(), iCloud->aCloud->getFamilly(), - iCloud->dist);
+ iCloud->aCloud->getRadius(), iCloud->aCloud->getFamilly(), - iCloud->dist, iCloud->aCloud->getId());
}
glBindTexture(GL_TEXTURE_2D, 0);
sgSubVec3( deltaPos, newSpriteDef.pos, thisBox->pos );
sgAddVec3( thisBox->center, deltaPos );
- r = r * 0.65f; // 0.5 * 1.xxx
+ r = r * 0.70f; // 0.5 * 1.xxx
if( x - r < minx )
minx = x - r;
if( y - r < miny )
sgVec3 pos;
sgSetVec3( pos, translate[SG_X], translate[SG_Z], translate[SG_Y] );
sgCopyVec3( translate, pos );
- sgNormaliseVec3( translate );
-#if 0
- // change view angle when near a sprite
- sgVec3 trans={translate[0], translate[2], translate[1]};
- float angle = sgScalarProductVec3( SGCloudField::view_vec, trans );
- if( fabs(angle) < 0.85f ) {
- // view not ok from under
- sgSetVec3( translate, -SGCloudField::view_vec[0],-SGCloudField::view_vec[2],-SGCloudField::view_vec[1] );
-// sgSetVec3( l0,1,0,0 );
-// sgSetVec3( l1,1,0,0 );
-// sgSetVec3( l2,1,0,0 );
-// sgSetVec3( l3,1,0,0 );
- }
-#endif
+ translate[2] -= FakeEyePos[1];
+// sgNormaliseVec3( translate );
+ float dist_sprite = sgLengthVec3 ( translate );
+ sgScaleVec3 ( translate, SG_ONE / dist_sprite ) ;
sgVec3 x, y, up = {0.0f, 0.0f, 1.0f};
- sgVectorProductVec3(x, translate, up);
- sgVectorProductVec3(y, x, translate);
+ if( dist_sprite > 2*r ) {
+ sgVectorProductVec3(x, translate, up);
+ sgVectorProductVec3(y, x, translate);
+ } else {
+ sgCopyVec3( x, SGCloudField::view_X );
+ sgCopyVec3( y, SGCloudField::view_Y );
+ }
sgScaleVec3(x, r);
sgScaleVec3(y, r);
sgVec3 pos;
sgSetVec3( pos, translate[SG_X], translate[SG_Z], translate[SG_Y] );
sgCopyVec3( translate, pos );
+ pos[2] += deltaPos[1];
+
sgNormaliseVec3( translate );
sgVec3 x, y, up = {0.0f, 0.0f, 1.0f};
sgVectorProductVec3(x, translate, up);
sgVec3 deltaPos;
sgCopyVec3( deltaPos, FakeEyePos);
+ deltaPos[1] = 0.0;
sgSubVec3( dist, center, FakeEyePos);
float dist_center = sgLengthVec3(dist);
}
// draw the newly built BB or an old one
glBindTexture(GL_TEXTURE_2D, texID);
- RenderBB(deltaPos, first_time, dist_center);
+ RenderBB(FakeEyePos, first_time, dist_center);
}
}
inline float getRadius() { return radius; }
inline sgVec3 *getCenter() { return ¢er; }
+ inline int getId() { return cloudId; }
inline CLFamilly_type getFamilly(void) { return familly; }