Author: Christian Mayer
Date started: 28.05.99
- ---------- Copyright (C) 1999 Christian Mayer (vader@t-online.de) ----------
+ -------- Copyright (C) 1999 Christian Mayer (fgfs@christianmayer.de) --------
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
16.06.1999 Durk Talsma Portability for Linux
20.06.1999 Christian Mayer added lots of consts
30.06.1999 Christian Mayer STL portability
+11.10.1999 Christian Mayer changed set<> to map<> on Bernie Bright's
+ 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.
*****************************************************************************/
/****************************************************************************/
/****************************************************************************/
/* 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 <simgear/misc/props.hxx>
+#include <simgear/constants.h>
+
+#include "sphrintp.h"
#include "FGPhysicalProperties.h"
-#include "FGGlobalWeatherDatabase.h"
-#include "FGMicroWeather.h"
+#include "FGPhysicalProperty.h"
+
#include "FGWeatherFeature.h"
#include "FGWeatherDefs.h"
-#include <vector>
+#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<Point2D> pointVector;
+ typedef vector<sgVec2> pointVector;
typedef vector<pointVector> tileVector;
/************************************************************************/
/* make tiles out of points on a 2D plane */
/************************************************************************/
- void tileLocalWeather(const FGPhysicalProperties2DVector& EntryList);
+ WeatherPrecision WeatherVisibility; //how far do I need to simulate the
+ //local weather? Unit: metres
- FGMicroWeatherList WeatherAreas;
+ _FGLocalWeatherDatabaseCache *cache;
+ inline void check_cache_for_update(void) const;
- WeatherPrecition WeatherVisibility; //how far do I need to simulate the
- //local weather? Unit: metres
- Point3D last_known_position;
+ bool Thunderstorm; //is there a thunderstorm near by?
+ FGThunderstorm *theThunderstorm; //pointer to the thunderstorm.
public:
+ /************************************************************************/
+ /* for tieing them to the property system */
+ /************************************************************************/
+ 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;
+
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
default_mode //use only default values
};
-protected:
DatabaseWorkingType DatabaseStatus;
- /************************************************************************/
- /* return the index of the area with point p */
- /************************************************************************/
- unsigned int AreaWith(const Point2D& p) const;
+ void init( const WeatherPrecision visibility,
+ const DatabaseWorkingType type,
+ const string &root );
-public:
/************************************************************************/
/* Constructor and Destructor */
/************************************************************************/
FGLocalWeatherDatabase(
- const Point3D& posititon,
- const WeatherPrecition& visibility = DEFAULT_WEATHER_VISIBILIY,
- const DatabaseWorkingType& type = PREFERED_WORKING_TYPE);
+ const sgVec3& position,
+ 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 string& root,
+ const DatabaseWorkingType type = PREFERED_WORKING_TYPE,
+ const WeatherPrecision visibility = DEFAULT_WEATHER_VISIBILITY)
+ {
+ cache = new _FGLocalWeatherDatabaseCache;
+ sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
+
+ init( visibility, type, root );
+
+ theFGLocalWeatherDatabase = this;
+ }
+
~FGLocalWeatherDatabase();
/************************************************************************/
/* reset the whole database */
/************************************************************************/
- void reset(const DatabaseWorkingType& type = PREFERED_WORKING_TYPE);
+ void reset(const DatabaseWorkingType type = PREFERED_WORKING_TYPE);
/************************************************************************/
/* update the database. Since the last call we had dt seconds */
/************************************************************************/
- void update(const WeatherPrecition& dt); //time has changed
- void update(const Point3D& p); //position has changed
- void update(const Point3D& p, const WeatherPrecition& dt); //time and/or position has changed
+ void update(const WeatherPrecision dt); //time has changed
+ void update(const sgVec3& p); //position has changed
+ void update(const sgVec3& p, const WeatherPrecision dt); //time and/or position has changed
/************************************************************************/
/* Get the physical properties on the specified point p */
/************************************************************************/
- FGPhysicalProperty get(const Point3D& p) const;
- WeatherPrecition getAirDensity(const Point3D& p) const;
+#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;
/************************************************************************/
/* Add a weather feature at the point p and surrounding area */
/************************************************************************/
+ // !! Adds aren't supported anymore !!
- void addWind(const FGWindItem& x, const Point2D& p);
- void addTurbulence(const FGTurbulenceItem& x, const Point2D& p);
- void addTemperature(const FGTemperatureItem& x, const Point2D& p);
- void addAirPressure(const FGAirPressureItem& x, const Point2D& p);
- void addVaporPressure(const FGVaporPressureItem& x, const Point2D& p);
- void addCloud(const FGCloudItem& x, const Point2D& p);
-
- void setSnowRainIntensity(const WeatherPrecition& x, const Point2D& p);
- void setSnowRainType(const SnowRainType& x, const Point2D& p);
- void setLightningProbability(const WeatherPrecition& x, const Point2D& p);
+ 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
/************************************************************************/
/* get/set weather visibility */
/************************************************************************/
- void setWeatherVisibility(const WeatherPrecition& visibility);
- WeatherPrecition getWeatherVisibility(void) const;
+ 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;
/****************************************************************************/
/* get/set weather visibility */
/****************************************************************************/
-void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecition& visibility)
+void inline FGLocalWeatherDatabase::setWeatherVisibility(const WeatherPrecision visibility)
{
- if (visibility >= MINIMUM_WEATHER_VISIBILIY)
+ if (visibility >= MINIMUM_WEATHER_VISIBILITY)
WeatherVisibility = visibility;
else
- WeatherVisibility = MINIMUM_WEATHER_VISIBILIY;
+ WeatherVisibility = MINIMUM_WEATHER_VISIBILITY;
+}
- //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...
+WeatherPrecision inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
+{
+ return WeatherVisibility;
+}
- 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";
-
+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);
}
-WeatherPrecition inline FGLocalWeatherDatabase::getWeatherVisibility(void) const
+inline WeatherPrecision FGLocalWeatherDatabase::get_wind_north() const
{
- //cerr << "FGLocalWeatherDatabase::getWeatherVisibility() = " << WeatherVisibility << "\n";
- return WeatherVisibility;
+ 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);
}