Merge lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium

Proposed by Alexander Wolf
Status: Merged
Merged at revision: 7109
Proposed branch: lp:~georg-zotti/stellarium/gz_milkyway-extinction
Merge into: lp:stellarium
Diff against target: 1165 lines (+376/-105)
17 files modified
src/core/RefractionExtinction.hpp (+1/-1)
src/core/StelObject.cpp (+1/-1)
src/core/StelObject.hpp (+1/-1)
src/core/StelPainter.cpp (+200/-40)
src/core/StelPainter.hpp (+22/-7)
src/core/StelProjector.hpp (+1/-1)
src/core/StelSphereGeometry.cpp (+4/-2)
src/core/StelSphereGeometry.hpp (+1/-1)
src/core/StelUtils.cpp (+8/-12)
src/core/StelUtils.hpp (+1/-3)
src/core/StelVertexArray.cpp (+3/-1)
src/core/StelVertexArray.hpp (+61/-17)
src/core/modules/Landscape.cpp (+1/-1)
src/core/modules/MilkyWay.cpp (+68/-15)
src/core/modules/MilkyWay.hpp (+1/-1)
src/core/modules/Nebula.hpp (+1/-0)
src/gui/LocationDialog.hpp (+1/-1)
To merge this branch: bzr merge lp:~georg-zotti/stellarium/gz_milkyway-extinction
Reviewer Review Type Date Requested Status
gzotti Approve
Fabien Chéreau Needs Information
Alexander Wolf Approve
Review via email: mp+239766@code.launchpad.net

This proposal supersedes a proposal from 2014-10-17.

Description of the change

I finally managed to add extinction to the Milky Way (and other extended objects could have the same now.) I added some comments where the new items are, these will be cleaned up during merge. I had to change the Milky Way texture (now half the size without loss of function).

To post a comment you must log in.
Revision history for this message
Fabien Chéreau (xalioth) wrote : Posted in a previous version of this proposal
Download full text (53.1 KiB)

Hi, thanks for the contribution!
Somehow I'm a bit afraid by the large change and the impact on
performances...

I wonder if there is not a much simpler way more in line with the way
refraction was done, I.e. process extinction more at projection time by
passing the vertex color in the project function.

Fabien
Le 17 oct. 2014 16:29, "gzotti" <email address hidden> a écrit :

> gzotti has proposed merging
> lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium.
>
> Commit message:
> Extinction for Milky Way
>
> Requested reviews:
> Stellarium (stellarium)
>
> For more details, see:
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/238721
>
> I finally managed to add extinction to the Milky Way (and other extended
> objects could have the same now.) I added some comments where the new items
> are, these will be cleaned up during merge. I had to change the Milky Way
> texture (now half the size without loss of function).
>
>
> --
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/238721
> You are subscribed to branch lp:stellarium.
>
> === modified file 'src/core/RefractionExtinction.hpp'
> --- src/core/RefractionExtinction.hpp 2013-11-15 14:34:44 +0000
> +++ src/core/RefractionExtinction.hpp 2014-10-17 14:28:29 +0000
> @@ -45,7 +45,7 @@
> class Extinction
> {
> public:
> - //! Define the extinction strategy for rendering underground
> objects (usefull when ground is not rendered)
> + //! Define the extinction strategy for rendering underground
> objects (useful when ground is not rendered)
> enum UndergroundExtinctionMode {
> UndergroundExtinctionZero = 0, //!< Zero extinction:
> stars visible in full brightness
> UndergroundExtinctionMax = 1, //!< Maximum extinction:
> coef 42, i.e practically invisible
>
> === modified file 'src/core/StelCore.hpp'
> --- src/core/StelCore.hpp 2014-10-05 11:32:51 +0000
> +++ src/core/StelCore.hpp 2014-10-17 14:28:29 +0000
> @@ -198,6 +198,7 @@
> Vec3d altAzToJ2000(const Vec3d& v, RefractionMode
> refMode=RefractionAuto) const;
> Vec3d j2000ToAltAz(const Vec3d& v, RefractionMode
> refMode=RefractionAuto) const;
> void j2000ToAltAzInPlaceNoRefraction(Vec3f* v) const
> {v->transfo4d(matJ2000ToAltAz);}
> + void j2000ToAltAzInPlaceNoRefraction(Vec3d* v) const
> {v->transfo4d(matJ2000ToAltAz);} // GZ NEW for milky way
> Vec3d galacticToJ2000(const Vec3d& v) const;
> Vec3d equinoxEquToJ2000(const Vec3d& v) const;
> Vec3d j2000ToEquinoxEqu(const Vec3d& v) const;
>
> === modified file 'src/core/StelPainter.cpp'
> --- src/core/StelPainter.cpp 2014-06-06 04:26:56 +0000
> +++ src/core/StelPainter.cpp 2014-10-17 14:28:29 +0000
> @@ -699,7 +699,7 @@
> // Project the passed triangle on the screen ensuring that it will look
> smooth, even for non linear distortion
> // by splitting it into subtriangles.
> void StelPainter::projectSphericalTriangle(const SphericalCap*
> clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>*
> outVertices,
> - const Vec2f* texturePos, QVarLengthAr...

Revision history for this message
Alexander Wolf (alexwolf) wrote : Posted in a previous version of this proposal

It's a very good feature! I checked the performance but this parameter not changed on my linux-box.

review: Approve
Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

Fabien, do you mean in StelPainter::projectArray() or even prj->project()? At this step we need azimuthal coordinates, I don't see how I could extract those from this overall projection to viewport. Where can this be done?

The longest change in code was the required extension of StelPainter into actually being able to use vertex color arrays - the shader was already here, but StelVertexArray had no color array.

I had to increase Milky Way vertex density for better accuracy, but decreased overall spherical coverage by removing half of the texture (the black parts at the poles) and so also removed about half the required vertices.

I don't know how often update() is called. If less frequently than draw() but still every few frames, the extinction loop could also go there.

I will try to test equal setups of trunk vs. this for performance comparison.

Revision history for this message
Fabien Chéreau (xalioth) wrote : Posted in a previous version of this proposal

Well in fact you are right, there is no other easy way to deal with a color modulation, excepted maybe by computing the extinction directly in the vertex shader (by revert projecting the 2D vertices to get the original 3D vertex).

So the remaining comments are more minor ones:
 - please avoid to add // GZ in comments, it doesn't makes sense to the reader in the long term
 - please cleanup debug stuff
 - For simplicity I would also avoid the draw a ring but rather the full sphere with the higher resolution texture. We would really need a better 1024x512 milky way texture by the way. I do have one from mellinger that I re-processed that he allowed us to use. I'll send it to you by email.

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

OK. Settings: all default, debug builds. Today evening, Stereographic, 138°fov, FullHD, NVidia GTX580M.

Original trunk, 20x20 vertices, : 97fps. Atmosphere off: 108fps.

Milky Way with 72x18: 79fps
Milky Way with 48x15: 86fps
Milky Way with 45x15: 87fps
Milky Way with 40x15: 88fps (same. All figures went up/down by about +/- 1fps.)
Atmosphere off: 108fps
Putting the extinction loop in update(): no noticeable change (Is update called for every frame?)

So I think somewhere 40x15 should stay, if not better. This means a grid of 9x6 degrees, I would not want to go anywhere larger given the fast increase of extinction below 10 degrees. Yes, there is a penalty with the new function, but in the release builds I usually had almost 200fps, so I think there is ample reserve. But if there is a faster way, I don't see it, please show it to me.
Would it be useful to add a configuration option for this? I mean, extinction is one of the hi-quality features of this program, so it should be applied to all visible objects.

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

Most of the "GZs" are to be removed during merge. They are just to show where I have changed things or explain things to reviewers. Is it OK to remove MilkyWay.cpp:912ff, the original X/Y/Z rotations?

The texture resolution was only 512x512. Removing black parts leave 512x256. Replacing the sphere by the ring avoids about half of the vertices which are only black, so I do think this makes sense. But yes, a higher res drop-in replacement texture would be very welcome!

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

I think it looks fine now. Any further objections?

review: Needs Resubmitting
Revision history for this message
Alexander Wolf (alexwolf) wrote :

I think this branch ready for merge. Maybe here required some calibration for brightness of Milky Way, but it can be solved in trunk.

review: Approve
Revision history for this message
Fabien Chéreau (xalioth) wrote :

I'm still not quite fond of the ring trick as it will make it harder for people to change the milky way map, some people like to use other images such as infrared maps etc..

What about we keep it simple for now with a full sphere, and try to optimize the nominal code rather than this way?

Revision history for this message
Fabien Chéreau (xalioth) :
review: Needs Information
Revision history for this message
gzotti (georg-zotti) wrote :

Hu?

I am now using your new texture, and must therefore use a full sphere.
Although I would prefer the ring with a reprojected texture without poles.

G.

Revision history for this message
Fabien Chéreau (xalioth) wrote :

Ooops, I read too quickly. then in this case fine for me for merging,
thanks!

On Mon, Oct 27, 2014 at 10:30 PM, gzotti <email address hidden> wrote:

> Hu?
>
> I am now using your new texture, and must therefore use a full sphere.
> Although I would prefer the ring with a reprojected texture without poles.
>
> G.
>
>
> --
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/239766
> You are reviewing the proposed merge of
> lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium.
>

Revision history for this message
gzotti (georg-zotti) wrote :

Of course I agree :-) I will cleanup some intermediate lines after merge.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/core/RefractionExtinction.hpp'
2--- src/core/RefractionExtinction.hpp 2013-11-15 14:34:44 +0000
3+++ src/core/RefractionExtinction.hpp 2014-10-27 19:13:24 +0000
4@@ -45,7 +45,7 @@
5 class Extinction
6 {
7 public:
8- //! Define the extinction strategy for rendering underground objects (usefull when ground is not rendered)
9+ //! Define the extinction strategy for rendering underground objects (useful when ground is not rendered)
10 enum UndergroundExtinctionMode {
11 UndergroundExtinctionZero = 0, //!< Zero extinction: stars visible in full brightness
12 UndergroundExtinctionMax = 1, //!< Maximum extinction: coef 42, i.e practically invisible
13
14=== modified file 'src/core/StelObject.cpp'
15--- src/core/StelObject.cpp 2014-10-26 11:18:06 +0000
16+++ src/core/StelObject.cpp 2014-10-27 19:13:24 +0000
17@@ -100,7 +100,7 @@
18 Vec3d altAzPos = getAltAzPosGeometric(core);
19 altAzPos.normalize();
20 float vMag = getVMagnitude(core);
21- // GZ 2014-01-02: without the test, planets flicker stupidly in fullsky atmosphere-less view.
22+ // without the test, planets flicker stupidly in fullsky atmosphere-less view.
23 if (core->getSkyDrawer()->getFlagHasAtmosphere())
24 core->getSkyDrawer()->getExtinction().forward(altAzPos, &vMag);
25 return vMag;
26
27=== modified file 'src/core/StelObject.hpp'
28--- src/core/StelObject.hpp 2014-07-31 10:51:23 +0000
29+++ src/core/StelObject.hpp 2014-10-27 19:13:24 +0000
30@@ -134,7 +134,7 @@
31 virtual float getVMagnitude(const StelCore* core) const;
32
33 //! Return object's apparent V magnitude as seen from observer including extinction.
34- //! GZ 2014-01-02: Extinction obviously only if atmosphere=on.
35+ //! Extinction obviously only if atmosphere=on.
36 float getVMagnitudeWithExtinction(const StelCore* core) const;
37
38 //! Return a priority value which is used to discriminate objects by priority
39
40=== modified file 'src/core/StelPainter.cpp'
41--- src/core/StelPainter.cpp 2014-06-06 04:26:56 +0000
42+++ src/core/StelPainter.cpp 2014-10-27 19:13:24 +0000
43@@ -699,7 +699,7 @@
44 // Project the passed triangle on the screen ensuring that it will look smooth, even for non linear distortion
45 // by splitting it into subtriangles.
46 void StelPainter::projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,
47- const Vec2f* texturePos, QVarLengthArray<Vec2f, 4096>* outTexturePos,
48+ const Vec2f* texturePos, QVarLengthArray<Vec2f, 4096>* outTexturePos, const Vec3f *colors, QVarLengthArray<Vec3f, 4096> *outColors,
49 const double maxSqDistortion, const int nbI, const bool checkDisc1, const bool checkDisc2, const bool checkDisc3) const
50 {
51 Q_ASSERT(fabs(vertices[0].length()-1.)<0.00001);
52@@ -758,6 +758,8 @@
53 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e1[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));
54 if (outTexturePos)
55 outTexturePos->append(texturePos,3);
56+ if (outColors)
57+ outColors->append(colors,3);
58 return;
59 }
60
61@@ -772,6 +774,8 @@
62 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e2[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));
63 if (outTexturePos)
64 outTexturePos->append(texturePos,3);
65+ if (outColors)
66+ outColors->append(colors,3);
67 return;
68 }
69
70@@ -779,6 +783,7 @@
71 // Depending on which combination of sides of the triangle has to be split a different strategy is used.
72 Vec3d va[3];
73 Vec2f ta[3];
74+ Vec3f ca[3];
75 // Only 1 side has to be split: split the triangle in 2
76 if (cDiscontinuity1 && !cDiscontinuity2 && !cDiscontinuity3)
77 {
78@@ -792,7 +797,13 @@
79 ta[1]=(texturePos[0]+texturePos[1])*0.5;
80 ta[2]=texturePos[2];
81 }
82- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);
83+ if (outColors)
84+ {
85+ ca[0]=colors[0];
86+ ca[1]=(colors[0]+colors[1])*0.5;
87+ ca[2]=colors[2];
88+ }
89+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
90
91 //va[0]=vertices[0]+vertices[1];
92 //va[0].normalize();
93@@ -805,7 +816,13 @@
94 ta[1]=texturePos[1];
95 ta[2]=texturePos[2];
96 }
97- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);
98+ if (outColors)
99+ {
100+ ca[0]=(colors[0]+colors[1])*0.5;
101+ ca[1]=colors[1];
102+ ca[2]=colors[2];
103+ }
104+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
105 return;
106 }
107
108@@ -821,7 +838,13 @@
109 ta[1]=texturePos[1];
110 ta[2]=(texturePos[1]+texturePos[2])*0.5;
111 }
112- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);
113+ if (outColors)
114+ {
115+ ca[0]=colors[0];
116+ ca[1]=colors[1];
117+ ca[2]=(colors[1]+colors[2])*0.5;
118+ }
119+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
120
121 va[0]=vertices[0];
122 //va[1]=vertices[1]+vertices[2];
123@@ -834,7 +857,13 @@
124 ta[1]=(texturePos[1]+texturePos[2])*0.5;
125 ta[2]=texturePos[2];
126 }
127- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);
128+ if (outColors)
129+ {
130+ ca[0]=colors[0];
131+ ca[1]=(colors[1]+colors[2])*0.5;
132+ ca[2]=colors[2];
133+ }
134+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
135 return;
136 }
137
138@@ -850,7 +879,13 @@
139 ta[1]=texturePos[1];
140 ta[2]=(texturePos[0]+texturePos[2])*0.5;
141 }
142- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);
143+ if (outColors)
144+ {
145+ ca[0]=colors[0];
146+ ca[1]=colors[1];
147+ ca[2]=(colors[0]+colors[2])*0.5;
148+ }
149+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
150
151 //va[0]=vertices[0]+vertices[2];
152 //va[0].normalize();
153@@ -863,7 +898,13 @@
154 ta[1]=texturePos[1];
155 ta[2]=texturePos[2];
156 }
157- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);
158+ if (outColors)
159+ {
160+ ca[0]=(colors[0]+colors[2])*0.5;
161+ ca[1]=colors[1];
162+ ca[2]=colors[2];
163+ }
164+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
165 return;
166 }
167
168@@ -881,7 +922,13 @@
169 ta[1]=(texturePos[0]+texturePos[1])*0.5;
170 ta[2]=(texturePos[1]+texturePos[2])*0.5;
171 }
172- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
173+ if (outColors)
174+ {
175+ ca[0]=colors[0];
176+ ca[1]=(colors[0]+colors[1])*0.5;
177+ ca[2]=(colors[1]+colors[2])*0.5;
178+ }
179+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
180
181 //va[0]=vertices[0]+vertices[1];
182 //va[0].normalize();
183@@ -895,7 +942,13 @@
184 ta[1]=texturePos[1];
185 ta[2]=(texturePos[1]+texturePos[2])*0.5;
186 }
187- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
188+ if (outColors)
189+ {
190+ ca[0]=(colors[0]+colors[1])*0.5;
191+ ca[1]=colors[1];
192+ ca[2]=(colors[1]+colors[2])*0.5;
193+ }
194+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
195
196 va[0]=vertices[0];
197 //va[1]=vertices[1]+vertices[2];
198@@ -908,7 +961,13 @@
199 ta[1]=(texturePos[1]+texturePos[2])*0.5;
200 ta[2]=texturePos[2];
201 }
202- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);
203+ if (outColors)
204+ {
205+ ca[0]=colors[0];
206+ ca[1]=(colors[1]+colors[2])*0.5;
207+ ca[2]=colors[2];
208+ }
209+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
210 return;
211 }
212 if (cDiscontinuity1 && !cDiscontinuity2 && cDiscontinuity3)
213@@ -924,7 +983,13 @@
214 ta[1]=(texturePos[0]+texturePos[1])*0.5;
215 ta[2]=(texturePos[0]+texturePos[2])*0.5;
216 }
217- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
218+ if (outColors)
219+ {
220+ ca[0]=colors[0];
221+ ca[1]=(colors[0]+colors[1])*0.5;
222+ ca[2]=(colors[0]+colors[2])*0.5;
223+ }
224+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
225
226 //va[0]=vertices[0]+vertices[1];
227 //va[0].normalize();
228@@ -938,7 +1003,13 @@
229 ta[1]=texturePos[2];
230 ta[2]=(texturePos[0]+texturePos[2])*0.5;
231 }
232- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
233+ if (outColors)
234+ {
235+ ca[0]=(colors[0]+colors[1])*0.5;
236+ ca[1]=colors[2];
237+ ca[2]=(colors[0]+colors[2])*0.5;
238+ }
239+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
240
241
242 //va[0]=vertices[0]+vertices[1];
243@@ -951,7 +1022,13 @@
244 ta[1]=texturePos[1];
245 ta[2]=texturePos[2];
246 }
247- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);
248+ if (outColors)
249+ {
250+ ca[0]=(colors[0]+colors[1])*0.5;
251+ ca[1]=colors[1];
252+ ca[2]=colors[2];
253+ }
254+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
255
256 return;
257 }
258@@ -967,7 +1044,13 @@
259 ta[1]=texturePos[1];
260 ta[2]=(texturePos[1]+texturePos[2])*0.5;
261 }
262- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);
263+ if (outColors)
264+ {
265+ ca[0]=colors[0];
266+ ca[1]=colors[1];
267+ ca[2]=(colors[1]+colors[2])*0.5;
268+ }
269+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
270
271 //va[0]=vertices[1]+vertices[2];
272 //va[0].normalize();
273@@ -981,7 +1064,13 @@
274 ta[1]=texturePos[2];
275 ta[2]=(texturePos[0]+texturePos[2])*0.5;
276 }
277- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
278+ if (outColors)
279+ {
280+ ca[0]=(colors[1]+colors[2])*0.5;
281+ ca[1]=colors[2];
282+ ca[2]=(colors[0]+colors[2])*0.5;
283+ }
284+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
285
286 va[1]=va[0];
287 va[0]=vertices[0];
288@@ -995,7 +1084,13 @@
289 ta[1]=(texturePos[1]+texturePos[2])*0.5;
290 ta[2]=(texturePos[0]+texturePos[2])*0.5;
291 }
292- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
293+ if (outColors)
294+ {
295+ ca[0]=colors[0];
296+ ca[1]=(colors[1]+colors[2])*0.5;
297+ ca[2]=(colors[0]+colors[2])*0.5;
298+ }
299+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
300 return;
301 }
302
303@@ -1012,7 +1107,13 @@
304 ta[1]=(texturePos[1]+texturePos[2])*0.5;
305 ta[2]=(texturePos[0]+texturePos[2])*0.5;
306 }
307- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
308+ if (outColors)
309+ {
310+ ca[0]=(colors[0]+colors[1])*0.5;
311+ ca[1]=(colors[1]+colors[2])*0.5;
312+ ca[2]=(colors[0]+colors[2])*0.5;
313+ }
314+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
315
316 va[1]=va[0];
317 va[0]=vertices[0];
318@@ -1026,7 +1127,13 @@
319 ta[1]=(texturePos[0]+texturePos[1])*0.5;
320 ta[2]=(texturePos[0]+texturePos[2])*0.5;
321 }
322- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
323+ if (outColors)
324+ {
325+ ca[0]=colors[0];
326+ ca[1]=(colors[0]+colors[1])*0.5;
327+ ca[2]=(colors[0]+colors[2])*0.5;
328+ }
329+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
330
331 //va[0]=vertices[0]+vertices[1];
332 //va[0].normalize();
333@@ -1040,7 +1147,13 @@
334 ta[1]=texturePos[1];
335 ta[2]=(texturePos[1]+texturePos[2])*0.5;
336 }
337- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
338+ if (outColors)
339+ {
340+ ca[0]=(colors[0]+colors[1])*0.5;
341+ ca[1]=colors[1];
342+ ca[2]=(colors[1]+colors[2])*0.5;
343+ }
344+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
345
346 va[0]=vertices[0];va[0]+=vertices[2];
347 va[0].normalize();
348@@ -1054,13 +1167,20 @@
349 ta[1]=(texturePos[1]+texturePos[2])*0.5;
350 ta[2]=texturePos[2];
351 }
352- projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);
353+ if (outColors)
354+ {
355+ ca[0]=(colors[0]+colors[2])*0.5;
356+ ca[1]=(colors[1]+colors[2])*0.5;
357+ ca[2]=colors[2];
358+ }
359+ projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
360
361 return;
362 }
363
364 static QVarLengthArray<Vec3f, 4096> polygonVertexArray;
365 static QVarLengthArray<Vec2f, 4096> polygonTextureCoordArray;
366+static QVarLengthArray<Vec3f, 4096> polygonColorArray;
367 static QVarLengthArray<unsigned int, 4096> indexArray;
368
369 void StelPainter::drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap)
370@@ -1097,26 +1217,38 @@
371 {
372 public:
373 VertexArrayProjector(const StelVertexArray& ar, StelPainter* apainter, const SphericalCap* aclippingCap,
374- QVarLengthArray<Vec3f, 4096>* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL, double amaxSqDistortion=5.)
375+ QVarLengthArray<Vec3f, 4096>* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL, QVarLengthArray<Vec3f, 4096>* aoutColors=NULL, double amaxSqDistortion=5.)
376 : vertexArray(ar), painter(apainter), clippingCap(aclippingCap), outVertices(aoutVertices),
377- outTexturePos(aoutTexturePos), maxSqDistortion(amaxSqDistortion)
378+ outColors(aoutColors), outTexturePos(aoutTexturePos), maxSqDistortion(amaxSqDistortion)
379 {
380 }
381
382 // Project a single triangle and add it into the output arrays
383 inline void operator()(const Vec3d* v0, const Vec3d* v1, const Vec3d* v2,
384 const Vec2f* t0, const Vec2f* t1, const Vec2f* t2,
385+ const Vec3f* c0, const Vec3f* c1, const Vec3f* c2,
386 unsigned int, unsigned int, unsigned)
387 {
388 // XXX: we may optimize more by putting the declaration and the test outside of this method.
389 const Vec3d tmpVertex[3] = {*v0, *v1, *v2};
390- if (outTexturePos)
391- {
392- const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
393- painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, maxSqDistortion);
394+ if ( (outTexturePos) && (outColors))
395+ {
396+ const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
397+ const Vec3f tmpColor[3] = {*c0, *c1, *c2};
398+ painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, tmpColor, outColors, maxSqDistortion);
399+ }
400+ else if (outTexturePos)
401+ {
402+ const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
403+ painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, NULL, NULL, maxSqDistortion);
404+ }
405+ else if (outColors)
406+ {
407+ const Vec3f tmpColor[3] = {*c0, *c1, *c2};
408+ painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, tmpColor, outColors, maxSqDistortion);
409 }
410 else
411- painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, maxSqDistortion);
412+ painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, NULL, NULL, maxSqDistortion);
413 }
414
415 // Draw the resulting arrays
416@@ -1125,7 +1257,10 @@
417 painter->setVertexPointer(3, GL_FLOAT, outVertices->constData());
418 if (outTexturePos)
419 painter->setTexCoordPointer(2, GL_FLOAT, outTexturePos->constData());
420- painter->enableClientStates(true, outTexturePos != NULL);
421+ if (outColors)
422+ painter->setColorPointer(3, GL_FLOAT, outColors->constData());
423+
424+ painter->enableClientStates(true, outTexturePos != NULL, outColors != NULL);
425 painter->drawFromArray(StelPainter::Triangles, outVertices->size(), 0, false);
426 painter->enableClientStates(false);
427 }
428@@ -1135,6 +1270,7 @@
429 StelPainter* painter;
430 const SphericalCap* clippingCap;
431 QVarLengthArray<Vec3f, 4096>* outVertices;
432+ QVarLengthArray<Vec3f, 4096>* outColors;
433 QVarLengthArray<Vec2f, 4096>* outTexturePos;
434 double maxSqDistortion;
435 };
436@@ -1152,11 +1288,23 @@
437 if (arr.isTextured())
438 {
439 setTexCoordPointer(2, GL_FLOAT, arr.texCoords.constData());
440- enableClientStates(true, true);
441+ if (arr.isColored())
442+ {
443+ setColorPointer(3, GL_FLOAT, arr.colors.constData());
444+ enableClientStates(true, true, true);
445+ }
446+ else
447+ enableClientStates(true, true, false);
448 }
449 else
450 {
451- enableClientStates(true, false);
452+ if (arr.isColored())
453+ {
454+ setColorPointer(3, GL_FLOAT, arr.colors.constData());
455+ enableClientStates(true, false, true);
456+ }
457+ else
458+ enableClientStates(true, false, false);
459 }
460 if (arr.isIndexed())
461 drawFromArray((StelPainter::DrawingMode)arr.primitiveType, arr.indices.size(), 0, true, arr.indices.constData());
462@@ -1166,7 +1314,7 @@
463 enableClientStates(false);
464 }
465
466-void StelPainter::drawSphericalTriangles(const StelVertexArray& va, const bool textured, const SphericalCap* clippingCap, const bool doSubDivide, const double maxSqDistortion)
467+void StelPainter::drawSphericalTriangles(const StelVertexArray& va, const bool textured, const bool colored, const SphericalCap* clippingCap, const bool doSubDivide, const double maxSqDistortion)
468 {
469 if (va.vertex.isEmpty())
470 return;
471@@ -1174,6 +1322,7 @@
472 Q_ASSERT(va.vertex.size()>2);
473 polygonVertexArray.clear();
474 polygonTextureCoordArray.clear();
475+
476 indexArray.clear();
477
478 if (!doSubDivide)
479@@ -1186,7 +1335,7 @@
480 // the last case. It is the slowest, it process the triangles one by one.
481 {
482 // Project all the triangles of the VertexArray into our buffer arrays.
483- VertexArrayProjector result = va.foreachTriangle(VertexArrayProjector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTextureCoordArray : NULL, maxSqDistortion));
484+ VertexArrayProjector result = va.foreachTriangle(VertexArrayProjector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTextureCoordArray : NULL, colored ? &polygonColorArray : NULL, maxSqDistortion));
485 result.drawResult();
486 return;
487 }
488@@ -1211,7 +1360,8 @@
489 glEnable(GL_CULL_FACE);
490 // The polygon is already tesselated as triangles
491 if (doSubDivise || prj->intersectViewportDiscontinuity(poly->getBoundingCap()))
492- drawSphericalTriangles(poly->getFillVertexArray(), drawMode==SphericalPolygonDrawModeTextureFill, clippingCap, doSubDivise, maxSqDistortion);
493+ // flag for color-modulated textured mode (e.g. for Milky Way/extincted)
494+ drawSphericalTriangles(poly->getFillVertexArray(), drawMode>=SphericalPolygonDrawModeTextureFill, drawMode==SphericalPolygonDrawModeTextureFillColormodulated, clippingCap, doSubDivise, maxSqDistortion);
495 else
496 drawStelVertexArray(poly->getFillVertexArray(), false);
497
498@@ -1373,7 +1523,7 @@
499
500 ///////////////////////////////////////////////////////////////////////////
501 // Drawing methods for general (non-linear) mode.
502-// GZ This used to draw a full sphere. Now it's possible to have a spherical zone only.
503+// This used to draw a full sphere. Since 0.13 it's possible to have a spherical zone only.
504 void StelPainter::sSphere(const float radius, const float oneMinusOblateness, const int slices, const int stacks, const int orientInside, const bool flipTexture, const float topAngle, const float bottomAngle)
505 {
506 GLfloat x, y, z;
507@@ -1394,14 +1544,14 @@
508
509 const float* cos_sin_rho = NULL;
510 Q_ASSERT(topAngle<bottomAngle); // don't forget: These are opening angles counted from top.
511- if ((bottomAngle>3.1415) && (topAngle<0.0001)) // safety margin.
512+ if ((bottomAngle>3.1415f) && (topAngle<0.0001f)) // safety margin.
513 cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);
514 else
515 {
516 const float drho = (bottomAngle-topAngle) / stacks; // deltaRho: originally just 180degrees/stacks, now the range clamped.
517 cos_sin_rho = StelUtils::ComputeCosSinRhoZone(drho, stacks, M_PI-bottomAngle);
518 }
519- // GZ: Allow parameters so that pole regions may remain free.
520+ // Allow parameters so that pole regions may remain free.
521 const float* cos_sin_rho_p;
522
523 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);
524@@ -1414,7 +1564,7 @@
525 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
526 const GLfloat dt = nsign / stacks; // from inside texture is reversed
527
528- // draw intermediate as quad strips
529+ // draw intermediate as quad strips
530 static QVector<double> vertexArr;
531 static QVector<float> texCoordArr;
532 static QVector<float> colorArr;
533@@ -1456,7 +1606,8 @@
534 drawFromArray(Triangles, indiceArr.size(), 0, true, indiceArr.constData());
535 }
536
537-StelVertexArray StelPainter::computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks, const int orientInside, const bool flipTexture)
538+StelVertexArray StelPainter::computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks,
539+ const int orientInside, const bool flipTexture, const float topAngle, const float bottomAngle)
540 {
541 StelVertexArray result(StelVertexArray::Triangles);
542 GLfloat x, y, z;
543@@ -1474,7 +1625,16 @@
544 t=1.f;
545 }
546
547- const float* cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);
548+ const float* cos_sin_rho = NULL; //StelUtils::ComputeCosSinRho(stacks);
549+ Q_ASSERT(topAngle<bottomAngle); // don't forget: These are opening angles counted from top.
550+ if ((bottomAngle>3.1415f) && (topAngle<0.0001f)) // safety margin.
551+ cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);
552+ else
553+ {
554+ const float drho = (bottomAngle-topAngle) / stacks; // deltaRho: originally just 180degrees/stacks, now the range clamped.
555+ cos_sin_rho = StelUtils::ComputeCosSinRhoZone(drho, stacks, M_PI-bottomAngle);
556+ }
557+ // Allow parameters so that pole regions may remain free.
558 const float* cos_sin_rho_p;
559
560 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);
561@@ -1487,7 +1647,7 @@
562 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
563 const GLfloat dt = nsign / stacks; // from inside texture is reversed
564
565- // draw intermediate as quad strips
566+ // draw intermediate as quad strips
567 for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_p+=2)
568 {
569 s = !flipTexture ? 0.f : 1.f;
570
571=== modified file 'src/core/StelPainter.hpp'
572--- src/core/StelPainter.hpp 2014-06-10 19:20:20 +0000
573+++ src/core/StelPainter.hpp 2014-10-27 19:13:24 +0000
574@@ -45,9 +45,10 @@
575 //! Define the drawing mode when drawing polygons
576 enum SphericalPolygonDrawMode
577 {
578- SphericalPolygonDrawModeFill=0, //!< Draw the interior of the polygon
579- SphericalPolygonDrawModeBoundary=1, //!< Draw the boundary of the polygon
580- SphericalPolygonDrawModeTextureFill=2 //!< Draw the interior of the polygon filled with the current texture
581+ SphericalPolygonDrawModeFill=0, //!< Draw the interior of the polygon
582+ SphericalPolygonDrawModeBoundary=1, //!< Draw the boundary of the polygon
583+ SphericalPolygonDrawModeTextureFill=2, //!< Draw the interior of the polygon filled with the current texture
584+ SphericalPolygonDrawModeTextureFillColormodulated=3 //!< Draw the interior of the polygon filled with the current texture multiplied by vertex colors
585 };
586
587 //! Define the drawing mode when drawing vertex
588@@ -97,7 +98,7 @@
589
590 void drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap=NULL);
591
592- void drawSphericalTriangles(const StelVertexArray& va, const bool textured, const SphericalCap* clippingCap=NULL, const bool doSubDivide=true, const double maxSqDistortion=5.);
593+ void drawSphericalTriangles(const StelVertexArray& va, const bool textured, const bool colored, const SphericalCap* clippingCap=NULL, const bool doSubDivide=true, const double maxSqDistortion=5.);
594
595 //! Draw a small circle arc between points start and stop with rotation point in rotCenter.
596 //! The angle between start and stop must be < 180 deg.
597@@ -165,7 +166,7 @@
598 //! @param slices: number of vertical segments ("meridian zones")
599 //! @param stacks: number of horizontal segments ("latitude zones")
600 //! @param orientInside: 1 to have normals point inside, e.g. for landscape horizons
601- //! @param flipTexture: if texture should be mapped to inside of shere, e.g. landscape horizons.
602+ //! @param flipTexture: if texture should be mapped to inside of sphere, e.g. landscape horizons.
603 //! @param topAngle GZ: new parameter. An opening angle [radians] at top of the sphere. Useful if there is an empty
604 //! region around the top pole, like for a spherical equirectangular horizon panorama (@class SphericalLandscape).
605 //! Example: your horizon line (pano photo) goes up to 26 degrees altitude (highest mountains/trees):
606@@ -178,8 +179,19 @@
607 const float topAngle=0.0f, const float bottomAngle=M_PI);
608
609 //! Generate a StelVertexArray for a sphere.
610+ //! @param radius
611+ //! @param oneMinusOblateness
612+ //! @param slices: number of vertical segments ("meridian zones")
613+ //! @param stacks: number of horizontal segments ("latitude zones")
614+ //! @param orientInside: 1 to have normals point inside, e.g. for Milky Way, Zodiacal Light, etc.
615+ //! @param flipTexture: if texture should be mapped to inside of sphere, e.g. Milky Way.
616+ //! @param topAngle GZ: new parameter. An opening angle [radians] at top of the sphere. Useful if there is an empty
617+ //! region around the top pole, like North Galactic Pole.
618+ //! @param bottomAngle GZ: new parameter. An opening angle [radians] at bottom of the sphere. Useful if there is an empty
619+ //! region around the bottom pole, like South Galactic Pole.
620 static StelVertexArray computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks,
621- const int orientInside = 0, const bool flipTexture = false);
622+ const int orientInside = 0, const bool flipTexture = false,
623+ const float topAngle=0.0f, const float bottomAngle=M_PI);
624
625 //! Re-implementation of gluCylinder : glu is overridden for non-standard projection.
626 void sCylinder(const float radius, const float height, const int slices, const int orientInside = 0);
627@@ -304,8 +316,11 @@
628 //! @param vertices a pointer to an array of 3 vertices.
629 //! @param edgeFlags a pointer to an array of 3 flags indicating whether the next segment is an edge.
630 //! @param texturePos a pointer to an array of 3 texture coordinates, or NULL if the triangle should not be textured.
631+ //! @param colors a pointer to an array of 3 colors, or NULL if the triangle should not be vertex-colored. If texture and color coords are present, texture is modulated by vertex colors. (e.g. extinction)
632 void projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,
633- const Vec2f* texturePos=NULL, QVarLengthArray<Vec2f, 4096>* outTexturePos=NULL, const double maxSqDistortion=5., const int nbI=0,
634+ const Vec2f* texturePos=NULL, QVarLengthArray<Vec2f, 4096>* outTexturePos=NULL,
635+ const Vec3f* colors=NULL, QVarLengthArray<Vec3f, 4096>* outColors=NULL,
636+ const double maxSqDistortion=5., const int nbI=0,
637 const bool checkDisc1=true, const bool checkDisc2=true, const bool checkDisc3=true) const;
638
639 void drawTextGravity180(float x, float y, const QString& str, const float xshift = 0, const float yshift = 0);
640
641=== modified file 'src/core/StelProjector.hpp'
642--- src/core/StelProjector.hpp 2014-04-18 19:29:32 +0000
643+++ src/core/StelProjector.hpp 2014-10-27 19:13:24 +0000
644@@ -45,7 +45,7 @@
645 //! Shared pointer on a ModelViewTranform instance (implement reference counting)
646 typedef QSharedPointer<ModelViewTranform> ModelViewTranformP;
647
648- //! @class PreModelViewFunc
649+ //! @class ModelViewTranform
650 //! Allows to define non linear operations in addition to the standard linear (Matrix 4d) ModelView transformation.
651 class ModelViewTranform
652 {
653
654=== modified file 'src/core/StelSphereGeometry.cpp'
655--- src/core/StelSphereGeometry.cpp 2014-04-19 09:40:17 +0000
656+++ src/core/StelSphereGeometry.cpp 2014-10-27 19:13:24 +0000
657@@ -709,7 +709,8 @@
658
659 TriangleSerializer() {}
660 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,
661- const Vec2f* , const Vec2f* , const Vec2f* ,
662+ const Vec2f* , const Vec2f* , const Vec2f* ,
663+ const Vec3f* , const Vec3f* , const Vec3f* , // GZ NEW
664 unsigned int , unsigned int , unsigned int )
665 {
666 QVariantList triangle;
667@@ -1151,7 +1152,8 @@
668
669 TriangleDumper() {}
670 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,
671- const Vec2f* , const Vec2f* , const Vec2f* ,
672+ const Vec2f* , const Vec2f* , const Vec2f* ,
673+ const Vec3f* , const Vec3f* , const Vec3f* , // GZ NEW
674 unsigned int , unsigned int , unsigned int )
675 {
676 QVector<Vec3d> triangle;
677
678=== modified file 'src/core/StelSphereGeometry.hpp'
679--- src/core/StelSphereGeometry.hpp 2014-02-20 15:07:04 +0000
680+++ src/core/StelSphereGeometry.hpp 2014-10-27 19:13:24 +0000
681@@ -284,7 +284,7 @@
682 //! @param an a unit vector indicating the direction.
683 //! @param ar cosinus of the aperture.
684 SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {//n.normalize();
685- Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
686+ Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
687 // FIXME: GZ reports 2013-03-02: apparently the Q_ASSERT is here because n should be normalized at this point, but
688 // for efficiency n.normalize() should not be called at this point.
689 // However, when zooming in a bit in Hammer-Aitoff and Mercator projections, this Assertion fires.
690
691=== modified file 'src/core/StelUtils.cpp'
692--- src/core/StelUtils.cpp 2014-10-26 11:18:06 +0000
693+++ src/core/StelUtils.cpp 2014-10-27 19:13:24 +0000
694@@ -546,13 +546,11 @@
695 *lng = atan2(v[1],v[0]);
696 }
697
698-// GZ: some additions. I need those just for quick conversions for text display.
699 void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad)
700 {
701 *lambdaRad=std::atan2(std::sin(raRad)*std::cos(eclRad)+std::tan(decRad)*std::sin(eclRad), std::cos(raRad));
702 *betaRad=std::asin(std::sin(decRad)*std::cos(eclRad)-std::cos(decRad)*std::sin(eclRad)*std::sin(raRad));
703 }
704-// GZ: done
705
706 double getDecAngle(const QString& str)
707 {
708@@ -1265,8 +1263,6 @@
709 // "Five Millennium Canon of Solar Eclipses" [Espenak and Meeus, 2006]
710 // A summary is described here:
711 // http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html
712- // GZ: I replaced the std::pow() calls by Horner's scheme with reversed factors, it's more accurate and efficient.
713- // Old code left for readability, but can also be deleted.
714
715 double y = year+((month-1)*30.5+day/31*30.5)/366;
716
717@@ -1532,7 +1528,7 @@
718
719 // Implementation of algorithm by JPL Horizons for DeltaT computation
720 double getDeltaTByJPLHorizons(const double jDay)
721-{ // GZ: TODO: FIXME! It does not make sense to have zeros after 1620 in a JPL Horizons compatible implementation!
722+{ // TODO: FIXME! It does not make sense to have zeros after 1620 in a JPL Horizons compatible implementation!
723 int year, month, day;
724 double u;
725 double deltaT = 0.;
726@@ -1716,16 +1712,16 @@
727 }
728
729 // Implementation of algorithm by Reingold & Dershowitz (Cal. Calc. 1997, 2001, 2007, Cal. Tab. 2002) for DeltaT computation.
730-// GZ: Created as yet another multi-segment polynomial fit through the table in Meeus: Astronomical Algorithms (1991).
731-// GZ: Note that only the Third edition (2007) adds the 1700-1799 term.
732-// GZ: More efficient reimplementation with stricter adherence to the source.
733+// Created as yet another multi-segment polynomial fit through the table in Meeus: Astronomical Algorithms (1991).
734+// Note that only the Third edition (2007) adds the 1700-1799 term.
735+// More efficient reimplementation with stricter adherence to the source.
736 double getDeltaTByReingoldDershowitz(const double jDay)
737 {
738 int year, month, day;
739 getDateFromJulianDay(jDay, &year, &month, &day);
740- // GZ: R&D don't use a float-fraction year, but explicitly only the integer year! And R&D use a proleptic Gregorian year before 1582.
741- // GZ: We cannot do that, but the difference is negligible.
742- // GZ: FIXME: why are displayed values so far off the computed values? It seems currently broken!
743+ // R&D don't use a float-fraction year, but explicitly only the integer year! And R&D use a proleptic Gregorian year before 1582.
744+ // We cannot do that, but the difference is negligible.
745+ // FIXME: why are displayed values so far off the computed values? It seems currently broken!
746 double deltaT=0.0; // If it returns 0, there is a bug!
747
748 if ((year >= 2019) || (year < 1620))
749@@ -1945,7 +1941,7 @@
750 //! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.
751 //! Values are stored in the global static array cos_sin_rho.
752 //! Used for the sin/cos values along a meridian.
753-//! GZ: allow leaving away pole caps. The array now contains values for the region minAngle+segments*phi
754+//! This allows leaving away pole caps. The array now contains values for the region minAngle+segments*phi
755 //! @param dRho a difference angle between the stops
756 //! @param segments number of segments
757 //! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi
758
759=== modified file 'src/core/StelUtils.hpp'
760--- src/core/StelUtils.hpp 2014-10-26 11:18:06 +0000
761+++ src/core/StelUtils.hpp 2014-10-27 19:13:24 +0000
762@@ -174,10 +174,8 @@
763 //! @param v the input 3D vector
764 void rectToSphe(float *lng, float *lat, const Vec3f& v);
765
766- // GZ: some additions. I need those just for quick conversions for text display.
767 //! Coordinate Transformation from equatorial to ecliptical
768 void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad);
769- // GZ: done
770
771 //! Convert a string longitude, latitude, RA or Declination angle
772 //! to radians.
773@@ -611,7 +609,7 @@
774 //! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.
775 //! Values are stored in the global static array cos_sin_rho.
776 //! Used for the sin/cos values along a meridian.
777- //! GZ: allow leaving away pole caps. The array now contains values for the region minAngle+segments*phi
778+ //! This allows leaving away pole caps. The array now contains values for the region minAngle+segments*phi
779 //! @param dRho a difference angle between the stops
780 //! @param segments number of segments
781 //! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi
782
783=== modified file 'src/core/StelVertexArray.cpp'
784--- src/core/StelVertexArray.cpp 2014-04-06 12:19:27 +0000
785+++ src/core/StelVertexArray.cpp 2014-10-27 19:13:24 +0000
786@@ -100,7 +100,7 @@
787 Q_ASSERT(false);
788 }
789 }
790- // Just in case we don't have any triangles, we also remove all the vertex.
791+ // Just in case we don't have any triangles, we also remove all the vertices.
792 // This is because we can't specify an empty indexed VertexArray.
793 // FIXME: we should use an attribute for indexed array.
794 if (ret.indices.isEmpty())
795@@ -114,6 +114,7 @@
796 {
797 out << p.vertex;
798 out << p.texCoords;
799+ out << p.colors; // GZ NEW
800 out << p.indices;
801 out << (unsigned int)p.primitiveType;
802 return out;
803@@ -123,6 +124,7 @@
804 {
805 in >> p.vertex;
806 in >> p.texCoords;
807+ in >> p.colors; // GZ NEW
808 in >> p.indices;
809 unsigned int t;
810 in >> t;
811
812=== modified file 'src/core/StelVertexArray.hpp'
813--- src/core/StelVertexArray.hpp 2014-02-18 06:36:58 +0000
814+++ src/core/StelVertexArray.hpp 2014-10-27 19:13:24 +0000
815@@ -49,6 +49,9 @@
816 QVector<Vec3d> vertex;
817 //! OpenGL compatible array of edge flags to be displayed using vertex arrays.
818 QVector<Vec2f> texCoords;
819+ //! OpenGL compatible array of vertex colors to be displayed using arrays. (GZ/NEW)
820+ //! The color (if exists) shall be multiplied with texture to modulate e.g. for extinction of Milky Way or other large items.
821+ QVector<Vec3f> colors;
822 //! OpenGL compatible array of indices for the vertex and the textures
823 QVector<unsigned short> indices;
824
825@@ -58,20 +61,24 @@
826
827 bool isTextured() const {return !texCoords.isEmpty();}
828
829+ bool isColored() const {return !colors.isEmpty();}
830+
831+
832 //! call a function for each triangle of the array.
833- //! func should define the following method :
834- //! void operator() (const Vec3d* vertex[3], const Vec2f* tex[3], unsigned int indices[3])
835+ //! func should define the following method : // GZ NEW: colors
836+ //! void operator() (const Vec3d* vertex[3], const Vec2f* tex[3], const Vec3f* colors[3], unsigned int indices[3])
837 //! The method takes arrays of *pointers* as arguments because we can't assume the values are contiguous
838 template<class Func>
839 inline Func foreachTriangle(Func func) const;
840
841- //! Create a copy of the array with all the triangles intersecting the projector discontinuty removed.
842+ //! Create a copy of the array with all the triangles intersecting the projector discontinuity removed.
843 StelVertexArray removeDiscontinuousTriangles(const class StelProjector* prj) const;
844
845 private:
846 // Below we define a few methods that are templated to be optimized according to different types of VertexArray :
847 // The template parameter <bool T> defines whether the array has a texture.
848 // The template parameter <bool I> defines whether the array is indexed.
849+ // The template parameter <bool C> defines whether the array is colored. // NEW GZ
850 template <bool I>
851 const Vec3d* specVertexAt(int i) const {
852 return &vertex.at(specIndiceAt<I>(i));
853@@ -82,12 +89,18 @@
854 return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;
855 }
856
857+ // NEW GZ
858+ template <bool C, bool I>
859+ const Vec3f* specColorAt(int i) const {
860+ return C ? &colors.at(specIndiceAt<I>(i)) : NULL;
861+ }
862+
863 template<bool I>
864 unsigned int specIndiceAt(unsigned int i) const {
865 return I ? indices.at(i) : i;
866 }
867
868- template<bool T, bool I, class Func>
869+ template<bool T, bool I, bool C, class Func> // GZ added bool C
870 inline Func specForeachTriangle(Func func) const;
871
872 };
873@@ -99,23 +112,49 @@
874 template<class Func>
875 Func StelVertexArray::foreachTriangle(Func func) const
876 {
877- // Here we just dispach the method into one of the 4 possible cases
878+ // Here we just dispatch the method into one of the 8 possible cases // GZ NEW: 8, not 4, cases
879 bool textured = isTextured();
880+ bool colored = isColored();
881 bool useIndice = isIndexed();
882
883 if (textured)
884- if (useIndice)
885- return specForeachTriangle<true, true, Func>(func);
886- else
887- return specForeachTriangle<true, false, Func>(func);
888- else
889- if (useIndice)
890- return specForeachTriangle<false, true, Func>(func);
891- else
892- return specForeachTriangle<false, false, Func>(func);
893+ {
894+ if (useIndice)
895+ {
896+ if (colored)
897+ return specForeachTriangle<true, true, true, Func>(func);
898+ else
899+ return specForeachTriangle<true, true, false, Func>(func);
900+ }
901+ else // not indiced
902+ {
903+ if (colored)
904+ return specForeachTriangle<true, false, true, Func>(func);
905+ else
906+ return specForeachTriangle<true, false, false, Func>(func);
907+ }
908+ }
909+ else // not textured
910+ {
911+ if (useIndice)
912+ {
913+ if (colored)
914+ return specForeachTriangle<false, true, true, Func>(func);
915+ else
916+ return specForeachTriangle<false, true, false, Func>(func);
917+ }
918+ else // not indiced
919+ {
920+ if (colored)
921+ return specForeachTriangle<false, false, true, Func>(func);
922+ else
923+ return specForeachTriangle<false, false, false, Func>(func);
924+ }
925+ }
926+ Q_ASSERT(0); // GZ. Just make sure...
927 }
928
929-template<bool T, bool I, class Func>
930+template<bool T, bool I, bool C, class Func>
931 Func StelVertexArray::specForeachTriangle(Func func) const
932 {
933 switch (primitiveType)
934@@ -126,6 +165,7 @@
935 {
936 func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
937 specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
938+ specColorAt<C, I>(i), specColorAt<C, I>(i+1), specColorAt<C, I>(i+2),
939 specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
940 }
941 break;
942@@ -133,12 +173,14 @@
943 {
944 const Vec3d* v0 = specVertexAt<I>(0);
945 const Vec2f* t0 = specTexCoordAt<T, I>(0);
946+ const Vec3f* c0 = specColorAt<C, I>(0);
947 unsigned int i0 = specIndiceAt<I>(0);
948 for (int i = 1; i < vertex.size() - 1; ++i)
949 {
950 func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
951 t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
952- i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
953+ c0, specColorAt<C, I>(i), specColorAt<C, I>(i+1),
954+ i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
955 }
956 break;
957 }
958@@ -149,16 +191,18 @@
959 if (i % 2 == 0)
960 func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
961 specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
962+ specColorAt<C, I>(i-2), specColorAt<C, I>(i-1), specColorAt<C, I>(i),
963 specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
964 else
965 func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
966 specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
967+ specColorAt<C, I>(i-1), specColorAt<C, I>(i-2), specColorAt<C, I>(i),
968 specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
969 }
970 break;
971 }
972 default:
973- Q_ASSERT_X(0, Q_FUNC_INFO, "unsuported primitive type");
974+ Q_ASSERT_X(0, Q_FUNC_INFO, "unsupported primitive type");
975 }
976 return func;
977 }
978
979=== modified file 'src/core/modules/Landscape.cpp'
980--- src/core/modules/Landscape.cpp 2014-10-25 00:04:08 +0000
981+++ src/core/modules/Landscape.cpp 2014-10-27 19:13:24 +0000
982@@ -589,7 +589,7 @@
983 if (side.light==drawLight)
984 {
985 side.tex->bind();
986- sPainter.drawSphericalTriangles(side.arr, true, NULL, false);
987+ sPainter.drawSphericalTriangles(side.arr, true, false, NULL, false);
988 }
989 }
990 }
991
992=== modified file 'src/core/modules/MilkyWay.cpp'
993--- src/core/modules/MilkyWay.cpp 2014-04-15 17:10:07 +0000
994+++ src/core/modules/MilkyWay.cpp 2014-10-27 19:13:24 +0000
995@@ -1,6 +1,7 @@
996 /*
997 * Stellarium
998 * Copyright (C) 2002 Fabien Chereau
999+ * Copyright (C) 2014 Georg Zotti (extinction parts)
1000 *
1001 * This program is free software; you can redistribute it and/or
1002 * modify it under the terms of the GNU General Public License
1003@@ -58,15 +59,35 @@
1004 QSettings* conf = StelApp::getInstance().getSettings();
1005 Q_ASSERT(conf);
1006
1007- tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway.png");
1008+ //tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway.png");
1009+ tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway_2048.png");
1010 setFlagShow(conf->value("astro/flag_milky_way").toBool());
1011 setIntensity(conf->value("astro/milky_way_intensity",1.f).toFloat());
1012-
1013- vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,20,20,1));
1014-}
1015-
1016-
1017-void MilkyWay::update(double deltaTime) {fader->update((int)(deltaTime*1000));}
1018+ // GZ: I cut the original milkyway.png 512x512 to 512x256. Center line was shifted southwards by 32 pixels to keep Magellanic Clouds visible.
1019+ // 256px were 90 degrees. 128:45, 64:22.5, 32:11.25. So this spherical ring goes from -45-11.25 to 45-11.25.
1020+
1021+ // A new texture was provided by Fabien. Better resolution, but in equatorial coordinates. I had to enhance it a bit, and shift it by 90 degrees.
1022+ // GZ: Note that a full sphere (i.e., a texture not aligned to galactic coordinates) costs performance!
1023+ //vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,45,15,1, true, (90.0f-33.75f)*M_PI/180.0f, (90.0f+56.25f)*M_PI/180.0f)); // GZ orig: slices=stacks=20.
1024+ vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,45,15,1, true)); // GZ orig: slices=stacks=20.
1025+ vertexArray->colors.resize(vertexArray->vertex.length());
1026+ vertexArray->colors.fill(Vec3f(1.0, 0.3, 0.9));
1027+
1028+ // If we have a texture in galactic coordinates, we can transform the vertex coordinates already here.
1029+ // The texture had to be rotated/flipped and shifted compared to 0.13.0
1030+// StelCore* core=StelApp::getInstance().getCore();
1031+// for (int i=0; i<vertexArray->vertex.size(); ++i)
1032+// {
1033+// Vec3d tmp=vertexArray->vertex.at(i);
1034+// vertexArray->vertex.replace(i, core->galacticToJ2000(tmp));
1035+// }
1036+}
1037+
1038+
1039+void MilkyWay::update(double deltaTime)
1040+{
1041+ fader->update((int)(deltaTime*1000));
1042+}
1043
1044 void MilkyWay::setFlagShow(bool b){*fader = b;}
1045 bool MilkyWay::getFlagShow() const {return *fader;}
1046@@ -77,27 +98,36 @@
1047 return;
1048
1049 StelProjector::ModelViewTranformP transfo = core->getJ2000ModelViewTransform();
1050- transfo->combine(Mat4d::xrotation(M_PI/180.*23.)*
1051- Mat4d::yrotation(M_PI/180.*120.)*
1052- Mat4d::zrotation(M_PI/180.*7.));
1053+ // GZ: No idea where this came from. Empirical correction? Now the vertices have been replaced already in init().
1054+ // (the "official" angles are not integers...)
1055+// transfo->combine(Mat4d::xrotation(M_PI/180.*23.)*
1056+// Mat4d::yrotation(M_PI/180.*120.)*
1057+// Mat4d::zrotation(M_PI/180.*7.));
1058
1059- const StelProjectorP prj = core->getProjection(transfo);
1060+ const StelProjectorP prj = core->getProjection(transfo); // GZ: Maybe this can now be simplified?
1061 StelToneReproducer* eye = core->getToneReproducer();
1062
1063 Q_ASSERT(tex); // A texture must be loaded before calling this
1064
1065 // This RGB color corresponds to the night blue scotopic color = 0.25, 0.25 in xyY mode.
1066 // since milky way is always seen white RGB value in the texture (1.0,1.0,1.0)
1067- Vec3f c = Vec3f(0.34165f, 0.429666f, 0.63586f);
1068+ // Vec3f c = Vec3f(0.34165f, 0.429666f, 0.63586f);
1069+ // GZ: This is the same color, just brighter to have Blue=1.
1070+ Vec3f c = Vec3f(0.53730381f, .675724216f, 1.0f);
1071
1072- float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(13.5f);
1073+ float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(13.5f); // Source? How to calibrate the new texture?
1074
1075 // Get the luminance scaled between 0 and 1
1076 float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate());
1077
1078- // Bound a maximum luminance
1079+ // Bound a maximum luminance. GZ: Is there any reference/reason, or just trial and error?
1080 aLum = qMin(0.38f, aLum*2.f);
1081
1082+ // GZ I have the impression we must also adjust milky way to light pollution.
1083+ // Is there any way to calibrate this?
1084+ int bortle=core->getSkyDrawer()->getBortleScaleIndex();
1085+ aLum*=(11.0f-bortle)*0.1f;
1086+
1087 // intensity of 1.0 is "proper", but allow boost for dim screens
1088 c*=aLum*intensity;
1089
1090@@ -105,8 +135,31 @@
1091 if (c[1]<0) c[1]=0;
1092 if (c[2]<0) c[2]=0;
1093
1094+ const bool withExtinction=(core->getSkyDrawer()->getFlagHasAtmosphere() && core->getSkyDrawer()->getExtinction().getExtinctionCoefficient()>=0.01f);
1095+
1096+ if (withExtinction)
1097+ {
1098+ // We must process the vertices to find geometric altitudes in order to compute vertex colors.
1099+ // Note that there is a visible boost of extinction for higher Bortle indices. I must reflect that as well.
1100+ Extinction extinction=core->getSkyDrawer()->getExtinction();
1101+ vertexArray->colors.clear();
1102+
1103+ for (int i=0; i<vertexArray->vertex.size(); ++i)
1104+ {
1105+ Vec3d vertAltAz=core->j2000ToAltAz(vertexArray->vertex.at(i), StelCore::RefractionOn);
1106+ Q_ASSERT(vertAltAz.lengthSquared()-1.0 < 0.001f);
1107+
1108+ float oneMag=0.0f;
1109+ extinction.forward(vertAltAz, &oneMag);
1110+ float extinctionFactor=std::pow(0.4f , oneMag) * (1.0f-bortle*0.1f); // drop of one magnitude: factor 2.5 or 40%
1111+ Vec3f thisColor=Vec3f(c[0]*extinctionFactor, c[1]*extinctionFactor, c[2]*extinctionFactor);
1112+ vertexArray->colors.append(thisColor);
1113+ }
1114+ }
1115+ else
1116+ vertexArray->colors.fill(Vec3f(c[0], c[1], c[2]));
1117+
1118 StelPainter sPainter(prj);
1119- sPainter.setColor(c[0],c[1],c[2]);
1120 glEnable(GL_CULL_FACE);
1121 sPainter.enableTexture2d(true);
1122 glDisable(GL_BLEND);
1123
1124=== modified file 'src/core/modules/MilkyWay.hpp'
1125--- src/core/modules/MilkyWay.hpp 2014-04-15 17:10:07 +0000
1126+++ src/core/modules/MilkyWay.hpp 2014-10-27 19:13:24 +0000
1127@@ -71,7 +71,7 @@
1128
1129 private:
1130 StelTextureSP tex;
1131- Vec3f color;
1132+ Vec3f color; // global color
1133 float intensity;
1134 class LinearFader* fader;
1135
1136
1137=== modified file 'src/core/modules/Nebula.hpp'
1138--- src/core/modules/Nebula.hpp 2014-04-06 14:34:01 +0000
1139+++ src/core/modules/Nebula.hpp 2014-10-27 19:13:24 +0000
1140@@ -30,6 +30,7 @@
1141 class StelPainter;
1142 class QDataStream;
1143
1144+// This only draws nebula icons. For the DSO images, see StelSkylayerMgr and StelSkyImageTile.
1145 class Nebula : public StelObject
1146 {
1147 friend class NebulaMgr;
1148
1149=== modified file 'src/gui/LocationDialog.hpp'
1150--- src/gui/LocationDialog.hpp 2014-09-08 12:47:22 +0000
1151+++ src/gui/LocationDialog.hpp 2014-10-27 19:13:24 +0000
1152@@ -82,7 +82,7 @@
1153 void updateFromProgram(const StelLocation& location);
1154
1155 //! Called when the map is clicked.
1156- //! GZ_New: create new list for places nearby and feed into location list box.
1157+ //! create new list for places nearby and feed into location list box.
1158 void setPositionFromMap(double longitude, double latitude);
1159
1160 //! Called when the user activates an item from the locations list.
1161
1162=== modified file 'textures/milkyway.png'
1163Binary files textures/milkyway.png 2005-10-30 19:51:28 +0000 and textures/milkyway.png 2014-10-27 19:13:24 +0000 differ
1164=== added file 'textures/milkyway_2048.png'
1165Binary files textures/milkyway_2048.png 1970-01-01 00:00:00 +0000 and textures/milkyway_2048.png 2014-10-27 19:13:24 +0000 differ