X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FWeatherCM%2FFGLocalWeatherDatabase.h;h=60063fa173bbdc7ae5fe9a04a42f9204e01f44f2;hb=7d3448294bc7486af3f4c1f0ff5c8493b03ffc90;hp=aa0c008e0fdfa5a1d7841997ffd8826958964341;hpb=eddea671a276ea5337867d09699730876fce7085;p=flightgear.git diff --git a/src/WeatherCM/FGLocalWeatherDatabase.h b/src/WeatherCM/FGLocalWeatherDatabase.h index aa0c008e0..60063fa17 100644 --- a/src/WeatherCM/FGLocalWeatherDatabase.h +++ b/src/WeatherCM/FGLocalWeatherDatabase.h @@ -4,7 +4,7 @@ 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 @@ -36,6 +36,14 @@ HISTORY 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. *****************************************************************************/ /****************************************************************************/ @@ -47,60 +55,105 @@ 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 -#endif -#include -#include - #include -#include "sg.h" +#include STL_STRING + +#include + +#include
+ +#include +#include + +#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 */ /****************************************************************************/ -class FGLocalWeatherDatabase +struct _FGLocalWeatherDatabaseCache +{ + sgVec3 last_known_position; + //sgVec3 current_position; + SGPropertyNode *latitude_deg; + SGPropertyNode *longitude_deg; + SGPropertyNode *altitude_ft; + FGPhysicalProperty last_known_property; +}; + +class FGLocalWeatherDatabase : public FGSubsystem { private: protected: - FGGlobalWeatherDatabase *global; //point to the global database - - typedef vector FGMicroWeatherList; - typedef FGMicroWeatherList::iterator FGMicroWeatherListIt; - - typedef vector pointVector; + SphereInterpolate *database_logic; + vector database_data; +#ifndef macintosh + FGPhysicalProperties DatabaseEvaluate(const sgVec2& p) const + { + sgVec2 p_converted = {p[0]*(SGD_2PI/360.0), + p[1]*(SGD_2PI/360.0)}; + EvaluateData d = database_logic->Evaluate(p_converted); + return database_data[d.index[0]]*d.percentage[0] + + database_data[d.index[1]]*d.percentage[1] + + database_data[d.index[2]]*d.percentage[2] ; + } +#endif + FGPhysicalProperties DatabaseEvaluate(const sgVec3& p) const + { + sgVec3 p_converted = {p[0]*(SGD_2PI/360.0), + p[1]*(SGD_2PI/360.0), + p[2] }; + EvaluateData d = database_logic->Evaluate(p_converted); + return database_data[d.index[0]]*d.percentage[0] + + database_data[d.index[1]]*d.percentage[1] + + database_data[d.index[2]]*d.percentage[2] ; + } + + typedef vector pointVector; typedef vector 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 @@ -108,69 +161,110 @@ public: 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 + + /************************************************************************/ + /* define methods requited for FGSubsystem */ + /************************************************************************/ + virtual void init () { /* do nothing; that's done in the constructor */ }; + virtual void bind (); + virtual void unbind (); + virtual void update (int dt) { update((float) dt); }; /************************************************************************/ /* Get the physical properties on the specified point p */ /************************************************************************/ - FGPhysicalProperty get(const Point3D& p) const; - FGPhysicalProperty get(const sgVec3& 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; - WeatherPrecition getAirDensity(const Point3D& p) const; - WeatherPrecition getAirDensity(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 WeatherPrecition alt, const Point3D& x, const Point2D& p); - void addTurbulence(const WeatherPrecition alt, const Point3D& x, const Point2D& p); - void addTemperature(const WeatherPrecition alt, const WeatherPrecition x, const Point2D& p); - void addAirPressure(const WeatherPrecition alt, const WeatherPrecition x, const Point2D& p); - void addVaporPressure(const WeatherPrecition alt, const WeatherPrecition x, const Point2D& p); - void addCloud(const WeatherPrecition alt, 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; @@ -179,41 +273,83 @@ void fgUpdateWeatherDatabase(void); /****************************************************************************/ /* 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); }