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 "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;
/************************************************************************/
/* 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
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();
/************************************************************************/
/* 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;
/************************************************************************/
/* 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
/************************************************************************/
/************************************************************************/
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;
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*/