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