X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FEnvironment%2Ffgclouds.cxx;h=e7273a7148ed6b44c05c13c74d6dba536c6d0431;hb=43bc61d1318abd52de6c723dbeef0e4058b1a823;hp=57d7ba42ef001a3a46c9c164af9063d5aac327f1;hpb=8330449c5fba742526175ce3e4fc0f9b97903d5e;p=flightgear.git diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index 57d7ba42e..e7273a714 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -30,9 +30,10 @@ #include #include #include -#include +//#include #include #include +#include #include #include @@ -44,15 +45,22 @@ extern SGSky *thesky; +static bool do_delete_3Dcloud (const SGPropertyNode *arg); +static bool do_move_3Dcloud (const SGPropertyNode *arg); +static bool do_add_3Dcloud (const SGPropertyNode *arg); FGClouds::FGClouds() : +#if 0 snd_lightning(0), - clouds_3d_enabled(false) +#endif + clouds_3d_enabled(false), + index(0) { update_event = 0; } -FGClouds::~FGClouds() { +FGClouds::~FGClouds() +{ } int FGClouds::get_update_event(void) const { @@ -64,7 +72,8 @@ void FGClouds::set_update_event(int count) { buildCloudLayers(); } -void FGClouds::init(void) { +void FGClouds::Init(void) { +#if 0 if( snd_lightning == NULL ) { snd_lightning = new SGSoundSample("Sounds/thunder.wav", SGPath()); snd_lightning->set_max_dist(7000.0f); @@ -72,8 +81,12 @@ void FGClouds::init(void) { SGSoundMgr *smgr = globals->get_soundmgr(); SGSampleGroup *sgr = smgr->find("weather", true); sgr->add( snd_lightning, "thunder" ); - sgEnviro.set_sampleGroup( sgr ); } +#endif + + globals->get_commands()->addCommand("add-cloud", do_add_3Dcloud); + globals->get_commands()->addCommand("del-cloud", do_delete_3Dcloud); + globals->get_commands()->addCommand("move-cloud", do_move_3Dcloud); } // Build an invidual cloud. Returns the extents of the cloud for coverage calculations @@ -87,7 +100,7 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ texture_root.append("Sky"); box_def = box_def_root->getChild(name.c_str()); - + string base_name = name.substr(0,2); if( !box_def ) { if( name[2] == '-' ) { @@ -100,9 +113,12 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ double x = sg_random() * SGCloudField::fieldSize - (SGCloudField::fieldSize / 2.0); double y = sg_random() * SGCloudField::fieldSize - (SGCloudField::fieldSize / 2.0); double z = grid_z_rand * (sg_random() - 0.5); - + + float lon = fgGetNode("/position/longitude-deg", false)->getFloatValue(); + float lat = fgGetNode("/position/latitude-deg", false)->getFloatValue(); + SGVec3f pos(x,y,z); - + for(int i = 0; i < box_def->nChildren() ; i++) { SGPropertyNode *abox = box_def->getChild(i); if( strcmp(abox->getName(), "box") == 0) { @@ -110,7 +126,7 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ string type = abox->getStringValue("type", "cu-small"); cld_def = cloud_def_root->getChild(type.c_str()); if ( !cld_def ) return 0.0; - + double w = abox->getDoubleValue("width", 1000.0); double h = abox->getDoubleValue("height", 1000.0); int hdist = abox->getIntValue("hdist", 1); @@ -119,7 +135,7 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ double c = abox->getDoubleValue("count", 5); int count = (int) (c + (sg_random() - 0.5) * c); - extent = max(w*w, extent); + extent = std::max(w*w, extent); for (int j = 0; j < count; j++) { @@ -145,39 +161,11 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ y = w * (y - 0.5) + pos[1]; // E/W z = h * z + pos[2]; // Up/Down. pos[2] is the cloudbase - SGVec3f newpos = SGVec3f(x, y, z); - - 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", "cu.png"); - - SGNewCloud *cld = - new SGNewCloud(type, - 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); + //SGVec3f newpos = SGVec3f(x, y, z); + SGNewCloud cld = SGNewCloud(texture_root, cld_def); + + //layer->addCloud(newpos, cld.genCloud()); + layer->addCloud(lon, lat, z, x, y, index++, cld.genCloud()); } } } @@ -186,27 +174,27 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ return extent; } -void FGClouds::buildLayer(int iLayer, const string& name, double alt, double coverage) { +void FGClouds::buildLayer(int iLayer, const string& name, double coverage) { struct { string name; double count; } tCloudVariety[20]; int CloudVarietyCount = 0; double totalCount = 0.0; - + 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); - SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D(); + SGCloudField *layer = thesky->get_cloud_layer(iLayer)->get_layer3D(); layer->clear(); - + // If we don't have the required properties, then render the cloud in 2D if ((! clouds_3d_enabled) || coverage == 0.0 || layer_def_root == NULL || cloud_def_root == NULL || box_def_root == NULL) { thesky->get_cloud_layer(iLayer)->set_enable3dClouds(false); return; } - + // If we can't find a definition for this cloud type, then render the cloud in 2D SGPropertyNode *layer_def=NULL; layer_def = layer_def_root->getChild(name.c_str()); @@ -248,25 +236,24 @@ void FGClouds::buildLayer(int iLayer, const string& name, double alt, double cov } totalCount = 1.0 / totalCount; - // Determine how much cloud coverage we need in m^2. - double cov = coverage * SGCloudField::fieldSize * SGCloudField::fieldSize; + // Determine how much cloud coverage we need in m^2. + double cov = coverage * SGCloudField::fieldSize * SGCloudField::fieldSize; - while (cov > 0.0f) { + while (cov > 0.0f) { double choice = sg_random(); - + for(int i = 0; i < CloudVarietyCount ; i ++) { choice -= tCloudVariety[i].count * totalCount; if( choice <= 0.0 ) { cov -= buildCloud(cloud_def_root, box_def_root, tCloudVariety[i].name, - grid_z_rand, + grid_z_rand, layer); break; } } - - } + } // Now we've built any clouds, enable them and set the density (coverage) //layer->setCoverage(coverage); @@ -279,12 +266,9 @@ void FGClouds::buildCloudLayers(void) { //double wind_speed_kt = metar_root->getDoubleValue("wind-speed-kt"); double temperature_degc = metar_root->getDoubleValue("temperature-sea-level-degc"); - double dewpoint_degc = metar_root->getDoubleValue("dewpoint-sea-level-degc"); - double pressure_mb = metar_root->getDoubleValue("pressure-sea-level-inhg") * SG_INHG_TO_PA / 100.0; - - double dewp = pow(10.0, 7.5 * dewpoint_degc / (237.7 + dewpoint_degc)); - double temp = pow(10.0, 7.5 * temperature_degc / (237.7 + temperature_degc)); - double rel_humidity = dewp * 100 / temp; + double dewpoint_degc = metar_root->getDoubleValue("dewpoint-sea-level-degc"); + double pressure_mb = metar_root->getDoubleValue("pressure-sea-level-inhg") * SG_INHG_TO_PA / 100.0; + double rel_humidity = metar_root->getDoubleValue("relative-humidity"); // formule d'Epsy, base d'un cumulus double cumulus_base = 122.0 * (temperature_degc - dewpoint_degc); @@ -295,8 +279,8 @@ void FGClouds::buildCloudLayers(void) { double alt_ft = cloud_root->getDoubleValue("elevation-ft"); double alt_m = alt_ft * SG_FEET_TO_METER; - string coverage = cloud_root->getStringValue("coverage"); - + string coverage = cloud_root->getStringValue("coverage"); + double coverage_norm = 0.0; if( coverage == "few" ) coverage_norm = 2.0/8.0; // <1-2 @@ -308,6 +292,7 @@ void FGClouds::buildCloudLayers(void) { coverage_norm = 8.0/8.0; // 8 string layer_type = "nn"; + if( coverage == "cirrus" ) { layer_type = "ci"; } else if( alt_ft > 16500 ) { @@ -336,20 +321,102 @@ void FGClouds::buildCloudLayers(void) { layer_type = "sc"; } } - - buildLayer(iLayer, layer_type, alt_m, coverage_norm); + + cloud_root->setStringValue("layer-type",layer_type); + buildLayer(iLayer, layer_type, coverage_norm); } } void FGClouds::set_3dClouds(bool enable) { - if (enable != clouds_3d_enabled) { - clouds_3d_enabled = enable; - buildCloudLayers(); - } + if (enable != clouds_3d_enabled) { + clouds_3d_enabled = enable; + buildCloudLayers(); + } } -bool FGClouds::get_3dClouds() const { - return clouds_3d_enabled; +bool FGClouds::get_3dClouds() const +{ + return clouds_3d_enabled; } - + +/** + * Adds a 3D cloud to a cloud layer. + * + * Property arguments + * layer - the layer index to add this cloud to. (Defaults to 0) + * index - the index for this cloud (to be used later) + * lon/lat/alt - the position for the cloud + * (Various) - cloud definition properties. See README.3DClouds + * + */ + static bool + do_add_3Dcloud (const SGPropertyNode *arg) + { + int l = arg->getIntValue("layer", 0); + int index = arg->getIntValue("index", 0); + + SGPath texture_root = globals->get_fg_root(); + texture_root.append("Textures"); + texture_root.append("Sky"); + + float lon = arg->getFloatValue("lon-deg", 0.0f); + float lat = arg->getFloatValue("lat-deg", 0.0f); + float alt = arg->getFloatValue("alt-ft", 0.0f); + float x = arg->getFloatValue("x-offset-m", 0.0f); + float y = arg->getFloatValue("y-offset-m", 0.0f); + + + SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D(); + SGNewCloud cld = SGNewCloud(texture_root, arg); + bool success = layer->addCloud(lon, lat, alt, x, y, index, cld.genCloud()); + + // Adding a 3D cloud immediately makes this layer 3D. + thesky->get_cloud_layer(l)->set_enable3dClouds(true); + + return success; + } + + /** + * Removes a 3D cloud from a cloud layer + * + * Property arguments + * + * layer - the layer index to remove this cloud from. (defaults to 0) + * index - the cloud index + * + */ + static bool + do_delete_3Dcloud (const SGPropertyNode *arg) + { + int l = arg->getIntValue("layer", 0); + int i = arg->getIntValue("index", 0); + + SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D(); + return layer->deleteCloud(i); + } + +/** + * Move a cloud within a 3D layer + * + * Property arguments + * layer - the layer index to add this cloud to. (Defaults to 0) + * index - the cloud index to move. + * lon/lat/alt - the position for the cloud + * + */ + static bool + do_move_3Dcloud (const SGPropertyNode *arg) + { + int l = arg->getIntValue("layer", 0); + int i = arg->getIntValue("index", 0); + + float lon = arg->getFloatValue("lon-deg", 0.0f); + float lat = arg->getFloatValue("lat-deg", 0.0f); + float alt = arg->getFloatValue("alt-ft", 0.0f); + float x = arg->getFloatValue("x-offset-m", 0.0f); + float y = arg->getFloatValue("y-offset-m", 0.0f); + + SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D(); + return layer->repositionCloud(i, lon, lat, alt, x, y); + }