From: Stuart Buchanan Date: Thu, 21 Apr 2011 19:43:05 +0000 (+0100) Subject: Improved 3D cloud support X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=38af5a2a072f8cb218612df6347a22686a9cf022;p=flightgear.git Improved 3D cloud support --- diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx index 4d05fab29..04208d304 100644 --- a/src/Environment/environment_mgr.cxx +++ b/src/Environment/environment_mgr.cxx @@ -97,6 +97,7 @@ FGEnvironmentMgr::init () { SG_LOG( SG_GENERAL, SG_INFO, "Initializing environment subsystem"); SGSubsystemGroup::init(); + fgClouds->Init(); } void @@ -111,7 +112,7 @@ FGEnvironmentMgr::bind () { SGSubsystemGroup::bind(); _environment->Tie( fgGetNode("/environment", true ) ); - + _tiedProperties.setRoot( fgGetNode( "/environment", true ) ); _tiedProperties.Tie( "effective-visibility-m", thesky, @@ -128,27 +129,27 @@ FGEnvironmentMgr::bind () for (int i = 0; i < MAX_CLOUD_LAYERS; i++) { SGPropertyNode_ptr layerNode = fgGetNode("/environment/clouds",true)->getChild("layer", i, true ); - _tiedProperties.Tie( layerNode->getNode("span-m",true), this, i, + _tiedProperties.Tie( layerNode->getNode("span-m",true), this, i, &FGEnvironmentMgr::get_cloud_layer_span_m, &FGEnvironmentMgr::set_cloud_layer_span_m); - _tiedProperties.Tie( layerNode->getNode("elevation-ft",true), this, i, + _tiedProperties.Tie( layerNode->getNode("elevation-ft",true), this, i, &FGEnvironmentMgr::get_cloud_layer_elevation_ft, &FGEnvironmentMgr::set_cloud_layer_elevation_ft); - _tiedProperties.Tie( layerNode->getNode("thickness-ft",true), this, i, + _tiedProperties.Tie( layerNode->getNode("thickness-ft",true), this, i, &FGEnvironmentMgr::get_cloud_layer_thickness_ft, &FGEnvironmentMgr::set_cloud_layer_thickness_ft); - _tiedProperties.Tie( layerNode->getNode("transition-ft",true), this, i, + _tiedProperties.Tie( layerNode->getNode("transition-ft",true), this, i, &FGEnvironmentMgr::get_cloud_layer_transition_ft, &FGEnvironmentMgr::set_cloud_layer_transition_ft); - _tiedProperties.Tie( layerNode->getNode("coverage",true), this, i, + _tiedProperties.Tie( layerNode->getNode("coverage",true), this, i, &FGEnvironmentMgr::get_cloud_layer_coverage, &FGEnvironmentMgr::set_cloud_layer_coverage); - _tiedProperties.Tie( layerNode->getNode("coverage-type",true), this, i, + _tiedProperties.Tie( layerNode->getNode("coverage-type",true), this, i, &FGEnvironmentMgr::get_cloud_layer_coverage_type, &FGEnvironmentMgr::set_cloud_layer_coverage_type); @@ -174,9 +175,9 @@ FGEnvironmentMgr::bind () _tiedProperties.Tie("clouds3d-vis-range", thesky, &SGSky::get_3dCloudVisRange, &SGSky::set_3dCloudVisRange); - + _tiedProperties.Tie("precipitation-enable", &sgEnviro, - &SGEnviro::get_precipitation_enable_state, + &SGEnviro::get_precipitation_enable_state, &SGEnviro::set_precipitation_enable_state); _tiedProperties.Tie("lightning-enable", &sgEnviro, @@ -198,7 +199,7 @@ void FGEnvironmentMgr::update (double dt) { SGSubsystemGroup::update(dt); - + _environment->set_elevation_ft( _altitudeNode->getDoubleValue() ); simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(), @@ -322,25 +323,25 @@ FGEnvironmentMgr::get_cloud_layer_coverage_type (int index) const return thesky->get_cloud_layer(index)->getCoverage(); } -double +double FGEnvironmentMgr::get_cloud_layer_visibility_m (int index) const { return thesky->get_cloud_layer(index)->getVisibility_m(); } -void +void FGEnvironmentMgr::set_cloud_layer_visibility_m (int index, double visibility_m) { thesky->get_cloud_layer(index)->setVisibility_m(visibility_m); } -double +double FGEnvironmentMgr::get_cloud_layer_maxalpha (int index ) const { return thesky->get_cloud_layer(index)->getMaxAlpha(); } -void +void FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha) { thesky->get_cloud_layer(index)->setMaxAlpha(maxalpha); @@ -349,7 +350,7 @@ FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha) -void +void FGEnvironmentMgr::set_cloud_layer_coverage_type (int index, int type ) { if( type < 0 || type >= SGCloudLayer::SG_MAX_CLOUD_COVERAGES ) { diff --git a/src/Environment/fgclouds.cxx b/src/Environment/fgclouds.cxx index f5a531382..ccd21e0ce 100644 --- a/src/Environment/fgclouds.cxx +++ b/src/Environment/fgclouds.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -47,12 +48,13 @@ extern SGSky *thesky; FGClouds::FGClouds() : snd_lightning(0), - clouds_3d_enabled(false) + clouds_3d_enabled(false), + index(0) { update_event = 0; } -FGClouds::~FGClouds() +FGClouds::~FGClouds() { } @@ -65,7 +67,7 @@ void FGClouds::set_update_event(int count) { buildCloudLayers(); } -void FGClouds::init(void) { +void FGClouds::Init(void) { if( snd_lightning == NULL ) { snd_lightning = new SGSoundSample("Sounds/thunder.wav", SGPath()); snd_lightning->set_max_dist(7000.0f); @@ -75,6 +77,10 @@ void FGClouds::init(void) { sgr->add( snd_lightning, "thunder" ); sgEnviro.set_sampleGroup( sgr ); } + + 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 @@ -101,7 +107,10 @@ 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++) { @@ -111,7 +120,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); @@ -147,38 +156,10 @@ double FGClouds::buildCloud(SGPropertyNode *cloud_def_root, SGPropertyNode *box_ z = h * z + pos[2]; // Up/Down. pos[2] is the cloudbase SGVec3f newpos = SGVec3f(x, y, z); + SGNewCloud cld = SGNewCloud(texture_root, cld_def); - 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 = - 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.genCloud()); + //layer->addCloud(newpos, cld.genCloud()); + layer->addCloud(lon, lat, z, x, y, index++, cld.genCloud()); } } } @@ -266,7 +247,6 @@ void FGClouds::buildLayer(int iLayer, const string& name, double coverage) { break; } } - } // Now we've built any clouds, enable them and set the density (coverage) @@ -335,7 +315,7 @@ void FGClouds::buildCloudLayers(void) { layer_type = "sc"; } } - + cloud_root->setStringValue("layer-type",layer_type); buildLayer(iLayer, layer_type, coverage_norm); } @@ -349,8 +329,80 @@ void FGClouds::set_3dClouds(bool enable) } } -bool FGClouds::get_3dClouds() const +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); + + // Adding a 3D cloud immediately makes this layer 3D. + thesky->get_cloud_layer(l)->set_enable3dClouds(true); + SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D(); + SGNewCloud cld = SGNewCloud(texture_root, arg); + return layer->addCloud(lon, lat, alt, index, cld.genCloud()); + } + + /** + * 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); + + SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D(); + return layer->repositionCloud(i, lon, lat, alt); + } diff --git a/src/Environment/fgclouds.hxx b/src/Environment/fgclouds.hxx index 34ac595e3..9d26419ff 100644 --- a/src/Environment/fgclouds.hxx +++ b/src/Environment/fgclouds.hxx @@ -47,17 +47,24 @@ private: int update_event; SGSoundSample *snd_lightning; bool clouds_3d_enabled; + int index; public: FGClouds(); ~FGClouds(); - void init(void); + void Init(void); int get_update_event(void) const; void set_update_event(int count); bool get_3dClouds() const; void set_3dClouds(bool enable); + }; +static bool do_delete_3Dcloud (const SGPropertyNode *arg); +static bool do_move_3Dcloud (const SGPropertyNode *arg); +static bool do_add_3Dcloud (const SGPropertyNode *arg); + #endif // _FGCLOUDS_HXX +