]> git.mxchange.org Git - flightgear.git/blob - Astro/solarsystem.cxx
New textured moon and rewritten/restructured Astro code contributed by Durk
[flightgear.git] / Astro / solarsystem.cxx
1 /**************************************************************************
2  * solarsystem.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 #include <GL/glut.h>
26 #include <XGL/xgl.h>
27 #include <Debug/fg_debug.h>
28 #include <Time/sunpos.hxx>
29 #include "solarsystem.hxx"
30
31 /***************************************************************************
32  * default constructor for class  SolarSystem:   
33  * or course there can only be one way to create an entire solar system -:) )
34  * the fgTIME argument is needed to properly initialize the the current orbital
35  * elements
36  *************************************************************************/
37 SolarSystem::SolarSystem(fgTIME *t)
38 {
39   if (theSolarSystem)
40     {
41       fgPrintf(FG_GENERAL, FG_EXIT, "Error: only one solarsystem allowed\n");
42     }
43   theSolarSystem = this;
44   ourSun     = new Star(t);   
45   earthsMoon = new Moon(t);
46   mercury    = new Mercury(t);
47   venus      = new Venus(t);
48   mars       = new Mars(t);
49   jupiter    = new Jupiter(t);
50   saturn     = new Saturn(t);
51   uranus     = new Uranus(t);
52   neptune    = new Neptune(t);
53
54   displayList = 0;
55 };
56
57 /* --------------------------------------------------------------------------
58    the destructor for class SolarSystem;
59    danger: Huge Explosions ahead! (-:))
60    ------------------------------------------------------------------------*/
61 SolarSystem::~SolarSystem()
62 {
63   delete ourSun;
64   delete earthsMoon;
65   delete mercury;
66   delete venus;
67   delete mars;
68   delete jupiter;
69   delete saturn;
70   delete uranus;
71   delete neptune;
72   //delete pluto;
73 }
74 /****************************************************************************
75  * void SolarSystem::rebuild()
76  *
77  * this member function updates the positions for the sun, moon, and planets,
78  * and then rebuilds the display list. 
79  *
80  * arguments: none
81  * return value: none
82  ***************************************************************************/
83 void SolarSystem::rebuild()
84 {
85   fgLIGHT *l = &cur_light_params;
86   fgTIME  *t = &cur_time_params;  
87   float x, y, z,
88     xx, yy,zz;
89   double ra, dec;
90   double x_2, x_4, x_8, x_10;
91   double magnitude;
92   GLfloat ambient;
93   GLfloat amb[4];
94   GLfloat moonColor[4] = {0.85, 0.75, 0.35, 1.0};
95   GLfloat black[4] = {0.0, 0.0,0.0,1.0};
96   GLfloat white[4] = {1.0, 1.0,1.0,1.0};
97
98   // Step 1: update all the positions
99   ourSun->updatePosition(t);
100   earthsMoon->updatePosition(t, ourSun);
101   mercury->updatePosition(t, ourSun);
102   venus->updatePosition(t, ourSun);
103   mars->updatePosition(t, ourSun);
104   jupiter->updatePosition(t, ourSun);
105   saturn->updatePosition(t, ourSun);
106   uranus->updatePosition(t, ourSun);
107   neptune->updatePosition(t, ourSun);
108   
109   fgUpdateSunPos();   // get the right sun angle (especially important when 
110                       // running for the first time.
111   if (displayList)
112     xglDeleteLists(displayList, 1);
113
114   displayList = xglGenLists(1);
115   // Step 2: rebuild the display list
116   xglNewList( displayList, GL_COMPILE);
117   {
118     // Step 2a: Add the moon...
119     xglEnable( GL_LIGHTING );
120     xglEnable( GL_LIGHT0 );
121     // set lighting parameters
122     xglLightfv(GL_LIGHT0, GL_AMBIENT, white );
123     xglLightfv(GL_LIGHT0, GL_DIFFUSE, white );
124     xglEnable( GL_CULL_FACE );
125     
126     // Enable blending, in order to effectively eliminate the dark side of the
127     // moon
128     glEnable(GL_BLEND);
129     glBlendFunc(GL_ONE, GL_ONE);
130     earthsMoon->getPos(&ra, &dec);
131     x = 60000.0 * cos(ra) * cos (dec);
132     y = 60000.0 * sin(ra) * cos (dec);
133     z = 60000.0 * sin(dec);
134     xx = cos(ra) * cos(dec);
135     yy = sin(ra) * cos(dec);
136     zz = sin(dec);
137     xglMaterialfv(GL_FRONT, GL_AMBIENT, black);
138     xglMaterialfv(GL_FRONT, GL_DIFFUSE, moonColor); 
139     xglPushMatrix();
140     {
141         earthsMoon->newImage(ra,dec);
142     }
143     xglPopMatrix();
144     glDisable(GL_BLEND);
145     xglDisable(GL_LIGHTING);
146  
147     // Step 2b:  Add the sun
148     x_2 = l -> sun_angle * l->sun_angle;
149     x_4 = x_2 * x_2;
150     x_8 = x_4 * x_4;
151     x_10 = x_8 * x_2;
152     ambient = (0.4 * pow (1.1, - x_10 / 30.0));
153     if (ambient < 0.3) ambient = 0.3;
154     if (ambient > 1.0) ambient = 1.0;
155
156     amb[0] = 0.00 + ((ambient * 6.0)  - 1.0); // minimum value = 0.8
157     amb[1] = 0.00 + ((ambient * 11.0) - 3.0); // minimum value = 0.3
158     amb[2] = 0.00 + ((ambient * 12.0) - 3.6); // minimum value = 0.0
159     amb[3] = 1.00;
160
161     if (amb[0] > 1.0) amb[0] = 1.0;
162     if (amb[1] > 1.0) amb[1] = 1.0;
163     if (amb[2] > 1.0) amb[2] = 1.0;
164
165     ourSun->getPos(&ra, &dec);
166     x = 60000.0 * cos(ra) * cos(dec);
167     y = 60000.0 * sin(ra) * cos(dec);
168     z = 60000.0 * sin(dec);
169     xglPushMatrix();
170     {
171       // xglPushMatrix();
172       xglTranslatef(x,y,z);
173       xglColor3f(amb[0], amb[1], amb[2]);
174       glutSolidSphere(1400.0, 10, 10);
175     }
176     glPopMatrix();
177     // Step 2c: Add the planets
178     xglBegin(GL_POINTS);
179     mercury->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
180     venus  ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
181     mars   ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
182     jupiter->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
183     saturn ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
184     uranus ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
185     neptune->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
186     xglEnd();
187     xglEnable(GL_LIGHTING);
188   }
189   xglEndList();
190 }
191
192 /*****************************************************************************
193  * double SolarSystem::scaleMagnitude(double magn)
194  * This private member function rescales the original magnitude, as used in the
195  * astronomical sense of the word, into a value used by OpenGL to draw a 
196  * convincing Star or planet
197  * 
198  * Argument: the astronomical magnitude
199  *
200  * return value: the rescaled magnitude
201  ****************************************************************************/
202 double SolarSystem::scaleMagnitude(double magn)
203 {
204   double magnitude = (0.0 - magn) / 5.0 + 1.0;
205   magnitude = magnitude * 0.7 + (3 * 0.1);
206   if (magnitude > 1.0) magnitude = 1.0;
207   if (magnitude < 0.0) magnitude = 0.0;
208   return magnitude;
209 }
210
211 /***************************************************************************
212  * void SolarSytem::addPlanetToList(double ra, double dec, double magn);
213  *
214  * This private member function first causes the magnitude to be properly
215  * rescaled, and then adds the planet to the display list.
216  * 
217  * arguments: Right Ascension, declination, and magnitude
218  *
219  * return value: none
220  **************************************************************************/
221 void SolarSystem::addPlanetToList(double ra, double dec, double magn)
222 {
223   double
224     magnitude = scaleMagnitude ( magn );
225
226   fgLIGHT *l = &cur_light_params;
227
228   if ((double) (l->sun_angle - FG_PI_2) > 
229       ((magnitude - 1.0) * - 20 * DEG_TO_RAD)) 
230     {
231       xglColor3f (magnitude, magnitude, magnitude);
232       xglVertex3f( 50000.0 * cos (ra) * cos (dec),
233                    50000.0 * sin (ra) * cos (dec),
234                    50000.0 * sin (dec));
235     }
236 }
237
238
239 SolarSystem* SolarSystem::theSolarSystem = 0;
240
241 /******************************************************************************
242  * void solarSystemRebuild()
243  * this a just a wrapper function, provided for use as an interface to the 
244  * event manager
245  *****************************************************************************/
246 void solarSystemRebuild()
247 {
248   SolarSystem::theSolarSystem->rebuild();
249 }
250
251
252
253
254
255
256