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:
ehofman
2005-05-30 09:04:57 +00:00
parent f4b05d46ed
commit 75ab8e697b
5 changed files with 89 additions and 37 deletions

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -158,6 +158,7 @@ public:
inline float getRadius() { return radius; }
inline sgVec3 *getCenter() { return &center; }
inline int getId() { return cloudId; }
inline CLFamilly_type getFamilly(void) { return familly; }