~ubuntu-branches/ubuntu/precise/stellarium/precise

« back to all changes in this revision

Viewing changes to src/core/SkyDrawer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cédric Delfosse
  • Date: 2009-03-13 20:07:22 UTC
  • mfrom: (1.1.8 upstream) (4.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090313200722-l66s4zy2s3e8up0s
Tags: 0.10.2-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Stellarium
3
 
 * Copyright (C) 2007 Fabien Chereau
4
 
 * 
5
 
 * This program is free software; you can redistribute it and/or
6
 
 * modify it under the terms of the GNU General Public License
7
 
 * as published by the Free Software Foundation; either version 2
8
 
 * of the License, or (at your option) any later version.
9
 
 * 
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 * 
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 
 */
19
 
 
20
 
#include "SkyDrawer.hpp"
21
 
#include "Projector.hpp"
22
 
#include "Navigator.hpp"
23
 
#include "ToneReproducer.hpp"
24
 
#include "StelTextureMgr.hpp"
25
 
#include "StelApp.hpp"
26
 
#include "StelCore.hpp"
27
 
#include "StelUtils.hpp"
28
 
 
29
 
#include <QStringList>
30
 
#include <QSettings>
31
 
#include <QDebug>
32
 
#include <QtGlobal>
33
 
 
34
 
// The 0.025 corresponds to the maximum eye resolution in degree
35
 
#define EYE_RESOLUTION (0.25)
36
 
#define MAX_LINEAR_RADIUS 8.f
37
 
 
38
 
SkyDrawer::SkyDrawer(StelCore* acore) : core(acore)
39
 
{
40
 
        prj = core->getProjection();
41
 
        eye = core->getToneReproducer();
42
 
 
43
 
        inScale = 1.;
44
 
        bortleScaleIndex = 3;
45
 
        limitMagnitude = -100.f;
46
 
        limitLuminance = 0;
47
 
        oldLum=-1.f;
48
 
        maxLum = 0.f;
49
 
        setMaxFov(180.f);
50
 
        setMinFov(0.1f);
51
 
        
52
 
        starAbsoluteScaleF = 1.f;
53
 
        starRelativeScale = 1.f;
54
 
        starLinearScale = 19.569f;
55
 
        
56
 
        update(0);
57
 
        
58
 
        QSettings* conf = StelApp::getInstance().getSettings();
59
 
        initColorTableFromConfigFile(conf);
60
 
        
61
 
        setTwinkleAmount(conf->value("stars/star_twinkle_amount",0.3).toDouble());
62
 
        setFlagTwinkle(conf->value("stars/flag_star_twinkle",true).toBool());
63
 
        setFlagPointStar(conf->value("stars/flag_point_star",false).toBool());
64
 
        setMaxFov(conf->value("stars/mag_converter_max_fov",70.0).toDouble());
65
 
        setMinFov(conf->value("stars/mag_converter_min_fov",0.1).toDouble());
66
 
        setFlagLuminanceAdaptation(conf->value("viewing/use_luminance_adaptation",true).toBool());
67
 
        
68
 
        bool ok=true;
69
 
 
70
 
        setBortleScale(conf->value("stars/init_bortle_scale",3).toInt(&ok));
71
 
        if (!ok)
72
 
        {
73
 
                conf->setValue("stars/init_bortle_scale",3);
74
 
                setBortleScale(3);
75
 
                ok = true;
76
 
        }
77
 
        
78
 
        setRelativeStarScale(conf->value("stars/relative_scale",1.0).toDouble(&ok));
79
 
        if (!ok)
80
 
        {
81
 
                conf->setValue("stars/relative_scale",1.0);
82
 
                setRelativeStarScale(1.0);
83
 
                ok = true;
84
 
        }
85
 
        
86
 
        setAbsoluteStarScale(conf->value("stars/absolute_scale",1.0).toDouble(&ok));
87
 
        if (!ok)
88
 
        {
89
 
                conf->setValue("stars/absolute_scale",1.0);
90
 
                setAbsoluteStarScale(1.0);
91
 
                ok = true;
92
 
        }
93
 
        
94
 
        // Initialize buffers for use by gl vertex array
95
 
        nbPointSources = 0;
96
 
        maxPointSources = 1000;
97
 
        verticesGrid = new Vec2f[maxPointSources*4];
98
 
        colorGrid = new Vec3f[maxPointSources*4];
99
 
        textureGrid = new Vec2f[maxPointSources*4];
100
 
        for (unsigned int i=0;i<maxPointSources; ++i)
101
 
        {
102
 
                textureGrid[i*4].set(0,0);
103
 
                textureGrid[i*4+1].set(1,0);
104
 
                textureGrid[i*4+2].set(1,1);
105
 
                textureGrid[i*4+3].set(0,1);
106
 
        }
107
 
}
108
 
 
109
 
 
110
 
SkyDrawer::~SkyDrawer()
111
 
{
112
 
        if (verticesGrid)
113
 
                delete[] verticesGrid;
114
 
        verticesGrid = NULL;
115
 
        if (colorGrid)
116
 
                delete[] colorGrid;
117
 
        colorGrid = NULL;
118
 
        if (textureGrid)
119
 
                delete[] textureGrid;
120
 
        textureGrid = NULL;
121
 
}
122
 
 
123
 
// Init parameters from config file
124
 
void SkyDrawer::init()
125
 
{
126
 
        StelApp::getInstance().getTextureManager().setDefaultParams();
127
 
        // Load star texture no mipmap:
128
 
        texHalo = StelApp::getInstance().getTextureManager().createTexture("star16x16.png");
129
 
        texBigHalo = StelApp::getInstance().getTextureManager().createTexture("haloLune.png");
130
 
        texSunHalo = StelApp::getInstance().getTextureManager().createTexture("halo.png");
131
 
}
132
 
 
133
 
void SkyDrawer::update(double deltaTime)
134
 
{
135
 
        float fov = prj->getFov();
136
 
        if (fov > maxFov)
137
 
        {
138
 
                fov = maxFov;
139
 
        }
140
 
        else
141
 
        {
142
 
                if (fov < minFov)
143
 
                        fov = minFov;
144
 
        }
145
 
        
146
 
        // This factor is fully arbitrary. It corresponds to the collecting area x exposure time of the instrument
147
 
        // It is based on a power law, so that it varies progressively with the FOV to smoothly switch from human 
148
 
        // vision to binocculares/telescope. Use a max of 0.7 because after that the atmosphere starts to glow too much!
149
 
        float powFactor = std::pow(60./qMax(0.7f,fov), 0.8);
150
 
        eye->setInputScale(inScale*powFactor);
151
 
        
152
 
        // Set the fov factor for point source luminance computation
153
 
        // the division by powFactor should in principle not be here, but it doesn't look nice if removed
154
 
        lnfovFactor = std::log(1./50.*2025000.f* 60.f*60.f / (fov*fov) / (EYE_RESOLUTION*EYE_RESOLUTION)/powFactor/1.4);
155
 
        
156
 
        // Precompute
157
 
        starLinearScale = std::pow(35.f*2.0f*starAbsoluteScaleF, 1.40f/2.f*starRelativeScale);
158
 
        
159
 
        // update limit mag
160
 
        limitMagnitude = computeLimitMagnitude();
161
 
        
162
 
        // update limit luminance
163
 
        limitLuminance = computeLimitLuminance();
164
 
}
165
 
 
166
 
// Compute the current limit magnitude by dichotomy
167
 
float SkyDrawer::computeLimitMagnitude() const
168
 
{
169
 
        float a=-26.f;
170
 
        float b=30.f;
171
 
        float rcmag[2];
172
 
        float lim = 0.f;
173
 
        int safety=0;
174
 
        while (std::fabs(lim-a)>0.05)
175
 
        {
176
 
                computeRCMag(lim, rcmag);
177
 
                if (rcmag[0]<=0.f)
178
 
                {
179
 
                        float tmp = lim;
180
 
                        lim=(a+lim)/2;
181
 
                        b=tmp;
182
 
                }
183
 
                else
184
 
                {
185
 
                        float tmp = lim;
186
 
                        lim=(b+lim)/2;
187
 
                        a=tmp;
188
 
                }
189
 
                ++safety;
190
 
                if (safety>20)
191
 
                {
192
 
                        lim=-99;
193
 
                        break;
194
 
                }
195
 
        }
196
 
        return lim;
197
 
}
198
 
 
199
 
// Compute the current limit luminance by dichotomy
200
 
float SkyDrawer::computeLimitLuminance() const
201
 
{
202
 
        float a=0.f;
203
 
        float b=500000.f;
204
 
        float lim=40.f;
205
 
        int safety=0;
206
 
        float adaptL;
207
 
        while (std::fabs(lim-a)>0.05)
208
 
        {
209
 
                adaptL = eye->adaptLuminanceScaled(lim);
210
 
                if (adaptL<=0.05f) // Object considered not visible if its adapted scaled luminance<0.05
211
 
                {
212
 
                        float tmp = lim;
213
 
                        lim=(b+lim)/2;
214
 
                        a=tmp;
215
 
                }
216
 
                else
217
 
                {
218
 
                        float tmp = lim;
219
 
                        lim=(a+lim)/2;
220
 
                        b=tmp;
221
 
                }
222
 
                ++safety;
223
 
                if (safety>30)
224
 
                {
225
 
                        lim=500000;
226
 
                        break;
227
 
                }
228
 
        }
229
 
        return lim;
230
 
}
231
 
 
232
 
// Compute the ln of the luminance for a point source with the given mag for the current FOV
233
 
float SkyDrawer::pointSourceMagToLnLuminance(float mag) const
234
 
{
235
 
        return -0.92103f*(mag + 12.12331f) + lnfovFactor;
236
 
}
237
 
 
238
 
float SkyDrawer::pointSourceLuminanceToMag(float lum)
239
 
{
240
 
        return (std::log(lum) - lnfovFactor)/-0.92103f - 12.12331f;
241
 
}
242
 
 
243
 
// Compute the luminance for an extended source with the given surface brightness in Vmag/arcmin^2
244
 
float SkyDrawer::surfacebrightnessToLuminance(float sb)
245
 
{
246
 
        return 2.*2025000.f*std::exp(-0.92103f*(sb + 12.12331f))/(1./60.*1./60.);
247
 
}
248
 
 
249
 
// Compute RMag and CMag from magnitude for a point source.
250
 
bool SkyDrawer::computeRCMag(float mag, float rcMag[2]) const
251
 
{
252
 
        rcMag[0] = eye->adaptLuminanceScaledLn(pointSourceMagToLnLuminance(mag), starRelativeScale*1.40f/2.f);
253
 
        rcMag[0]*=starLinearScale;
254
 
        
255
 
        // Use now statically min_rmag = 0.5, because higher and too small values look bad
256
 
        if (rcMag[0] < 0.5f)
257
 
        {
258
 
                rcMag[0] = rcMag[1] = 0.f;
259
 
                return false;
260
 
        }
261
 
        
262
 
        // if size of star is too small (blink) we put its size to 1.2 --> no more blink
263
 
        // And we compensate the difference of brighteness with cmag
264
 
        if (rcMag[0]<1.2f)
265
 
        {
266
 
                rcMag[1] = rcMag[0] * rcMag[0] / 1.44f;
267
 
                if (rcMag[1] < 0.07f)
268
 
                {
269
 
                        rcMag[0] = rcMag[1] = 0.f;
270
 
                        return false;
271
 
                }
272
 
                rcMag[0] = 1.2f;
273
 
        }
274
 
        else
275
 
        {
276
 
                // cmag:
277
 
                rcMag[1] = 1.0f;
278
 
                if (rcMag[0]>MAX_LINEAR_RADIUS)
279
 
                {
280
 
                        rcMag[0]=MAX_LINEAR_RADIUS+std::sqrt(1.f+rcMag[0]-MAX_LINEAR_RADIUS)-1.f;
281
 
                }
282
 
        }
283
 
        return true;
284
 
}
285
 
 
286
 
void SkyDrawer::preDrawPointSource()
287
 
{
288
 
        assert(nbPointSources==0);
289
 
        glDisable(GL_LIGHTING);
290
 
        // Blending is really important. Otherwise faint stars in the vicinity of
291
 
        // bright star will cause tiny black squares on the bright star, e.g. see Procyon.
292
 
        glEnable(GL_BLEND);
293
 
        glBlendFunc(GL_ONE, GL_ONE);
294
 
        
295
 
        if (getFlagPointStar())
296
 
        {
297
 
                glDisable(GL_TEXTURE_2D);
298
 
                glPointSize(0.1);
299
 
        }
300
 
        else
301
 
        {
302
 
                glEnable(GL_TEXTURE_2D);
303
 
        }
304
 
}
305
 
 
306
 
// Finalize the drawing of point sources
307
 
void SkyDrawer::postDrawPointSource()
308
 
{
309
 
        if (nbPointSources==0)
310
 
                return;
311
 
        
312
 
        texHalo->bind();
313
 
        
314
 
        glEnableClientState(GL_VERTEX_ARRAY);
315
 
        glEnableClientState(GL_COLOR_ARRAY);
316
 
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
317
 
                
318
 
        // Load the color components
319
 
        glColorPointer(3, GL_FLOAT, 0, colorGrid);
320
 
        // Load the vertex array
321
 
        glVertexPointer(2, GL_FLOAT, 0, verticesGrid);
322
 
        // Load the vertex array
323
 
        glTexCoordPointer(2, GL_FLOAT, 0, textureGrid);
324
 
        
325
 
        // And draw everything at once
326
 
        glDrawArrays(GL_QUADS, 0, nbPointSources*4);
327
 
                
328
 
        glDisableClientState(GL_VERTEX_ARRAY);
329
 
        glDisableClientState(GL_COLOR_ARRAY);
330
 
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
331
 
        
332
 
        nbPointSources = 0;     
333
 
}
334
 
 
335
 
// Draw a point source halo.
336
 
bool SkyDrawer::drawPointSource(double x, double y, const float rcMag[2], const Vec3f& color)
337
 
{       
338
 
        if (rcMag[0]<=0.f)
339
 
                return false;
340
 
        
341
 
        // Random coef for star twinkling
342
 
        const float tw = flagStarTwinkle ? (1.f-twinkleAmount*rand()/RAND_MAX) : 1.f;
343
 
        
344
 
        if (flagPointStar)
345
 
        {
346
 
                // Draw the star rendered as GLpoint. This may be faster but it is not so nice
347
 
                glColor3fv(color*(rcMag[1]*tw));
348
 
                prj->drawPoint2d(x, y);
349
 
        }
350
 
        else
351
 
        {
352
 
                // Store the drawing instructions in the vertex arrays
353
 
                colorGrid[nbPointSources*4+3] = color*(rcMag[1]*tw);            
354
 
                const double radius = rcMag[0];
355
 
                Vec2f* v = &(verticesGrid[nbPointSources*4]);
356
 
                v->set(x-radius,y-radius); ++v;
357
 
                v->set(x+radius,y-radius); ++v;
358
 
                v->set(x+radius,y+radius); ++v;
359
 
                v->set(x-radius,y+radius); ++v;
360
 
                
361
 
                // If the rmag is big, draw a big halo
362
 
                if (radius>MAX_LINEAR_RADIUS+5.f)
363
 
                {
364
 
                        float cmag = qMin(rcMag[1],(float)(radius-(MAX_LINEAR_RADIUS+5.))/30.f);
365
 
                        float rmag = 150.f;
366
 
                        if (cmag>1.f)
367
 
                                cmag = 1.f;
368
 
 
369
 
                        texBigHalo->bind();
370
 
                        glEnable(GL_TEXTURE_2D);
371
 
                        glColor3f(color[0]*cmag, color[1]*cmag, color[2]*cmag);
372
 
 
373
 
                        glBegin(GL_QUADS);
374
 
                                glTexCoord2i(0,0); glVertex2f(x-rmag,y-rmag);
375
 
                                glTexCoord2i(1,0); glVertex2f(x+rmag,y-rmag);
376
 
                                glTexCoord2i(1,1); glVertex2f(x+rmag,y+rmag);
377
 
                                glTexCoord2i(0,1); glVertex2f(x-rmag,y+rmag);
378
 
                        glEnd();
379
 
                }
380
 
                
381
 
                
382
 
                ++nbPointSources;
383
 
                if (nbPointSources>=maxPointSources)
384
 
                {
385
 
                        // Flush the buffer (draw all buffered stars)
386
 
                        postDrawPointSource();
387
 
                }
388
 
        }
389
 
        return true;
390
 
}
391
 
 
392
 
 
393
 
void SkyDrawer::preDrawSky3dModel(double illuminatedArea, float mag, bool lighting)
394
 
{
395
 
        // Set the main source of light to be the sun
396
 
        const Vec3d sunPos = core->getNavigation()->getHelioToEyeMat()*Vec3d(0,0,0);
397
 
        glLightfv(GL_LIGHT0,GL_POSITION,Vec4f(sunPos[0],sunPos[1],sunPos[2],1.f));
398
 
        
399
 
        if (lighting)
400
 
        {
401
 
                glEnable(GL_LIGHTING);
402
 
                const float diffuse[4] = {2.,2.,2.,1};
403
 
                glLightfv(GL_LIGHT0,GL_DIFFUSE, diffuse);
404
 
        }
405
 
        else
406
 
        {
407
 
                glDisable(GL_LIGHTING);
408
 
                glColor3fv(Vec3f(1.f,1.f,1.f));
409
 
        }
410
 
}
411
 
 
412
 
// Terminate drawing of a 3D model, draw the halo
413
 
void SkyDrawer::postDrawSky3dModel(double x, double y, double illuminatedArea, float mag, const Vec3f& color)
414
 
{
415
 
        glDisable(GL_LIGHTING);
416
 
        
417
 
        const float pixPerRad = core->getProjection()->getPixelPerRadAtCenter();
418
 
        // Assume a disk shape
419
 
        float pixRadius = std::sqrt(illuminatedArea/(60.*60.)*M_PI/180.*M_PI/180.*(pixPerRad*pixPerRad))/M_PI;
420
 
        
421
 
        bool noStarHalo = false;
422
 
        
423
 
        if (mag<-15.f)
424
 
        {
425
 
                // Sun, halo size varies in function of the magnitude because sun as seen from pluto should look dimmer
426
 
                // as the sun as seen from earth
427
 
                texSunHalo->bind();
428
 
                glEnable(GL_BLEND);
429
 
                glBlendFunc(GL_ONE, GL_ONE);
430
 
                glEnable(GL_TEXTURE_2D);
431
 
                float rmag = 150.f*(mag+15.f)/-11.f;
432
 
                float cmag = 1.f;
433
 
                if (rmag<pixRadius*3.f+100.)
434
 
                        cmag = qMax(0.f, 1.f-(pixRadius*3.f+100-rmag)/100);
435
 
                glColor3f(color[0]*cmag, color[1]*cmag, color[2]*cmag);
436
 
                glBegin(GL_QUADS);
437
 
                        glTexCoord2i(0,0); glVertex2f(x-rmag,y-rmag);
438
 
                        glTexCoord2i(1,0); glVertex2f(x+rmag,y-rmag);
439
 
                        glTexCoord2i(1,1); glVertex2f(x+rmag,y+rmag);
440
 
                        glTexCoord2i(0,1); glVertex2f(x-rmag,y+rmag);
441
 
                glEnd();
442
 
                
443
 
                noStarHalo = true;
444
 
        }
445
 
        
446
 
        // Now draw the halo according the object brightness
447
 
        bool save = flagStarTwinkle;
448
 
        flagStarTwinkle = false;
449
 
        
450
 
        float rcm[2];
451
 
        computeRCMag(mag, rcm);
452
 
        
453
 
        // We now have the radius and luminosity of the small halo
454
 
        // If the disk of the planet is big enough to be visible, we should adjust the eye adaptation luminance
455
 
        // so that the radius of the halo is small enough to be not visible (so that we see the disk)
456
 
 
457
 
        float tStart = 2.f;
458
 
        float tStop = 6.f;
459
 
        bool truncated=false;
460
 
        
461
 
        float maxHaloRadius = qMax(tStart*3., pixRadius*3.);
462
 
        if (rcm[0]>maxHaloRadius)
463
 
        {
464
 
                truncated = true;
465
 
                rcm[0]=maxHaloRadius+std::sqrt(rcm[0]-maxHaloRadius);
466
 
        }
467
 
        
468
 
        // Fade the halo away when the disk is too big
469
 
        if (pixRadius>=tStop)
470
 
        {
471
 
                rcm[1]=0.f;
472
 
        }
473
 
        if (pixRadius>tStart && pixRadius<tStop)
474
 
        {
475
 
                rcm[1]=(tStop-pixRadius)/(tStop-tStart);
476
 
        }
477
 
        
478
 
        if (truncated && flagLuminanceAdaptation)
479
 
        {
480
 
                float wl = findWorldLumForMag(mag, rcm[0]);
481
 
                if (wl>0)
482
 
                {
483
 
                        reportLuminanceInFov(qMin(700., qMin((double)wl/50, (60.*60.)/(prj->getFov()*prj->getFov())*6.)));
484
 
                }
485
 
        }
486
 
        
487
 
        if (!noStarHalo)
488
 
        {
489
 
                preDrawPointSource();
490
 
                drawPointSource(x,y,rcm,color);
491
 
                postDrawPointSource();
492
 
        }
493
 
        flagStarTwinkle=save;
494
 
}
495
 
 
496
 
float SkyDrawer::findWorldLumForMag(float mag, float targetRadius)
497
 
{
498
 
        const float saveLum = eye->getWorldAdaptationLuminance();       // save
499
 
        
500
 
        // Compute the luminance by dichotomy
501
 
        float a=0.001f;
502
 
        float b=500000.f;
503
 
        float rcmag[2];
504
 
        rcmag[0]=-99;
505
 
        float curLum = 500.f;
506
 
        int safety=0;
507
 
        while (std::fabs(rcmag[0]-targetRadius)>0.1)
508
 
        {
509
 
                eye->setWorldAdaptationLuminance(curLum);
510
 
                computeRCMag(mag, rcmag);
511
 
                if (rcmag[0]<=targetRadius)
512
 
                {
513
 
                        float tmp = curLum;
514
 
                        curLum=(a+curLum)/2;
515
 
                        b=tmp;
516
 
                }
517
 
                else
518
 
                {
519
 
                        float tmp = curLum;
520
 
                        curLum=(b+curLum)/2;
521
 
                        a=tmp;
522
 
                }
523
 
                ++safety;
524
 
                if (safety>20)
525
 
                {
526
 
                        if (curLum>490000.f)
527
 
                        {
528
 
                                curLum = 500000.f;
529
 
                        }
530
 
                        else
531
 
                        {
532
 
                                curLum=-1;
533
 
                        }
534
 
                        break;
535
 
                }
536
 
        }
537
 
        
538
 
        eye->setWorldAdaptationLuminance(saveLum);      // restore
539
 
        
540
 
        return curLum;
541
 
}
542
 
 
543
 
// Report that an object of luminance lum is currently displayed
544
 
void SkyDrawer::reportLuminanceInFov(double lum, bool fastAdaptation)
545
 
{
546
 
        if (lum > maxLum)
547
 
        {
548
 
                if (oldLum<0)
549
 
                        oldLum=lum;
550
 
                // Use a log law for smooth transitions
551
 
                if (fastAdaptation==true && lum>oldLum)
552
 
                {
553
 
                        maxLum = lum;
554
 
                }
555
 
                else
556
 
                {
557
 
                        float transitionSpeed = 0.2f;
558
 
                        maxLum = std::exp(std::log(oldLum)+(std::log(lum)-std::log(oldLum))* qMin(1.f, 1.f/StelApp::getInstance().getFps()/transitionSpeed));
559
 
                }
560
 
        }
561
 
}
562
 
 
563
 
void SkyDrawer::preDraw()
564
 
{
565
 
        eye->setWorldAdaptationLuminance(maxLum);
566
 
        // Re-initialize for next stage
567
 
        oldLum = maxLum;
568
 
        maxLum = 0;
569
 
}
570
 
 
571
 
 
572
 
// Set the parameters so that the stars disapear at about the limit given by the bortle scale
573
 
// See http://en.wikipedia.org/wiki/Bortle_Dark-Sky_Scale
574
 
void SkyDrawer::setBortleScale(int bIndex)
575
 
{
576
 
        // Associate the Bortle index (1 to 9) to inScale value
577
 
        if (bIndex<1)
578
 
        {
579
 
                qWarning() << "WARING: Bortle scale index range is [1;9], given" << bIndex;
580
 
                bIndex = 1;
581
 
        }
582
 
        if (bIndex>9)
583
 
        {
584
 
                qWarning() << "WARING: Bortle scale index range is [1;9], given" << bIndex;
585
 
                bIndex = 9;
586
 
        }
587
 
        
588
 
        bortleScaleIndex = bIndex;
589
 
        
590
 
        // These value have been calibrated by hand, looking at the faintest star in stellarium at around 40 deg FOV
591
 
        // They should roughly match the scale described at http://en.wikipedia.org/wiki/Bortle_Dark-Sky_Scale
592
 
        static const float bortleToInScale[9] = {2.45, 1.55, 1.0, 0.63, 0.40, 0.24, 0.23, 0.145, 0.09};
593
 
        setInputScale(bortleToInScale[bIndex-1]);
594
 
}
595
 
 
596
 
// Old colors
597
 
// Vec3f SkyDrawer::colorTable[128] = {
598
 
//      Vec3f(0.587877,0.755546,1.000000),
599
 
//      Vec3f(0.609856,0.750638,1.000000),
600
 
//      Vec3f(0.624467,0.760192,1.000000),
601
 
//      Vec3f(0.639299,0.769855,1.000000),
602
 
//      Vec3f(0.654376,0.779633,1.000000),
603
 
//      Vec3f(0.669710,0.789527,1.000000),
604
 
//      Vec3f(0.685325,0.799546,1.000000),
605
 
//      Vec3f(0.701229,0.809688,1.000000),
606
 
//      Vec3f(0.717450,0.819968,1.000000),
607
 
//      Vec3f(0.733991,0.830383,1.000000),
608
 
//      Vec3f(0.750857,0.840932,1.000000),
609
 
//      Vec3f(0.768091,0.851637,1.000000),
610
 
//      Vec3f(0.785664,0.862478,1.000000),
611
 
//      Vec3f(0.803625,0.873482,1.000000),
612
 
//      Vec3f(0.821969,0.884643,1.000000),
613
 
//      Vec3f(0.840709,0.895965,1.000000),
614
 
//      Vec3f(0.859873,0.907464,1.000000),
615
 
//      Vec3f(0.879449,0.919128,1.000000),
616
 
//      Vec3f(0.899436,0.930956,1.000000),
617
 
//      Vec3f(0.919907,0.942988,1.000000),
618
 
//      Vec3f(0.940830,0.955203,1.000000),
619
 
//      Vec3f(0.962231,0.967612,1.000000),
620
 
//      Vec3f(0.984110,0.980215,1.000000),
621
 
//      Vec3f(1.000000,0.986617,0.993561),
622
 
//      Vec3f(1.000000,0.977266,0.971387),
623
 
//      Vec3f(1.000000,0.967997,0.949602),
624
 
//      Vec3f(1.000000,0.958816,0.928210),
625
 
//      Vec3f(1.000000,0.949714,0.907186),
626
 
//      Vec3f(1.000000,0.940708,0.886561),
627
 
//      Vec3f(1.000000,0.931787,0.866303),
628
 
//      Vec3f(1.000000,0.922929,0.846357),
629
 
//      Vec3f(1.000000,0.914163,0.826784),
630
 
//      Vec3f(1.000000,0.905497,0.807593),
631
 
//      Vec3f(1.000000,0.896884,0.788676),
632
 
//      Vec3f(1.000000,0.888389,0.770168),
633
 
//      Vec3f(1.000000,0.879953,0.751936),
634
 
//      Vec3f(1.000000,0.871582,0.733989),
635
 
//      Vec3f(1.000000,0.863309,0.716392),
636
 
//      Vec3f(1.000000,0.855110,0.699088),
637
 
//      Vec3f(1.000000,0.846985,0.682070),
638
 
//      Vec3f(1.000000,0.838928,0.665326),
639
 
//      Vec3f(1.000000,0.830965,0.648902),
640
 
//      Vec3f(1.000000,0.823056,0.632710),
641
 
//      Vec3f(1.000000,0.815254,0.616856),
642
 
//      Vec3f(1.000000,0.807515,0.601243),
643
 
//      Vec3f(1.000000,0.799820,0.585831),
644
 
//      Vec3f(1.000000,0.792222,0.570724),
645
 
//      Vec3f(1.000000,0.784675,0.555822),
646
 
//      Vec3f(1.000000,0.777212,0.541190),
647
 
//      Vec3f(1.000000,0.769821,0.526797),
648
 
//      Vec3f(1.000000,0.762496,0.512628),
649
 
//      Vec3f(1.000000,0.755229,0.498664),
650
 
//      Vec3f(1.000000,0.748032,0.484926),
651
 
//      Vec3f(1.000000,0.740897,0.471392),
652
 
//      Vec3f(1.000000,0.733811,0.458036),
653
 
//      Vec3f(1.000000,0.726810,0.444919),
654
 
//      Vec3f(1.000000,0.719856,0.431970),
655
 
//      Vec3f(1.000000,0.712983,0.419247),
656
 
//      Vec3f(1.000000,0.706154,0.406675),
657
 
//      Vec3f(1.000000,0.699375,0.394265),
658
 
//      Vec3f(1.000000,0.692681,0.382075),
659
 
//      Vec3f(1.000000,0.686003,0.369976),
660
 
//      Vec3f(1.000000,0.679428,0.358120),
661
 
//      Vec3f(1.000000,0.672882,0.346373),
662
 
//      Vec3f(1.000000,0.666372,0.334740),
663
 
//      Vec3f(1.000000,0.659933,0.323281),
664
 
//      Vec3f(1.000000,0.653572,0.312004),
665
 
//      Vec3f(1.000000,0.647237,0.300812),
666
 
//      Vec3f(1.000000,0.640934,0.289709),
667
 
//      Vec3f(1.000000,0.634698,0.278755),
668
 
//      Vec3f(1.000000,0.628536,0.267954),
669
 
//      Vec3f(1.000000,0.622390,0.257200),
670
 
//      Vec3f(1.000000,0.616298,0.246551),
671
 
//      Vec3f(1.000000,0.610230,0.235952),
672
 
//      Vec3f(1.000000,0.604259,0.225522),
673
 
//      Vec3f(1.000000,0.598288,0.215083),
674
 
//      Vec3f(1.000000,0.592391,0.204756),
675
 
//      Vec3f(1.000000,0.586501,0.194416),
676
 
//      Vec3f(1.000000,0.580657,0.184120),
677
 
//      Vec3f(1.000000,0.574901,0.173930),
678
 
//      Vec3f(1.000000,0.569127,0.163645),
679
 
//      Vec3f(1.000000,0.563449,0.153455),
680
 
//      Vec3f(1.000000,0.557758,0.143147),
681
 
//      Vec3f(1.000000,0.552134,0.132843),
682
 
//      Vec3f(1.000000,0.546541,0.122458),
683
 
//      Vec3f(1.000000,0.540984,0.111966),
684
 
//      Vec3f(1.000000,0.535464,0.101340),
685
 
//      Vec3f(1.000000,0.529985,0.090543),
686
 
//      Vec3f(1.000000,0.524551,0.079292),
687
 
//      Vec3f(1.000000,0.519122,0.068489),
688
 
//      Vec3f(1.000000,0.513743,0.058236),
689
 
//      Vec3f(1.000000,0.508417,0.048515),
690
 
//      Vec3f(1.000000,0.503104,0.039232),
691
 
//      Vec3f(1.000000,0.497805,0.030373),
692
 
//      Vec3f(1.000000,0.492557,0.021982),
693
 
//      Vec3f(1.000000,0.487338,0.014007),
694
 
//      Vec3f(1.000000,0.482141,0.006417),
695
 
//      Vec3f(1.000000,0.477114,0.000000),
696
 
//      Vec3f(1.000000,0.473268,0.000000),
697
 
//      Vec3f(1.000000,0.469419,0.000000),
698
 
//      Vec3f(1.000000,0.465552,0.000000),
699
 
//      Vec3f(1.000000,0.461707,0.000000),
700
 
//      Vec3f(1.000000,0.457846,0.000000),
701
 
//      Vec3f(1.000000,0.453993,0.000000),
702
 
//      Vec3f(1.000000,0.450129,0.000000),
703
 
//      Vec3f(1.000000,0.446276,0.000000),
704
 
//      Vec3f(1.000000,0.442415,0.000000),
705
 
//      Vec3f(1.000000,0.438549,0.000000),
706
 
//      Vec3f(1.000000,0.434702,0.000000),
707
 
//      Vec3f(1.000000,0.430853,0.000000),
708
 
//      Vec3f(1.000000,0.426981,0.000000),
709
 
//      Vec3f(1.000000,0.423134,0.000000),
710
 
//      Vec3f(1.000000,0.419268,0.000000),
711
 
//      Vec3f(1.000000,0.415431,0.000000),
712
 
//      Vec3f(1.000000,0.411577,0.000000),
713
 
//      Vec3f(1.000000,0.407733,0.000000),
714
 
//      Vec3f(1.000000,0.403874,0.000000),
715
 
//      Vec3f(1.000000,0.400029,0.000000),
716
 
//      Vec3f(1.000000,0.396172,0.000000),
717
 
//      Vec3f(1.000000,0.392331,0.000000),
718
 
//      Vec3f(1.000000,0.388509,0.000000),
719
 
//      Vec3f(1.000000,0.384653,0.000000),
720
 
//      Vec3f(1.000000,0.380818,0.000000),
721
 
//      Vec3f(1.000000,0.376979,0.000000),
722
 
//      Vec3f(1.000000,0.373166,0.000000),
723
 
//      Vec3f(1.000000,0.369322,0.000000),
724
 
//      Vec3f(1.000000,0.365506,0.000000),
725
 
//      Vec3f(1.000000,0.361692,0.000000),
726
 
// };
727
 
 
728
 
// New colors
729
 
Vec3f SkyDrawer::colorTable[128] = {
730
 
        Vec3f(0.602745,0.713725,1.000000),
731
 
        Vec3f(0.604902,0.715294,1.000000),
732
 
        Vec3f(0.607059,0.716863,1.000000),
733
 
        Vec3f(0.609215,0.718431,1.000000),
734
 
        Vec3f(0.611372,0.720000,1.000000),
735
 
        Vec3f(0.613529,0.721569,1.000000),
736
 
        Vec3f(0.635490,0.737255,1.000000),
737
 
        Vec3f(0.651059,0.749673,1.000000),
738
 
        Vec3f(0.666627,0.762092,1.000000),
739
 
        Vec3f(0.682196,0.774510,1.000000),
740
 
        Vec3f(0.697764,0.786929,1.000000),
741
 
        Vec3f(0.713333,0.799347,1.000000),
742
 
        Vec3f(0.730306,0.811242,1.000000),
743
 
        Vec3f(0.747278,0.823138,1.000000),
744
 
        Vec3f(0.764251,0.835033,1.000000),
745
 
        Vec3f(0.781223,0.846929,1.000000),
746
 
        Vec3f(0.798196,0.858824,1.000000),
747
 
        Vec3f(0.812282,0.868236,1.000000),
748
 
        Vec3f(0.826368,0.877647,1.000000),
749
 
        Vec3f(0.840455,0.887059,1.000000),
750
 
        Vec3f(0.854541,0.896470,1.000000),
751
 
        Vec3f(0.868627,0.905882,1.000000),
752
 
        Vec3f(0.884627,0.916862,1.000000),
753
 
        Vec3f(0.900627,0.927843,1.000000),
754
 
        Vec3f(0.916627,0.938823,1.000000),
755
 
        Vec3f(0.932627,0.949804,1.000000),
756
 
        Vec3f(0.948627,0.960784,1.000000),
757
 
        Vec3f(0.964444,0.972549,1.000000),
758
 
        Vec3f(0.980261,0.984313,1.000000),
759
 
        Vec3f(0.996078,0.996078,1.000000),
760
 
        Vec3f(1.000000,1.000000,1.000000),
761
 
        Vec3f(1.000000,0.999643,0.999287),
762
 
        Vec3f(1.000000,0.999287,0.998574),
763
 
        Vec3f(1.000000,0.998930,0.997861),
764
 
        Vec3f(1.000000,0.998574,0.997148),
765
 
        Vec3f(1.000000,0.998217,0.996435),
766
 
        Vec3f(1.000000,0.997861,0.995722),
767
 
        Vec3f(1.000000,0.997504,0.995009),
768
 
        Vec3f(1.000000,0.997148,0.994296),
769
 
        Vec3f(1.000000,0.996791,0.993583),
770
 
        Vec3f(1.000000,0.996435,0.992870),
771
 
        Vec3f(1.000000,0.996078,0.992157),
772
 
        Vec3f(1.000000,0.991140,0.981554),
773
 
        Vec3f(1.000000,0.986201,0.970951),
774
 
        Vec3f(1.000000,0.981263,0.960349),
775
 
        Vec3f(1.000000,0.976325,0.949746),
776
 
        Vec3f(1.000000,0.971387,0.939143),
777
 
        Vec3f(1.000000,0.966448,0.928540),
778
 
        Vec3f(1.000000,0.961510,0.917938),
779
 
        Vec3f(1.000000,0.956572,0.907335),
780
 
        Vec3f(1.000000,0.951634,0.896732),
781
 
        Vec3f(1.000000,0.946695,0.886129),
782
 
        Vec3f(1.000000,0.941757,0.875526),
783
 
        Vec3f(1.000000,0.936819,0.864924),
784
 
        Vec3f(1.000000,0.931881,0.854321),
785
 
        Vec3f(1.000000,0.926942,0.843718),
786
 
        Vec3f(1.000000,0.922004,0.833115),
787
 
        Vec3f(1.000000,0.917066,0.822513),
788
 
        Vec3f(1.000000,0.912128,0.811910),
789
 
        Vec3f(1.000000,0.907189,0.801307),
790
 
        Vec3f(1.000000,0.902251,0.790704),
791
 
        Vec3f(1.000000,0.897313,0.780101),
792
 
        Vec3f(1.000000,0.892375,0.769499),
793
 
        Vec3f(1.000000,0.887436,0.758896),
794
 
        Vec3f(1.000000,0.882498,0.748293),
795
 
        Vec3f(1.000000,0.877560,0.737690),
796
 
        Vec3f(1.000000,0.872622,0.727088),
797
 
        Vec3f(1.000000,0.867683,0.716485),
798
 
        Vec3f(1.000000,0.862745,0.705882),
799
 
        Vec3f(1.000000,0.858617,0.695975),
800
 
        Vec3f(1.000000,0.854490,0.686068),
801
 
        Vec3f(1.000000,0.850362,0.676161),
802
 
        Vec3f(1.000000,0.846234,0.666254),
803
 
        Vec3f(1.000000,0.842107,0.656346),
804
 
        Vec3f(1.000000,0.837979,0.646439),
805
 
        Vec3f(1.000000,0.833851,0.636532),
806
 
        Vec3f(1.000000,0.829724,0.626625),
807
 
        Vec3f(1.000000,0.825596,0.616718),
808
 
        Vec3f(1.000000,0.821468,0.606811),
809
 
        Vec3f(1.000000,0.817340,0.596904),
810
 
        Vec3f(1.000000,0.813213,0.586997),
811
 
        Vec3f(1.000000,0.809085,0.577090),
812
 
        Vec3f(1.000000,0.804957,0.567183),
813
 
        Vec3f(1.000000,0.800830,0.557275),
814
 
        Vec3f(1.000000,0.796702,0.547368),
815
 
        Vec3f(1.000000,0.792574,0.537461),
816
 
        Vec3f(1.000000,0.788447,0.527554),
817
 
        Vec3f(1.000000,0.784319,0.517647),
818
 
        Vec3f(1.000000,0.784025,0.520882),
819
 
        Vec3f(1.000000,0.783731,0.524118),
820
 
        Vec3f(1.000000,0.783436,0.527353),
821
 
        Vec3f(1.000000,0.783142,0.530588),
822
 
        Vec3f(1.000000,0.782848,0.533824),
823
 
        Vec3f(1.000000,0.782554,0.537059),
824
 
        Vec3f(1.000000,0.782259,0.540294),
825
 
        Vec3f(1.000000,0.781965,0.543529),
826
 
        Vec3f(1.000000,0.781671,0.546765),
827
 
        Vec3f(1.000000,0.781377,0.550000),
828
 
        Vec3f(1.000000,0.781082,0.553235),
829
 
        Vec3f(1.000000,0.780788,0.556471),
830
 
        Vec3f(1.000000,0.780494,0.559706),
831
 
        Vec3f(1.000000,0.780200,0.562941),
832
 
        Vec3f(1.000000,0.779905,0.566177),
833
 
        Vec3f(1.000000,0.779611,0.569412),
834
 
        Vec3f(1.000000,0.779317,0.572647),
835
 
        Vec3f(1.000000,0.779023,0.575882),
836
 
        Vec3f(1.000000,0.778728,0.579118),
837
 
        Vec3f(1.000000,0.778434,0.582353),
838
 
        Vec3f(1.000000,0.778140,0.585588),
839
 
        Vec3f(1.000000,0.777846,0.588824),
840
 
        Vec3f(1.000000,0.777551,0.592059),
841
 
        Vec3f(1.000000,0.777257,0.595294),
842
 
        Vec3f(1.000000,0.776963,0.598530),
843
 
        Vec3f(1.000000,0.776669,0.601765),
844
 
        Vec3f(1.000000,0.776374,0.605000),
845
 
        Vec3f(1.000000,0.776080,0.608235),
846
 
        Vec3f(1.000000,0.775786,0.611471),
847
 
        Vec3f(1.000000,0.775492,0.614706),
848
 
        Vec3f(1.000000,0.775197,0.617941),
849
 
        Vec3f(1.000000,0.774903,0.621177),
850
 
        Vec3f(1.000000,0.774609,0.624412),
851
 
        Vec3f(1.000000,0.774315,0.627647),
852
 
        Vec3f(1.000000,0.774020,0.630883),
853
 
        Vec3f(1.000000,0.773726,0.634118),
854
 
        Vec3f(1.000000,0.773432,0.637353),
855
 
        Vec3f(1.000000,0.773138,0.640588),
856
 
        Vec3f(1.000000,0.772843,0.643824),
857
 
        Vec3f(1.000000,0.772549,0.647059),
858
 
};
859
 
 
860
 
static double Gamma(double gamma,double x)
861
 
{
862
 
        return ((x<=0.0) ? 0.0 : exp(gamma*log(x)));
863
 
}
864
 
 
865
 
static Vec3f Gamma(double gamma,const Vec3f &x)
866
 
{
867
 
        return Vec3f(Gamma(gamma,x[0]),Gamma(gamma,x[1]),Gamma(gamma,x[2]));
868
 
}
869
 
 
870
 
// Load B-V conversion parameters from config file
871
 
void SkyDrawer::initColorTableFromConfigFile(QSettings* conf) 
872
 
{
873
 
        std::map<float,Vec3f> color_map;
874
 
        for (float bV=-0.5f;bV<=4.0f;bV+=0.01) 
875
 
        {
876
 
                char entry[256];
877
 
                sprintf(entry,"bv_color_%+5.2f",bV);
878
 
                const QStringList s(conf->value(QString("stars/") + entry).toStringList());
879
 
                if (!s.isEmpty())
880
 
                {
881
 
                        Vec3f c;
882
 
                        if (s.size()==1)
883
 
                                c = StelUtils::strToVec3f(s[0]);
884
 
                        else
885
 
                                c =StelUtils::strToVec3f(s);
886
 
                        color_map[bV] = Gamma(eye->getDisplayGamma(),c);
887
 
                }
888
 
        }
889
 
 
890
 
        if (color_map.size() > 1) 
891
 
        {
892
 
                for (int i=0;i<128;i++) 
893
 
                {
894
 
                        const float bV = SkyDrawer::indexToBV(i);
895
 
                        std::map<float,Vec3f>::const_iterator greater(color_map.upper_bound(bV));
896
 
                        if (greater == color_map.begin()) 
897
 
                        {
898
 
                                colorTable[i] = greater->second;
899
 
                        } 
900
 
                        else 
901
 
                        {
902
 
                                std::map<float,Vec3f>::const_iterator less(greater);--less;
903
 
                                if (greater == color_map.end()) 
904
 
                                {
905
 
                                        colorTable[i] = less->second;
906
 
                                } 
907
 
                                else 
908
 
                                {
909
 
                                        colorTable[i] = Gamma(1.f/eye->getDisplayGamma(), ((bV-less->first)*greater->second + (greater->first-bV)*less->second) *(1.f/(greater->first-less->first)));
910
 
                                }
911
 
                        }
912
 
                }
913
 
        }
914
 
 
915
 
//      QString res;
916
 
//      for (int i=0;i<128;i++) 
917
 
//      {
918
 
//              res += QString("Vec3f(%1,%2,%3),\n").arg(colorTable[i][0], 0, 'g', 6).arg(colorTable[i][1], 0, 'g', 6).arg(colorTable[i][2], 0, 'g', 6);
919
 
//      }
920
 
//      qDebug() << res;
921
 
}