]> git.mxchange.org Git - flightgear.git/blob - src/Astro/moon.cxx
d109942a25559856238908e23d9629b628313d61
[flightgear.git] / src / Astro / moon.cxx
1 /**************************************************************************
2  * moon.cxx
3  * Written by Durk Talsma. Originally started October 1997, for distribution  
4  * with the FlightGear project. Version 2 was written in August and 
5  * September 1998. This code is based upon algorithms and data kindly 
6  * provided by Mr. Paul Schlyter. (pausch@saaf.se). 
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of the
11  * License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * $Id$
23  **************************************************************************/
24
25 #include <FDM/flight.hxx>
26
27 #include <string.h>
28 #include "moon.hxx"
29
30 #include <Debug/logstream.hxx>
31 #include <Main/options.hxx>
32 #include <Misc/fgpath.hxx>
33 #include <Objects/texload.h>
34
35 #ifdef __BORLANDC__
36 #  define exception c_exception
37 #endif
38 #include <math.h>
39
40
41 /*************************************************************************
42  * Moon::Moon(FGTime *t)
43  * Public constructor for class Moon. Initializes the orbital elements and 
44  * sets up the moon texture.
45  * Argument: The current time.
46  * the hard coded orbital elements for Moon are passed to 
47  * CelestialBody::CelestialBody();
48  ************************************************************************/
49 Moon::Moon(FGTime *t) :
50   CelestialBody(125.1228, -0.0529538083,
51                 5.1454,    0.00000,
52                 318.0634,  0.1643573223,
53                 60.266600, 0.000000,
54                 0.054900,  0.000000,
55                 115.3654,  13.0649929509, t)
56 {
57   int width, height;
58   
59   FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
60 #ifdef GL_VERSION_1_1
61   xglGenTextures(1, &moon_texid);
62   xglBindTexture(GL_TEXTURE_2D, moon_texid);
63 #elif GL_EXT_texture_object
64   xglGenTexturesEXT(1, &moon_texid);
65   xglBindTextureEXT(GL_TEXTURE_2D, moon_texid);
66 #else
67 #  error port me
68 #endif
69
70   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
71   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
72   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
73
74   // load in the texture data
75   FGPath tpath( current_options.get_fg_root() );
76   tpath.append( "Textures" );
77   tpath.append( "moon.rgb" );
78
79   if ( (moon_texbuf = read_rgb_texture(tpath.c_str(), &width, &height)) 
80        == NULL )
81   {
82     // Try compressed
83     FGPath fg_tpath = tpath;
84     fg_tpath.append( ".gz" );
85     if ( (moon_texbuf = read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
86          == NULL )
87     {
88         FG_LOG( FG_GENERAL, FG_ALERT, 
89                 "Error in loading moon texture " << tpath.str() );
90         exit(-1);
91     } 
92   } 
93
94   glTexImage2D( GL_TEXTURE_2D,
95                 0,
96                 GL_RGB,
97                 256, 256,
98                 0,
99                 GL_RGB, GL_UNSIGNED_BYTE,
100                 moon_texbuf);
101
102   // setup the halo texture
103   FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
104 #ifdef GL_VERSION_1_1
105   xglGenTextures(1, &moon_halotexid);
106   xglBindTexture(GL_TEXTURE_2D, moon_halotexid);
107 #elif GL_EXT_texture_object
108   xglGenTexturesEXT(1, &moon_halotexid);
109   xglBindTextureEXT(GL_TEXTURE_2D, moon_halotexid);
110 #else
111 #  error port me
112 #endif
113
114   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
115   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117   setHalo();
118   glTexImage2D( GL_TEXTURE_2D,
119                 0,
120                 GL_RGBA,
121                 256, 256,
122                 0,
123                 GL_RGBA, GL_UNSIGNED_BYTE,
124                 moon_halotexbuf);
125   moonObject = gluNewQuadric();
126 }
127
128 Moon::~Moon()
129 {
130   //delete moonObject;
131   delete moon_texbuf;
132   delete moon_halotexbuf;
133 }
134
135
136 static int texWidth = 256;      /* 64x64 is plenty */
137
138 void Moon::setHalo()
139 {
140   int texSize;
141   //void *textureBuf;
142   GLubyte *p;
143   int i,j;
144   double radius;
145   
146   texSize = texWidth*texWidth;
147   
148   moon_halotexbuf = new GLubyte[texSize*4];
149   if (!moon_halotexbuf) 
150     return;  // Ugly!
151   
152   p = moon_halotexbuf;
153   
154   radius = (double)(texWidth / 2);
155   
156   for (i=0; i < texWidth; i++) {
157     for (j=0; j < texWidth; j++) {
158       double x, y, d;
159             
160       x = fabs((double)(i - (texWidth / 2)));
161       y = fabs((double)(j - (texWidth / 2)));
162
163       d = sqrt((x * x) + (y * y));
164       if (d < radius) 
165         {
166           double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
167           // inverse square looks nice 
168           *p = (int)((double)0xff * (t * t));
169           *(p+1) = (int)((double) 0xff * (t*t));
170           *(p+2) = (int)((double) 0xff * (t*t));
171           *(p+3) = 0x11;
172         } 
173       else
174         {
175           *p = 0x00;
176           *(p+1) = 0x00;
177           *(p+2) = 0x00;
178           *(p+3) = 0x11;
179         }
180       p += 4;
181     }
182   }
183   //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth, 
184   //        GL_LUMINANCE,
185   //        GL_UNSIGNED_BYTE, textureBuf);
186   //free(textureBuf);
187 }
188
189
190 /*****************************************************************************
191  * void Moon::updatePosition(FGTime *t, Star *ourSun)
192  * this member function calculates the actual topocentric position (i.e.) 
193  * the position of the moon as seen from the current position on the surface
194  * of the moon. 
195  ****************************************************************************/
196 void Moon::updatePosition(FGTime *t, Star *ourSun)
197 {
198   double 
199     eccAnom, ecl, actTime,
200     xv, yv, v, r, xh, yh, zh, xg, yg, zg, xe, ye, ze,
201     Ls, Lm, D, F, mpar, gclat, rho, HA, g,
202     geoRa, geoDec;
203   
204   fgAIRCRAFT *air;
205   FGInterface *f;
206
207   air = &current_aircraft;
208   f = air->fdm_state;
209  
210   updateOrbElements(t);
211   actTime = fgCalcActTime(t);
212
213   // calculate the angle between ecliptic and equatorial coordinate system
214   // in Radians
215   ecl = ((DEG_TO_RAD * 23.4393) - (DEG_TO_RAD * 3.563E-7) * actTime);  
216   eccAnom = fgCalcEccAnom(M, e);  // Calculate the eccentric anomaly
217   xv = a * (cos(eccAnom) - e);
218   yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
219   v = atan2(yv, xv);               // the moon's true anomaly
220   r = sqrt (xv*xv + yv*yv);       // and its distance
221   
222   // estimate the geocentric rectangular coordinates here
223   xh = r * (cos(N) * cos (v+w) - sin (N) * sin(v+w) * cos(i));
224   yh = r * (sin(N) * cos (v+w) + cos (N) * sin(v+w) * cos(i));
225   zh = r * (sin(v+w) * sin(i));
226
227   // calculate the ecliptic latitude and longitude here
228   lonEcl = atan2 (yh, xh);
229   latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
230
231   /* Calculate a number of perturbatioin, i.e. disturbances caused by the 
232    * gravitational infuence of the sun and the other major planets.
233    * The largest of these even have a name */
234   Ls = ourSun->getM() + ourSun->getw();
235   Lm = M + w + N;
236   D = Lm - Ls;
237   F = Lm - N;
238   
239   lonEcl += DEG_TO_RAD * (-1.274 * sin (M - 2*D)
240                           +0.658 * sin (2*D)
241                           -0.186 * sin(ourSun->getM())
242                           -0.059 * sin(2*M - 2*D)
243                           -0.057 * sin(M - 2*D + ourSun->getM())
244                           +0.053 * sin(M + 2*D)
245                           +0.046 * sin(2*D - ourSun->getM())
246                           +0.041 * sin(M - ourSun->getM())
247                           -0.035 * sin(D)
248                           -0.031 * sin(M + ourSun->getM())
249                           -0.015 * sin(2*F - 2*D)
250                           +0.011 * sin(M - 4*D)
251                           );
252   latEcl += DEG_TO_RAD * (-0.173 * sin(F-2*D)
253                           -0.055 * sin(M - F - 2*D)
254                           -0.046 * sin(M + F - 2*D)
255                           +0.033 * sin(F + 2*D)
256                           +0.017 * sin(2*M + F)
257                           );
258   r += (-0.58 * cos(M - 2*D)
259         -0.46 * cos(2*D)
260         );
261   FG_LOG(FG_GENERAL, FG_INFO, "Running moon update");
262   xg = r * cos(lonEcl) * cos(latEcl);
263   yg = r * sin(lonEcl) * cos(latEcl);
264   zg = r *               sin(latEcl);
265   
266   xe = xg;
267   ye = yg * cos(ecl) -zg * sin(ecl);
268   ze = yg * sin(ecl) +zg * cos(ecl);
269
270   geoRa  = atan2(ye, xe);
271   geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
272
273   /* FG_LOG( FG_GENERAL, FG_INFO, 
274           "(geocentric) geoRa = (" << (RAD_TO_DEG * geoRa) 
275           << "), geoDec= (" << (RAD_TO_DEG * geoDec) << ")" ); */
276
277
278   // Given the moon's geocentric ra and dec, calculate its 
279   // topocentric ra and dec. i.e. the position as seen from the
280   // surface of the earth, instead of the center of the earth
281
282   // First calculate the moon's parrallax, that is, the apparent size of the 
283   // (equatorial) radius of the earth, as seen from the moon 
284   mpar = asin ( 1 / r);
285   // FG_LOG( FG_GENERAL, FG_INFO, "r = " << r << " mpar = " << mpar );
286   // FG_LOG( FG_GENERAL, FG_INFO, "lat = " << f->get_Latitude() );
287
288   gclat = f->get_Latitude() - 0.003358 * 
289       sin (2 * DEG_TO_RAD * f->get_Latitude() );
290   // FG_LOG( FG_GENERAL, FG_INFO, "gclat = " << gclat );
291
292   rho = 0.99883 + 0.00167 * cos(2 * DEG_TO_RAD * f->get_Latitude());
293   // FG_LOG( FG_GENERAL, FG_INFO, "rho = " << rho );
294   
295   if (geoRa < 0)
296     geoRa += (2*FG_PI);
297   
298   HA = t->getLst() - (3.8197186 * geoRa);
299   /* FG_LOG( FG_GENERAL, FG_INFO, "t->getLst() = " << t->getLst() 
300           << " HA = " << HA ); */
301
302   g = atan (tan(gclat) / cos ((HA / 3.8197186)));
303   // FG_LOG( FG_GENERAL, FG_INFO, "g = " << g );
304
305   rightAscension = geoRa - mpar * rho * cos(gclat) * sin(HA) / cos (geoDec);
306   declination = geoDec - mpar * rho * sin (gclat) * sin (g - geoDec) / sin(g);
307
308   /* FG_LOG( FG_GENERAL, FG_INFO, 
309           "Ra = (" << (RAD_TO_DEG *rightAscension) 
310           << "), Dec= (" << (RAD_TO_DEG *declination) << ")" ); */
311 }
312
313
314 /************************************************************************
315  * void Moon::newImage()
316  *
317  * This function regenerates a new visual image of the moon, which is added to
318  * solarSystem display list.
319  *
320  * Arguments: Right Ascension and declination
321  *
322  * return value: none
323  **************************************************************************/
324 void Moon::newImage()
325 {
326   fgLIGHT *l = &cur_light_params;
327   float moon_angle = l->moon_angle;
328   
329   /*double x_2, x_4, x_8, x_10;
330   GLfloat ambient;
331   GLfloat amb[4];*/
332   int moonSize = 750;
333
334   GLfloat moonColor[4] = {0.85, 0.75, 0.35, 1.0};
335   GLfloat black[4] = {0.0, 0.0, 0.0, 1.0};
336   GLfloat white[4] = {1.0, 1.0, 1.0, 0.0};
337   
338   if( moon_angle*RAD_TO_DEG < 100 ) 
339     {
340       FG_LOG( FG_ASTRO, FG_INFO, "Generating Moon Image" );
341
342       xglPushMatrix();
343       {
344         xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
345         xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
346         
347         FG_LOG( FG_GENERAL, FG_INFO, 
348                 "Ra = (" << (RAD_TO_DEG *rightAscension) 
349                 << "), Dec= (" << (RAD_TO_DEG *declination) << ")" );
350         xglTranslatef(0.0, 60000.0, 0.0);
351         glEnable(GL_BLEND);     // BLEND ENABLED
352
353         // Draw the halo...
354         if (current_options.get_textures())
355           {
356             glBlendFunc(GL_SRC_ALPHA, GL_ONE);
357             glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
358             glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  
359             glBindTexture(GL_TEXTURE_2D, moon_halotexid);
360           
361             glBegin(GL_QUADS);
362             glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
363             glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
364             glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0,  5000);
365             glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0,  5000);
366             glEnd();
367           }
368         
369         xglEnable(GL_LIGHTING); // LIGHTING ENABLED
370         xglEnable( GL_LIGHT0 );
371         // set lighting parameters
372         xglLightfv(GL_LIGHT0, GL_AMBIENT, white );
373         xglLightfv(GL_LIGHT0, GL_DIFFUSE, white );
374         // xglEnable( GL_CULL_FACE );
375         xglMaterialfv(GL_FRONT, GL_AMBIENT, black);
376         xglMaterialfv(GL_FRONT, GL_DIFFUSE, moonColor); 
377         
378         //glEnable(GL_TEXTURE_2D);
379         
380         glBlendFunc(GL_ONE, GL_ONE);
381         
382         //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 
383         // Draw the moon-proper
384         
385         if (current_options.get_textures())
386           {
387             glBindTexture(GL_TEXTURE_2D, moon_texid);                         
388             gluQuadricTexture(moonObject, GL_TRUE );
389           }
390         gluSphere(moonObject,  moonSize, 12, 12 );
391         glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
392         glDisable(GL_BLEND);    // BLEND DISABLED
393       }
394       xglPopMatrix();
395       glDisable(GL_LIGHTING);   // Lighting Disabled.
396       
397     }
398   else
399     {
400     }
401 }