#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
-//#include <simgear/constants.h>
+#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sg_path.hxx>
#ifndef _FG_ATC_HXX
#define _FG_ATC_HXX
+#include <simgear/constants.h>
#include <simgear/compiler.h>
#include <simgear/misc/sgstream.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include "ATCDialog.hxx"
#include <Airports/runways.hxx>
+#include <simgear/math/polar3d.hxx>
#include <simgear/misc/sg_path.hxx>
#ifdef FG_WEATHERCM
#include "Glue.hpp"
namespace yasim {
-// WGS84 numbers
-static const double EQURAD = 6378137; // equatorial radius
-static const double STRETCH = 1.003352810665; // equ./polar radius
-
-// Derived from the above
-static const double SQUASH = 0.99665839311; // 1/STRETCH
-static const double POLRAD = 6356823.77346; // EQURAD*SQUASH
-static const double iPOLRAD = 1.57311266701e-07; // 1/POLRAD
-
void Glue::calcAlphaBeta(State* s, float* alpha, float* beta)
{
// Convert the velocity to the aircraft frame.
*pitch = Math::dot3(pitchAxis, s->rot);
}
-void Glue::xyz2geoc(double* xyz, double* lat, double* lon, double* alt)
-{
- double x=xyz[0], y=xyz[1], z=xyz[2];
-
- // Cylindrical radius from the polar axis
- double rcyl = Math::sqrt(x*x + y*y);
-
- // In geocentric coordinates, these are just the angles in
- // cartesian space.
- *lon = Math::atan2(y, x);
- *lat = Math::atan2(z, rcyl);
-
- // To get XYZ coordinate of "ground", we "squash" the cylindric
- // radius into a coordinate system where the earth is a sphere,
- // find the fraction of the xyz vector that is above ground.
- double rsquash = SQUASH * rcyl;
- double frac = POLRAD/Math::sqrt(rsquash*rsquash + z*z);
- double len = Math::sqrt(x*x + y*y + z*z);
-
- *alt = len * (1-frac);
-}
-
-void Glue::geoc2xyz(double lat, double lon, double alt, double* out)
-{
- // Generate a unit vector
- double rcyl = Math::cos(lat);
- double x = rcyl*Math::cos(lon);
- double y = rcyl*Math::sin(lon);
- double z = Math::sin(lat);
-
- // Convert to "squashed" space, renormalize the unit vector,
- // multiply by the polar radius, and back convert to get us the
- // point of intersection of the unit vector with the surface.
- // Then just add the altitude.
- double rtmp = rcyl*SQUASH;
- double renorm = POLRAD/Math::sqrt(rtmp*rtmp + z*z);
- double ztmp = z*renorm;
- rtmp *= renorm*STRETCH;
- double len = Math::sqrt(rtmp*rtmp + ztmp*ztmp);
- len += alt;
-
- out[0] = x*len;
- out[1] = y*len;
- out[2] = z*len;
-}
-
-double Glue::geod2geocLat(double lat)
-{
- double r = Math::cos(lat)*STRETCH*STRETCH;
- double z = Math::sin(lat);
- return Math::atan2(z, r);
-}
-
-double Glue::geoc2geodLat(double lat)
-{
- double r = Math::cos(lat)*SQUASH*SQUASH;
- double z = Math::sin(lat);
- return Math::atan2(z, r);
-}
-
-void Glue::xyz2geod(double* xyz, double* lat, double* lon, double* alt)
-{
- xyz2geoc(xyz, lat, lon, alt);
- *lat = geoc2geodLat(*lat);
-}
-
-void Glue::geod2xyz(double lat, double lon, double alt, double* out)
-{
- lat = geod2geocLat(lat);
- geoc2xyz(lat, lon, alt, out);
-}
-
void Glue::xyz2nedMat(double lat, double lon, float* out)
{
// Shorthand for our output vectors:
*roll = Math::atan2(pz, py);
}
-void Glue::geodUp(double* pos, float* out)
+void Glue::geodUp(double lat, double lon, float* up)
{
- double lat, lon, alt;
- xyz2geod(pos, &lat, &lon, &alt);
-
- float slat = (float)Math::sin(lat);
- float clat = (float)Math::cos(lat);
- float slon = (float)Math::sin(lon);
- float clon = (float)Math::cos(lon);
- out[0] = clon * clat;
- out[1] = slon * clat;
- out[2] = slat;
+ double coslat = Math::cos(lat);
+ up[0] = (float)(Math::cos(lon) * coslat);
+ up[1] = (float)(Math::sin(lon) * coslat);
+ up[2] = (float)(Math::sin(lat));
+}
+
+// FIXME: Hardcoded WGS84 numbers...
+void Glue::geodUp(double* pos, float* up)
+{
+ const double SQUASH = 0.9966471893352525192801545;
+ const double STRETCH = 1.0033640898209764189003079;
+ float x = (float)(pos[0] * SQUASH);
+ float y = (float)(pos[1] * SQUASH);
+ float z = (float)(pos[2] * STRETCH);
+ float norm = 1/Math::sqrt(x*x + y*y + z*z);
+ up[0] = x * norm;
+ up[1] = y * norm;
+ up[2] = z * norm;
}
}; // namespace yasim
static void calcEulerRates(State* s,
float* roll, float* pitch, float* hdg);
- static void xyz2geoc(double* xyz,
- double* lat, double* lon, double* alt);
- static void geoc2xyz(double lat, double lon, double alt,
- double* out);
- static void xyz2geod(double* xyz,
- double* lat, double* lon, double* alt);
- static void geod2xyz(double lat, double lon, double alt,
- double* out);
-
- static double geod2geocLat(double lat);
- static double geoc2geodLat(double lat);
-
// Returns a global to "local" (north, east, down) matrix. Note
// that the latitude passed in is geoDETic.
static void xyz2nedMat(double lat, double lon, float* out);
static void orient2euler(float* o,
float* roll, float* pitch, float* hdg);
- // Returns a geodetic (i.e. gravitational, "level", etc...) "up"
- // vector for the specified xyz position.
- static void geodUp(double* pos, float* out);
+ static void geodUp(double lat, double lon, float* up);
+ static void geodUp(double* pos, float* up);
};
}; // namespace yasim
#include <simgear/debug/logstream.hxx>
+#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/scene/model/location.hxx>
#include <simgear/scene/model/placement.hxx>
Glue::xyz2nedMat(lat, lon, xyz2ned);
// position
- Glue::geod2xyz(lat, lon, alt, s.pos);
+ sgGeodToCart(lat, lon, alt, s.pos);
// orientation
Glue::euler2orient(roll, pitch, hdg, s.orient);
// us, find the (geodetic) up vector normal to the ground, then
// use that to find the final (radius) term of the plane equation.
double xyz[3], gplane[3]; float up[3];
- Glue::geod2xyz(lat, lon, ground, xyz);
- Glue::geodUp(xyz, up); // FIXME, needless reverse computation...
+ sgGeodToCart(lat, lon, ground, xyz);
+ Glue::geodUp(lat, lon, up); // FIXME, needless reverse computation...
int i;
for(i=0; i<3; i++) gplane[i] = up[i];
double rad = gplane[0]*xyz[0] + gplane[1]*xyz[1] + gplane[2]*xyz[2];
// position
double lat, lon, alt;
- Glue::xyz2geod(s->pos, &lat, &lon, &alt);
+ sgCartToGeod(s->pos, &lat, &lon, &alt);
_set_Geodetic_Position(lat, lon, alt*M2FT);
// UNUSED
// This file is in the Public Domain and comes with no warranty.
#include <simgear/compiler.h>
+#include <simgear/constants.h>
#include <simgear/math/sg_geodesy.hxx>
#include <Main/fg_props.hxx>
globals->inc_sim_time_sec( delta_time_sec );
SGAnimation::set_sim_time_sec( globals->get_sim_time_sec() );
+ // These are useful, especially for Nasal scripts.
+ fgSetDouble("/sim/time/delta-realtime-sec", real_delta_time_sec);
+ fgSetDouble("/sim/time/delta-sec", delta_time_sec);
+
static long remainder = 0;
long elapsed;
#ifdef FANCY_FRAME_COUNTER
#include <simgear/compiler.h>
+#include <simgear/constants.h>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sgstream.hxx>
int hitcount = hit_list->num_hits();
// cout << "hits = " << hitcount << endl;
for ( int i = 0; i < hitcount; ++i ) {
- geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
- double lat_geod, alt, sea_level_r;
- sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
- &alt, &sea_level_r);
+ // FIXME: sgCartToGeod is slow. Call it just once for the
+ // "sc" point, and then handle the rest with a geodetic "up"
+ // vector approximation. Across one tile, this will be
+ // acceptable.
+ double alt = sgCartToGeod( sc + hit_list->get_point(i) ).elev();
// cout << "hit " << i << " lon = " << geoc.lon() << " lat = "
// << lat_geod << " alt = " << alt << " max alt = " << max_alt_m
// << endl;
int hitcount = hit_list->num_hits();
// cout << "hits = " << hitcount << endl;
for ( int i = 0; i < hitcount; ++i ) {
- geoc = sgCartToPolar3d( sc + hit_list->get_point(i) );
- double lat_geod, alt, sea_level_r;
- sgGeocToGeod(geoc.lat(), geoc.radius(), &lat_geod,
- &alt, &sea_level_r);
+ // FIXME: sgCartToGeod is slow. Call it just once for the
+ // "sc" point, and then handle the rest with a geodetic "up"
+ // vector approximation. Across one tile, this will be
+ // acceptable.
+ double alt = sgCartToGeod( sc + hit_list->get_point(i) ).elev();
// cout << "hit " << i << " lon = " << geoc.lon() << " lat = "
// << lat_geod << " alt = " << alt << " max alt = " << max_alt_m
// << endl;
SG_LOG( SG_EVENT, SG_DEBUG, " Updating Sun position" );
SG_LOG( SG_EVENT, SG_DEBUG, " Gst = " << t.getGst() );
- double sun_lon, sun_gd_lat, sun_gc_lat, sl_radius;
+ double sun_lon, sun_gd_lat;
fgSunPositionGST( t.getGst(), &sun_lon, &sun_gd_lat );
-
- sgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &sun_gc_lat);
-
- p = Point3D( sun_lon, sun_gc_lat, sl_radius );
- Point3D sunpos = sgPolarToCart3d(p);
+ Point3D sunpos = sgGeodToCart(Point3D(sun_lon, sun_gd_lat, 0));
SG_LOG( SG_EVENT, SG_DEBUG, " t.cur_time = " << t.get_cur_time() );
SG_LOG( SG_EVENT, SG_DEBUG,
- " Sun Geodetic lat = " << sun_gd_lat
- << " Geocentric lat = " << sun_gc_lat );
+ " Sun Geodetic lat = " << sun_gd_lat );
// calculate the sun's relative angle to local up
sgCopyVec3( nup, world_up );