Eatdirt: Implement parallax effects for the Moon at the rendering stage and not with the ephemeris.

This commit is contained in:
Erik Hofman 2020-12-30 11:13:42 +01:00
parent 60f5df2998
commit 62501e5ede
9 changed files with 267 additions and 57 deletions

View File

@ -68,7 +68,8 @@ SGEphemeris::~SGEphemeris( void ) {
void SGEphemeris::update( double mjd, double lst, double lat ) { void SGEphemeris::update( double mjd, double lst, double lat ) {
// update object positions // update object positions
our_sun->updatePosition( mjd ); our_sun->updatePosition( mjd );
moon->updatePosition( mjd, lst, lat, our_sun ); // moon->updatePositionTopo( mjd, lst, lat, our_sun );
moon->updatePosition( mjd, our_sun );
mercury->updatePosition( mjd, our_sun ); mercury->updatePosition( mjd, our_sun );
venus->updatePosition( mjd, our_sun ); venus->updatePosition( mjd, our_sun );
mars->updatePosition( mjd, our_sun ); mars->updatePosition( mjd, our_sun );

View File

@ -51,7 +51,7 @@
* Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson * Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson
* <http://www.flightgear.org/~curt> * <http://www.flightgear.org/~curt>
* *
* Introduction * Introduction
* *
* The SGEphemeris class computes and stores the positions of the Sun, * The SGEphemeris class computes and stores the positions of the Sun,
* the Moon, the planets, and the brightest stars. These positions * the Moon, the planets, and the brightest stars. These positions
@ -146,6 +146,11 @@ public:
return moon->getDeclination(); return moon->getDeclination();
} }
/** @return the geocentric distance to the Moon in unit of its semi-mayor axis. */
inline double getMoonDistanceInMayorAxis() const {
return moon->getDistanceInMayorAxis();
}
/** @return the numbers of defined planets. */ /** @return the numbers of defined planets. */
inline int getNumPlanets() const { return nplanets; } inline int getNumPlanets() const { return nplanets; }

View File

@ -1,9 +1,9 @@
/************************************************************************** /**************************************************************************
* moonpos.cxx * moonpos.cxx
* Written by Durk Talsma. Originally started October 1997, for distribution * Written by Durk Talsma. Originally started October 1997, for distribution
* with the FlightGear project. Version 2 was written in August and * with the FlightGear project. Version 2 was written in August and
* September 1998. This code is based upon algorithms and data kindly * September 1998. This code is based upon algorithms and data kindly
* provided by Mr. Paul Schlyter. (pausch@saaf.se). * provided by Mr. Paul Schlyter. (pausch@saaf.se).
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public * modify it under the terms of the GNU Library General Public
@ -37,10 +37,10 @@
/************************************************************************* /*************************************************************************
* MoonPos::MoonPos(double mjd) * MoonPos::MoonPos(double mjd)
* Public constructor for class MoonPos. Initializes the orbital elements and * Public constructor for class MoonPos. Initializes the orbital elements and
* sets up the moon texture. * sets up the moon texture.
* Argument: The current time. * Argument: The current time.
* the hard coded orbital elements for MoonPos are passed to * the hard coded orbital elements for MoonPos are passed to
* CelestialBody::CelestialBody(); * CelestialBody::CelestialBody();
************************************************************************/ ************************************************************************/
MoonPos::MoonPos(double mjd) : MoonPos::MoonPos(double mjd) :
@ -70,21 +70,23 @@ MoonPos::~MoonPos()
/***************************************************************************** /*****************************************************************************
* void MoonPos::updatePosition(double mjd, Star *ourSun) * void MoonPos::updatePositionTopo(double mjd, double lst, double
* this member function calculates the actual topocentric position (i.e.) * lat, Star *ourSun) this member function calculates the actual
* the position of the moon as seen from the current position on the surface * topocentric position (i.e.) the position of the moon as seen from
* of the moon. * the current position on the surface of the earth. This include
* parallax effects, the moon appears on different stars background
* for different observers on the surface of the earth.
****************************************************************************/ ****************************************************************************/
void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun) void MoonPos::updatePositionTopo(double mjd, double lst, double lat, Star *ourSun)
{ {
double double
eccAnom, ecl, actTime, eccAnom, ecl, actTime,
xv, yv, v, r, xh, yh, zh, zg, xe, xv, yv, v, r, xh, yh, zh, zg, xe,
Ls, Lm, D, F, mpar, gclat, rho, HA, g, Ls, Lm, D, F, mpar, gclat, rho, HA, g,
geoRa, geoDec, geoRa, geoDec,
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl, cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha; FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
double max_loglux = -0.504030345621; double max_loglux = -0.504030345621;
double min_loglux = -4.39964634562; double min_loglux = -4.39964634562;
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor. double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
@ -99,7 +101,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom)); yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
v = atan2(yv, xv); // the moon's true anomaly v = atan2(yv, xv); // the moon's true anomaly
r = sqrt (xv*xv + yv*yv); // and its distance r = sqrt (xv*xv + yv*yv); // and its distance
// repetitive calculations, minimised for speed // repetitive calculations, minimised for speed
cosN = cos(N); cosN = cos(N);
sinN = sin(N); sinN = sin(N);
@ -118,7 +120,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
lonEcl = atan2 (yh, xh); lonEcl = atan2 (yh, xh);
latEcl = atan2(zh, sqrt(xh*xh + yh*yh)); latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
/* Calculate a number of perturbation, i.e. disturbances caused by the /* Calculate a number of perturbation, i.e. disturbances caused by the
* gravitational influence of the sun and the other major planets. * gravitational influence of the sun and the other major planets.
* The largest of these even have a name */ * The largest of these even have a name */
Ls = ourSun->getM() + ourSun->getw(); Ls = ourSun->getM() + ourSun->getw();
@ -130,7 +132,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
twoM = 2 * M; twoM = 2 * M;
FlesstwoD = F - twoD; FlesstwoD = F - twoD;
MlesstwoD = M - twoD; MlesstwoD = M - twoD;
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD) lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
+0.658 * sin(twoD) +0.658 * sin(twoD)
-0.186 * sin(ourSun->getM()) -0.186 * sin(ourSun->getM())
@ -154,12 +156,13 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
-0.46 * cos(twoD) -0.46 * cos(twoD)
); );
distance = r; distance = r;
distance_in_a = r/a;
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update"); // SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
rcoslatEcl = r * cos(latEcl); rcoslatEcl = r * cos(latEcl);
xg = cos(lonEcl) * rcoslatEcl; xg = cos(lonEcl) * rcoslatEcl;
yg = sin(lonEcl) * rcoslatEcl; yg = sin(lonEcl) * rcoslatEcl;
zg = r * sin(latEcl); zg = r * sin(latEcl);
xe = xg; xe = xg;
ye = yg * cosecl -zg * sinecl; ye = yg * cosecl -zg * sinecl;
ze = yg * sinecl +zg * cosecl; ze = yg * sinecl +zg * cosecl;
@ -167,17 +170,17 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
geoRa = atan2(ye, xe); geoRa = atan2(ye, xe);
geoDec = atan2(ze, sqrt(xe*xe + ye*ye)); geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
/* SG_LOG( SG_GENERAL, SG_INFO, /* SG_LOG( SG_GENERAL, SG_INFO,
"(geocentric) geoRa = (" << (SGD_RADIANS_TO_DEGREES * geoRa) "(geocentric) geoRa = (" << (SGD_RADIANS_TO_DEGREES * geoRa)
<< "), geoDec= (" << (SGD_RADIANS_TO_DEGREES * geoDec) << ")" ); */ << "), geoDec= (" << (SGD_RADIANS_TO_DEGREES * geoDec) << ")" ); */
// Given the moon's geocentric ra and dec, calculate its // Given the moon's geocentric ra and dec, calculate its
// topocentric ra and dec. i.e. the position as seen from the // topocentric ra and dec. i.e. the position as seen from the
// surface of the earth, instead of the center of the earth // surface of the earth, instead of the center of the earth
// First calculate the moon's parallax, that is, the apparent size of the // First calculate the moon's parallax, that is, the apparent size of the
// (equatorial) radius of the earth, as seen from the moon // (equatorial) radius of the earth, as seen from the moon
mpar = asin ( 1 / r); mpar = asin ( 1 / r);
// SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar ); // SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar );
// SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() ); // SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() );
@ -188,12 +191,12 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
rho = 0.99883 + 0.00167 * cos(twolat); rho = 0.99883 + 0.00167 * cos(twolat);
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho ); // SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
if (geoRa < 0) if (geoRa < 0)
geoRa += SGD_2PI; geoRa += SGD_2PI;
HA = lst - (3.8197186 * geoRa); HA = lst - (3.8197186 * geoRa);
/* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst() /* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst()
<< " HA = " << HA ); */ << " HA = " << HA ); */
g = atan (tan(gclat) / cos ((HA / 3.8197186))); g = atan (tan(gclat) / cos ((HA / 3.8197186)));
@ -212,8 +215,140 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
// << SGD_RADIANS_TO_DEGREES * (geoDec - declination) << endl; // << SGD_RADIANS_TO_DEGREES * (geoDec - declination) << endl;
} }
/* SG_LOG( SG_GENERAL, SG_INFO, /* SG_LOG( SG_GENERAL, SG_INFO,
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension) "Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
// Moon age and phase calculation
age = lonEcl - ourSun->getlonEcl();
phase = (1 - cos(age)) / 2;
// The log of the illuminance of the moon outside the atmosphere.
// This is the base 10 log of equation 20 from Krisciunas K. and Schaefer B.E.
// (1991). A model of the brightness of moonlight, Publ. Astron. Soc. Pacif.
// 103(667), 1033-1039 (DOI: http://dx.doi.org/10.1086/132921).
alpha = SGD_RADIANS_TO_DEGREES * SGMiscd::normalizeAngle(age + SGMiscd::pi());
log_I = -0.4 * (3.84 + 0.026*fabs(alpha) + 4e-9*pow(alpha, 4.0));
// Convert from foot-candles to lux.
log_I += conv;
// The moon's illuminance factor, bracketed between 0 and 1.
I_factor = (log_I - max_loglux) / (max_loglux - min_loglux) + 1.0;
I_factor = SGMiscd::clip(I_factor, 0, 1);
}
/*****************************************************************************
* void MoonPos::updatePosition(double mjd, Star *ourSun) this member
* function calculates the geocentric position (i.e.) the position of
* the moon as seen from the center of earth. As such, it does not
* include any parallax effects. These are taken into account during
* the rendering.
****************************************************************************/
void MoonPos::updatePosition(double mjd, Star *ourSun)
{
double
eccAnom, ecl, actTime,
xv, yv, v, r, xh, yh, zh, zg, xe,
Ls, Lm, D, F, geoRa, geoDec,
cosN, sinN, cosvw, sinvw, sinvw_cosi, cosecl, sinecl, rcoslatEcl,
FlesstwoD, MlesstwoD, twoD, twoM, twolat, alpha;
double max_loglux = -0.504030345621;
double min_loglux = -4.39964634562;
double conv = 1.0319696543787917; // The log foot-candle to log lux conversion factor.
updateOrbElements(mjd);
actTime = sgCalcActTime(mjd);
// calculate the angle between ecliptic and equatorial coordinate system
// in Radians
ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 * actTime);
eccAnom = sgCalcEccAnom(M, e); // Calculate the eccentric anomaly
xv = a * (cos(eccAnom) - e);
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
v = atan2(yv, xv); // the moon's true anomaly
r = sqrt (xv*xv + yv*yv); // and its distance
// repetitive calculations, minimised for speed
cosN = cos(N);
sinN = sin(N);
cosvw = cos(v+w);
sinvw = sin(v+w);
sinvw_cosi = sinvw * cos(i);
cosecl = cos(ecl);
sinecl = sin(ecl);
// estimate the geocentric rectangular coordinates here
xh = r * (cosN * cosvw - sinN * sinvw_cosi);
yh = r * (sinN * cosvw + cosN * sinvw_cosi);
zh = r * (sinvw * sin(i));
// calculate the ecliptic latitude and longitude here
lonEcl = atan2 (yh, xh);
latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
/* Calculate a number of perturbation, i.e. disturbances caused by the
* gravitational influence of the sun and the other major planets.
* The largest of these even have a name */
Ls = ourSun->getM() + ourSun->getw();
Lm = M + w + N;
D = Lm - Ls;
F = Lm - N;
twoD = 2 * D;
twoM = 2 * M;
FlesstwoD = F - twoD;
MlesstwoD = M - twoD;
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin(MlesstwoD)
+0.658 * sin(twoD)
-0.186 * sin(ourSun->getM())
-0.059 * sin(twoM - twoD)
-0.057 * sin(MlesstwoD + ourSun->getM())
+0.053 * sin(M + twoD)
+0.046 * sin(twoD - ourSun->getM())
+0.041 * sin(M - ourSun->getM())
-0.035 * sin(D)
-0.031 * sin(M + ourSun->getM())
-0.015 * sin(2*F - twoD)
+0.011 * sin(M - 4*D)
);
latEcl += SGD_DEGREES_TO_RADIANS * (-0.173 * sin(FlesstwoD)
-0.055 * sin(M - FlesstwoD)
-0.046 * sin(M + FlesstwoD)
+0.033 * sin(F + twoD)
+0.017 * sin(twoM + F)
);
r += (-0.58 * cos(MlesstwoD)
-0.46 * cos(twoD)
);
// from the orbital elements, the unit of the distance is in Earth radius, around 60.
distance = r;
distance_in_a = r/a;
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
rcoslatEcl = r * cos(latEcl);
xg = cos(lonEcl) * rcoslatEcl;
yg = sin(lonEcl) * rcoslatEcl;
zg = r * sin(latEcl);
xe = xg;
ye = yg * cosecl -zg * sinecl;
ze = yg * sinecl +zg * cosecl;
geoRa = atan2(ye, xe);
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
if (geoRa < 0)
geoRa += SGD_2PI;
rightAscension = geoRa;
declination = geoDec;
/* SG_LOG( SG_GENERAL, SG_INFO,
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */ << "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
// Moon age and phase calculation // Moon age and phase calculation

View File

@ -39,6 +39,7 @@ private:
double xg, yg; // the moon's rectangular geocentric coordinates double xg, yg; // the moon's rectangular geocentric coordinates
double ye, ze; // the moon's rectangular equatorial coordinates double ye, ze; // the moon's rectangular equatorial coordinates
double distance; // the moon's distance to the earth double distance; // the moon's distance to the earth
double distance_in_a; // the moon's distance to the earth in unit of its semi-mayor axis a
double age; // the moon's age from 0 to 2pi double age; // the moon's age from 0 to 2pi
double phase; // the moon's phase double phase; // the moon's phase
double log_I; // the moon's illuminance outside the atmosphere (logged) double log_I; // the moon's illuminance outside the atmosphere (logged)
@ -59,8 +60,9 @@ public:
MoonPos(double mjd); MoonPos(double mjd);
MoonPos(); MoonPos();
~MoonPos(); ~MoonPos();
void updatePosition(double mjd, double lst, double lat, Star *ourSun); void updatePositionTopo(double mjd, double lst, double lat, Star *ourSun);
// void newImage(); void updatePosition(double mjd, Star *ourSun);
// void newImage();
double getM() const; double getM() const;
double getw() const; double getw() const;
double getxg() const; double getxg() const;
@ -68,6 +70,7 @@ public:
double getye() const; double getye() const;
double getze() const; double getze() const;
double getDistance() const; double getDistance() const;
double getDistanceInMayorAxis() const;
double getAge() const; double getAge() const;
double getPhase() const; double getPhase() const;
double getLogIlluminance() const; double getLogIlluminance() const;
@ -109,6 +112,11 @@ inline double MoonPos::getDistance() const
return distance; return distance;
} }
inline double MoonPos::getDistanceInMayorAxis() const
{
return distance_in_a;
}
inline double MoonPos::getAge() const inline double MoonPos::getAge() const
{ {
return age; return age;

View File

@ -82,7 +82,7 @@ inline T magnitude2(const simd4_t<T,N>& vi) {
template<typename T, int N> template<typename T, int N>
inline simd4_t<T,N> interpolate(T tau, const simd4_t<T,N>& v1, const simd4_t<T,N>& v2) { inline simd4_t<T,N> interpolate(T tau, const simd4_t<T,N>& v1, const simd4_t<T,N>& v2) {
return (T(1)-tau)*v1 + tau*v2; return v1 + tau*(v2-v1);
} }
template<typename T, int N> template<typename T, int N>

View File

@ -1,9 +1,9 @@
// moon.hxx -- model earth's moon // moon.hxx -- model earth's moon
// //
// Written by Durk Talsma. Originally started October 1997, for distribution // Written by Durk Talsma. Originally started October 1997, for distribution
// with the FlightGear project. Version 2 was written in August and // with the FlightGear project. Version 2 was written in August and
// September 1998. This code is based upon algorithms and data kindly // September 1998. This code is based upon algorithms and data kindly
// provided by Mr. Paul Schlyter. (pausch@saaf.se). // provided by Mr. Paul Schlyter. (pausch@saaf.se).
// //
// Separated out rendering pieces and converted to ssg by Curt Olson, // Separated out rendering pieces and converted to ssg by Curt Olson,
// March 2000 // March 2000
@ -69,7 +69,7 @@ SGMoon::~SGMoon( void ) {
osg::Node* osg::Node*
SGMoon::build( SGPath path, double moon_size ) { SGMoon::build( SGPath path, double moon_size ) {
osg::Node* orb = SGMakeSphere(moon_size, 15, 15); osg::Node* orb = SGMakeSphere(moon_size, 40, 20);
osg::StateSet* stateSet = orb->getOrCreateStateSet(); osg::StateSet* stateSet = orb->getOrCreateStateSet();
stateSet->setRenderBinDetails(-5, "RenderBin"); stateSet->setRenderBinDetails(-5, "RenderBin");
@ -141,18 +141,18 @@ bool SGMoon::repaint( double moon_angle ) {
prev_moon_angle = moon_angle; prev_moon_angle = moon_angle;
float moon_factor = 4*cos(moon_angle); float moon_factor = 4*cos(moon_angle);
if (moon_factor > 1) moon_factor = 1.0; if (moon_factor > 1) moon_factor = 1.0;
if (moon_factor < -1) moon_factor = -1.0; if (moon_factor < -1) moon_factor = -1.0;
moon_factor = moon_factor/2 + 0.5; moon_factor = moon_factor/2 + 0.5;
osg::Vec4 color; osg::Vec4 color;
color[1] = sqrt(moon_factor); color[1] = sqrt(moon_factor);
color[0] = sqrt(color[1]); color[0] = sqrt(color[1]);
color[2] = moon_factor * moon_factor; color[2] = moon_factor * moon_factor;
color[2] *= color[2]; color[2] *= color[2];
color[3] = 1.0; color[3] = 1.0;
gamma_correct_rgb( color._v ); gamma_correct_rgb( color._v );
orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color); orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
@ -162,22 +162,74 @@ bool SGMoon::repaint( double moon_angle ) {
// reposition the moon at the specified right ascension and // reposition the moon at the specified right ascension and
// declination, offset by our current position (p) so that it appears // declination from the center of Earth. Because the view is actually
// fixed at a great distance from the viewer. Also add in an optional // offset by our current position (p), we first evaluate our current
// rotation (i.e. for the current time of day.) // position w.r.t the Moon and then shift to the articial center of
bool SGMoon::reposition( double rightAscension, double declination, // earth before shifting to the rendered moon distance. This allows to
double moon_dist ) // implement any parallax effects. moon_dist_bare is expected to not
{ // change during the rendering, it gives us the normalisation factors
osg::Matrix T2, RA, DEC; // between real distances and units used in the
// rendering. moon_dist_fact is any extra factors to put the moon
// further or closer.
bool SGMoon::reposition( double rightAscension, double declination,
double moon_dist_bare, double moon_dist_factor,
double lst, double lat, double alt )
{
osg::Matrix TE, T2, RA, DEC;
// semi mayor axis
const double moon_a_in_rearth = 60.266600;
// average (we could also account for equatorial streching like in
// oursun.cxx if required)
const double earth_radius_in_meters = 6371000.0;
//local hour angle in radians
double lha;
// in unit of the rendering
double moon_dist;
double earth_radius, viewer_radius;
double xp,yp,zp;
//rendered earth radius according to what has been specified by
//moon_dist_bare
earth_radius = moon_dist_bare/moon_a_in_rearth;
//how far are we from the center of Earth
viewer_radius = (1.0 + alt/earth_radius_in_meters)*earth_radius;
// the local hour angle of the moon, .i.e. its angle with respect
// to the meridian of the viewer
lha = lst - rightAscension;
// the shift vector of the observer w.r.t. earth center (funny
// convention on x?)
zp = viewer_radius * sin(lat);
yp = viewer_radius * cos(lat)*cos(lha);
xp = viewer_radius * cos(lat)*sin(-lha);
//rotate along the z axis
RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS, RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS,
osg::Vec3(0, 0, 1)); osg::Vec3(0, 0, 1));
//rotate along the rotated x axis
DEC.makeRotate(declination, osg::Vec3(1, 0, 0)); DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
//move to the center of Earth
TE.makeTranslate(osg::Vec3(-xp,-yp,-zp));
//move the moon from the center of Earth to moon_dist
moon_dist = moon_dist_bare * moon_dist_factor;
T2.makeTranslate(osg::Vec3(0, moon_dist, 0)); T2.makeTranslate(osg::Vec3(0, moon_dist, 0));
moon_transform->setMatrix(T2*DEC*RA); // cout << " viewer radius= " << viewer_radius << endl;
// cout << " xp yp zp= " << xp <<" " << yp << " " << zp << endl;
// cout << " lha= " << lha << endl;
// cout << " moon_dist_bare= " << moon_dist_bare << endl;
// cout << " moon_dist_factor= " << moon_dist_factor << endl;
// cout << " moon_dist= " << moon_dist << endl;
moon_transform->setMatrix(T2*TE*DEC*RA);
return true; return true;
} }

View File

@ -65,11 +65,12 @@ public:
bool repaint( double moon_angle ); bool repaint( double moon_angle );
// reposition the moon at the specified right ascension and // reposition the moon at the specified right ascension and
// declination, offset by our current position (p) so that it // declination, at moon_dist_bare*moon_dist_factor from the center
// appears fixed at a great distance from the viewer. Also add in // of Earth. lst, lat and alt are need to estimate where is the
// an optional rotation (i.e. for the current time of day.) // center of Earth from the current view).
bool reposition( double rightAscension, double declination, bool reposition( double rightAscension, double declination,
double moon_dist ); double moon_dist_bare, double moon_dist_factor,
double lst, double lat, double alt );
}; };

View File

@ -152,7 +152,7 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
double angleRad = SGMiscd::deg2rad(angle); double angleRad = SGMiscd::deg2rad(angle);
SGVec3f zero_elev, view_up; SGVec3f zero_elev, view_up;
double lon, lat, alt; double lon, lat, alt, lst;
SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0); SGGeod geodZeroViewPos = SGGeod::fromGeodM(st.pos_geod, 0);
zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) ); zero_elev = toVec3f( SGVec3d::fromGeod(geodZeroViewPos) );
@ -165,7 +165,9 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
lon = st.pos_geod.getLongitudeRad(); lon = st.pos_geod.getLongitudeRad();
lat = st.pos_geod.getLatitudeRad(); lat = st.pos_geod.getLatitudeRad();
alt = st.pos_geod.getElevationM(); alt = st.pos_geod.getElevationM();
// Local sidereal time
lst = angleRad + lon;
dome->reposition( zero_elev, alt, lon, lat, st.spin ); dome->reposition( zero_elev, alt, lon, lat, st.spin );
osg::Matrix m = osg::Matrix::rotate(angleRad, osg::Vec3(0, 0, -1)); osg::Matrix m = osg::Matrix::rotate(angleRad, osg::Vec3(0, 0, -1));
@ -178,7 +180,12 @@ bool SGSky::reposition( const SGSkyState &st, const SGEphemeris& eph, double dt
double moon_ra = eph.getMoonRightAscension(); double moon_ra = eph.getMoonRightAscension();
double moon_dec = eph.getMoonDeclination(); double moon_dec = eph.getMoonDeclination();
moon->reposition( moon_ra, moon_dec, st.moon_dist ); double moon_r = eph.getMoonDistanceInMayorAxis();
//this allows to render the moon closer to the viewer when the
//moon is closer to the center of Earth, times any articial extra factors
double moon_dist_factor = moon_r * st.moon_dist_factor;
moon->reposition( moon_ra, moon_dec, st.moon_dist_bare, moon_dist_factor, lst, lat, alt );
for ( unsigned i = 0; i < cloud_layers.size(); ++i ) { for ( unsigned i = 0; i < cloud_layers.size(); ++i ) {
if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR || if ( cloud_layers[i]->getCoverage() != SGCloudLayer::SG_CLOUD_CLEAR ||

View File

@ -63,7 +63,8 @@ struct SGSkyState
double gst; //!< GMT side real time. double gst; //!< GMT side real time.
double sun_dist; //!< the sun's distance from the current view point double sun_dist; //!< the sun's distance from the current view point
// (to keep it inside your view volume). // (to keep it inside your view volume).
double moon_dist;//!< The moon's distance from the current view point. double moon_dist_bare ;//!< The moon's semi-mayor axis in the rendering (constant)
double moon_dist_factor ;//!< Any factor that are needed to artificially change the moon distance
double sun_angle; double sun_angle;
}; };