]> git.mxchange.org Git - flightgear.git/commitdiff
precipitation effects from Nicolas Vivien
authortimoore <timoore>
Tue, 4 Mar 2008 09:02:24 +0000 (09:02 +0000)
committertimoore <timoore>
Tue, 4 Mar 2008 09:02:24 +0000 (09:02 +0000)
src/Environment/Makefile.am
src/Environment/precipitation_mgr.cxx [new file with mode: 0644]
src/Environment/precipitation_mgr.hxx [new file with mode: 0644]
src/Main/main.cxx
src/Main/renderer.cxx
src/Scenery/tileentry.cxx

index 77ce29eea1715b3b59c029cc6b29ec77a14dafb9..d7b43abece31b84e18c057f79b8a03f6ab4280c5 100644 (file)
@@ -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 (file)
index 0000000..fcabe72
--- /dev/null
@@ -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 <osgDB/ReadFile>
+#include <osgDB/FileUtils>
+#include <osgUtil/Optimizer>
+#include <osgUtil/CullVisitor>
+#include <osgViewer/Viewer>
+
+#include <osg/Depth>
+#include <osg/Stencil>
+#include <osg/ClipPlane>
+#include <osg/ClipNode>
+#include <osg/MatrixTransform>
+#include <osgUtil/TransformCallback>
+
+#include <simgear/constants.h>
+#include <simgear/scene/sky/sky.hxx>
+#include <simgear/scene/sky/cloud.hxx>
+
+#include <Main/fg_props.hxx>
+
+#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; i<thesky->get_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 (file)
index 0000000..2d24579
--- /dev/null
@@ -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 <simgear/environment/precipitation.hxx>
+
+#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
+
index bb14ae0fedb50a6b6fdeb796e32785a0daacfefd..dd29fb8b85cab46a8213043388324dd6c1b67694 100644 (file)
@@ -71,6 +71,7 @@
 #include <Time/tmp.hxx>
 #include <Time/fg_timer.hxx>
 #include <Environment/environment_mgr.hxx>
+#include <Environment/precipitation_mgr.hxx>
 #include <GUI/new_gui.hxx>
 #include <MultiPlayer/multiplaymgr.hxx>
 
@@ -81,6 +82,8 @@
 #include "main.hxx"
 
 
+extern FGPrecipitationMgr *fgPrecipitationMgr;
+
 
 static double real_delta_time_sec = 0.0;
 double delta_time_sec = 0.0;
@@ -847,6 +850,11 @@ static void fgIdleFunction ( void ) {
                        globals->get_ephem()->getStars(),
                        fgGetNode("/environment", true));
 
+
+               // Precipitation Manager...
+               fgPrecipitationMgr = new FGPrecipitationMgr();
+
+
         // Initialize MagVar model
         SGMagVar *magvar = new SGMagVar();
         globals->set_mag( magvar );
index 6e93d57c3198d1d681c90ec1ca2dffe774419a31..3d5cc51a56d2b4cf9037e37d92c583d3cdb26880 100644 (file)
@@ -99,6 +99,7 @@
 #include <GUI/new_gui.hxx>
 #include <Instrumentation/instrument_mgr.hxx>
 #include <Instrumentation/HUD/HUD.hxx>
+#include <Environment/precipitation_mgr.hxx>
 
 #include <Include/general.hxx>
 #include "splash.hxx"
@@ -386,6 +387,9 @@ public:
 // Sky structures
 SGSky *thesky;
 
+// Precipitations
+FGPrecipitationMgr *fgPrecipitationMgr;
+
 static osg::ref_ptr<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
 static osg::ref_ptr<SGUpdateVisitor> mUpdateVisitor= new SGUpdateVisitor;
 
@@ -501,6 +505,11 @@ FGRenderer::init( void ) {
     stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
     stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
 
+
+       // Add Precipitation object
+       sceneGroup->addChild( fgPrecipitationMgr->getObject() );
+
+
     // need to update the light on every frame
     osg::LightSource* lightSource = new osg::LightSource;
     lightSource->setUpdateCallback(new FGLightSourceUpdateCallback);
@@ -790,6 +799,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
 //                current_view_origin_airspeed_horiz_kt
 //                );
 
+       // Update precipitation informations...
+       fgPrecipitationMgr->update();
+
+
     // OSGFIXME
 //     if( is_internal )
 //         shadows->endOfFrame();
index 2eab669aa77906dc7d978931dd9e6e1d4a104db3..bc89446117f677d35559d69be7da883b5697c0a8 100644 (file)
@@ -165,7 +165,7 @@ FGTileEntry::~FGTileEntry ()
 {
 }
 
-static void WorldCoordinate( osg::Matrix& obj_pos, double lat,
+void WorldCoordinate( osg::Matrix& obj_pos, double lat,
                              double lon, double elev, double hdg )
 {
     double lon_rad = lon * SGD_DEGREES_TO_RADIANS;