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