]> git.mxchange.org Git - flightgear.git/blobdiff - src/WeatherCM/FGLocalWeatherDatabase.h
Additional changes including updates to JSBSim to try to get interface and
[flightgear.git] / src / WeatherCM / FGLocalWeatherDatabase.h
index 8898078524267d245352ff290fb7aa6db0c3fbc5..c3d5d1a3ccd26de7436e35e48f0e5f05437f6003 100644 (file)
@@ -38,6 +38,12 @@ HISTORY
                                suggestion
 19.10.1999 Christian Mayer     change to use PLIB's sg instead of Point[2/3]D
                                and lots of wee code cleaning
+14.12.1999 Christian Mayer     Changed the internal structure to use Dave
+                                Eberly's spherical interpolation code. This
+                               stops our dependancy on the (ugly) voronoi
+                               code and simplyfies the code structure a lot.
+18.07.2001 Christian Mayer      Added the posibility to limit the amount of 
+                                stations for a faster init.
 *****************************************************************************/
 
 /****************************************************************************/
@@ -49,41 +55,46 @@ HISTORY
 /****************************************************************************/
 /* INCLUDES                                                                */
 /****************************************************************************/
-//This is only here for smoother code change. In the end the WD should be clean
-//of *any* OpenGL:
-#ifdef HAVE_WINDOWS_H
-#  include <windows.h>
-#endif
-#include <GL/glut.h>
-#include <XGL/xgl.h>
-
 #include <vector>
+#include STL_STRING
+
+#include <plib/sg.h>
 
-#include "sg.h"
+#include "sphrintp.h"
 
 #include "FGPhysicalProperties.h"
-#include "FGGlobalWeatherDatabase.h"
-#include "FGMicroWeather.h"
+#include "FGPhysicalProperty.h"
+
+
 #include "FGWeatherFeature.h"
 #include "FGWeatherDefs.h"
+#include "FGThunderstorm.h"
 
 /****************************************************************************/
 /* DEFINES                                                                 */
 /****************************************************************************/
-FG_USING_STD(vector);
-FG_USING_NAMESPACE(std);
+SG_USING_STD(vector);
+SG_USING_STD(string);
+SG_USING_NAMESPACE(std);
 
 /****************************************************************************/
 /* CLASS DECLARATION                                                       */
 /****************************************************************************/
+struct _FGLocalWeatherDatabaseCache
+{
+    sgVec3             last_known_position;
+    //sgVec3             current_position;
+    SGPropertyNode     *latitude_deg;
+    SGPropertyNode     *longitude_deg;
+    SGPropertyNode     *altitude_ft;
+    FGPhysicalProperty last_known_property;
+};
+
 class FGLocalWeatherDatabase
 {
 private:
 protected:
-    FGGlobalWeatherDatabase *global;   //point to the global database
-
-    typedef vector<FGMicroWeather>       FGMicroWeatherList;
-    typedef FGMicroWeatherList::iterator FGMicroWeatherListIt;
+    SphereInterpolate<FGPhysicalProperties> *database;
 
     typedef vector<sgVec2>      pointVector;
     typedef vector<pointVector> tileVector;
@@ -91,32 +102,32 @@ protected:
     /************************************************************************/
     /* make tiles out of points on a 2D plane                              */
     /************************************************************************/
-    void tileLocalWeather(const FGPhysicalProperties2DVector& EntryList);
-
-    FGMicroWeatherList WeatherAreas;
-
     WeatherPrecision WeatherVisibility;        //how far do I need to simulate the
                                        //local weather? Unit: metres
-    sgVec3 last_known_position;
 
+    _FGLocalWeatherDatabaseCache *cache;
+    inline void check_cache_for_update(void) const;
+
+    bool Thunderstorm;                 //is there a thunderstorm near by?
+    FGThunderstorm *theThunderstorm;   //pointer to the thunderstorm.
 
+public:
     /************************************************************************/
-    /* return the index of the area with point p                           */
+    /* for tieing them to the property system                              */
     /************************************************************************/
-    unsigned int AreaWith(const sgVec2& p) const;
-    unsigned int AreaWith(const sgVec3& p) const
-    {
-       sgVec2 temp;
-       sgSetVec2(temp, p[0], p[1]);
+    inline WeatherPrecision get_wind_north() const;
+    inline WeatherPrecision get_wind_east() const;
+    inline WeatherPrecision get_wind_up() const;
+    inline WeatherPrecision get_temperature() const;
+    inline WeatherPrecision get_air_pressure() const;
+    inline WeatherPrecision get_vapor_pressure() const;
+    inline WeatherPrecision get_air_density() const;
 
-       return AreaWith(temp);
-    }
-
-public:
     static FGLocalWeatherDatabase *theFGLocalWeatherDatabase;  
     
     enum DatabaseWorkingType {
-       use_global,     //use global database for data
+       use_global,     //use global database for data !!obsolete!!
+       use_internet,   //use the weather data that came from the internet
        manual,         //use only user inputs
        distant,        //use distant information, e.g. like LAN when used in
                        //a multiplayer environment
@@ -126,32 +137,41 @@ public:
 
     DatabaseWorkingType DatabaseStatus;
 
+    void init( const WeatherPrecision visibility,
+              const DatabaseWorkingType type,
+              const string &root );
+
     /************************************************************************/
     /* Constructor and Destructor                                          */
     /************************************************************************/
     FGLocalWeatherDatabase(
        const sgVec3&             position,
-       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY,
-       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE);
+       const string&             root,
+       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
+       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
+    {
+        cache = new _FGLocalWeatherDatabaseCache;
+       sgCopyVec3( cache->last_known_position, position );
+
+       init( visibility, type, root );
+
+       theFGLocalWeatherDatabase = this;
+    }
 
     FGLocalWeatherDatabase(
        const WeatherPrecision    position_lat,
        const WeatherPrecision    position_lon,
        const WeatherPrecision    position_alt,
-       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY,
-       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE)
+       const string&             root,
+       const DatabaseWorkingType type       = PREFERED_WORKING_TYPE,
+       const WeatherPrecision    visibility = DEFAULT_WEATHER_VISIBILITY)
     {
-       cout << "This constructor is broken and should *NOT* be used!" << endl;
-       exit(-1);
-
-       sgVec3 position;
-       sgSetVec3( position, position_lat, position_lon, position_alt );
+        cache = new _FGLocalWeatherDatabaseCache;
+       sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
 
-       // Christian: the following line does not do what you intend.
-       // It just creates a new FGLocalWeatherDatabase which isn't
-       // assigned to anything so it is immediately discared.
+       init( visibility, type, root );
 
-       /* BAD --> */ FGLocalWeatherDatabase( position, visibility, type );
+       theFGLocalWeatherDatabase = this;
     }
 
     ~FGLocalWeatherDatabase();
@@ -171,7 +191,15 @@ public:
     /************************************************************************/
     /* Get the physical properties on the specified point p                */
     /************************************************************************/
+#ifdef macintosh
+    /* fix a problem with mw compilers in that they don't know the
+       difference between the next two methods. Since the first one
+       doesn't seem to be used anywhere, I commented it out. This is
+       supposed to be fixed in the forthcoming CodeWarrior Release
+       6. */
+#else
     FGPhysicalProperties get(const sgVec2& p) const;
+#endif
     FGPhysicalProperty   get(const sgVec3& p) const;
 
     WeatherPrecision     getAirDensity(const sgVec3& p) const;
@@ -179,19 +207,12 @@ public:
     /************************************************************************/
     /* Add a weather feature at the point p and surrounding area           */
     /************************************************************************/
-
-    void addWind         (const WeatherPrecision alt, const sgVec3& x,          const sgVec2& p);
-    void addTurbulence   (const WeatherPrecision alt, const sgVec3& x,          const sgVec2& p);
-    void addTemperature  (const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p);
-    void addAirPressure  (const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p);
-    void addVaporPressure(const WeatherPrecision alt, const WeatherPrecision x, const sgVec2& p);
-    void addCloud        (const WeatherPrecision alt, const FGCloudItem& x,     const sgVec2& p);
+    // !! Adds aren't supported anymore !!
 
     void setSnowRainIntensity   (const WeatherPrecision x, const sgVec2& p);
     void setSnowRainType        (const SnowRainType x,     const sgVec2& p);
     void setLightningProbability(const WeatherPrecision x, const sgVec2& p);
 
-    void addProperties(const FGPhysicalProperties2D& x);    //add a property
     void setProperties(const FGPhysicalProperties2D& x);    //change a property
 
     /************************************************************************/
@@ -199,6 +220,17 @@ public:
     /************************************************************************/
     void             setWeatherVisibility(const WeatherPrecision visibility);
     WeatherPrecision getWeatherVisibility(void) const;
+
+    /************************************************************************/
+    /* figure out if there's a thunderstorm that has to be taken care of    */
+    /************************************************************************/
+    void updateThunderstorm(const float dt)
+    {
+       if (Thunderstorm == false)
+           return;
+
+       theThunderstorm->update( dt );
+    }
 };
 
 extern FGLocalWeatherDatabase *WeatherDatabase;
@@ -213,37 +245,79 @@ void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecision
        WeatherVisibility = visibility;
     else
        WeatherVisibility = MINIMUM_WEATHER_VISIBILITY;
-
-#if 0
-    //This code doesn't belong here as this is the optical visibility and not
-    //the visibility of the weather database (that should be bigger...). The
-    //optical visibility should be calculated from the vapor pressure e.g.
-    //But for the sake of a smoother change from the old way to the new one...
-
-    GLfloat fog_exp_density;
-    GLfloat fog_exp2_density;
-    
-    // for GL_FOG_EXP
-    fog_exp_density = -log(0.01 / WeatherVisibility);
-    
-    // for GL_FOG_EXP2
-    fog_exp2_density = sqrt( -log(0.01) ) / WeatherVisibility;
-    
-    // Set correct opengl fog density
-    xglFogf (GL_FOG_DENSITY, fog_exp2_density);
-    
-    // FG_LOG( FG_INPUT, FG_DEBUG, "Fog density = " << w->fog_density );
-    //cerr << "FGLocalWeatherDatabase::setWeatherVisibility(" << visibility << "):\n";
-    //cerr << "Fog density = " << fog_exp_density << "\n";
-#endif
 }
 
 WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
 {
-    //cerr << "FGLocalWeatherDatabase::getWeatherVisibility() = " << WeatherVisibility << "\n";
     return WeatherVisibility;
 }
 
+inline void FGLocalWeatherDatabase::check_cache_for_update(void) const
+{
+  if ( ( cache->last_known_position[0] == cache->latitude_deg->getFloatValue() ) &&
+       ( cache->last_known_position[1] == cache->longitude_deg->getFloatValue() ) &&
+       ( cache->last_known_position[2] == cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER ) )
+    return; //nothing to do 
+
+  sgVec3 position = { cache->latitude_deg->getFloatValue(), 
+                      cache->longitude_deg->getFloatValue(), 
+                      cache->altitude_ft->getFloatValue() * SG_FEET_TO_METER };
+
+  sgCopyVec3(cache->last_known_position, position);
+  cache->last_known_property = get(position);
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[0];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_east() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[1];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_up() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Wind[2];
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_temperature() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.Temperature;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_air_pressure() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.AirPressure;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_vapor_pressure() const
+{
+  check_cache_for_update();
+
+  return cache->last_known_property.VaporPressure;
+}
+
+inline WeatherPrecision FGLocalWeatherDatabase::get_air_density() const
+{
+  // check_for_update();
+  // not required, as the called functions will do that
+
+  return (get_air_pressure()*FG_WEATHER_DEFAULT_AIRDENSITY*FG_WEATHER_DEFAULT_TEMPERATURE) / 
+        (get_temperature()*FG_WEATHER_DEFAULT_AIRPRESSURE);
+}
+
 
 /****************************************************************************/
 #endif /*FGLocalWeatherDatabase_H*/