Fix the calculation of the moons longitude since the moon does not specify xs but xg instead. This required a nasty strcmp of the body name so switch to parsing a boolean instead and convert to strings when required.
This commit is contained in:
parent
afb43edbdf
commit
9a54ff575c
5 changed files with 51 additions and 39 deletions
|
@ -416,19 +416,19 @@ void TimeManager::setTimeOffset(const std::string& offset_type, long int offset)
|
|||
if ( offset_type == "real" ) {
|
||||
warp = 0;
|
||||
} else if ( offset_type == "dawn" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, true, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, true, true );
|
||||
} else if ( offset_type == "morning" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, true, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, true, true );
|
||||
} else if ( offset_type == "noon" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 0.0, true, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 0.0, true, true );
|
||||
} else if ( offset_type == "afternoon" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, false, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 75.0, false, true );
|
||||
} else if ( offset_type == "dusk" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, false, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 90.0, false, true );
|
||||
} else if ( offset_type == "evening" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 100.0, false, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 100.0, false, true );
|
||||
} else if ( offset_type == "midnight" ) {
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 180.0, false, "sun" );
|
||||
warp = fgTimeSecondsUntilBodyAngle( cur_time, loc, 180.0, false, true );
|
||||
} else if ( offset_type == "system-offset" ) {
|
||||
warp = offset;
|
||||
orig_warp = 0;
|
||||
|
|
|
@ -50,16 +50,18 @@ static const time_t step_secs = 60;
|
|||
* solar system body is directly overhead. (lat, lon are reported in
|
||||
* radians) */
|
||||
|
||||
void fgBodyPositionGST(double gst, double *lon, double *lat, const char *body) {
|
||||
void fgBodyPositionGST(double gst, double& lon, double& lat, bool sun_not_moon) {
|
||||
/* time_t ssue; seconds since unix epoch */
|
||||
/* double *lat; (return) latitude */
|
||||
/* double *lon; (return) longitude */
|
||||
/* double& lat; (return) latitude */
|
||||
/* double& lon; (return) longitude */
|
||||
|
||||
double tmp;
|
||||
|
||||
SGPropertyNode* body_node = fgGetNode("/ephemeris/" + std::string(body));
|
||||
std::string body = sun_not_moon ? "sun" : "moon";
|
||||
SGPropertyNode* body_node = fgGetNode("/ephemeris/" + body);
|
||||
assert(body_node);
|
||||
double xs = body_node->getDoubleValue("xs");
|
||||
double xs = sun_not_moon ? body_node->getDoubleValue("xs")
|
||||
: body_node->getDoubleValue("xg");
|
||||
//double ys = body_node->getDoubleValue("ys");
|
||||
double ye = body_node->getDoubleValue("ye");
|
||||
double ze = body_node->getDoubleValue("ze");
|
||||
|
@ -71,16 +73,17 @@ void fgBodyPositionGST(double gst, double *lon, double *lat, const char *body) {
|
|||
double signedPI = (tmp < 0.0) ? -SGD_PI : SGD_PI;
|
||||
tmp = fmod(tmp+signedPI, SGD_2PI) - signedPI;
|
||||
|
||||
*lon = tmp;
|
||||
*lat = dec;
|
||||
lon = tmp;
|
||||
lat = dec;
|
||||
}
|
||||
|
||||
static double body_angle( const SGTime &t, const SGVec3d& world_up, const char* body) {
|
||||
static double body_angle( const SGTime &t, const SGVec3d& world_up, bool sun_not_moon) {
|
||||
const char *body = sun_not_moon ? "sun" : "moon";
|
||||
SG_LOG( SG_EVENT, SG_DEBUG, " Updating " << body << " position" );
|
||||
SG_LOG( SG_EVENT, SG_DEBUG, " Gst = " << t.getGst() );
|
||||
|
||||
double lon, gc_lat;
|
||||
fgBodyPositionGST( t.getGst(), &lon, &gc_lat, body );
|
||||
fgBodyPositionGST( t.getGst(), lon, gc_lat, body );
|
||||
SGVec3d bodypos = SGVec3d::fromGeoc(SGGeoc::fromRadM(lon, gc_lat,
|
||||
SGGeodesy::EQURAD));
|
||||
|
||||
|
@ -121,7 +124,7 @@ time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
|||
const SGGeod& loc,
|
||||
double target_angle_deg,
|
||||
bool ascending,
|
||||
const char *body )
|
||||
bool sun_not_moon )
|
||||
{
|
||||
SGVec3d world_up = SGVec3d::fromGeod(loc);
|
||||
SGTime t = SGTime( loc, SGPath(), 0 );
|
||||
|
@ -135,7 +138,7 @@ time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
|||
secs += step_secs )
|
||||
{
|
||||
t.update( loc, secs, 0 );
|
||||
double angle_deg = body_angle( t, world_up, body );
|
||||
double angle_deg = body_angle( t, world_up, sun_not_moon );
|
||||
double diff = fabs( angle_deg - target_angle_deg );
|
||||
if ( diff < best_diff ) {
|
||||
if ( last_angle <= 180.0 && ascending
|
||||
|
|
|
@ -51,7 +51,7 @@ time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
|||
const SGGeod& loc,
|
||||
double target_angle_deg,
|
||||
bool ascending,
|
||||
const char *body );
|
||||
bool sun_not_moon );
|
||||
|
||||
/**
|
||||
* given a particular time expressed in side real time at prime
|
||||
|
@ -59,7 +59,7 @@ time_t fgTimeSecondsUntilBodyAngle( time_t cur_time,
|
|||
* solar system body is directly overhead. (lat, lon are reported in
|
||||
* radians)
|
||||
*/
|
||||
void fgBodyPositionGST(double gst, double *lon, double *lat, const char *body);
|
||||
void fgBodyPositionGST(double gst, double& lon, double& lat, bool sun_not_moon);
|
||||
|
||||
|
||||
#endif /* _BODYSOLVER_HXX */
|
||||
|
|
|
@ -354,34 +354,42 @@ void FGLight::update_adj_fog_color () {
|
|||
void FGLight::updateObjects()
|
||||
{
|
||||
// update the sun position
|
||||
updateBodyPos("sun", &_sun_lon, &_sun_lat, &_sun_vec, &_sun_vec_inv,
|
||||
&_sun_angle, _sunAngleRad, &_sun_rotation);
|
||||
bool sun_not_moon = true;
|
||||
updateBodyPos(sun_not_moon, _sun_lon, _sun_lat,
|
||||
_sun_vec, _sun_vec_inv,
|
||||
_sun_angle, _sunAngleRad,
|
||||
_sun_rotation);
|
||||
|
||||
// update the moon position
|
||||
updateBodyPos("moon", &_moon_lon, &_moon_gc_lat, &_moon_vec, &_moon_vec_inv,
|
||||
&_moon_angle, _moonAngleRad, &_moon_rotation);
|
||||
sun_not_moon = false;
|
||||
updateBodyPos(sun_not_moon, _moon_lon, _moon_gc_lat,
|
||||
_moon_vec, _moon_vec_inv,
|
||||
_moon_angle, _moonAngleRad,
|
||||
_moon_rotation);
|
||||
}
|
||||
|
||||
// update the position of one solar system body
|
||||
void FGLight::updateBodyPos(const char *body, double *lon, double *lat,
|
||||
SGVec4f *vec, SGVec4f *vec_inv, double *angle, SGPropertyNode_ptr AngleRad,
|
||||
double *rotation)
|
||||
void FGLight::updateBodyPos(bool sun_not_moon, double& lon, double& lat,
|
||||
SGVec4f& vec, SGVec4f& vec_inv,
|
||||
double& angle, SGPropertyNode_ptr AngleRad,
|
||||
double& rotation)
|
||||
{
|
||||
SGTime *t = globals->get_time_params();
|
||||
|
||||
fgBodyPositionGST(t->getGst(), lon, lat, body);
|
||||
// returns lon and lat based on GST
|
||||
fgBodyPositionGST(t->getGst(), lon, lat, sun_not_moon);
|
||||
|
||||
// It might seem that gc_lat needs to be converted to geodetic
|
||||
// latitude here, but it doesn't. The body latitude is the latitude
|
||||
// of the point on the earth where the up vector has the same
|
||||
// angle from geocentric Z as the body direction. But geodetic
|
||||
// latitude is defined as 90 - angle of up vector from Z!
|
||||
SGVec3d bodypos = SGVec3d::fromGeoc(SGGeoc::fromRadM(*lon, *lat,
|
||||
SGVec3d bodypos = SGVec3d::fromGeoc(SGGeoc::fromRadM(lon, lat,
|
||||
SGGeodesy::EQURAD));
|
||||
|
||||
// update the body vector
|
||||
*vec = SGVec4f(toVec3f(normalize(bodypos)), 0);
|
||||
*vec_inv = - *vec;
|
||||
vec = SGVec4f(toVec3f(normalize(bodypos)), 0);
|
||||
vec_inv = - vec;
|
||||
|
||||
// calculate the body's relative angle to local up
|
||||
SGQuatd hlOr = SGQuatd::fromLonLat( globals->get_view_position() );
|
||||
|
@ -393,10 +401,10 @@ void FGLight::updateBodyPos(const char *body, double *lon, double *lat,
|
|||
|
||||
SGVec3d nbody = normalize(bodypos);
|
||||
SGVec3d nup = normalize(world_up);
|
||||
*angle = acos( dot( nup, nbody ) );
|
||||
angle = acos( dot( nup, nbody ) );
|
||||
|
||||
double signedPI = (*angle < 0.0) ? -SGD_PI : SGD_PI;
|
||||
*angle = fmod(*angle+signedPI, SGD_2PI) - signedPI;
|
||||
double signedPI = (angle < 0.0) ? -SGD_PI : SGD_PI;
|
||||
angle = fmod(angle+signedPI, SGD_2PI) - signedPI;
|
||||
|
||||
// Get direction to the body in the local frame.
|
||||
SGVec3d local_vec = hlOr.transform(nbody);
|
||||
|
@ -408,12 +416,12 @@ void FGLight::updateBodyPos(const char *body, double *lon, double *lat,
|
|||
// y-positive pointing East we need to negate local_vec.x()
|
||||
// rotation is positive counterclockwise from South (body in the East)
|
||||
// and negative clockwise from South (body in the West)
|
||||
*rotation = atan2(local_vec.y(), -local_vec.x());
|
||||
rotation = atan2(local_vec.y(), -local_vec.x());
|
||||
|
||||
// cout << " Sky needs to rotate = " << rotation << " rads = "
|
||||
// << rotation * SGD_RADIANS_TO_DEGREES << " degrees." << endl;
|
||||
|
||||
AngleRad->setDoubleValue(*angle);
|
||||
AngleRad->setDoubleValue(angle);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,9 +114,10 @@ private:
|
|||
void updateObjects();
|
||||
|
||||
// update the position of one solar system body
|
||||
void updateBodyPos(const char *body, double *lon, double *lat,
|
||||
SGVec4f *vec, SGVec4f *vec_inv, double *angle, SGPropertyNode_ptr AngleRad,
|
||||
double *rotation);
|
||||
void updateBodyPos(bool sun_not_moon, double& lon, double& lat,
|
||||
SGVec4f& vec, SGVec4f& vec_inv,
|
||||
double& angle, SGPropertyNode_ptr AngleRad,
|
||||
double& rotation);
|
||||
|
||||
// properties for chrome light; not a tie because I want to fire
|
||||
// property listeners when the values change.
|
||||
|
|
Loading…
Reference in a new issue