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