From eb26cb35905cb1894cb0346700826cff512e437e Mon Sep 17 00:00:00 2001 From: timoore Date: Tue, 4 Mar 2008 09:02:24 +0000 Subject: [PATCH] precipitation effects from Nicolas Vivien --- src/Environment/Makefile.am | 3 +- src/Environment/precipitation_mgr.cxx | 228 ++++++++++++++++++++++++++ src/Environment/precipitation_mgr.hxx | 55 +++++++ src/Main/main.cxx | 8 + src/Main/renderer.cxx | 13 ++ src/Scenery/tileentry.cxx | 2 +- 6 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 src/Environment/precipitation_mgr.cxx create mode 100644 src/Environment/precipitation_mgr.hxx diff --git a/src/Environment/Makefile.am b/src/Environment/Makefile.am index 77ce29eea..d7b43abec 100644 --- a/src/Environment/Makefile.am +++ b/src/Environment/Makefile.am @@ -9,6 +9,7 @@ libEnvironment_a_SOURCES = \ environment_mgr.cxx environment_mgr.hxx \ environment_ctrl.cxx environment_ctrl.hxx \ fgmetar.cxx fgmetar.hxx fgclouds.cxx fgclouds.hxx \ - atmosphere.cxx atmosphere.hxx + atmosphere.cxx atmosphere.hxx \ + precipitation_mgr.cxx fgprecipitation_mgr.hxx INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src diff --git a/src/Environment/precipitation_mgr.cxx b/src/Environment/precipitation_mgr.cxx new file mode 100644 index 000000000..fcabe72ba --- /dev/null +++ b/src/Environment/precipitation_mgr.cxx @@ -0,0 +1,228 @@ +/** + * @file precipitation_mgr.cxx + * @author Nicolas VIVIEN + * @date 2008-02-10 + * + * @note Copyright (C) 2008 Nicolas VIVIEN + * + * @brief Precipitation manager + * This manager calculate the intensity of precipitation in function of the altitude, + * calculate the wind direction and velocity, then update the drawing of precipitation. + * + * @par Licences + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * @par CVS + * $Id$ + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include
+ +#include "precipitation_mgr.hxx" + + +extern SGSky *thesky; + + +void WorldCoordinate( osg::Matrix&, double, + double, double, double); + +/** + * @brief FGPrecipitation Manager constructor + * + * Build a new object to manage the precipitation object + */ +FGPrecipitationMgr::FGPrecipitationMgr() +{ + osg::Matrix position; + double latitude, longitude; + + + group = new osg::Group(); + transform = new osg::MatrixTransform(); + precipitation = new SGPrecipitation(); + + + // By default, none precipitation + precipitation->setRainIntensity(0); + precipitation->setSnowIntensity(0); + + + // Read latitude and longitude position + latitude = fgGetDouble("/position/latitude-deg", 0.0); + longitude = fgGetDouble("/position/longitude-deg", 0.0); + + WorldCoordinate(position, latitude, longitude, 0, 0); + + + // Move the precipitation object to player position + transform->setMatrix(position); + transform->addChild(precipitation->build()); + + group->addChild(transform); +} + + +/** + * @brief FGPrecipitaiton Manager destructor + */ +FGPrecipitationMgr::~FGPrecipitationMgr() +{ + delete precipitation; +} + + +/** + * @brief Get OSG precipitation object + * + * @returns A pointer on the OSG object (osg::Group *) + */ +osg::Group * FGPrecipitationMgr::getObject(void) +{ + return this->group; +} + + +/** + * @brief Calculate the max alitutude with precipitation + * + * @returns Elevation max in meter + * + * This function permits you to know what is the altitude max where we can + * find precipitation. The value is returned in meter. + */ +float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void) +{ + int i; + int max; + float result; + + + // By default (not cloud layer) + max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES; + result = 0; + + // To avoid messing up + if (thesky == NULL) + return result; + + // For each cloud layer + for (i=0; iget_cloud_layer_count(); i++) { + int q; + + // Get coverage + // Value for q are (meaning / thickness) : + // 5 : "clear" / 0 + // 4 : "cirrus" / ?? + // 3 : "few" / 65 + // 2 : "scattered" / 600 + // 1 : "broken" / 750 + // 0 : "overcast" / 1000 + q = thesky->get_cloud_layer(i)->getCoverage(); + + // Save the coverage max + if (q < max) { + max = q; + result = thesky->get_cloud_layer(i)->getElevation_m(); + } + } + + return result; +} + + +/** + * @brief Update the precipitation drawing + * + * @returns true is all is OK + * + * This function permits you to update the precipitation drawing. + * This function is called by the renderer. + */ +bool FGPrecipitationMgr::update(void) +{ + double dewtemp; + double currtemp; + double rain_intensity; + double snow_intensity; + + float altitudeAircraft; + float altitudeCloudLayer; + + // Get the elevation of aicraft and of the cloud layer + altitudeAircraft = fgGetDouble("/position/altitude-ft", 0.0); + altitudeCloudLayer = this->getPrecipitationAtAltitudeMax() * SG_METER_TO_FEET; + + if (altitudeAircraft > altitudeCloudLayer) { + // The aircraft is above the cloud layer + rain_intensity = 0; + snow_intensity = 0; + } + else { + // The aircraft is bellow the cloud layer + rain_intensity = fgGetDouble("/environment/metar/rain-norm", 0.0); + snow_intensity = fgGetDouble("/environment/metar/snow-norm", 0.0); + } + + // Get the current and dew temperature + dewtemp = fgGetDouble("/environment/dewpoint-degc", 0.0); + currtemp = fgGetDouble("/environment/temperature-degc", 0.0); + + if (currtemp < dewtemp) { + // There is fog... and the weather is very steamy + if (rain_intensity == 0) + rain_intensity = 0.15; + } + + // If the current temperature is below 0°C, we turn off the rain to snow... + if (currtemp < 0) + precipitation->setFreezing(true); + else + precipitation->setFreezing(false); + + + // Set the wind property + precipitation->setWindProperty( + fgGetDouble("/environment/wind-from-heading-deg", 0.0), + fgGetDouble("/environment/wind-speed-kt", 0.0)); + + // Set the intensity of precipitation + precipitation->setRainIntensity(rain_intensity); + precipitation->setSnowIntensity(snow_intensity); + + // Update the drawing... + precipitation->update(); + + return true; +} + + diff --git a/src/Environment/precipitation_mgr.hxx b/src/Environment/precipitation_mgr.hxx new file mode 100644 index 000000000..2d2457976 --- /dev/null +++ b/src/Environment/precipitation_mgr.hxx @@ -0,0 +1,55 @@ +/** + * @file precipitation_mgr.hxx + * @author Nicolas VIVIEN + * @date 2008-02-10 + * + * @note Copyright (C) 2008 Nicolas VIVIEN + * + * @brief Precipitation manager + * This manager calculate the intensity of precipitation in function of the altitude, + * calculate the wind direction and velocity, then update the drawing of precipitation. + * + * @par Licences + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * @par CVS + * $Id$ + */ + +#ifndef _PRECIPITATION_MGR_HXX +#define _PRECIPITATION_MGR_HXX + +#include + +#include "precipitation_mgr.hxx" + + +class FGPrecipitationMgr { +private: + osg::Group *group; + osg::MatrixTransform *transform; + SGPrecipitation *precipitation; + float getPrecipitationAtAltitudeMax(void); + + +public: + FGPrecipitationMgr(); + ~FGPrecipitationMgr(); + bool update(void); + osg::Group * getObject(void); +}; + +#endif + diff --git a/src/Main/main.cxx b/src/Main/main.cxx index bb14ae0fe..dd29fb8b8 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -71,6 +71,7 @@ #include