Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Sky.cpp

Go to the documentation of this file.
00001 /*
00002  * Sky.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00028 #include "../Include/Globals.h"
00029 #include "../Include/Sky.h"
00030 #include "../Include/Utility.h"
00031 #include "../Include/Ui.h"
00032 #include "../Include/TimeManager.h"
00033 #include "../Include/Situation.h"
00034 
00035 
00036 //
00037 // Calculate zenith angle and azimuth for a celestial body
00038 //
00039 // Inputs:
00040 //    ra    Right Ascension in radians
00041 //    dec   Declination in radians
00042 //    lat   Latitude, in degrees north/south of Equator
00043 //    lon   Longitude, in degrees east of Prime Meridian
00044 //
00045 // Outputs:
00046 //    za    Zenith angle, in radians
00047 //    azm   Azimuth angle, in radians west of south
00048 //
00049 static void calc_zenith_azimuth_angles (double ra, double dec,
00050                     double lat, double lon,
00051                     double *theta, double *phi)
00052 {
00053   // Get local sidereal time in decimal hours, convert to radians
00054   double lst = globals->timemgr->GetLocalSiderealTime (lon * 3600);
00055   lst = SGD_TWO * SGD_PI * lst / 24.0;
00056 
00057   // Calculate local hour angle in radians
00058   double lha = lst - ra;
00059 
00060   // Convert latitude to radians
00061   double latrad = DegToRad (lat);
00062 
00063   // Calculate zenith angle theta
00064   double thetaFactor1 = sin(latrad)*sin(dec);
00065   double thetaFactor2 = cos(latrad)*cos(dec)*cos(lha);
00066   double thetaArg = thetaFactor1 + thetaFactor2;
00067   *theta = WrapTwoPi ((SGD_PI / 2.0) - asin (thetaArg));
00068 
00069   double phiArgY = -cos(dec)*sin(lha);
00070   double phiArgX = cos(latrad)*sin(dec) - sin(latrad)*cos(dec)*cos(lha);
00071   *phi = WrapTwoPi (atan2 (phiArgY, phiArgX));
00072 }
00073 
00074 
00075 
00076 
00077 CSkyManager::CSkyManager (void)
00078 {
00079   // Initialize darkness phase
00080   old_phase = PHASE_INVALID;
00081 
00082   // Instantiate SSG tree entities
00083   pre_root = new ssgRoot;
00084   pre_root->setName ("Sky Predraw Root");
00085 
00086   pre_transform = new ssgTransform;
00087   pre_transform->setName ("Top Transform");
00088 
00089   // Instantiate and initialize sky lighting model
00090   skylight = new CSkyLight ();
00091   skylight->Init ();
00092 
00093   // Initialize effective visibility to 60 miles
00094   effective_visibility = 60.0 * 5280.0;
00095 
00096   // Instantiate ephemeris classes for sun, moon and planets
00097   moon = new CMoon ();
00098   sol = new CSol ();
00099   mercury = new CMercury ();
00100   venus = new CVenus ();
00101   mars = new CMars ();
00102   jupiter = new CJupiter ();
00103   saturn = new CSaturn ();
00104 
00105 //  skyDistance = 1.0E+6;
00106   skyDistance = effective_visibility;
00107 
00108   // Instantiate sky dome
00110   domeimage = new CSkyDomeImage (skyDistance);
00111   domeimage->Repaint (0.0, 0.0);
00112   pre_transform->addKid (domeimage->GetSSGEntity ());
00113 
00114   // Instantiate star images
00115   starimage = new CStarImages (skyDistance);
00116   pre_transform->addKid (starimage->GetSSGEntity ());
00117 
00118   // Instantiate Mercury image
00119   mercuryimage = new CMercuryImage ();
00120   pre_transform->addKid (mercuryimage->GetSSGEntity ());
00121 
00122   // Instantiate Venus image
00123   venusimage = new CVenusImage ();
00124   pre_transform->addKid (venusimage->GetSSGEntity ());
00125 
00126   // Instantiate Mars image
00127   marsimage = new CMarsImage ();
00128   pre_transform->addKid (marsimage->GetSSGEntity ());
00129 
00130   // Instantiate Jupiter image
00131   jupiterimage = new CJupiterImage ();
00132   pre_transform->addKid (jupiterimage->GetSSGEntity ());
00133 
00134   // Instantiate Saturn image
00135   saturnimage = new CSaturnImage ();
00136   pre_transform->addKid (saturnimage->GetSSGEntity ());
00137 
00138   // Instantiate moon image.  Image "size" and "distance" are tweaked to adjust
00139   //   the size of the moon orb in the sky
00140   moonimage = new CMoonImage (skyDistance);
00141   moonimage->Repaint (PI/2, 0.0);
00142 //  pre_transform->addKid (moonimage->GetSSGEntity ());
00143 
00149 /*
00150  * Sol image removed from sky scene 2005-Mar-6.
00151 
00152   // Instantiate Sol image.  Image "size" and "distance" are tweaked to adjust
00153   //   the size of the sun in the sky
00154   char *tag3 = new char[32];
00155   strcpy (tag3, "solimage start");
00156   solimage = new CSolImage (skyDistance);
00157   solimage->Repaint (PI/2);
00158   pre_transform->addKid (solimage->GetSSGEntity ());
00159   char *tag4 = new char[32];
00160   strcpy (tag4, "solimage End");
00161 
00162   *
00163   */
00164 
00165   // Link everything up to the root node
00166   pre_root->addKid (pre_transform);
00167 }
00168 
00169 CSkyManager::~CSkyManager (void)
00170 {
00175   pre_root->removeAllKids();
00176   delete pre_root;
00177 
00178   delete skylight;
00179   delete domeimage;
00180   delete starimage;
00181   delete mercuryimage;
00182   delete venusimage;
00183   delete marsimage;
00184   delete jupiterimage;
00185   delete saturnimage;
00186   delete moonimage;
00187 //  delete solimage;
00188 
00189   delete moon;
00190   delete sol;
00191   delete mercury;
00192   delete venus;
00193   delete mars;
00194   delete jupiter;
00195   delete saturn;
00196 }
00197 
00198 
00199 //
00200 // This function returns the limiting visual magnitude based on the sun's elevation.
00201 //
00202 static EDarkPhase limitingMagnitude (double solTheta, float *limit, float *factor)
00203 {
00206   
00207   EDarkPhase phase = PHASE_DEEP_NIGHT;
00208 
00209   // Calculate phase of darkness based on sun elevation
00210   double solElevation = 90 - RadToDeg (solTheta);
00211 /*
00212   if (solElevation < -18.0) {
00213     // Deep night
00214     phase = PHASE_DEEP_NIGHT;
00215         *factor = 1.0;
00216         *limit = 6.5;
00217   } else if (solElevation < -12.0) {
00218     // Night
00219     phase = PHASE_NIGHT;
00220         *factor = 1.0;
00221         *limit = 5.5;
00222   } else if (solElevation <  -6.0) {
00223     // Late Dusk
00224     phase = PHASE_LATE_DUSK;
00225         *factor = 0.95;
00226         *limit = 3.5;
00227   } else if (solElevation < -3.0) {
00228     // Dusk
00229     phase = PHASE_DUSK;
00230         *factor = 0.9;
00231         *limit = 2.0;
00232   } else if (solElevation < -1.5) {
00233     // Early Dusk
00234     phase = PHASE_EARLY_DUSK;
00235         *factor = 0.85;
00236         *limit = 1.0;
00237   } else if (solElevation < 0.0) {
00238     // Late Twilight
00239     phase = PHASE_LATE_TWILIGHT;
00240         *factor = 0.8;
00241         *limit = 0.5;
00242   } else if (solElevation < 0.5) {
00243     // Early Twilight
00244     phase = PHASE_EARLY_TWILIGHT;
00245         *factor = 0.75;
00246     *limit = 0.2;
00247   } else {
00248     // Daylight
00249     phase = PHASE_DAYLIGHT;
00250         *factor = 0.7;
00251     *limit = 0.0;
00252   }
00253 */
00254 
00255   // Experimental star limit/factor
00256   if (solElevation > 0) {
00257     // Sun is above horizon
00258     float f = (90.0 - solElevation) / 90.0;
00259     *limit = -10 + (10.5 * f);
00260     *factor = 0.7 * f;
00261   } else if (solElevation > -18.0) {
00262     // Twilight
00263     *limit = 0.5 + (-solElevation / 3.0);
00264     *factor = 0.7 + (0.3 * (-solElevation / 18.0));
00265   } else {
00266     // Astronomical night
00267     *limit = 6.5;
00268     *factor = 1.0;
00269   }
00270 
00271 
00272   // DEBUG
00273 //  char debug[80];
00274 //  sprintf (debug, "elevation=%7.3f  factor=%5.3f  limit=%5.3f", 
00275 //    solElevation, *factor, *limit);
00276 //  DrawNoticeToUser (debug, 1);
00277   
00278   return phase;
00279 }
00280 
00281 
00282 void CSkyManager::Update (float dT)
00283 {
00284   SPosition eyePos = globals->sit->GetUserVehicle()->GetPosition ();
00285   double mjd = globals->timemgr->GetModifiedJulianDate ();
00286   double lst = globals->timemgr->GetLocalSiderealTime(eyePos.lon);
00287 
00288   // Convert camera eye position to cartesian coordinates
00289   SVector v;
00290   v = GeodToCartesian (eyePos);
00291   sgVec3 p;
00292   sgSetVec3 (p, v.x, v.y, v.z);
00293 
00294   // Make translation matrix for eye altitude
00295   sgVec3 t;
00296   sgSetVec3 (t, 0, 0, -eyePos.alt);
00297   sgMat4 TRANSLATE;
00298   sgMakeTransMat4 (TRANSLATE, t);
00299   pre_transform->setTransform (TRANSLATE);
00300 
00301   // Convert latitude and longitude to degrees for sky object repositioning
00302   double lat = eyePos.lat / 3600;
00303   double lon = eyePos.lon / 3600;
00304 
00305   // Update sky lighting model
00306   skylight->Update ();
00307 
00310 
00311   // Update ephemeris calculations for sun.  This needs to be done first since
00312   //   the sun elevation is needed to update the other celestial objects
00313   sol->UpdatePosition (mjd);
00314 
00315   // Update ephemeris calculations for other celestial objects
00316   moon->UpdatePosition (mjd, lst, lat, sol);
00317 
00319   mercury->UpdatePosition (mjd, sol);
00320   venus->UpdatePosition (mjd, sol);
00321   mars->UpdatePosition (mjd, sol);
00322   jupiter->UpdatePosition (mjd, sol);
00323   saturn->UpdatePosition (mjd, sol);
00324 
00325   // Get solar zenith and azimuth angles
00326   double solTheta, solPhi;
00327   calc_zenith_azimuth_angles (sol->GetRightAscension(), sol->GetDeclination(),
00328                               lat, lon,
00329                               &solTheta, &solPhi);
00330 
00331   double moonTheta, moonPhi;
00332   calc_zenith_azimuth_angles (moon->GetRightAscension(), moon->GetDeclination(),
00333                               lat, lon,
00334                               &moonTheta, &moonPhi);
00335 
00336   // DEBUG
00337 //  char debug[80];
00338 //  sprintf (debug, "solTheta=%7.3f deg, solPhi=%7.3f deg",
00339 //    RadToDeg (solTheta), RadToDeg (solPhi));
00340 //  DrawNoticeToUser (debug, 1);
00341 
00342   // Update appearance and position of sky dome
00343   domeimage->Repaint (solTheta, solPhi);
00344   domeimage->Reposition (solPhi);
00345 
00346   // Update appearance and position of Sol
00347 //  solimage->Repaint (solTheta);
00348 //  solimage->Reposition (p, lst, lat,
00349 //                      sol->GetRightAscension(), sol->GetDeclination(),
00350 //                      skyDistance);
00351 
00352   // Update appearance and position of the Moon
00354   moonimage->Repaint (moonTheta, moon->GetAge ());
00355   moonimage->Reposition (p, moonTheta, lst, lat,
00356                        moon->GetRightAscension(), moon->GetDeclination(), 0,
00357                        skyDistance);
00358 
00359   // Determine limiting magnitude and ambient light factor for night sky objects
00360   float limit, factor;
00361   float limitLastUpdate = 10.0;
00362 //  EDarkPhase phase = limitingMagnitude (solTheta, &limit, &factor);
00363   limitingMagnitude (solTheta, &limit, &factor);
00364 
00365   // If the limiting magnitude has changed by more than the preset value, repaint
00366   //   the stars and planets
00367 //  if (phase != old_phase) {
00368   if (fabs (limitLastUpdate - limit) > 0.1) {
00369     limitLastUpdate = limit;
00370     // Update appearance for all planets
00371     mercuryimage->Repaint (mercury->GetMagnitude (), limit, factor);
00372     venusimage->Repaint (venus->GetMagnitude(), limit, factor);
00373     marsimage->Repaint (mars->GetMagnitude(), limit, factor);
00374     jupiterimage->Repaint (jupiter->GetMagnitude(), limit, factor);
00375     saturnimage->Repaint (saturn->GetMagnitude(), limit, factor);
00376 
00377     // Update appearance for all stars
00378     starimage->Repaint (limit, factor);
00379   }
00380 
00381   // Update positions of all planets
00382   mercuryimage->Reposition (p, lst, lat,
00383                             mercury->GetRightAscension(), mercury->GetDeclination(),
00384                             skyDistance);
00385   venusimage->Reposition (p, lst, lat,
00386                           venus->GetRightAscension(), venus->GetDeclination(),
00387                           skyDistance);
00388   marsimage->Reposition (p, lst, lat,
00389                          mars->GetRightAscension(), mars->GetDeclination(),
00390                          skyDistance);
00391   jupiterimage->Reposition (p, lst, lat,
00392                             jupiter->GetRightAscension(), jupiter->GetDeclination(),
00393                             skyDistance);
00394   saturnimage->Reposition (p, lst, lat,
00395                            saturn->GetRightAscension(), saturn->GetDeclination(),
00396                            skyDistance);
00397 
00398   // Update positions of stars
00399   starimage->Reposition (p, lon, lat, lst);
00400 }
00401 
00402 void CSkyManager::SetCamera (SPosition pos, SVector orient)
00403 {
00404   sgVec3 eye, lookat, up;
00405   sgSetVec3 (eye, 0, 0, 0);
00406 
00407   float x_lookat = sin(-orient.h) * cos(orient.p);
00408   float y_lookat = cos (-orient.h) * cos(orient.p);
00409   float z_lookat = -sin(orient.p);
00410   sgSetVec3 (lookat, x_lookat, y_lookat, z_lookat);
00411 
00413   float x_up = 0;
00414   float y_up = 0;
00415   float z_up = 1;
00416   sgSetVec3 (up, x_up, y_up, z_up);
00417 
00418   // DEBUG
00419 //  char debug[80];
00420 //  sprintf (debug, "x=%7.3f y=%7.3f z=%7.3f  up x=%7.3f y=%7.3f z=%7.3f",
00421 //    x_lookat, y_lookat, z_lookat, x_up, y_up, z_up);
00422 //  DrawNoticeToUser (debug, 1);
00423 
00424   ssgSetCameraLookAt (eye, lookat, up);
00425 
00426   // Set field of view and near/far clipping planes
00427   ssgSetNearFar (1.0E+5, 1.0E+9);
00428 }
00429 
00430 void CSkyManager::PreDraw (void)
00431 {
00432   // Special skay drawing GL commands
00433   glPushAttrib (GL_ENABLE_BIT);
00434   glDisable (GL_DEPTH_TEST);
00435 
00436   // Draw sky root
00437   ssgCullAndDraw (pre_root);
00438 
00439   glPopAttrib ();
00440 }
00441 
00442 
00443 //
00444 // Dump the contents of the CSkyManager class to a file for debugging
00445 //
00446 void CSkyManager::Print (FILE *f)
00447 {
00448   //
00449   // Sky dome shading parameter sets
00450   //
00451   domeimage->Print (f);
00452 
00453   //
00454   // Ephemeris data for the sun moon and planes
00455   //
00456   fprintf (f, "Ephemeris Data:\n");
00457 
00458   double mjd = globals->timemgr->GetModifiedJulianDate ();
00459   fprintf (f, "MJD      : %f\n", mjd);
00460 
00461   SDateTime dt = globals->timemgr->GetUTCDateTime ();
00462   fprintf (f, "UTC Date : %04d/%02d/%02d \n", dt.date.year + 1900, dt.date.month, dt.date.day);
00463   fprintf (f, "UTC Time : %02d:%02d:%02d.%03d\n",
00464     dt.time.hour, dt.time.minute, dt.time.second, dt.time.msecs);
00465 
00466   fprintf (f, "                  RA               Dec\n");
00467   char radec[64];
00468   FormatRADec (sol->GetRightAscension(), sol->GetDeclination(), radec);
00469   fprintf (f, "Sun:      %s\n", radec);
00470 
00471   FormatRADec (moon->GetRightAscension(), moon->GetDeclination(), radec);
00472   fprintf (f, "Moon:     %s\n", radec);
00473 
00474   FormatRADec (mercury->GetRightAscension(), mercury->GetDeclination(), radec);
00475   fprintf (f, "Mercury:  %s\n", radec);
00476 
00477   FormatRADec (venus->GetRightAscension(), venus->GetDeclination(), radec);
00478   fprintf (f, "Venus:    %s\n", radec);
00479 
00480   FormatRADec (mars->GetRightAscension(), mars->GetDeclination(), radec);
00481   fprintf (f, "Mars:     %s\n", radec);
00482 
00483   FormatRADec (jupiter->GetRightAscension(), jupiter->GetDeclination(), radec);
00484   fprintf (f, "Jupiter:  %s\n", radec);
00485 
00486   FormatRADec (saturn->GetRightAscension(), saturn->GetDeclination(), radec);
00487   fprintf (f, "Saturn:   %8s\n", radec);
00488 
00489   //
00490   // SSG tree
00491   //
00492   fprintf (f, "\n");
00493   fprintf (f, "Sky SSG Tree:\n");
00494   pre_root->print (f, " ", 4);
00495   fprintf (f, "\n");
00496 }
SourceForge.net Logo Documentation generated by doxygen