1
0
Fork 0

3D clouds from Stuart Buchanan. Need a recent driver update, --enable-clouds3d option and a Weather Scenario to show up

This commit is contained in:
fredb 2008-10-26 09:38:21 +00:00
parent 8dd517621d
commit bc240daaf3
3 changed files with 80 additions and 54 deletions

View file

@ -182,21 +182,12 @@ FGEnvironmentMgr::bind ()
&FGEnvironmentMgr::set_cloud_layer_coverage); &FGEnvironmentMgr::set_cloud_layer_coverage);
fgSetArchivable(buf); fgSetArchivable(buf);
} }
fgTie("/sim/rendering/clouds3d-enable", &sgEnviro, fgTie("/sim/rendering/clouds3d-enable", thesky,
&SGEnviro::get_clouds_enable_state, &SGSky::get_3dClouds,
&SGEnviro::set_clouds_enable_state); &SGSky::set_3dClouds);
fgTie("/sim/rendering/clouds3d-vis-range", &sgEnviro, fgTie("/sim/rendering/clouds3d-density", thesky,
&SGEnviro::get_clouds_visibility, &SGSky::get_3dCloudDensity,
&SGEnviro::set_clouds_visibility); &SGSky::set_3dCloudDensity);
fgTie("/sim/rendering/clouds3d-density", &sgEnviro,
&SGEnviro::get_clouds_density,
&SGEnviro::set_clouds_density);
fgTie("/sim/rendering/clouds3d-cache-size", &sgEnviro,
&SGEnviro::get_clouds_CacheSize,
&SGEnviro::set_clouds_CacheSize);
fgTie("/sim/rendering/clouds3d-cache-resolution", &sgEnviro,
&SGEnviro::get_CacheResolution,
&SGEnviro::set_CacheResolution);
fgTie("/sim/rendering/precipitation-enable", &sgEnviro, fgTie("/sim/rendering/precipitation-enable", &sgEnviro,
&SGEnviro::get_precipitation_enable_state, &SGEnviro::get_precipitation_enable_state,
&SGEnviro::set_precipitation_enable_state); &SGEnviro::set_precipitation_enable_state);

View file

@ -80,55 +80,92 @@ void FGClouds::init(void) {
} }
} }
SGNewCloud *FGClouds::buildCloud(SGPropertyNode *cloud_def_root, const string& name) { void FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer) {
SGPropertyNode *cld_def=NULL; SGPropertyNode *box_def=NULL;
SGPropertyNode *cld_def=NULL;
SGPath texture_root = globals->get_fg_root();
texture_root.append("Textures");
texture_root.append("Sky");
cld_def = cloud_def_root->getChild(name.c_str()); box_def = box_def_root->getChild(name.c_str());
string base_name = name.substr(0,2); string base_name = name.substr(0,2);
if( !cld_def ) { if( !box_def ) {
if( name[2] == '-' ) { if( name[2] == '-' ) {
cld_def = cloud_def_root->getChild(base_name.c_str()); box_def = box_def_root->getChild(base_name.c_str());
} }
if( !cld_def ) if( !box_def )
return NULL; return;
} }
string familly = cld_def->getStringValue("familly", base_name.c_str());
SGNewCloud *cld = new SGNewCloud(familly); for(int i = 0; i < box_def->nChildren() ; i++) {
for(int i = 0; i < cld_def->nChildren() ; i++) { SGPropertyNode *abox = box_def->getChild(i);
SGPropertyNode *abox = cld_def->getChild(i);
if( strcmp(abox->getName(), "box") == 0) { if( strcmp(abox->getName(), "box") == 0) {
double x = abox->getDoubleValue("x"); double x = abox->getDoubleValue("x") + pos[0];
double y = abox->getDoubleValue("y"); double y = abox->getDoubleValue("y") + pos[1];
double z = abox->getDoubleValue("z"); double z = abox->getDoubleValue("z") + pos[2];
double size = abox->getDoubleValue("size"); SGVec3f newpos = SGVec3f(x, z, y);
int type = abox->getIntValue("type", SGNewCloud::CLbox_standard);
cld->addContainer(x, y, z, size, (SGNewCloud::CLbox_type) type); string type = abox->getStringValue("type", "cu-small");
cld_def = cloud_def_root->getChild(type.c_str());
if ( !cld_def ) return;
double min_width = cld_def->getDoubleValue("min-cloud-width-m", 500.0);
double max_width = cld_def->getDoubleValue("max-cloud-width-m", 1000.0);
double min_height = cld_def->getDoubleValue("min-cloud-height-m", min_width);
double max_height = cld_def->getDoubleValue("max-cloud-height-m", max_width);
double min_sprite_width = cld_def->getDoubleValue("min-sprite-width-m", 200.0);
double max_sprite_width = cld_def->getDoubleValue("max-sprite-width-m", min_sprite_width);
double min_sprite_height = cld_def->getDoubleValue("min-sprite-height-m", min_sprite_width);
double max_sprite_height = cld_def->getDoubleValue("max-sprite-height-m", max_sprite_width);
int num_sprites = cld_def->getIntValue("num-sprites", 20);
int num_textures_x = cld_def->getIntValue("num-textures-x", 1);
int num_textures_y = cld_def->getIntValue("num-textures-y", 1);
double bottom_shade = cld_def->getDoubleValue("bottom-shade", 1.0);
string texture = cld_def->getStringValue("texture", "cl_cumulus.rgb");
SGNewCloud *cld =
new SGNewCloud(texture_root,
texture,
min_width,
max_width,
min_height,
max_height,
min_sprite_width,
max_sprite_width,
min_sprite_height,
max_sprite_height,
bottom_shade,
num_sprites,
num_textures_x,
num_textures_y);
layer->addCloud(newpos, cld);
} }
} }
cld->genSprites();
return cld;
} }
void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, double coverage) { void FGClouds::buildLayer(int iLayer, const string& name, double alt, double coverage) {
struct { struct {
string name; string name;
double count; double count;
} tCloudVariety[20]; } tCloudVariety[20];
int CloudVarietyCount = 0; int CloudVarietyCount = 0;
double totalCount = 0.0; double totalCount = 0.0;
SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false); SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false);
SGPropertyNode *box_def_root = fgGetNode("/environment/cloudlayers/boxes", false);
SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false); SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false);
SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D();
layer->clear(); layer->clear();
// when we don't generate clouds the layer is rendered in 2D // when we don't generate clouds the layer is rendered in 2D
if( coverage == 0.0 ) if( coverage == 0.0 )
return; return;
if( layer_def_root == NULL || cloud_def_root == NULL) if( layer_def_root == NULL || cloud_def_root == NULL || box_def_root == NULL)
return; return;
if( name == "ci" || name == "sc" || name == "st")
return;
SGPropertyNode *layer_def=NULL; SGPropertyNode *layer_def=NULL;
layer_def = layer_def_root->getChild(name.c_str()); layer_def = layer_def_root->getChild(name.c_str());
@ -140,7 +177,7 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
if( !layer_def ) if( !layer_def )
return; return;
} }
double grid_x_size = layer_def->getDoubleValue("grid-x-size", 1000.0); double grid_x_size = layer_def->getDoubleValue("grid-x-size", 1000.0);
double grid_y_size = layer_def->getDoubleValue("grid-y-size", 1000.0); double grid_y_size = layer_def->getDoubleValue("grid-y-size", 1000.0);
double grid_x_rand = layer_def->getDoubleValue("grid-x-rand", grid_x_size); double grid_x_rand = layer_def->getDoubleValue("grid-x-rand", grid_x_size);
@ -160,7 +197,7 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
do { do {
variety++; variety++;
snprintf(variety_name, sizeof(variety_name), cloud_name.c_str(), variety); snprintf(variety_name, sizeof(variety_name), cloud_name.c_str(), variety);
} while( cloud_def_root->getChild(variety_name, 0, false) ); } while( box_def_root->getChild(variety_name, 0, false) );
totalCount += count; totalCount += count;
if( CloudVarietyCount < 20 ) if( CloudVarietyCount < 20 )
@ -172,8 +209,8 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) { for(double px = 0.0; px < SGCloudField::fieldSize; px += grid_x_size) {
for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) { for(double py = 0.0; py < SGCloudField::fieldSize; py += grid_y_size) {
double x = px + grid_x_rand * (sg_random() - 0.5); double x = px + grid_x_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
double y = py + grid_y_rand * (sg_random() - 0.5); double y = py + grid_y_rand * (sg_random() - 0.5) - (SGCloudField::fieldSize / 2.0);
double z = alt + grid_z_rand * (sg_random() - 0.5); double z = alt + grid_z_rand * (sg_random() - 0.5);
double choice = sg_random(); double choice = sg_random();
currCoverage += coverage; currCoverage += coverage;
@ -184,23 +221,23 @@ void FGClouds::buildLayer(SGCloudField *layer, const string& name, double alt, d
for(int i = 0; i < CloudVarietyCount ; i ++) { for(int i = 0; i < CloudVarietyCount ; i ++) {
choice -= tCloudVariety[i].count * totalCount; choice -= tCloudVariety[i].count * totalCount;
if( choice <= 0.0 ) { if( choice <= 0.0 ) {
SGNewCloud *cld = buildCloud(cloud_def_root, tCloudVariety[i].name);
sgVec3 pos={x,z,y}; sgVec3 pos={x,z,y};
if( cld )
layer->addCloud(pos, cld);
buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, pos, layer);
break; break;
} }
} }
} }
} }
// Now we've built any clouds, enable them
thesky->get_cloud_layer(iLayer)->set_enable3dClouds(thesky->get_3dClouds());
} }
// TODO:call this after real metar updates // TODO:call this after real metar updates
void FGClouds::buildMETAR(void) { void FGClouds::buildMETAR(void) {
SGPropertyNode *metar_root = fgGetNode("/environment", true); SGPropertyNode *metar_root = fgGetNode("/environment", true);
double wind_speed_kt = metar_root->getDoubleValue("wind-speed-kt"); double wind_speed_kt = metar_root->getDoubleValue("wind-speed-kt");
double temperature_degc = metar_root->getDoubleValue("temperature-sea-level-degc"); double temperature_degc = metar_root->getDoubleValue("temperature-sea-level-degc");
double dewpoint_degc = metar_root->getDoubleValue("dewpoint-sea-level-degc"); double dewpoint_degc = metar_root->getDoubleValue("dewpoint-sea-level-degc");
@ -262,8 +299,7 @@ void FGClouds::buildMETAR(void) {
} }
} }
SGCloudField *layer3D = thesky->get_cloud_layer(iLayer)->get_layer3D(); buildLayer(iLayer, layer_type, alt_m, coverage_norm);
buildLayer(layer3D, layer_type, alt_m, coverage_norm);
} }
} }
@ -395,8 +431,7 @@ void FGClouds::setLayer( int iLayer, float alt_ft, const string& coverage, const
else if( coverage == "overcast" ) else if( coverage == "overcast" )
coverage_norm = 8.0/8.0; // 8 coverage_norm = 8.0/8.0; // 8
SGCloudField *layer3D = thesky->get_cloud_layer(iLayer)->get_layer3D(); buildLayer(iLayer, layer_type, station_elevation_ft + alt_ft * SG_FEET_TO_METER, coverage_norm);
buildLayer(layer3D, layer_type, station_elevation_ft + alt_ft * SG_FEET_TO_METER, coverage_norm);
} }
void FGClouds::buildScenario( const string& scenario ) { void FGClouds::buildScenario( const string& scenario ) {

View file

@ -42,8 +42,8 @@ class FGEnvironmentCtrl;
class FGClouds { class FGClouds {
private: private:
SGNewCloud *buildCloud(SGPropertyNode *cloud_def_root, const string& name); void buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_def_root, const string& name, sgVec3 pos, SGCloudField *layer);
void buildLayer(SGCloudField *layer, const string& name, double alt, double coverage); void buildLayer(int iLayer, const string& name, double alt, double coverage);
void buildMETAR(void); void buildMETAR(void);