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 */
/****************************************************************************/
#include <vector>
+#include STL_STRING
#include <plib/sg.h>
-#include <Math/sphrintp.h>
+#include <Main/fgfs.hxx>
+
+#include <simgear/constants.h>
+#include <simgear/misc/props.hxx>
+
+#include "sphrintp.h"
#include "FGPhysicalProperties.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:
- SphereInterpolate<FGPhysicalProperties> *database;
+ SphereInterpolate *database_logic;
+ vector<FGPhysicalProperties> 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<sgVec2> pointVector;
typedef vector<pointVector> tileVector;
/************************************************************************/
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:
+ /************************************************************************/
+ /* 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 {
DatabaseWorkingType DatabaseStatus;
- void init( const WeatherPrecision visibility, const DatabaseWorkingType type );
+ 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)
{
- sgCopyVec3( last_known_position, position );
+ cache = new _FGLocalWeatherDatabaseCache;
+ sgCopyVec3( cache->last_known_position, position );
- init( visibility, type );
+ init( visibility, type, root );
theFGLocalWeatherDatabase = this;
}
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)
{
- sgSetVec3( last_known_position, position_lat, position_lon, position_alt );
+ cache = new _FGLocalWeatherDatabaseCache;
+ sgSetVec3( cache->last_known_position, position_lat, position_lon, position_alt );
- init( visibility, type );
+ init( visibility, type, root );
theFGLocalWeatherDatabase = this;
}
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 */
/************************************************************************/
+#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;
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*/