Merge lp:~georg-zotti/stellarium/gz_comet-tail-extinction into lp:stellarium
- gz_comet-tail-extinction
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 7129 |
Proposed branch: | lp:~georg-zotti/stellarium/gz_comet-tail-extinction |
Merge into: | lp:stellarium |
Diff against target: |
611 lines (+161/-94) 11 files modified
src/core/StelApp.hpp (+2/-1) src/core/StelPainter.cpp (+2/-1) src/core/StelProjector.cpp (+1/-1) src/core/StelProjector.hpp (+2/-2) src/core/StelToneReproducer.hpp (+5/-5) src/core/modules/Comet.cpp (+125/-68) src/core/modules/Comet.hpp (+14/-6) src/core/modules/MilkyWay.cpp (+1/-1) src/core/modules/MinorPlanet.cpp (+0/-1) src/core/modules/Planet.cpp (+5/-5) src/core/modules/Planet.hpp (+4/-3) |
To merge this branch: | bzr merge lp:~georg-zotti/stellarium/gz_comet-tail-extinction |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Fabien Chéreau | Approve | ||
Review via email: mp+241181@code.launchpad.net |
Commit message
Improved brightness control and colors for comet tails: extinction and twilight mixing.
Description of the change
My original comet tails of winter 2013/14 had one big flaw: brightness was computed globally. This made them almost pop out of twilight in full length, and bright comets were just too bright.
This branch has I think much better brightness balancing (query atmosphere and eye adaptation), and can reduce/influence tail brightness not only by vertex-wise extinction, but also by vertex-wise adaptation of tail length visibility to overall sky brightness. The increase in quality can at least be called "significant" IMHO.
To test, I recommend you copy ssystem_
Preview Diff
1 | === modified file 'src/core/StelApp.hpp' |
2 | --- src/core/StelApp.hpp 2014-11-04 10:59:12 +0000 |
3 | +++ src/core/StelApp.hpp 2014-11-08 17:16:48 +0000 |
4 | @@ -148,7 +148,8 @@ |
5 | void update(double deltaTime); |
6 | |
7 | //! Draw all registered StelModule in the order defined by the order lists. |
8 | - //! @return the max squared distance in pixels that any object has travelled since the last update. |
9 | + // 2014-11: OLD COMMENT? What does a void return? |
10 | + // @return the max squared distance in pixels that any object has travelled since the last update. |
11 | void draw(); |
12 | |
13 | //! Call this when the size of the GL window has changed. |
14 | |
15 | === modified file 'src/core/StelPainter.cpp' |
16 | --- src/core/StelPainter.cpp 2014-11-04 12:15:15 +0000 |
17 | +++ src/core/StelPainter.cpp 2014-11-08 17:16:48 +0000 |
18 | @@ -544,7 +544,7 @@ |
19 | |
20 | // Translate/rotate |
21 | if (!noGravity) |
22 | - angleDeg += prj->defautAngleForGravityText; |
23 | + angleDeg += prj->defaultAngleForGravityText; |
24 | |
25 | if (std::fabs(angleDeg)>1.f) |
26 | { |
27 | @@ -1357,6 +1357,7 @@ |
28 | break; |
29 | case SphericalPolygonDrawModeFill: |
30 | case SphericalPolygonDrawModeTextureFill: |
31 | + case SphericalPolygonDrawModeTextureFillColormodulated: |
32 | glEnable(GL_CULL_FACE); |
33 | // The polygon is already tesselated as triangles |
34 | if (doSubDivise || prj->intersectViewportDiscontinuity(poly->getBoundingCap())) |
35 | |
36 | === modified file 'src/core/StelProjector.cpp' |
37 | --- src/core/StelProjector.cpp 2013-10-01 22:05:10 +0000 |
38 | +++ src/core/StelProjector.cpp 2014-11-08 17:16:48 +0000 |
39 | @@ -116,7 +116,7 @@ |
40 | viewportCenter = params.viewportCenter; |
41 | viewportCenter *= devicePixelsPerPixel; |
42 | gravityLabels = params.gravityLabels; |
43 | - defautAngleForGravityText = params.defautAngleForGravityText; |
44 | + defaultAngleForGravityText = params.defautAngleForGravityText; |
45 | flipHorz = params.flipHorz ? -1.f : 1.f; |
46 | flipVert = params.flipVert ? -1.f : 1.f; |
47 | viewportFovDiameter = params.viewportFovDiameter * devicePixelsPerPixel; |
48 | |
49 | === modified file 'src/core/StelProjector.hpp' |
50 | --- src/core/StelProjector.hpp 2014-10-16 17:32:50 +0000 |
51 | +++ src/core/StelProjector.hpp 2014-11-08 17:16:48 +0000 |
52 | @@ -291,7 +291,7 @@ |
53 | oneOverZNearMinusZFar(0.f), |
54 | viewportFovDiameter(0.f), |
55 | gravityLabels(true), |
56 | - defautAngleForGravityText(0.f), |
57 | + defaultAngleForGravityText(0.f), |
58 | devicePixelsPerPixel(1.f) {;} |
59 | |
60 | //! Return whether the projection presents discontinuities. Used for optimization. |
61 | @@ -317,7 +317,7 @@ |
62 | Vec2f viewportCenter; // Viewport center in screen pixel |
63 | float viewportFovDiameter; // diameter of the FOV disk in pixel |
64 | bool gravityLabels; // should label text align with the horizon? |
65 | - float defautAngleForGravityText; // a rotation angle to apply to gravity text (only if gravityLabels is set to false) |
66 | + float defaultAngleForGravityText; // a rotation angle to apply to gravity text (only if gravityLabels is set to false) |
67 | SphericalCap boundingCap; // Bounding cap of the whole viewport |
68 | float devicePixelsPerPixel; // The number of device pixel per "Device Independent Pixels" (value is usually 1, but 2 for mac retina screens) |
69 | |
70 | |
71 | === modified file 'src/core/StelToneReproducer.hpp' |
72 | --- src/core/StelToneReproducer.hpp 2014-11-04 10:59:12 +0000 |
73 | +++ src/core/StelToneReproducer.hpp 2014-11-08 17:16:48 +0000 |
74 | @@ -79,7 +79,7 @@ |
75 | //! It is the parameter to modify to simulate aperture*exposition time |
76 | //! @param scale the global input scale |
77 | void setInputScale(float scale=1.f); |
78 | - //! Get the global scale applied to input lumiances, i.e before the adaptation |
79 | + //! Get the global scale applied to input luminances, i.e before the adaptation |
80 | float getInputScale() const |
81 | { |
82 | return inputScale; |
83 | @@ -125,14 +125,14 @@ |
84 | |
85 | //! Return adapted luminance from world to display with 1 corresponding to full display white |
86 | //! @param worldLuminance the world luminance to convert in cd/m^2 |
87 | - //! @return the converted display luminance with 1 corresponding to full display white. The value can be more than 1 when saturation.. |
88 | + //! @return the converted display luminance with 1 corresponding to full display white. The value can be more than 1 when saturated. |
89 | float adaptLuminanceScaled(float worldLuminance) const |
90 | { |
91 | return adaptLuminance(worldLuminance)*oneOverMaxdL; |
92 | } |
93 | |
94 | //! Return adapted luminance from display to world with 1 corresponding to full display white |
95 | - //! @param displayLuminance the display luminance with 1 corresponding to full display white. The value can be more than 1 when saturation.. |
96 | + //! @param displayLuminance the display luminance with 1 corresponding to full display white. The value can be more than 1 when saturated. |
97 | //! @return the converted world luminance in cd/m^2 |
98 | float reverseAdaptLuminanceScaled(float displayLuminance) const |
99 | { |
100 | @@ -141,8 +141,8 @@ |
101 | |
102 | //! Return adapted ln(luminance) from world to display with 1 corresponding to full display white |
103 | //! @param lnWorldLuminance the world luminance to convert in ln(cd/m^2) |
104 | - //! @param pFact the power at whihc the result should be set. The default is 0.5 and therefore return the square root of the adapted luminance |
105 | - //! @return the converted display set at the pFact power. Luminance with 1 corresponding to full display white. The value can be more than 1 when saturation.. |
106 | + //! @param pFact the power at which the result should be set. The default is 0.5 and therefore return the square root of the adapted luminance |
107 | + //! @return the converted display set at the pFact power. Luminance with 1 corresponding to full display white. The value can be more than 1 when saturated. |
108 | float adaptLuminanceScaledLn(float lnWorldLuminance, float pFact=0.5f) const |
109 | { |
110 | const float lnPix0p0001 = -8.0656104861f; |
111 | |
112 | === modified file 'src/core/modules/Comet.cpp' |
113 | --- src/core/modules/Comet.cpp 2014-10-19 05:54:43 +0000 |
114 | +++ src/core/modules/Comet.cpp 2014-11-08 17:16:48 +0000 |
115 | @@ -1,6 +1,7 @@ |
116 | /* |
117 | * Stellarium |
118 | * Copyright (C) 2010 Bogdan Marinov |
119 | + * Copyright (C) 2014 Georg Zotti (Tails) |
120 | * |
121 | * This program is free software; you can redistribute it and/or |
122 | * modify it under the terms of the GNU General Public License |
123 | @@ -26,6 +27,7 @@ |
124 | |
125 | #include "StelTexture.hpp" |
126 | #include "StelTextureMgr.hpp" |
127 | +#include "StelToneReproducer.hpp" |
128 | #include "StelTranslator.hpp" |
129 | #include "StelUtils.hpp" |
130 | #include "StelFileMgr.hpp" |
131 | @@ -71,6 +73,7 @@ |
132 | true, //halo |
133 | pTypeStr), |
134 | tailActive(false), |
135 | + tailBright(false), |
136 | dustTailWidthFactor(dustTailWidthFact), |
137 | dustTailLengthFactor(dustTailLengthFact), |
138 | dustTailBrightnessFactor(dustTailBrightnessFact) |
139 | @@ -90,6 +93,8 @@ |
140 | gastailVertexArr.clear(); |
141 | dusttailVertexArr.clear(); |
142 | comaVertexArr.clear(); |
143 | + gastailColorArr.clear(); |
144 | + dusttailColorArr.clear(); |
145 | |
146 | //Comet specific members |
147 | absoluteMagnitude = 0; |
148 | @@ -281,19 +286,27 @@ |
149 | return apparentMagnitude; |
150 | } |
151 | |
152 | -// Compute the position in the parent Planet coordinate system |
153 | -// Actually call the provided function to compute the ecliptical position, and buildup the tails! |
154 | -void Comet::computePosition(const double date) |
155 | +void Comet::update(int deltaTime) |
156 | { |
157 | - Planet::computePosition(date); |
158 | - //GZ: I think we can make deltaJD adaptive, depending on distance to sun! For some reason though, this leads to a crash! |
159 | - //deltaJD=StelCore::JD_SECOND * qMax(1.0, qMin(eclipticPos.length(), 20.0)); |
160 | + Planet::update(deltaTime); |
161 | + |
162 | + // The rest used to be in computePosition(), but is better in update(). Unfortunately we need date (JD). |
163 | + StelCore* core=StelApp::getInstance().getCore(); |
164 | + double date=core->getJDay(); |
165 | + |
166 | + // The CometOrbit is in fact available in userDataPtr! |
167 | + CometOrbit* orbit=(CometOrbit*)userDataPtr; |
168 | + Q_ASSERT(orbit); |
169 | + if (!orbit->objectDateValid(core->getJDay())) return; // don't do anything if out of useful date range. This allows having hundreds of comet elements. |
170 | + |
171 | + |
172 | + //GZ: I think we can make deltaJDtail adaptive, depending on distance to sun! For some reason though, this leads to a crash! |
173 | + //deltaJDtail=StelCore::JD_SECOND * qMax(1.0, qMin(eclipticPos.length(), 20.0)); |
174 | |
175 | if (fabs(lastJDtail-date)>deltaJDtail) |
176 | { |
177 | lastJDtail=date; |
178 | |
179 | - // GZ: Moved from draw() :-) |
180 | // The CometOrbit is in fact available in userDataPtr! |
181 | CometOrbit* orbit=(CometOrbit*)userDataPtr; |
182 | Q_ASSERT(orbit); |
183 | @@ -301,11 +314,10 @@ |
184 | |
185 | if (orbit->getUpdateTails()){ |
186 | // Compute lengths and orientations from orbit object, but only if required. |
187 | - // This part moved from draw() to keep draw() free from too much computation. |
188 | tailFactors=getComaDiameterAndTailLengthAU(); |
189 | |
190 | // Note that we use a diameter larger than what the formula returns. A scale factor of 1.2 is ad-hoc/empirical (GZ), but may look better. |
191 | - computeComa(1.0f*tailFactors[0]); |
192 | + computeComa(1.0f*tailFactors[0]); // TBD: APPARENTLY NO SCALING? REMOVE 1.0 and note above. |
193 | |
194 | tailActive = (tailFactors[1] > tailFactors[0]); // Inhibit tails drawing if too short. Would be nice to include geometric projection angle, but this is too costly. |
195 | |
196 | @@ -318,10 +330,10 @@ |
197 | |
198 | // Find valid parameters to create paraboloid vertex arrays: dustTail, gasTail. |
199 | computeParabola(gasparameter, gasTailEndRadius, -0.5f*gasparameter, gastailVertexArr, tailTexCoordArr, tailIndices); |
200 | - // This was for a rotated straight parabola: |
201 | - //computeParabola(dustparameter, 2.0f*tailFactors[0], -0.5f*dustparameter, dusttailVertexArr, dusttailTexCoordArr, dusttailIndices); |
202 | + //gastailColorArr.fill(Vec3f(0.3,0.3,0.3), gastailVertexArr.length()); |
203 | // Now we make a skewed parabola. Skew factor (xOffset, last arg) is rather ad-hoc/empirical. TBD later: Find physically correct solution. |
204 | computeParabola(dustparameter, dustTailWidthFactor*gasTailEndRadius, -0.5f*dustparameter, dusttailVertexArr, tailTexCoordArr, tailIndices, 25.0f*orbit->getVelocity().length()); |
205 | + //dusttailColorArr.fill(Vec3f(0.3,0.3,0.3), dusttailVertexArr.length()); |
206 | |
207 | |
208 | // 2014-08 for 0.13.1 Moved from drawTail() to save lots of computation per frame (There *are* folks downloading all 730 MPC current comet elements...) |
209 | @@ -336,7 +348,7 @@ |
210 | // In addition, we let the dust tail already start with a light tilt. |
211 | dustTailRot=gasTailRot * Mat4d::zrotation(atan2(velocity[1], velocity[0]) + M_PI) * Mat4d::yrotation(5.0f*velocity.length()); |
212 | |
213 | - // TODO: If we want to be even faster, rotate vertex arrays here and not in drawTail()! |
214 | + // Rotate vertex arrays: |
215 | Vec3d* gasVertices=(Vec3d*) (gastailVertexArr.data()); |
216 | Vec3d* dustVertices=(Vec3d*) (dusttailVertexArr.data()); |
217 | for (int i=0; i<COMET_TAIL_SLICES*COMET_TAIL_STACKS+1; ++i) |
218 | @@ -345,34 +357,105 @@ |
219 | dustVertices[i].transfo4d(dustTailRot); |
220 | } |
221 | } |
222 | - |
223 | orbit->setUpdateTails(false); // don't update until position has been recalculated elsewhere |
224 | } |
225 | - // Note: we can make deltaJDtail adaptive, depending on distance to sun! |
226 | - //deltaJDtail=5.0*StelCore::JD_MINUTE * qMax(0.01, qMin(eclipticPos.length(), 20.0)); |
227 | - } |
228 | + } |
229 | + |
230 | + // And also update magnitude and tail brightness/extinction here. |
231 | + const bool withAtmosphere=(core->getSkyDrawer()->getFlagHasAtmosphere()); |
232 | + |
233 | + StelToneReproducer* eye = core->getToneReproducer(); |
234 | + float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(getVMagnitude(core)+13.0f); // How to calibrate? |
235 | + // Get the luminance scaled between 0 and 1 |
236 | + float aLum =eye->adaptLuminanceScaled(lum); |
237 | + |
238 | + |
239 | + // To make comet more apparent in overviews, take field of view into account: |
240 | + const float fov=core->getProjection(core->getAltAzModelViewTransform())->getFov(); |
241 | + if (fov>20) |
242 | + aLum*= (fov/20.0f); |
243 | + |
244 | + // Now inhibit tail drawing if still too dim. |
245 | + if (aLum<0.002f) |
246 | + { |
247 | + // Far too dim: don't even show tail... |
248 | + tailBright=false; |
249 | + return; |
250 | + } else |
251 | + tailBright=true; |
252 | + |
253 | + // Separate factors, but avoid overly bright tails. I limit to about 0.7 for overlapping both tails which should not exceed full-white. |
254 | + float gasMagFactor=qMin(0.9f*aLum, 0.7f); |
255 | + float dustMagFactor=qMin(dustTailBrightnessFactor*aLum, 0.7f); |
256 | + |
257 | + Vec3f gasColor(0.15f*gasMagFactor,0.35f*gasMagFactor,0.6f*gasMagFactor); // Orig color 0.15/0.15/0.6 |
258 | + Vec3f dustColor(dustMagFactor, dustMagFactor,0.6f*dustMagFactor); |
259 | + |
260 | + if (withAtmosphere) |
261 | + { |
262 | + Extinction extinction=core->getSkyDrawer()->getExtinction(); |
263 | + |
264 | + // Not only correct the color values for extinction, but for twilight conditions, also make tail end less visible. |
265 | + // I consider sky brightness over 1cd/m^2 as reason to shorten tail. |
266 | + // Below this brightness, the tail brightness loss by this method is insignificant: |
267 | + // Just counting through the vertices might make a spiral apperance. Maybe even better than stackwise? Let's see... |
268 | + const float avgAtmLum=GETSTELMODULE(LandscapeMgr)->getAtmosphereAverageLuminance(); |
269 | + const float brightnessDecreasePerVertexFromHead=1.0f/(COMET_TAIL_SLICES*COMET_TAIL_STACKS) * avgAtmLum; |
270 | + float brightnessPerVertexFromHead=1.0f; |
271 | + |
272 | + gastailColorArr.clear(); |
273 | + dusttailColorArr.clear(); |
274 | + for (int i=0; i<gastailVertexArr.size(); ++i) |
275 | + { |
276 | + // Gastail extinction: |
277 | + Vec3d vertAltAz=core->j2000ToAltAz(gastailVertexArr.at(i), StelCore::RefractionOn); |
278 | + vertAltAz.normalize(); |
279 | + Q_ASSERT(fabs(vertAltAz.lengthSquared()-1.0) < 0.001); |
280 | + float oneMag=0.0f; |
281 | + extinction.forward(vertAltAz, &oneMag); |
282 | + float extinctionFactor=std::pow(0.4f, oneMag); // drop of one magnitude: factor 2.5 or 40% |
283 | + gastailColorArr.append(gasColor*extinctionFactor* brightnessPerVertexFromHead); |
284 | + |
285 | + // dusttail extinction: |
286 | + vertAltAz=core->j2000ToAltAz(dusttailVertexArr.at(i), StelCore::RefractionOn); |
287 | + vertAltAz.normalize(); |
288 | + Q_ASSERT(fabs(vertAltAz.lengthSquared()-1.0) < 0.001); |
289 | + oneMag=0.0f; |
290 | + extinction.forward(vertAltAz, &oneMag); |
291 | + extinctionFactor=std::pow(0.4f, oneMag); // drop of one magnitude: factor 2.5 or 40% |
292 | + dusttailColorArr.append(dustColor*extinctionFactor * brightnessPerVertexFromHead); |
293 | + |
294 | + brightnessPerVertexFromHead-=brightnessDecreasePerVertexFromHead; |
295 | + } |
296 | + } |
297 | + else // no atmosphere: set all vertices to same brightness. |
298 | + { |
299 | + gastailColorArr.fill(gasColor, gastailVertexArr.length()); |
300 | + dusttailColorArr.fill(dustColor, dusttailVertexArr.length()); |
301 | + } |
302 | + //qDebug() << "Comet " << getEnglishName() << "JD: " << date << "gasR" << gasColor[0] << " dustR" << dustColor[0]; |
303 | } |
304 | |
305 | |
306 | -// Draw the Comet and all the related infos : name, circle etc... GZ: Taken from Planet.cpp 2013-11-05 and extended |
307 | +// Draw the Comet and all the related infos: name, circle etc... GZ: Taken from Planet.cpp 2013-11-05 and extended |
308 | void Comet::draw(StelCore* core, float maxMagLabels, const QFont& planetNameFont) |
309 | { |
310 | if (hidden) |
311 | return; |
312 | if (getEnglishName() == core->getCurrentLocation().planetName) |
313 | - { // GZ: Maybe even don't do that? E.g., draw tail while riding the comet? Decide later. |
314 | + { // Maybe even don't do that? E.g., draw tail while riding the comet? Decide later. |
315 | return; |
316 | } |
317 | |
318 | - // GZ: If comet is too faint to be seen, don't bother rendering. (oops, should have been here in 2014-01... ;-) |
319 | - if ((getVMagnitude(core)-2.0f) > core->getSkyDrawer()->getLimitMagnitude()) |
320 | + // If comet is too faint to be seen, don't bother rendering. (Massive speedup if people have hundreds of comets!) |
321 | + if ((getVMagnitude(core)+2.0f) > core->getSkyDrawer()->getLimitMagnitude()) |
322 | { |
323 | return; |
324 | } |
325 | // The CometOrbit is in fact available in userDataPtr! |
326 | CometOrbit* orbit=(CometOrbit*)userDataPtr; |
327 | Q_ASSERT(orbit); |
328 | - if (!orbit->objectDateValid(core->getJDay())) return; // don't draw at all out of useful date range. This allows having hundreds of comet elements. |
329 | + if (!orbit->objectDateValid(core->getJDay())) return; // don't draw at all if out of useful date range. This allows having hundreds of comet elements. |
330 | |
331 | Mat4d mat = Mat4d::translation(eclipticPos) * rotLocalToParent; |
332 | // This removed totally the Planet shaking bug!!! |
333 | @@ -408,8 +491,8 @@ |
334 | |
335 | draw3dModel(core,transfo,screenSz); |
336 | } |
337 | - // tails should also be drawn if comet core is off-screen... |
338 | - if (tailActive) |
339 | + // but tails should also be drawn if comet core is off-screen... |
340 | + if (tailActive && tailBright) |
341 | { |
342 | drawTail(core,transfo,true); // gas tail |
343 | drawTail(core,transfo,false); // dust tail |
344 | @@ -420,46 +503,24 @@ |
345 | } |
346 | |
347 | void Comet::drawTail(StelCore* core, StelProjector::ModelViewTranformP transfo, bool gas) |
348 | -{ |
349 | +{ |
350 | StelPainter* sPainter = new StelPainter(core->getProjection(transfo)); |
351 | glEnable(GL_BLEND); |
352 | glBlendFunc(GL_ONE, GL_ONE); |
353 | glDisable(GL_CULL_FACE); |
354 | |
355 | - // GZ: If we use getVMagnitudeWithExtinction(), a head extincted in the horizon mist can completely hide an otherwise frighteningly long tail. |
356 | - // we must use unextincted mag, but mix/dim with atmosphere/sky brightness. |
357 | - // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. |
358 | - float magFactor=std::pow(0.6f , getVMagnitude(core)); |
359 | - if (core->getSkyDrawer()->getFlagHasAtmosphere()) |
360 | - { |
361 | - // Mix with sky brightness and light pollution: This is very ad-hoc, if someone finds a better solution, please go ahead! |
362 | - // Light pollution: |
363 | - float bortleIndexFactor=0.1f * (11 - core->getSkyDrawer()->getBortleScaleIndex()); |
364 | - magFactor*= bortleIndexFactor*bortleIndexFactor; // GZ-Guesstimate for light pollution influence |
365 | - // sky brightness: This is about 10 for twilight where bright comet tails should already be visible. Dark night is close to 0. |
366 | - float avgAtmLum=GETSTELMODULE(LandscapeMgr)->getAtmosphereAverageLuminance(); |
367 | - float atmLumFactor=(15.0f-avgAtmLum)/15.0f; if (atmLumFactor<0.05f) atmLumFactor=0.05f; //atmLumFactor=std::sqrt(atmLumFactor); |
368 | - magFactor*=atmLumFactor*atmLumFactor; |
369 | - } |
370 | - magFactor*=(gas? 0.9 : dustTailBrightnessFactor); // TBD: empirical adjustment for texture brightness. |
371 | - magFactor=qMin(magFactor, 1.05f); // Limit excessively bright display. |
372 | - |
373 | tailTexture->bind(); |
374 | |
375 | if (gas) { |
376 | - sPainter->setColor(0.15f*magFactor,0.15f*magFactor,0.6f*magFactor); |
377 | - sPainter->setArrays((Vec3d*)gastailVertexArr.constData(), (Vec2f*)tailTexCoordArr.constData()); |
378 | + sPainter->setArrays((Vec3d*)gastailVertexArr.constData(), (Vec2f*)tailTexCoordArr.constData(), (Vec3f*)gastailColorArr.constData()); |
379 | sPainter->drawFromArray(StelPainter::Triangles, tailIndices.size(), 0, true, tailIndices.constData()); |
380 | |
381 | } else { |
382 | - sPainter->setColor(magFactor, magFactor,0.6f*magFactor); |
383 | - sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)tailTexCoordArr.constData()); |
384 | + sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)tailTexCoordArr.constData(), (Vec3f*)dusttailColorArr.constData()); |
385 | sPainter->drawFromArray(StelPainter::Triangles, tailIndices.size(), 0, true, tailIndices.constData()); |
386 | } |
387 | glDisable(GL_BLEND); |
388 | |
389 | - |
390 | - |
391 | if (sPainter) |
392 | delete sPainter; |
393 | sPainter=NULL; |
394 | @@ -478,16 +539,13 @@ |
395 | glBlendFunc(GL_ONE, GL_ONE); |
396 | glDisable(GL_CULL_FACE); |
397 | |
398 | - // GZ: For the coma, we can use extinction via atmosphere. |
399 | - // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. |
400 | - float minSkyMag=core->getSkyDrawer()->getLimitMagnitude(); |
401 | - float mag100pct=minSkyMag-6.0f; // should be 5, but let us draw it a bit brighter. |
402 | - float magDrop=getVMagnitudeWithExtinction(core)-mag100pct; |
403 | - float magFactor=std::pow(0.6f , magDrop); |
404 | - magFactor=qMin(magFactor, 2.0f); // Limit excessively bright display. |
405 | - |
406 | + StelToneReproducer* eye = core->getToneReproducer(); |
407 | + float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(getVMagnitudeWithExtinction(core)+11.0f); // How to calibrate? |
408 | + // Get the luminance scaled between 0 and 1 |
409 | + float aLum =eye->adaptLuminanceScaled(lum); |
410 | + float magFactor=qMin(qMax(aLum, 0.25f), 2.0f); |
411 | comaTexture->bind(); |
412 | - sPainter->setColor(magFactor,magFactor,0.6f*magFactor); |
413 | + sPainter->setColor(0.3f*magFactor,0.7*magFactor,magFactor); |
414 | sPainter->setArrays((Vec3d*)comaVertexArr.constData(), (Vec2f*)comaTexCoordArr.constData()); |
415 | sPainter->drawFromArray(StelPainter::Triangles, comaVertexArr.size()/3); |
416 | |
417 | @@ -521,11 +579,11 @@ |
418 | // Parabola equation: z=x²/2p. |
419 | // xOffset for the dust tail, this may introduce a bend. Units are x per sqrt(z). |
420 | void Comet::computeParabola(const float parameter, const float radius, const float zshift, |
421 | - QVector<double>& vertexArr, QVector<float>& texCoordArr, QVector<unsigned short> &indices, const float xOffset) { |
422 | + QVector<Vec3d>& vertexArr, QVector<float>& texCoordArr, QVector<unsigned short> &indices, const float xOffset) { |
423 | |
424 | - // GZ: keep the array and replace contents. However, using replace() is only slightly faster. |
425 | - if (vertexArr.length() < (3*(COMET_TAIL_SLICES*COMET_TAIL_STACKS+1))) |
426 | - vertexArr.resize(3*(COMET_TAIL_SLICES*COMET_TAIL_STACKS+1)); |
427 | + // keep the array and replace contents. However, using replace() is only slightly faster. |
428 | + if (vertexArr.length() < ((COMET_TAIL_SLICES*COMET_TAIL_STACKS+1))) |
429 | + vertexArr.resize((COMET_TAIL_SLICES*COMET_TAIL_STACKS+1)); |
430 | if (createTailIndices) indices.clear(); |
431 | if (createTailTextureCoords) texCoordArr.clear(); |
432 | int i; |
433 | @@ -541,8 +599,8 @@ |
434 | ya[i]=cos(i*da); |
435 | } |
436 | |
437 | - vertexArr.replace(0, 0.0); vertexArr.replace(1, 0.0); vertexArr.replace(2, zshift); |
438 | - int vertexArrIndex=3; |
439 | + vertexArr.replace(0, Vec3d(0.0, 0.0, zshift)); |
440 | + int vertexArrIndex=1; |
441 | if (createTailTextureCoords) texCoordArr << 0.5f << 0.5f; |
442 | // define the indices lying on circles, starting at 1: odd rings have 1/slices+1/2slices, even-numbered rings straight 1/slices |
443 | // inner ring#1 |
444 | @@ -553,9 +611,7 @@ |
445 | for (i=ring & 1; i<2*COMET_TAIL_SLICES; i+=2) { // i.e., ring1 has shifted vertices, ring2 has even ones. |
446 | x=xa[i]*radius*ring/COMET_TAIL_STACKS; |
447 | y=ya[i]*radius*ring/COMET_TAIL_STACKS; |
448 | - vertexArr.replace(vertexArrIndex++, x+xShift); |
449 | - vertexArr.replace(vertexArrIndex++, y); |
450 | - vertexArr.replace(vertexArrIndex++, z); |
451 | + vertexArr.replace(vertexArrIndex++, Vec3d(x+xShift, y, z)); |
452 | if (createTailTextureCoords) texCoordArr << 0.5+ 0.5*x/radius << 0.5+0.5*y/radius; |
453 | } |
454 | } |
455 | @@ -591,10 +647,11 @@ |
456 | createTailTextureCoords=false; |
457 | } |
458 | |
459 | + |
460 | // These are to avoid having index arrays for each comet when all are equal. |
461 | bool Comet::createTailIndices=true; |
462 | bool Comet::createTailTextureCoords=true; |
463 | StelTextureSP Comet::comaTexture; |
464 | StelTextureSP Comet::tailTexture; |
465 | -QVector<float> Comet::tailTexCoordArr; // computed only once FOR ALL COMETS! |
466 | -QVector<unsigned short> Comet::tailIndices; // computed only once FOR ALL COMETS! |
467 | +QVector<float> Comet::tailTexCoordArr; // computed only once for all Comets. |
468 | +QVector<unsigned short> Comet::tailIndices; // computed only once for all Comets. |
469 | |
470 | === modified file 'src/core/modules/Comet.hpp' |
471 | --- src/core/modules/Comet.hpp 2014-08-31 08:35:52 +0000 |
472 | +++ src/core/modules/Comet.hpp 2014-11-08 17:16:48 +0000 |
473 | @@ -32,6 +32,7 @@ |
474 | 2013-12: GZ: New algorithms for position computation following Paul Heafner: Fundamental Ephemeris Computations (Willmann-Bell 1999). |
475 | 2014-01: GZ: Parabolic tails appropriately scaled/rotated. Much is currently empirical, leaving room for physics-based improvements. |
476 | 2014-08: GZ: speedup in case hundreds of comets are loaded. |
477 | + 2014-11: GZ: tail extinction, better brightness balance. |
478 | */ |
479 | class Comet : public Planet |
480 | { |
481 | @@ -91,11 +92,15 @@ |
482 | virtual double getSiderealPeriod() const; |
483 | |
484 | //! GZ: override from Planet: extend with tail details. |
485 | - virtual void computePosition(const double date); |
486 | + //virtual void computePosition(const double date); |
487 | |
488 | //! re-implementation of Planet's draw() |
489 | virtual void draw(StelCore* core, float maxMagLabels, const QFont& planetNameFont); |
490 | |
491 | + // re-implementation of Planet's update() to prepare tails (extinction etc). @param deltaTime: ms (since last call) |
492 | + // TODO: computePosition can be removed and things added here! |
493 | + virtual void update(int deltaTime); |
494 | + |
495 | private: |
496 | //! @returns estimates for (Coma diameter [AU], gas tail length [AU]). |
497 | //! Using the formula from Guide found by the GSoC2012 initiative at http://www.projectpluto.com/update7b.htm#comet_tail_formula |
498 | @@ -117,7 +122,7 @@ |
499 | //! @param colorArr vertex colors (if not textured) r0, g0, b0, r1, g1, b1, ... |
500 | //! @param indices into the former arrays (zero-starting), triplets forming triangles: t0,0, t0,1, t0,2, t1,0, t1,1, t1,2, ... |
501 | //! @param xOffset for the dust tail, this may introduce a bend. Units are x per sqrt(z). |
502 | - void computeParabola(const float parameter, const float topradius, const float zshift, QVector<double>& vertexArr, QVector<float>& texCoordArr, QVector<unsigned short>& indices, const float xOffset=0.0f); |
503 | + void computeParabola(const float parameter, const float topradius, const float zshift, QVector<Vec3d>& vertexArr, QVector<float>& texCoordArr, QVector<unsigned short>& indices, const float xOffset=0.0f); |
504 | |
505 | double absoluteMagnitude; |
506 | double slopeParameter; |
507 | @@ -127,9 +132,10 @@ |
508 | |
509 | //GZ Tail additions |
510 | Vec2f tailFactors; // result of latest call to getComaDiameterAndTailLengthAU(); Results cached here for infostring. [0]=Coma diameter, [1] gas tail length. |
511 | - bool tailActive; //! true if there is a tail worth bothering (longer than COMET_MIN_TAIL_LENGTH_AU)? Drawing tails is quite costly. |
512 | + bool tailActive; //! true if there is a tail long enough to be worth drawing. Drawing tails is quite costly. |
513 | + bool tailBright; //! true if tail is bright enough to draw. |
514 | double deltaJDtail; //! like deltaJD, but time difference between tail geometry updates. |
515 | - double lastJDtail; //! like lastJD, but time of last tail geometry update. |
516 | + double lastJDtail; //! like lastJD, but time of last tail geometry update. |
517 | Mat4d gasTailRot; //! rotation matrix for gas tail parabola |
518 | Mat4d dustTailRot; //! rotation matrix for the skewed dust tail parabola |
519 | float dustTailWidthFactor; //!< empirical individual broadening of the dust tail end, compared to the gas tail end. Actually, dust tail width=2*comaWidth*dustTailWidthFactor. Default 1.5 |
520 | @@ -142,8 +148,10 @@ |
521 | static bool createTailIndices; |
522 | static bool createTailTextureCoords; |
523 | |
524 | - QVector<double> gastailVertexArr; // computed frequently, describes parabolic shape (along z axis) of gas tail. |
525 | - QVector<double> dusttailVertexArr; // computed frequently, describes parabolic shape (along z axis) of dust tail. |
526 | + QVector<Vec3d> gastailVertexArr; // computed frequently, describes parabolic shape (along z axis) of gas tail. |
527 | + QVector<Vec3d> dusttailVertexArr; // computed frequently, describes parabolic shape (along z axis) of dust tail. |
528 | + QVector<Vec3f> gastailColorArr; // NEW computed for every 5 mins, modulates gas tail brightness for extinction |
529 | + QVector<Vec3f> dusttailColorArr; // NEW computed for every 5 mins, modulates dust tail brightness for extinction |
530 | static QVector<float> tailTexCoordArr; // computed only once for all comets! |
531 | static QVector<unsigned short> tailIndices; // computed only once for all comets! |
532 | static StelTextureSP comaTexture; |
533 | |
534 | === modified file 'src/core/modules/MilkyWay.cpp' |
535 | --- src/core/modules/MilkyWay.cpp 2014-10-27 22:40:49 +0000 |
536 | +++ src/core/modules/MilkyWay.cpp 2014-11-08 17:16:48 +0000 |
537 | @@ -128,7 +128,7 @@ |
538 | for (int i=0; i<vertexArray->vertex.size(); ++i) |
539 | { |
540 | Vec3d vertAltAz=core->j2000ToAltAz(vertexArray->vertex.at(i), StelCore::RefractionOn); |
541 | - Q_ASSERT(vertAltAz.lengthSquared()-1.0 < 0.001f); |
542 | + Q_ASSERT(fabs(vertAltAz.lengthSquared()-1.0) < 0.001); |
543 | |
544 | float oneMag=0.0f; |
545 | extinction.forward(vertAltAz, &oneMag); |
546 | |
547 | === modified file 'src/core/modules/MinorPlanet.cpp' |
548 | --- src/core/modules/MinorPlanet.cpp 2014-08-31 10:34:41 +0000 |
549 | +++ src/core/modules/MinorPlanet.cpp 2014-11-08 17:16:48 +0000 |
550 | @@ -293,7 +293,6 @@ |
551 | //Calculate phase angle |
552 | //(Code copied from Planet::getVMagnitude()) |
553 | //(this is actually vector subtraction + the cosine theorem :)) |
554 | - // GZ Try now in float... speed difference is negligible, though. |
555 | const Vec3d& observerHelioPos = core->getObserverHeliocentricEclipticPos(); |
556 | const float observerRq = observerHelioPos.lengthSquared(); |
557 | const Vec3d& planetHelioPos = getHeliocentricEclipticPos(); |
558 | |
559 | === modified file 'src/core/modules/Planet.cpp' |
560 | --- src/core/modules/Planet.cpp 2014-11-05 14:49:44 +0000 |
561 | +++ src/core/modules/Planet.cpp 2014-11-08 17:16:48 +0000 |
562 | @@ -679,7 +679,7 @@ |
563 | double Planet::computeDistance(const Vec3d& obsHelioPos) |
564 | { |
565 | distance = (obsHelioPos-getHeliocentricEclipticPos()).length(); |
566 | - // GZ: improve fps by juggling updates for asteroids. They must be fast if close to observer, but can be slow if further away. |
567 | + // improve fps by juggling updates for asteroids. They must be fast if close to observer, but can be slow if further away. |
568 | if (pType == Planet::isAsteroid) |
569 | deltaJD=distance*StelCore::JD_SECOND; |
570 | return distance; |
571 | @@ -928,11 +928,11 @@ |
572 | { |
573 | if (hidden) |
574 | return; |
575 | - // GZ: Try to improve speed for minor planets: test if visible at all. |
576 | + // Try to improve speed for minor planets: test if visible at all. |
577 | // For a full catalog of NEAs (11000 objects), with this and resetting deltaJD according to distance, rendering time went 4.5fps->12fps. |
578 | - // AW: Apply this rule to asteroids only |
579 | - // Note that taking away the asteroids at this stage breaks dim-asteroid occultation of stars! |
580 | - if (((getVMagnitude(core)-1.0f) > core->getSkyDrawer()->getLimitMagnitude()) && pType==Planet::isAsteroid) |
581 | + // TBD: Note that taking away the asteroids at this stage breaks dim-asteroid occultation of stars! |
582 | + // Maybe make another configurable flag for those interested? |
583 | + if (((getVMagnitude(core)+1.0f) > core->getSkyDrawer()->getLimitMagnitude()) && pType==Planet::isAsteroid) |
584 | { |
585 | return; |
586 | } |
587 | |
588 | === modified file 'src/core/modules/Planet.hpp' |
589 | --- src/core/modules/Planet.hpp 2014-11-01 15:03:47 +0000 |
590 | +++ src/core/modules/Planet.hpp 2014-11-08 17:16:48 +0000 |
591 | @@ -192,7 +192,8 @@ |
592 | |
593 | // Compute the position in the parent Planet coordinate system |
594 | void computePositionWithoutOrbits(const double dateJD); |
595 | - virtual void computePosition(const double dateJD);// GZ: gets overridden in Comet! |
596 | + //virtual void computePosition(const double dateJD);// GZ: gets overridden in Comet! |
597 | + void computePosition(const double dateJD);// GZ: gets overridden in Comet! |
598 | |
599 | // Compute the transformation matrix from the local Planet coordinate to the parent Planet coordinate |
600 | void computeTransMatrix(double date); |
601 | @@ -237,8 +238,8 @@ |
602 | static void setLabelColor(const Vec3f& lc) {labelColor = lc;} |
603 | static const Vec3f& getLabelColor(void) {return labelColor;} |
604 | |
605 | - // update displayed elements. @param deltaTime: ms (?) |
606 | - void update(int deltaTime); |
607 | + // update displayed elements. @param deltaTime: ms (since last call) |
608 | + virtual void update(int deltaTime); |
609 | |
610 | void setFlagHints(bool b){hintFader = b;} |
611 | bool getFlagHints(void) const {return hintFader;} |
Looks good to me :)