Harald JOHSEN:
Changes ======= - changed the rotation of sprites, they don't rotate strangely when we approach them now - corrected the strange movement of clouds when banking quickly - it no more rain above cloud layers - add a radar echo container used by the weather radar instrument
This commit is contained in:
@@ -99,12 +99,13 @@ SGEnviro::SGEnviro(void) :
|
||||
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) {
|
||||
@@ -150,6 +151,9 @@ void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double
|
||||
last_lon = lon;
|
||||
last_lat = lat;
|
||||
last_alt = alt;
|
||||
|
||||
radarEcho.clear();
|
||||
precipitation_max_alt = 400.0;
|
||||
}
|
||||
|
||||
void SGEnviro::endOfFrame(void) {
|
||||
@@ -241,7 +245,7 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@@ -313,11 +317,14 @@ void SGEnviro::callback_cloud(float heading, float alt, float radius, int famill
|
||||
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;
|
||||
@@ -333,8 +340,22 @@ void SGEnviro::callback_cloud(float heading, float alt, float radius, int famill
|
||||
// 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
|
||||
@@ -387,7 +408,6 @@ void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down,
|
||||
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);
|
||||
@@ -433,8 +453,8 @@ void SGEnviro::set_soundMgr(SGSoundMgr *mgr) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -564,7 +584,8 @@ void SGLightning::lt_Render(void) {
|
||||
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 )
|
||||
|
||||
@@ -30,6 +30,35 @@ SG_USING_STD(string);
|
||||
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.
|
||||
*/
|
||||
@@ -42,6 +71,7 @@ private:
|
||||
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;
|
||||
@@ -56,6 +86,9 @@ private:
|
||||
|
||||
float fov_width, fov_height;
|
||||
|
||||
/** a list of all the radar echo. */
|
||||
list_of_SGWxRadarEcho radarEcho;
|
||||
|
||||
public:
|
||||
SGEnviro();
|
||||
~SGEnviro();
|
||||
@@ -75,7 +108,7 @@ public:
|
||||
* @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);
|
||||
/**
|
||||
@@ -183,6 +216,7 @@ public:
|
||||
void setFOV( float w, float h );
|
||||
void getFOV( float &w, float &h );
|
||||
|
||||
list_of_SGWxRadarEcho *get_radar_echo(void);
|
||||
};
|
||||
|
||||
extern SGEnviro sgEnviro;
|
||||
|
||||
@@ -305,7 +305,7 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
|
||||
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);
|
||||
@@ -390,19 +390,17 @@ void SGCloudField::Render(void) {
|
||||
|
||||
// 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
|
||||
@@ -449,7 +447,7 @@ void SGCloudField::Render(void) {
|
||||
// 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);
|
||||
|
||||
@@ -243,7 +243,7 @@ void SGNewCloud::addSprite(float x, float y, float z, float r, CLbox_type type,
|
||||
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 )
|
||||
@@ -555,23 +555,18 @@ void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos,
|
||||
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);
|
||||
|
||||
@@ -665,6 +660,8 @@ void SGNewCloud::RenderBB(sgVec3 deltaPos, bool first_time, float dist_center) {
|
||||
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);
|
||||
@@ -745,6 +742,7 @@ void SGNewCloud::Render(sgVec3 FakeEyePos) {
|
||||
|
||||
sgVec3 deltaPos;
|
||||
sgCopyVec3( deltaPos, FakeEyePos);
|
||||
deltaPos[1] = 0.0;
|
||||
sgSubVec3( dist, center, FakeEyePos);
|
||||
float dist_center = sgLengthVec3(dist);
|
||||
|
||||
@@ -804,7 +802,7 @@ void SGNewCloud::Render(sgVec3 FakeEyePos) {
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ public:
|
||||
|
||||
inline float getRadius() { return radius; }
|
||||
inline sgVec3 *getCenter() { return ¢er; }
|
||||
inline int getId() { return cloudId; }
|
||||
|
||||
inline CLFamilly_type getFamilly(void) { return familly; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user