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