Merge lp:~cardinot/stellarium/MeteorShower into lp:stellarium
- MeteorShower
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 6894 |
Proposed branch: | lp:~cardinot/stellarium/MeteorShower |
Merge into: | lp:stellarium |
Diff against target: |
1982 lines (+796/-552) 13 files modified
plugins/MeteorShowers/resources/showers.json (+133/-0) plugins/MeteorShowers/src/MeteorShower.cpp (+22/-8) plugins/MeteorShowers/src/MeteorShower.hpp (+9/-8) plugins/MeteorShowers/src/MeteorShowers.cpp (+37/-36) plugins/MeteorShowers/src/MeteorShowers.hpp (+17/-26) plugins/MeteorShowers/src/MeteorStream.cpp (+58/-155) plugins/MeteorShowers/src/MeteorStream.hpp (+16/-28) plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp (+1/-2) plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp (+1/-2) src/core/modules/Meteor.cpp (+371/-202) src/core/modules/Meteor.hpp (+69/-27) src/core/modules/MeteorMgr.cpp (+53/-51) src/core/modules/MeteorMgr.hpp (+9/-7) |
To merge this branch: | bzr merge lp:~cardinot/stellarium/MeteorShower |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexander Wolf | Approve | ||
Fabien Chéreau | Needs Fixing | ||
Review via email: mp+224654@code.launchpad.net |
Commit message
Description of the change
* refactoring Meteor and MeteorMgr classes based on MeteorShowers plugin
- it makes us able to reuse the code on MeteorShowers plugin
* drawing train as a triangular prism;
- reduce aliasing
- it makes us able to control thickness
* implements the color of meteors
- JSON format:
"colors":
[
{
"color": "white",
"intensity": 90
},
{
"color": "red",
"intensity": 10
},
* initial implementation of bolides
* improvements on magnitude managment
- 6886. By Alexander Wolf
-
updated Windows stuff
- 6887. By Alexander Wolf
-
a bit cleanup of the code
Marcos Cardinot (cardinot) wrote : | # |
> Please update default showers.json file.
Done! =D
Fabien Chéreau (xalioth) wrote : | # |
Please wait a bit before merging I want to make the review as well
Le 26 juin 2014 21:23, "Marcos CARDINOT" <email address hidden> a écrit :
> > Please update default showers.json file.
>
> Done! =D
> --
> https:/
> You are subscribed to branch lp:stellarium.
>
- 6888. By barrykgerdes
-
updated textures for M105 area
- 6889. By Alexander Wolf
-
updated README
Fabien Chéreau (xalioth) wrote : | # |
Good work!
Please avoid using double when float could do it. It's faster and uses less memory.
Also we should try to avoid using GL_DOUBLE as OpenGL ES2 doesn't support it
Fabien Chéreau (xalioth) wrote : | # |
So needs a bit of fixinf, but I like the code
- 6890. By Alexander Wolf
-
Updated message for InnoSetup
Marcos Cardinot (cardinot) wrote : | # |
Hello Fabien,
thanks a million for your review!
> Please avoid using double when float could do it. It's faster and uses less memory.
Yeah, good point!
done
> Also we should try to avoid using GL_DOUBLE as OpenGL ES2 doesn't support it
Hmmm... what's your suggestion to sort it out?
I saw that we have a Q_ASSERT(array.type == GL_DOUBLE); in StelPainter:
Alexander Wolf (alexwolf) wrote : | # |
Marcos, please see diff comments also :)
Marcos Cardinot (cardinot) wrote : | # |
> Marcos, please see diff comments also :)
Thanks Alex, I hadn't noticed it! =D
Anyway, it seems that I just left things around GL_DOUBLE issue.
What would be the best way to use GL_FLOAT? it seems that just change the type of the vertexArrays is not enough, because we have a QASSERT(
Alexander Wolf (alexwolf) wrote : | # |
>Also we should try to avoid using GL_DOUBLE as OpenGL ES2 doesn't support it
What about make a test - use only GL_FLOAT (in StelPainter too)?
- 6891. By Alexander Wolf
-
apply translations for testing (0.13.0beta1)
Fabien Chéreau (xalioth) wrote : | # |
Hey Marcos,
you are right for the GL_DOUBLE in fact if you let the StelProjector do the
vertex projection it's OK to have GL_DOUBLE, because they are converted to
GL_FLOAT before being sent to opengl.
Fabien
On Sun, Jun 29, 2014 at 8:45 AM, Alexander Wolf <email address hidden>
wrote:
> >Also we should try to avoid using GL_DOUBLE as OpenGL ES2 doesn't support
> it
>
> What about make a test - use only GL_FLOAT (in StelPainter too)?
> --
> https:/
> You are reviewing the proposed merge of
> lp:~mcardinot/stellarium/MeteorShower into lp:stellarium.
>
- 6892. By Alexander Wolf
-
Updated settings for MSVC
- 6893. By Alexander Wolf
-
tiny fix for MSVC2012
Alexander Wolf (alexwolf) wrote : | # |
I think it's ready to merge
Fabien Chéreau (xalioth) wrote : | # |
OK for me
On Sun, Jun 29, 2014 at 7:10 PM, Alexander Wolf <email address hidden>
wrote:
> Review: Approve
>
> I think it's ready to merge
> --
> https:/
> You are reviewing the proposed merge of
> lp:~mcardinot/stellarium/MeteorShower into lp:stellarium.
>
- 6894. By Marcos Cardinot
-
MeteorMgr and MeteorShowers Improvements
Preview Diff
1 | === modified file 'plugins/MeteorShowers/resources/showers.json' |
2 | --- plugins/MeteorShowers/resources/showers.json 2014-05-10 23:16:09 +0000 |
3 | +++ plugins/MeteorShowers/resources/showers.json 2014-06-29 14:51:17 +0000 |
4 | @@ -290,6 +290,17 @@ |
5 | "radiantDelta": "-10", |
6 | "driftAlpha": "5", |
7 | "driftDelta": "1", |
8 | + "colors": |
9 | + [ |
10 | + { |
11 | + "color": "white", |
12 | + "intensity": 60 |
13 | + }, |
14 | + { |
15 | + "color": "yellow", |
16 | + "intensity": 40 |
17 | + } |
18 | + ], |
19 | "parentObj": "Comet 169P/NEAT", |
20 | "pidx": 2.5 |
21 | }, |
22 | @@ -487,6 +498,21 @@ |
23 | "radiantDelta": "+54", |
24 | "driftAlpha": "0", |
25 | "driftDelta": "0", |
26 | + "colors": |
27 | + [ |
28 | + { |
29 | + "color": "white", |
30 | + "intensity": 50 |
31 | + }, |
32 | + { |
33 | + "color": "orangeYellow", |
34 | + "intensity": 30 |
35 | + }, |
36 | + { |
37 | + "color": "yellow", |
38 | + "intensity": 20 |
39 | + } |
40 | + ], |
41 | "parentObj": "Comet 21P/Giacobini-Zinner", |
42 | "pidx": 2.6 |
43 | }, |
44 | @@ -630,6 +656,17 @@ |
45 | "radiantDelta": "-1", |
46 | "driftAlpha": "5", |
47 | "driftDelta": "2", |
48 | + "colors": |
49 | + [ |
50 | + { |
51 | + "color": "white", |
52 | + "intensity": 70 |
53 | + }, |
54 | + { |
55 | + "color": "yellow", |
56 | + "intensity": 30 |
57 | + } |
58 | + ], |
59 | "parentObj": "Comet 1P/Halley", |
60 | "pidx": 2.4 |
61 | }, |
62 | @@ -705,6 +742,21 @@ |
63 | "radiantDelta": "+33", |
64 | "driftAlpha": "5", |
65 | "driftDelta": "-0.1", |
66 | + "colors": |
67 | + [ |
68 | + { |
69 | + "color": "white", |
70 | + "intensity": 65 |
71 | + }, |
72 | + { |
73 | + "color": "yellow", |
74 | + "intensity": 25 |
75 | + }, |
76 | + { |
77 | + "color": "greenBlue", |
78 | + "intensity": 10 |
79 | + } |
80 | + ], |
81 | "parentObj": "Minor planet (3200) Phaethon", |
82 | "pidx": 2.6 |
83 | }, |
84 | @@ -1008,6 +1060,17 @@ |
85 | "radiantDelta": "+22", |
86 | "driftAlpha": "3", |
87 | "driftDelta": "-1.25", |
88 | + "colors": |
89 | + [ |
90 | + { |
91 | + "color": "blueGreen", |
92 | + "intensity": 50 |
93 | + }, |
94 | + { |
95 | + "color": "white", |
96 | + "intensity": 50 |
97 | + } |
98 | + ], |
99 | "parentObj": "Comet 55P/Tempel-Tuttle", |
100 | "pidx": 2.5 |
101 | }, |
102 | @@ -1215,6 +1278,17 @@ |
103 | "radiantDelta": "+22", |
104 | "driftAlpha": "5", |
105 | "driftDelta": "1", |
106 | + "colors": |
107 | + [ |
108 | + { |
109 | + "color": "yellow", |
110 | + "intensity": 80 |
111 | + }, |
112 | + { |
113 | + "color": "white", |
114 | + "intensity": 20 |
115 | + } |
116 | + ], |
117 | "parentObj": "Comet C/1917 F1 (Mellish)", |
118 | "pidx": 2.3 |
119 | }, |
120 | @@ -1268,6 +1342,21 @@ |
121 | "radiantDelta": "+16", |
122 | "driftAlpha": "3", |
123 | "driftDelta": "0.5", |
124 | + "colors": |
125 | + [ |
126 | + { |
127 | + "color": "white", |
128 | + "intensity": 50 |
129 | + }, |
130 | + { |
131 | + "color": "greenBlue", |
132 | + "intensity": 30 |
133 | + }, |
134 | + { |
135 | + "color": "yellow", |
136 | + "intensity": 20 |
137 | + } |
138 | + ], |
139 | "pidx": 2.5 |
140 | }, |
141 | "PAU": |
142 | @@ -1371,6 +1460,17 @@ |
143 | "radiantDelta": "+58", |
144 | "driftAlpha": "6", |
145 | "driftDelta": "1", |
146 | + "colors": |
147 | + [ |
148 | + { |
149 | + "color": "white", |
150 | + "intensity": 70 |
151 | + }, |
152 | + { |
153 | + "color": "blueGreen", |
154 | + "intensity": 30 |
155 | + } |
156 | + ], |
157 | "parentObj": "Comet 109P/Swift-Tuttle", |
158 | "pidx": 2.2 |
159 | }, |
160 | @@ -1548,6 +1648,17 @@ |
161 | "radiantDelta": "49", |
162 | "driftAlpha": "3", |
163 | "driftDelta": "-1", |
164 | + "colors": |
165 | + [ |
166 | + { |
167 | + "color": "white", |
168 | + "intensity": 70 |
169 | + }, |
170 | + { |
171 | + "color": "blueGreen", |
172 | + "intensity": 30 |
173 | + } |
174 | + ], |
175 | "parentObj": "Minor planet 2003 EH1 and Comet C/1490 Y1", |
176 | "pidx": 2.1 |
177 | }, |
178 | @@ -1622,6 +1733,17 @@ |
179 | "radiantDelta": "-16", |
180 | "driftAlpha": "4", |
181 | "driftDelta": "0.5", |
182 | + "colors": |
183 | + [ |
184 | + { |
185 | + "color": "white", |
186 | + "intensity": 60 |
187 | + }, |
188 | + { |
189 | + "color": "yellow", |
190 | + "intensity": 40 |
191 | + } |
192 | + ], |
193 | "parentObj": "Comet 96P/Machholz", |
194 | "pidx": 3.2 |
195 | }, |
196 | @@ -1727,6 +1849,17 @@ |
197 | "radiantDelta": "+15", |
198 | "driftAlpha": "3", |
199 | "driftDelta": "1", |
200 | + "colors": |
201 | + [ |
202 | + { |
203 | + "color": "yellow", |
204 | + "intensity": 80 |
205 | + }, |
206 | + { |
207 | + "color": "white", |
208 | + "intensity": 20 |
209 | + } |
210 | + ], |
211 | "parentObj": "Comet 2P/Encke", |
212 | "pidx": 2.3 |
213 | }, |
214 | |
215 | === modified file 'plugins/MeteorShowers/src/MeteorShower.cpp' |
216 | --- plugins/MeteorShowers/src/MeteorShower.cpp 2014-05-22 08:08:43 +0000 |
217 | +++ plugins/MeteorShowers/src/MeteorShower.cpp 2014-06-29 14:51:17 +0000 |
218 | @@ -1,4 +1,5 @@ |
219 | /* |
220 | + * Stellarium: Meteor Showers Plug-in |
221 | * Copyright (C) 2013 Marcos Cardinot |
222 | * Copyright (C) 2011 Alexander Wolf |
223 | * |
224 | @@ -22,17 +23,9 @@ |
225 | #include "StelApp.hpp" |
226 | #include "StelCore.hpp" |
227 | #include "StelModuleMgr.hpp" |
228 | -#include "StelObject.hpp" |
229 | -#include "StelPainter.hpp" |
230 | #include "StelTexture.hpp" |
231 | #include "StelUtils.hpp" |
232 | |
233 | -#include <QDebug> |
234 | -#include <QList> |
235 | -#include <QTextStream> |
236 | -#include <QVariant> |
237 | -#include <QVariantMap> |
238 | - |
239 | StelTextureSP MeteorShower::radiantTexture; |
240 | float MeteorShower::showLabels = true; |
241 | bool MeteorShower::radiantMarkerEnabled = true; |
242 | @@ -82,6 +75,17 @@ |
243 | } |
244 | } |
245 | |
246 | + if(map.contains("colors")) |
247 | + { |
248 | + foreach(const QVariant &ms, map.value("colors").toList()) |
249 | + { |
250 | + QVariantMap colorMap = ms.toMap(); |
251 | + QString color = colorMap.value("color").toString(); |
252 | + int intensity = colorMap.value("intensity").toInt(); |
253 | + colors.append(colorPair(color, intensity)); |
254 | + } |
255 | + } |
256 | + |
257 | updateCurrentData(getSkyQDateTime()); |
258 | // ensures that all objects will be drawn once |
259 | // that's to avoid crashes by trying select a nonexistent object |
260 | @@ -123,6 +127,16 @@ |
261 | } |
262 | map["activity"] = activityList; |
263 | |
264 | + QVariantList colorList; |
265 | + foreach(const colorPair &c, colors) |
266 | + { |
267 | + QVariantMap colorMap; |
268 | + colorMap["color"] = c.first; |
269 | + colorMap["intensity"] = c.second; |
270 | + colorList << colorMap; |
271 | + } |
272 | + map["colors"] = colorList; |
273 | + |
274 | return map; |
275 | } |
276 | |
277 | |
278 | === modified file 'plugins/MeteorShowers/src/MeteorShower.hpp' |
279 | --- plugins/MeteorShowers/src/MeteorShower.hpp 2014-05-06 12:09:45 +0000 |
280 | +++ plugins/MeteorShowers/src/MeteorShower.hpp 2014-06-29 14:51:17 +0000 |
281 | @@ -1,4 +1,5 @@ |
282 | /* |
283 | + * Stellarium: Meteor Showers Plug-in |
284 | * Copyright (C) 2013 Marcos Cardinot |
285 | * Copyright (C) 2011 Alexander Wolf |
286 | * |
287 | @@ -21,8 +22,6 @@ |
288 | #define _METEORSHOWER_HPP_ |
289 | |
290 | #include <QDateTime> |
291 | -#include <QVariantMap> |
292 | -#include <QString> |
293 | |
294 | #include "StelFader.hpp" |
295 | #include "StelObject.hpp" |
296 | @@ -30,8 +29,6 @@ |
297 | #include "StelTextureTypes.hpp" |
298 | #include "StelTranslator.hpp" |
299 | |
300 | -class StelPainter; |
301 | - |
302 | //! @class MeteorShower |
303 | //! A MeteorShower object represents one meteor shower on the sky. |
304 | //! Details about the meteor showers are passed using a QVariant which contains |
305 | @@ -105,6 +102,9 @@ |
306 | return zhr; |
307 | } |
308 | |
309 | + //! <colorName, intensity> |
310 | + typedef QPair<QString, int> colorPair; |
311 | + |
312 | private: |
313 | Vec3d XYZ; //! Cartesian equatorial position |
314 | Vec3d XY; //! Store temporary 2D position |
315 | @@ -131,12 +131,13 @@ |
316 | QString designation; //! The designation of the meteor shower |
317 | QList<activityData> activity; //! List of activity |
318 | int speed; //! Speed of meteors |
319 | - double rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day |
320 | - double rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day |
321 | - double driftAlpha; //! Drift of R.A. |
322 | - double driftDelta; //! Drift of Dec. |
323 | + float rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day |
324 | + float rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day |
325 | + float driftAlpha; //! Drift of R.A. |
326 | + float driftDelta; //! Drift of Dec. |
327 | QString parentObj; //! Parent object for meteor shower |
328 | float pidx; //! The population index |
329 | + QList<colorPair> colors; //! <colorName, 0-100> |
330 | |
331 | //current information |
332 | double radiantAlpha; //! Current R.A. for radiant of meteor shower |
333 | |
334 | === modified file 'plugins/MeteorShowers/src/MeteorShowers.cpp' |
335 | --- plugins/MeteorShowers/src/MeteorShowers.cpp 2014-05-31 07:52:58 +0000 |
336 | +++ plugins/MeteorShowers/src/MeteorShowers.cpp 2014-06-29 14:51:17 +0000 |
337 | @@ -1,4 +1,5 @@ |
338 | /* |
339 | + * Stellarium: Meteor Showers Plug-in |
340 | * Copyright (C) 2013 Marcos Cardinot |
341 | * Copyright (C) 2011 Alexander Wolf |
342 | * |
343 | @@ -17,22 +18,16 @@ |
344 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. |
345 | */ |
346 | |
347 | -#include <QColor> |
348 | -#include <QDebug> |
349 | #include <QDir> |
350 | -#include <QFileInfo> |
351 | -#include <QList> |
352 | -#include <QNetworkAccessManager> |
353 | #include <QNetworkReply> |
354 | +#include <QSettings> |
355 | #include <QTimer> |
356 | -#include <QSettings> |
357 | |
358 | #include "LabelMgr.hpp" |
359 | #include "LandscapeMgr.hpp" |
360 | -#include "MeteorShower.hpp" |
361 | +#include "MeteorMgr.hpp" |
362 | +#include "MeteorShowerDialog.hpp" |
363 | #include "MeteorShowers.hpp" |
364 | -#include "MeteorShowerDialog.hpp" |
365 | -#include "MeteorStream.hpp" |
366 | #include "Planet.hpp" |
367 | #include "StelApp.hpp" |
368 | #include "StelCore.hpp" |
369 | @@ -42,15 +37,12 @@ |
370 | #include "StelJsonParser.hpp" |
371 | #include "StelModuleMgr.hpp" |
372 | #include "StelObjectMgr.hpp" |
373 | -#include "StelPainter.hpp" |
374 | #include "StelProgressController.hpp" |
375 | -#include "StelProjector.hpp" |
376 | #include "StelTextureMgr.hpp" |
377 | -#include "StelUtils.hpp" |
378 | |
379 | #define CATALOG_FORMAT_VERSION 1 /* Version of format of catalog */ |
380 | |
381 | -const double MeteorShowers::zhrToWsr = 1.6667f / 3600.f; |
382 | +const double MeteorShowers::zhrToWsr = MeteorMgr::zhrToWsr; |
383 | |
384 | /* |
385 | This method is the one called automatically by the StelModuleMgr just |
386 | @@ -138,7 +130,7 @@ |
387 | { |
388 | if (actionName == StelModule::ActionDraw) |
389 | { |
390 | - return StelApp::getInstance().getModuleMgr().getModule("MeteorMgr")->getCallOrder(actionName)+0; |
391 | + return GETSTELMODULE(MeteorMgr)->getCallOrder(actionName)+10.; |
392 | } |
393 | |
394 | return 0; |
395 | @@ -371,16 +363,12 @@ |
396 | |
397 | void MeteorShowers::drawStream(StelCore* core, StelPainter& painter) |
398 | { |
399 | - LandscapeMgr* landmgr = (LandscapeMgr*)StelApp::getInstance().getModuleMgr().getModule("LandscapeMgr"); |
400 | + LandscapeMgr* landmgr = GETSTELMODULE(LandscapeMgr); |
401 | if (landmgr->getFlagAtmosphere() && landmgr->getLuminance()>5) |
402 | { |
403 | return; |
404 | } |
405 | |
406 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
407 | - glEnable(GL_BLEND); |
408 | - painter.enableTexture2d(false); |
409 | - |
410 | int index = 0; |
411 | if (active.size() > 0) |
412 | { |
413 | @@ -388,7 +376,8 @@ |
414 | { |
415 | Q_UNUSED(a); |
416 | // step through and draw all active meteors |
417 | - for (std::vector<MeteorStream*>::iterator iter = active[index].begin(); iter != active[index].end(); ++iter) |
418 | + std::vector<MeteorStream*>::iterator iter; |
419 | + for (iter = active[index].begin(); iter != active[index].end(); ++iter) |
420 | { |
421 | (*iter)->draw(core, painter); |
422 | } |
423 | @@ -480,6 +469,7 @@ |
424 | newData.finish = ms->finish; |
425 | newData.peak = ms->peak; |
426 | newData.status = ms->status; |
427 | + newData.colors = ms->colors; |
428 | activeInfo.append(newData); |
429 | } |
430 | else //just overwrites |
431 | @@ -505,6 +495,20 @@ |
432 | } |
433 | |
434 | StelCore* core = StelApp::getInstance().getCore(); |
435 | + |
436 | + double tspeed = core->getTimeRate()*86400; // sky seconds per actual second |
437 | + if (!tspeed) { // is paused? |
438 | + return; // freeze meteors at the current position |
439 | + } |
440 | + |
441 | + deltaTime*=1000; |
442 | + // if stellarium has been suspended, don't create huge number of meteors to |
443 | + // make up for lost time! |
444 | + if (deltaTime > 500) |
445 | + { |
446 | + deltaTime = 500; |
447 | + } |
448 | + |
449 | QList<activeData> old_activeInfo; |
450 | |
451 | //check if the sky date changed |
452 | @@ -546,8 +550,6 @@ |
453 | } |
454 | } |
455 | |
456 | - deltaTime*=1000; |
457 | - |
458 | std::vector<std::vector<MeteorStream*> >::iterator iterOut; |
459 | std::vector<MeteorStream*>::iterator iterIn; |
460 | index = 0; |
461 | @@ -578,19 +580,23 @@ |
462 | index = 0; |
463 | foreach (const activeData ¤t, activeInfo) |
464 | { |
465 | + std::vector<MeteorStream*> aux; |
466 | + if (active.empty() || active.size() < (unsigned) activeInfo.size()) |
467 | + { |
468 | + if(tspeed<0 || fabs(tspeed)>1.) |
469 | + { |
470 | + activeInfo.removeAt(index); |
471 | + continue; // don't create new meteors |
472 | + } |
473 | + active.push_back(aux); |
474 | + } |
475 | + |
476 | int ZHR = calculateZHR(current.zhr, |
477 | current.variable, |
478 | current.start, |
479 | current.finish, |
480 | current.peak); |
481 | |
482 | - // if stellarium has been suspended, don't create huge number of meteors to |
483 | - // make up for lost time! |
484 | - if (deltaTime > 500) |
485 | - { |
486 | - deltaTime = 500; |
487 | - } |
488 | - |
489 | // determine average meteors per frame needing to be created |
490 | int mpf = (int)((double)ZHR*zhrToWsr*deltaTime/1000.0 + 0.5); |
491 | if (mpf<1) |
492 | @@ -598,12 +604,6 @@ |
493 | mpf = 1; |
494 | } |
495 | |
496 | - std::vector<MeteorStream*> aux; |
497 | - if (active.empty() || active.size() < (unsigned) activeInfo.size()) |
498 | - { |
499 | - active.push_back(aux); |
500 | - } |
501 | - |
502 | for (int i=0; i<mpf; ++i) |
503 | { |
504 | // start new meteor based on ZHR time probability |
505 | @@ -614,7 +614,8 @@ |
506 | current.speed, |
507 | current.radiantAlpha, |
508 | current.radiantDelta, |
509 | - current.pidx); |
510 | + current.pidx, |
511 | + current.colors); |
512 | active[index].push_back(m); |
513 | } |
514 | } |
515 | |
516 | === modified file 'plugins/MeteorShowers/src/MeteorShowers.hpp' |
517 | --- plugins/MeteorShowers/src/MeteorShowers.hpp 2014-04-25 12:54:45 +0000 |
518 | +++ plugins/MeteorShowers/src/MeteorShowers.hpp 2014-06-29 14:51:17 +0000 |
519 | @@ -1,4 +1,5 @@ |
520 | /* |
521 | + * Stellarium: Meteor Showers Plug-in |
522 | * Copyright (C) 2013 Marcos Cardinot |
523 | * Copyright (C) 2011 Alexander Wolf |
524 | * |
525 | @@ -20,27 +21,16 @@ |
526 | #ifndef METEORSHOWERS_HPP_ |
527 | #define METEORSHOWERS_HPP_ |
528 | |
529 | +#include <QColor> |
530 | + |
531 | #include "MeteorShower.hpp" |
532 | #include "MeteorStream.hpp" |
533 | -#include "StelFader.hpp" |
534 | -#include "StelModule.hpp" |
535 | #include "StelObjectModule.hpp" |
536 | -#include "StelTextureTypes.hpp" |
537 | - |
538 | -#include <QColor> |
539 | -#include <QDateTime> |
540 | -#include <QFont> |
541 | -#include <QSharedPointer> |
542 | -#include <QVariantMap> |
543 | - |
544 | + |
545 | +class MeteorShowerDialog; |
546 | class QNetworkAccessManager; |
547 | class QNetworkReply; |
548 | -class QProgressBar; |
549 | -class QSettings; |
550 | -class QTimer; |
551 | -class MeteorShowerDialog; |
552 | class StelButton; |
553 | -class StelPainter; |
554 | |
555 | typedef QSharedPointer<MeteorShower> MeteorShowerP; |
556 | |
557 | @@ -365,17 +355,18 @@ |
558 | |
559 | typedef struct |
560 | { |
561 | - QString showerID; //! The ID of the meteor shower |
562 | - QDateTime start; //! First day for activity |
563 | - QDateTime finish; //! Latest day for activity |
564 | - QDateTime peak; //! Day with maximum for activity |
565 | - int status; //! 0:inactive 1:activeRealData 2:activeGenericData |
566 | - int zhr; //! ZHR of shower |
567 | - QString variable; //! value of variable for ZHR |
568 | - int speed; //! Speed of meteors |
569 | - double radiantAlpha; //! R.A. for radiant of meteor shower |
570 | - double radiantDelta; //! Dec. for radiant of meteor shower |
571 | - float pidx; //! Population index |
572 | + QString showerID; //! The ID of the meteor shower |
573 | + QDateTime start; //! First day for activity |
574 | + QDateTime finish; //! Latest day for activity |
575 | + QDateTime peak; //! Day with maximum for activity |
576 | + int status; //! 0:inactive 1:activeRealData 2:activeGenericData |
577 | + int zhr; //! ZHR of shower |
578 | + QString variable; //! value of variable for ZHR |
579 | + int speed; //! Speed of meteors |
580 | + float radiantAlpha; //! R.A. for radiant of meteor shower |
581 | + float radiantDelta; //! Dec. for radiant of meteor shower |
582 | + float pidx; //! Population index |
583 | + QList<MeteorShower::colorPair> colors; //! Population index |
584 | } activeData; |
585 | |
586 | QList<activeData> activeInfo; //! List of active meteors |
587 | |
588 | === modified file 'plugins/MeteorShowers/src/MeteorStream.cpp' |
589 | --- plugins/MeteorShowers/src/MeteorStream.cpp 2014-05-08 21:22:20 +0000 |
590 | +++ plugins/MeteorShowers/src/MeteorStream.cpp 2014-06-29 14:51:17 +0000 |
591 | @@ -1,4 +1,5 @@ |
592 | /* |
593 | + * Stellarium: Meteor Showers Plug-in |
594 | * Copyright (C) 2013 Marcos Cardinot |
595 | * |
596 | * This program is free software; you can redistribute it and/or |
597 | @@ -16,116 +17,78 @@ |
598 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. |
599 | */ |
600 | |
601 | -#include <cstdlib> |
602 | - |
603 | +#include "MeteorShowers.hpp" |
604 | #include "MeteorStream.hpp" |
605 | -#include "StelCore.hpp" |
606 | -#include "StelToneReproducer.hpp" |
607 | -#include "StelMovementMgr.hpp" |
608 | -#include "StelPainter.hpp" |
609 | |
610 | MeteorStream::MeteorStream(const StelCore* core, |
611 | - double speed, |
612 | - double radiantAlpha, |
613 | - double radiantDelta, |
614 | - float pidx) |
615 | + int speed, |
616 | + float radiantAlpha, |
617 | + float radiantDelta, |
618 | + float pidx, |
619 | + QList<MeteorShower::colorPair> colors) |
620 | : m_speed(speed) |
621 | - , m_pidx(pidx) |
622 | - , m_minDist(0.) |
623 | - , m_distMultiplier(0.) |
624 | - , m_startH(0.) |
625 | - , m_endH(0.) |
626 | - , m_mag(1.f) |
627 | + , m_segments(10) |
628 | { |
629 | - |
630 | // if speed is zero, use a random value |
631 | if (!speed) |
632 | { |
633 | m_speed = 11+(double)rand()/((double)RAND_MAX+1)*61; // abs range 11-72 km/s |
634 | } |
635 | |
636 | - // the meteor starts dead, after we'll calculate the position |
637 | - // if the position is within the bounds, this parameter will be changed to TRUE |
638 | - m_alive = false; |
639 | - |
640 | - double high_range = EARTH_RADIUS+HIGH_ALTITUDE; |
641 | - double low_range = EARTH_RADIUS+LOW_ALTITUDE; |
642 | - |
643 | // view matrix of meteor model |
644 | m_viewMatrix = Mat4d::zrotation(radiantAlpha) * Mat4d::yrotation(M_PI_2 - radiantDelta); |
645 | |
646 | - // find observer position in meteor coordinate system |
647 | - m_obs = core->altAzToJ2000(Vec3d(0,0,EARTH_RADIUS)); |
648 | - m_obs.transfo4d(m_viewMatrix.transpose()); |
649 | - |
650 | - // select random trajectory using polar coordinates in XY plane, centered on observer |
651 | - m_xydistance = (double)rand() / ((double)RAND_MAX+1)*(VISIBLE_RADIUS); |
652 | - double angle = (double)rand() / ((double)RAND_MAX+1)*2*M_PI; |
653 | - |
654 | - // set meteor start x,y |
655 | - m_position[0] = m_posInternal[0] = m_posTrain[0] = m_xydistance*cos(angle) + m_obs[0]; |
656 | - m_position[1] = m_posInternal[1] = m_posTrain[1] = m_xydistance*sin(angle) + m_obs[1]; |
657 | - |
658 | - // D is distance from center of earth |
659 | - double D = sqrt(m_position[0]*m_position[0] + m_position[1]*m_position[1]); |
660 | - |
661 | - if (D > high_range) // won't be visible, meteor still dead |
662 | + // building meteor model |
663 | + m_alive = Meteor::initMeteorModel(core, m_segments, m_viewMatrix, meteor); |
664 | + if (!m_alive) |
665 | { |
666 | return; |
667 | } |
668 | |
669 | - m_posTrain[2] = m_position[2] = m_startH = sqrt(high_range*high_range - D*D); |
670 | - |
671 | - // determine end of burn point, and nearest point to observer for distance mag calculation |
672 | - // mag should be max at nearest point still burning |
673 | - m_endH = -m_startH; // earth grazing |
674 | - m_minDist = m_xydistance; |
675 | - if (D <= low_range) |
676 | - { |
677 | - m_endH = sqrt(low_range*low_range - D*D); |
678 | - m_minDist = sqrt(m_xydistance*m_xydistance + pow(m_endH - m_obs[2], 2)); |
679 | - } |
680 | - |
681 | - if (m_minDist > VISIBLE_RADIUS) |
682 | - { |
683 | - // on average, not visible (although if were zoomed ...) |
684 | - return; //meteor still dead |
685 | - } |
686 | - |
687 | - // If everything is ok until here, |
688 | - m_alive = true; //the meteor is alive |
689 | - |
690 | - // determine intensity [-3; 4.5] |
691 | - float Mag1 = (double)rand()/((double)RAND_MAX+1)*7.5f - 3; |
692 | - float Mag2 = (double)rand()/((double)RAND_MAX+1)*7.5f - 3; |
693 | - float Mag = (Mag1 + Mag2)/2.0f; |
694 | - |
695 | - // compute RMag and CMag |
696 | - RCMag rcMag; |
697 | - core->getSkyDrawer()->computeRCMag(Mag, &rcMag); |
698 | - m_mag = rcMag.luminance; |
699 | - |
700 | - // most visible meteors are under about 180km distant |
701 | - // scale max mag down if outside this range |
702 | - float scale = 1; |
703 | - if (m_minDist!=0) |
704 | - { |
705 | - scale = 180*180 / (m_minDist*m_minDist); |
706 | - } |
707 | - if (scale < 1) |
708 | - { |
709 | - m_mag *= scale; |
710 | - } |
711 | - |
712 | // implements the population index |
713 | float oneMag = -0.2; // negative, working in different scale ( 0 to 1 - where 1 is brighter) |
714 | - if (m_pidx) // is not zero |
715 | + if (pidx) // is not zero |
716 | { |
717 | if (rand()%100 < 100.f/pidx) // probability |
718 | { |
719 | - m_mag += oneMag; // (m+1) |
720 | - } |
721 | - } |
722 | + meteor.mag += oneMag; // (m+1) |
723 | + } |
724 | + } |
725 | + |
726 | + // determine the meteor color |
727 | + if (colors.isEmpty()) { |
728 | + colors.push_back(MeteorShower::colorPair("white", 100)); |
729 | + } else { |
730 | + // handle cases when the total intensity is less than 100 |
731 | + int totalIntensity = 0; |
732 | + int indexWhite = -1; |
733 | + for (int i=0; i<colors.size(); i++) { |
734 | + totalIntensity += colors.at(i).second; |
735 | + if (colors.at(i).first == "white") { |
736 | + indexWhite = i; |
737 | + } |
738 | + } |
739 | + |
740 | + int increaseWhite = 0; |
741 | + if (totalIntensity > 100) { |
742 | + qDebug() << "MeteorShowers plugin (showers.json): Total intensity must be less than 100"; |
743 | + colors.clear(); |
744 | + colors.push_back(MeteorShower::colorPair("white", 100)); |
745 | + } else { |
746 | + increaseWhite = 100 - totalIntensity; |
747 | + } |
748 | + |
749 | + if (increaseWhite > 0) { |
750 | + if (indexWhite == -1) { |
751 | + colors.push_back(MeteorShower::colorPair("white", increaseWhite)); |
752 | + } else { |
753 | + colors[indexWhite].second = increaseWhite; |
754 | + } |
755 | + } |
756 | + } |
757 | + |
758 | + // building lineColorArray and trainColorArray |
759 | + Meteor::buildColorArrays(m_segments, colors, m_lineColorArray, m_trainColorArray); |
760 | } |
761 | |
762 | MeteorStream::~MeteorStream() |
763 | @@ -140,34 +103,11 @@ |
764 | return false; |
765 | } |
766 | |
767 | - if (m_position[2] < m_endH) |
768 | - { |
769 | - // burning has stopped so magnitude fades out |
770 | - // assume linear fade out |
771 | - m_mag -= deltaTime/1000.0f; |
772 | - if(m_mag < 0) |
773 | - { |
774 | - m_alive = false; // no longer visible |
775 | - } |
776 | - } |
777 | - |
778 | - // *** would need time direction multiplier to allow reverse time replay |
779 | - m_position[2] -= m_speed*deltaTime/1000.0f; |
780 | - |
781 | - // train doesn't extend beyond start of burn |
782 | - if (m_position[2] + m_speed*0.5f > m_startH) |
783 | - { |
784 | - m_posTrain[2] = m_startH; |
785 | - } |
786 | - else |
787 | - { |
788 | - m_posTrain[2] -= m_speed*deltaTime/1000.0f; |
789 | - } |
790 | + m_alive = Meteor::updateMeteorModel(deltaTime, m_speed, meteor); |
791 | |
792 | return m_alive; |
793 | } |
794 | |
795 | - |
796 | // returns true if visible |
797 | // Assumes that we are in local frame |
798 | void MeteorStream::draw(const StelCore* core, StelPainter& sPainter) |
799 | @@ -177,48 +117,11 @@ |
800 | return; |
801 | } |
802 | |
803 | - Vec3d spos = m_position; |
804 | - Vec3d epos = m_posTrain; |
805 | - |
806 | - // convert to equ |
807 | - spos.transfo4d(m_viewMatrix); |
808 | - epos.transfo4d(m_viewMatrix); |
809 | - |
810 | - // convert to local and correct for earth radius |
811 | - //[since equ and local coordinates in stellarium use same 0 point!] |
812 | - spos = core->j2000ToAltAz(spos); |
813 | - epos = core->j2000ToAltAz(epos); |
814 | - spos[2] -= EARTH_RADIUS; |
815 | - epos[2] -= EARTH_RADIUS; |
816 | - // 1216 is to scale down under 1 for desktop version |
817 | - spos/=1216; |
818 | - epos/=1216; |
819 | - |
820 | - QVector<Vec4f> colorArray; |
821 | - QVector<Vec3d> vertexArray; |
822 | - // last point - dark |
823 | - colorArray.push_back(Vec4f(0,0,0,0)); |
824 | - vertexArray.push_back(epos); |
825 | - // compute intermediate points to curve along projection distortions |
826 | - int segments = 10; |
827 | - for (int i=1; i<segments; i++) { |
828 | - Vec3d posi = m_posInternal; |
829 | - posi[2] = m_posTrain[2] + i*(m_position[2] - m_posTrain[2])/segments; |
830 | - posi.transfo4d(m_viewMatrix); |
831 | - posi = core->j2000ToAltAz(posi); |
832 | - posi[2] -= EARTH_RADIUS; |
833 | - posi/=1216; |
834 | - |
835 | - colorArray.push_back(Vec4f(1,1,1,i*m_mag/segments)); |
836 | - vertexArray.push_back(posi); |
837 | - } |
838 | - // first point - light |
839 | - colorArray.push_back(Vec4f(1,1,1,m_mag)); |
840 | - vertexArray.push_back(spos); |
841 | - |
842 | - sPainter.setColorPointer(4, GL_FLOAT, colorArray.constData()); |
843 | - sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray.constData()); |
844 | - sPainter.enableClientStates(true, false, true); |
845 | - sPainter.drawFromArray(StelPainter::LineStrip, vertexArray.size(), 0, true); |
846 | - sPainter.enableClientStates(false); |
847 | + float thickness, bolideSize; |
848 | + Meteor::calculateThickness(core, thickness, bolideSize); |
849 | + |
850 | + Meteor::drawTrain(core, sPainter, meteor, m_viewMatrix, thickness, |
851 | + m_segments, m_lineColorArray, m_trainColorArray); |
852 | + |
853 | + Meteor::drawBolide(core, sPainter, meteor, m_viewMatrix, bolideSize); |
854 | } |
855 | |
856 | === modified file 'plugins/MeteorShowers/src/MeteorStream.hpp' |
857 | --- plugins/MeteorShowers/src/MeteorStream.hpp 2014-05-08 21:22:20 +0000 |
858 | +++ plugins/MeteorShowers/src/MeteorStream.hpp 2014-06-29 14:51:17 +0000 |
859 | @@ -1,4 +1,5 @@ |
860 | /* |
861 | + * Stellarium: Meteor Showers Plug-in |
862 | * Copyright (C) 2013 Marcos Cardinot |
863 | * |
864 | * This program is free software; you can redistribute it and/or |
865 | @@ -19,22 +20,17 @@ |
866 | #ifndef _METEORSTREAM_HPP_ |
867 | #define _METEORSTREAM_HPP_ |
868 | |
869 | +#include "Meteor.hpp" |
870 | #include "VecMath.hpp" |
871 | + |
872 | class StelCore; |
873 | class StelPainter; |
874 | |
875 | -// all in km - altitudes make up meteor range |
876 | -#define EARTH_RADIUS 6369.f |
877 | -#define VISIBLE_RADIUS 457.8f |
878 | -#define HIGH_ALTITUDE 115.f |
879 | -#define LOW_ALTITUDE 70.f |
880 | - |
881 | //! @class MeteorStream |
882 | //! Models a single meteor. |
883 | //! Control of the meteor rate is performed in the MeteorShowers class. Once |
884 | //! created, a meteor object only lasts for some amount of time, and then |
885 | -//! "dies", after which, the update() member returns false. The live/dead |
886 | -//! status of a meteor may also be determined using the isAlive member. |
887 | +//! "dies", after which, the update() member returns false. |
888 | class MeteorStream |
889 | { |
890 | public: |
891 | @@ -44,10 +40,11 @@ |
892 | //! @param rDelta the radiant delta in rad |
893 | //! @param pidx population index |
894 | MeteorStream(const StelCore*, |
895 | - double speed, |
896 | - double radiantAlpha, |
897 | - double radiantDelta, |
898 | - float pidx); |
899 | + int speed, |
900 | + float radiantAlpha, |
901 | + float radiantDelta, |
902 | + float pidx, |
903 | + QList<MeteorShower::colorPair> colors); |
904 | |
905 | virtual ~MeteorStream(); |
906 | |
907 | @@ -61,22 +58,13 @@ |
908 | private: |
909 | bool m_alive; //! Indicate if the meteor it still visible |
910 | |
911 | - Mat4d m_viewMatrix; //! View Matrix |
912 | - Vec3d m_obs; //! Observer position |
913 | - Vec3d m_position; //! Equatorial coordinate position |
914 | - Vec3d m_posInternal; //! Middle of train |
915 | - Vec3d m_posTrain; //! End of train |
916 | - |
917 | - double m_speed; //! Velocity of meteor in km/s |
918 | - float m_pidx; //! population index |
919 | - double m_xydistance; //! Distance in XY plane (orthogonal to meteor path) from observer to meteor |
920 | - double m_minDist; //! Nearest point to observer along path |
921 | - double m_distMultiplier; //! Scale magnitude due to changes in distance |
922 | - |
923 | - double m_startH; //! Start height above center of earth |
924 | - double m_endH; //! End height |
925 | - |
926 | - float m_mag; //! Apparent magnitude at head, 0-1 |
927 | + float m_speed; //! Velocity of meteor in km/s |
928 | + Mat4d m_viewMatrix; //! View Matrix |
929 | + Meteor::MeteorModel meteor; //! Parameters of meteor model |
930 | + |
931 | + QList<Vec4f> m_trainColorArray; |
932 | + QList<Vec4f> m_lineColorArray; |
933 | + int m_segments; //! Number of segments along the train |
934 | }; |
935 | |
936 | #endif // _METEORSTREAM_HPP_ |
937 | |
938 | === modified file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp' |
939 | --- plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 2014-04-25 12:36:50 +0000 |
940 | +++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 2014-06-29 14:51:17 +0000 |
941 | @@ -1,6 +1,5 @@ |
942 | /* |
943 | - * Stellarium Meteor Shower plugin config dialog |
944 | - * |
945 | + * Stellarium: Meteor Showers Plug-in |
946 | * Copyright (C) 2013 Marcos Cardinot |
947 | * Copyright (C) 2011 Alexander Wolf |
948 | * |
949 | |
950 | === modified file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp' |
951 | --- plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 2014-04-15 02:05:50 +0000 |
952 | +++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 2014-06-29 14:51:17 +0000 |
953 | @@ -1,6 +1,5 @@ |
954 | /* |
955 | - * Stellarium Meteor Shower Plug-in GUI |
956 | - * |
957 | + * Stellarium: Meteor Showers Plug-in |
958 | * Copyright (C) 2013 Marcos Cardinot |
959 | * Copyright (C) 2011 Alexander Wolf |
960 | * |
961 | |
962 | === modified file 'src/core/modules/Meteor.cpp' |
963 | --- src/core/modules/Meteor.cpp 2014-04-15 19:00:10 +0000 |
964 | +++ src/core/modules/Meteor.cpp 2014-06-29 14:51:17 +0000 |
965 | @@ -1,6 +1,7 @@ |
966 | /* |
967 | * Stellarium |
968 | - * This file Copyright (C) 2004 Robert Spearman |
969 | + * Copyright (C) 2004 Robert Spearman |
970 | + * Copyright (C) 2014 Marcos Cardinot |
971 | * |
972 | * This program is free software; you can redistribute it and/or |
973 | * modify it under the terms of the GNU General Public License |
974 | @@ -17,248 +18,416 @@ |
975 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. |
976 | */ |
977 | |
978 | -// This is an ad hoc meteor model |
979 | -// Could use a simple ablation physics model in the future |
980 | - |
981 | -/* |
982 | -NOTE: Here the radiant is always along the ecliptic at the apex of the Earth's way. |
983 | -In reality, individual meteor streams have varying velocity vectors and therefore radiants |
984 | -which are generally not at the apex of the Earth's way, such as the Perseids shower. |
985 | -*/ |
986 | - |
987 | -// Improved realism and efficiency 2004-12 |
988 | - |
989 | -#include <cstdlib> |
990 | #include "Meteor.hpp" |
991 | #include "StelCore.hpp" |
992 | - |
993 | -#include "StelToneReproducer.hpp" |
994 | #include "StelMovementMgr.hpp" |
995 | #include "StelPainter.hpp" |
996 | - |
997 | -Meteor::Meteor(const StelCore* core, double v) |
998 | - : train(false) |
999 | - , startH(0.) |
1000 | - , endH(0.) |
1001 | - , mag(1.) |
1002 | - , absMag(1.) |
1003 | - , visMag(1.) |
1004 | - , initDist(0.) |
1005 | - , minDist(0.) |
1006 | - , distMultiplier(0.) |
1007 | +#include "StelTexture.hpp" |
1008 | + |
1009 | +StelTextureSP Meteor::bolideTexture; |
1010 | + |
1011 | +Meteor::Meteor(const StelCore* core, float v) |
1012 | + : m_distMultiplier(0.) |
1013 | + , m_segments(10) |
1014 | { |
1015 | - const StelToneReproducer* eye = core->getToneReproducer(); |
1016 | - |
1017 | - velocity = 11+(double)rand()/((double)RAND_MAX+1)*(v-11); // abs range 11-72 km/s by default (see line 427 in StelApp.cpp) |
1018 | - maxMag = 1; |
1019 | + // determine meteor velocity |
1020 | + // abs range 11-72 km/s by default (see line 427 in StelApp.cpp) |
1021 | + m_speed = 11+(float)rand()/((float)RAND_MAX+1)*(v-11); |
1022 | |
1023 | // view matrix of sporadic meteors model |
1024 | - double alpha = (double)rand()/((double)RAND_MAX+1)*2*M_PI; |
1025 | - double delta = M_PI_2 - (double)rand()/((double)RAND_MAX+1)*M_PI; |
1026 | - mmat = Mat4d::zrotation(alpha) * Mat4d::yrotation(delta); |
1027 | + float alpha = (double)rand()/((double)RAND_MAX+1)*2*M_PI; |
1028 | + float delta = M_PI_2 - (double)rand()/((double)RAND_MAX+1)*M_PI; |
1029 | + m_viewMatrix = Mat4d::zrotation(alpha) * Mat4d::yrotation(delta); |
1030 | + |
1031 | + // building meteor model |
1032 | + m_alive = initMeteorModel(core, m_segments, m_viewMatrix, meteor); |
1033 | + if (!m_alive) |
1034 | + { |
1035 | + return; |
1036 | + } |
1037 | + |
1038 | + // building lineColorArray and trainColorArray |
1039 | + buildColorArrays(m_segments, getRandColor(), m_lineColorArray, m_trainColorArray); |
1040 | +} |
1041 | + |
1042 | +Meteor::~Meteor() |
1043 | +{ |
1044 | +} |
1045 | + |
1046 | +// returns true if alive |
1047 | +bool Meteor::initMeteorModel(const StelCore* core, const int segments, const Mat4d viewMatrix, MeteorModel &mm) |
1048 | +{ |
1049 | + float high_range = EARTH_RADIUS + HIGH_ALTITUDE; |
1050 | + float low_range = EARTH_RADIUS + LOW_ALTITUDE; |
1051 | + |
1052 | + // find observer position in meteor coordinate system |
1053 | + mm.obs = core->altAzToJ2000(Vec3d(0,0,EARTH_RADIUS)); |
1054 | + mm.obs.transfo4d(viewMatrix.transpose()); |
1055 | |
1056 | // select random trajectory using polar coordinates in XY plane, centered on observer |
1057 | - xydistance = (double)rand()/((double)RAND_MAX+1)*(VISIBLE_RADIUS); |
1058 | - double angle = (double)rand()/((double)RAND_MAX+1)*2*M_PI; |
1059 | - |
1060 | - // find observer position in meteor coordinate system |
1061 | - obs = core->altAzToEquinoxEqu(Vec3d(0,0,EARTH_RADIUS)); |
1062 | - obs.transfo4d(mmat.transpose()); |
1063 | + mm.xydistance = (double)rand() / ((double)RAND_MAX+1)*(VISIBLE_RADIUS); |
1064 | + float angle = (double)rand() / ((double)RAND_MAX+1)*2*M_PI; |
1065 | |
1066 | // set meteor start x,y |
1067 | - posInternal[0] = posTrain[0] = position[0] = xydistance*cos(angle) +obs[0]; |
1068 | - posInternal[1] = posTrain[1] = position[1] = xydistance*sin(angle) +obs[1]; |
1069 | - |
1070 | - // determine life of meteor (start and end z value based on atmosphere burn altitudes) |
1071 | + mm.position[0] = mm.posTrain[0] = mm.xydistance*cos(angle) + mm.obs[0]; |
1072 | + mm.position[1] = mm.posTrain[1] = mm.xydistance*sin(angle) + mm.obs[1]; |
1073 | |
1074 | // D is distance from center of earth |
1075 | - double D = sqrt( position[0]*position[0] + position[1]*position[1] ); |
1076 | + float D = sqrt(mm.position[0]*mm.position[0] + mm.position[1]*mm.position[1]); |
1077 | |
1078 | - if( D > EARTH_RADIUS+HIGH_ALTITUDE ) { |
1079 | - // won't be visible |
1080 | - alive = 0; |
1081 | - return; |
1082 | + if (D > high_range) // won't be visible, meteor still dead |
1083 | + { |
1084 | + return false; |
1085 | } |
1086 | |
1087 | - startH = sqrt( pow(EARTH_RADIUS+HIGH_ALTITUDE,2) - D*D); |
1088 | + mm.posTrain[2] = mm.position[2] = mm.startH = sqrt(high_range*high_range - D*D); |
1089 | |
1090 | // determine end of burn point, and nearest point to observer for distance mag calculation |
1091 | // mag should be max at nearest point still burning |
1092 | - if( D > EARTH_RADIUS+LOW_ALTITUDE ) { |
1093 | - endH = -startH; // earth grazing |
1094 | - minDist = xydistance; |
1095 | - } else { |
1096 | - endH = sqrt( pow(EARTH_RADIUS+LOW_ALTITUDE,2) - D*D); |
1097 | - minDist = sqrt( xydistance*xydistance + pow( endH - obs[2], 2) ); |
1098 | + if (D > low_range) |
1099 | + { |
1100 | + mm.endH = -mm.startH; // earth grazing |
1101 | + mm.minDist = mm.xydistance; |
1102 | + } |
1103 | + else |
1104 | + { |
1105 | + mm.endH = sqrt(low_range*low_range - D*D); |
1106 | + mm.minDist = sqrt(mm.xydistance*mm.xydistance + pow(mm.endH - mm.obs[2], 2)); |
1107 | } |
1108 | |
1109 | - if(minDist > VISIBLE_RADIUS ) { |
1110 | + if (mm.minDist > VISIBLE_RADIUS) |
1111 | + { |
1112 | // on average, not visible (although if were zoomed ...) |
1113 | - alive = 0; |
1114 | - return; |
1115 | - } |
1116 | - |
1117 | - /* experiment |
1118 | - // limit lifetime to 0.5-3.0 sec |
1119 | - double tmp_h = startH - velocity * (0.5 + (double)rand()/((double)RAND_MAX+1) * 2.5); |
1120 | - if( tmp_h > endH ) { |
1121 | - endH = tmp_h; |
1122 | - } |
1123 | - */ |
1124 | - |
1125 | - posTrain[2] = position[2] = startH; |
1126 | - |
1127 | - // qDebug("New meteor: %f %f s:%f e:%f v:%f\n", position[0], position[1], startH, endH, velocity); |
1128 | - |
1129 | - alive = 1; |
1130 | - train=0; |
1131 | - |
1132 | - // Determine drawing color given magnitude and eye |
1133 | - // (won't be visible during daylight) |
1134 | - |
1135 | - // *** color varies somewhat based on velocity, plus atmosphere reddening |
1136 | - |
1137 | - // determine intensity |
1138 | - float Mag1 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3; |
1139 | - float Mag2 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3; |
1140 | + return false; //meteor still dead |
1141 | + } |
1142 | + |
1143 | + // determine intensity [-3; 4.5] |
1144 | + float Mag1 = (double)rand()/((double)RAND_MAX+1)*7.5f - 3; |
1145 | + float Mag2 = (double)rand()/((double)RAND_MAX+1)*7.5f - 3; |
1146 | float Mag = (Mag1 + Mag2)/2.0f; |
1147 | |
1148 | - mag = (5. + Mag) / 256.0; |
1149 | - if (mag>250) mag = mag - 256; |
1150 | - |
1151 | - float term1 = std::exp(-0.92103f*(mag + 12.12331f)) * 108064.73f; |
1152 | - |
1153 | - float cmag=1.f; |
1154 | - float rmag; |
1155 | - |
1156 | - // Compute the equivalent star luminance for a 5 arc min circle and convert it |
1157 | - // in function of the eye adaptation |
1158 | - rmag = eye->adaptLuminanceScaled(term1); |
1159 | - rmag = rmag/powf(core->getMovementMgr()->getCurrentFov(),0.85f)*500.f; |
1160 | - |
1161 | - // if size of star is too small (blink) we put its size to 1.2 --> no more blink |
1162 | - // And we compensate the difference of brighteness with cmag |
1163 | - if (rmag<1.2f) { |
1164 | - cmag=rmag*rmag/1.44f; |
1165 | - } |
1166 | - |
1167 | - mag = cmag; // assumes white |
1168 | + // compute RMag and CMag |
1169 | + RCMag rcMag; |
1170 | + core->getSkyDrawer()->computeRCMag(Mag, &rcMag); |
1171 | + mm.mag = rcMag.luminance; |
1172 | |
1173 | // most visible meteors are under about 180km distant |
1174 | // scale max mag down if outside this range |
1175 | float scale = 1; |
1176 | - if(minDist!=0) scale = 180*180/(minDist*minDist); |
1177 | - if( scale < 1 ) mag *= scale; |
1178 | - |
1179 | -} |
1180 | - |
1181 | -Meteor::~Meteor() |
1182 | -{ |
1183 | -} |
1184 | - |
1185 | -// returns true if alive |
1186 | -bool Meteor::update(double deltaTime) |
1187 | -{ |
1188 | - if(!alive) return(0); |
1189 | - |
1190 | - if( position[2] < endH ) { |
1191 | + if (mm.minDist) |
1192 | + { |
1193 | + scale = 180*180 / (mm.minDist*mm.minDist); |
1194 | + } |
1195 | + if (scale < 1) |
1196 | + { |
1197 | + mm.mag *= scale; |
1198 | + } |
1199 | + |
1200 | + mm.firstBrightSegment = (double)rand()/((double)RAND_MAX+1)*segments; |
1201 | + |
1202 | + // If everything is ok until here, |
1203 | + return true; //the meteor is alive |
1204 | +} |
1205 | + |
1206 | +Vec4f Meteor::getColorFromName(QString colorName) { |
1207 | + int R, G, B; // 0-255 |
1208 | + if (colorName == "violet") { // Calcium |
1209 | + R = 176; |
1210 | + G = 67; |
1211 | + B = 172; |
1212 | + } else if (colorName == "blueGreen") { // Magnesium |
1213 | + R = 0; |
1214 | + G = 255; |
1215 | + B = 152; |
1216 | + } else if (colorName == "yellow") { // Iron |
1217 | + R = 255; |
1218 | + G = 255; |
1219 | + B = 0; |
1220 | + } else if (colorName == "orangeYellow") { // Sodium |
1221 | + R = 255; |
1222 | + G = 160; |
1223 | + B = 0; |
1224 | + } else if (colorName == "red") { // atmospheric nitrogen and oxygen |
1225 | + R = 255; |
1226 | + G = 30; |
1227 | + B = 0; |
1228 | + } else { // white |
1229 | + R = 255; |
1230 | + G = 255; |
1231 | + B = 255; |
1232 | + } |
1233 | + |
1234 | + return Vec4f(R/255.f, G/255.f, B/255.f, 1); |
1235 | +} |
1236 | + |
1237 | +QList<Meteor::colorPair> Meteor::getRandColor() { |
1238 | + QList<colorPair> colors; |
1239 | + float prob = (double)rand()/((double)RAND_MAX+1); |
1240 | + if (prob > 0.9) { |
1241 | + colors.push_back(Meteor::colorPair("white", 70)); |
1242 | + colors.push_back(Meteor::colorPair("orangeYellow", 10)); |
1243 | + colors.push_back(Meteor::colorPair("yellow", 10)); |
1244 | + colors.push_back(Meteor::colorPair("blueGreen", 10)); |
1245 | + } else if (prob > 0.85) { |
1246 | + colors.push_back(Meteor::colorPair("white", 80)); |
1247 | + colors.push_back(Meteor::colorPair("violet", 20)); |
1248 | + } else if (prob > 0.80) { |
1249 | + colors.push_back(Meteor::colorPair("white", 80)); |
1250 | + colors.push_back(Meteor::colorPair("orangeYellow", 20)); |
1251 | + } else { |
1252 | + colors.push_back(Meteor::colorPair("white", 100)); |
1253 | + } |
1254 | + |
1255 | + return colors; |
1256 | +} |
1257 | + |
1258 | +void Meteor::buildColorArrays(const int segments, |
1259 | + const QList<colorPair> colors, |
1260 | + QList<Vec4f> &lineColorArray, |
1261 | + QList<Vec4f> &trainColorArray) |
1262 | +{ |
1263 | + // building color arrays (line and prism) |
1264 | + int totalOfSegments = 0; |
1265 | + int currentSegment = 1+(double)rand()/((double)RAND_MAX+1)*(segments-1); |
1266 | + for (int colorIndex=0; colorIndex<colors.size(); colorIndex++) { |
1267 | + colorPair currentColor = colors[colorIndex]; |
1268 | + |
1269 | + // segments which we'll paint with the current color |
1270 | + int numOfSegments = segments*(currentColor.second / 100.f) + 0.4f; // +0.4 affect approximation |
1271 | + if (colorIndex == colors.size()-1) { |
1272 | + numOfSegments = segments - totalOfSegments; |
1273 | + } |
1274 | + |
1275 | + totalOfSegments += numOfSegments; |
1276 | + for (int i=0; i<numOfSegments; i++) { |
1277 | + lineColorArray.insert(currentSegment, getColorFromName(currentColor.first)); |
1278 | + trainColorArray.insert(currentSegment, getColorFromName(currentColor.first)); |
1279 | + if (currentSegment >= segments-1) { |
1280 | + currentSegment = 0; |
1281 | + } else { |
1282 | + currentSegment++; |
1283 | + } |
1284 | + trainColorArray.insert(currentSegment, getColorFromName(currentColor.first)); |
1285 | + } |
1286 | + } |
1287 | +} |
1288 | + |
1289 | +bool Meteor::updateMeteorModel(double deltaTime, double speed, MeteorModel &mm) |
1290 | +{ |
1291 | + if (mm.position[2] < mm.endH) |
1292 | + { |
1293 | // burning has stopped so magnitude fades out |
1294 | // assume linear fade out |
1295 | - |
1296 | - mag -= maxMag * deltaTime/500.0f; |
1297 | - if( mag < 0 ) alive=0; // no longer visible |
1298 | - |
1299 | + mm.mag -= deltaTime/500.0f; |
1300 | + if(mm.mag < 0) |
1301 | + { |
1302 | + return false; // no longer visible |
1303 | + } |
1304 | } |
1305 | |
1306 | // *** would need time direction multiplier to allow reverse time replay |
1307 | - position[2] = position[2] - velocity*deltaTime/1000.0f; |
1308 | + float dt = 820+(double)rand()/((double)RAND_MAX+1)*185; // range 820-1005 |
1309 | + mm.position[2] -= speed*deltaTime/dt; |
1310 | |
1311 | // train doesn't extend beyond start of burn |
1312 | - if( position[2] + velocity*0.5f > startH ) { |
1313 | - posTrain[2] = startH ; |
1314 | - } else { |
1315 | - posTrain[2] -= velocity*deltaTime/1000.0f; |
1316 | - } |
1317 | - |
1318 | - //qDebug("meteor position: %f delta_t %d\n", position[2], deltaTime); |
1319 | + if (mm.position[2] + speed*0.5f > mm.startH) |
1320 | + { |
1321 | + mm.posTrain[2] = mm.startH; |
1322 | + } |
1323 | + else |
1324 | + { |
1325 | + mm.posTrain[2] -= speed*deltaTime/dt; |
1326 | + } |
1327 | + |
1328 | + return true; |
1329 | +} |
1330 | + |
1331 | +// returns true if alive |
1332 | +bool Meteor::update(double deltaTime) |
1333 | +{ |
1334 | + if (!m_alive) |
1335 | + { |
1336 | + return false; |
1337 | + } |
1338 | + |
1339 | + m_alive = updateMeteorModel(deltaTime, m_speed, meteor); |
1340 | |
1341 | // determine visual magnitude based on distance to observer |
1342 | - double dist = sqrt( xydistance*xydistance + pow( position[2]-obs[2], 2) ); |
1343 | - |
1344 | - if( dist == 0 ) dist = .01; // just to be cautious (meteor hits observer!) |
1345 | - |
1346 | - distMultiplier = minDist*minDist / (dist*dist); |
1347 | - |
1348 | - return(alive); |
1349 | -} |
1350 | - |
1351 | + double dist = sqrt(meteor.xydistance*meteor.xydistance + pow(meteor.position[2]-meteor.obs[2], 2)); |
1352 | + if (dist == 0) |
1353 | + { |
1354 | + dist = .01; // just to be cautious (meteor hits observer!) |
1355 | + } |
1356 | + m_distMultiplier = meteor.minDist*meteor.minDist / (dist*dist); |
1357 | + |
1358 | + return m_alive; |
1359 | +} |
1360 | + |
1361 | +void Meteor::insertVertex(const StelCore* core, const Mat4d& viewMatrix, QVector<Vec3d> &vertexArray, Vec3d vertex) |
1362 | +{ |
1363 | + vertex.transfo4d(viewMatrix); |
1364 | + vertex = core->j2000ToAltAz(vertex); |
1365 | + vertex[2] -= EARTH_RADIUS; |
1366 | + vertex/=1216; // 1216 is to scale down under 1 for desktop version |
1367 | + vertexArray.push_back(vertex); |
1368 | +} |
1369 | + |
1370 | +void Meteor::calculateThickness(const StelCore* core, float& thickness, float& bolideSize) |
1371 | +{ |
1372 | + float maxFOV = core->getMovementMgr()->getMaxFov(); |
1373 | + float FOV = core->getMovementMgr()->getCurrentFov(); |
1374 | + thickness = 2*log(FOV + 0.25)/(1.2*maxFOV - (FOV + 0.25)) + 0.01; |
1375 | + if (FOV <= 0.5) |
1376 | + { |
1377 | + thickness = 0.013 * FOV; // decreasing faster |
1378 | + } else if (FOV > 100.0) { |
1379 | + thickness = 0; // remove prism |
1380 | + } |
1381 | + bolideSize = thickness*3; |
1382 | +} |
1383 | + |
1384 | +void Meteor::drawBolide(const StelCore* core, StelPainter& sPainter, const MeteorModel& mm, |
1385 | + const Mat4d& viewMatrix, const float bolideSize) |
1386 | +{ |
1387 | + if (!bolideSize) { |
1388 | + return; |
1389 | + } |
1390 | + |
1391 | + // bolide |
1392 | + // |
1393 | + QVector<Vec3d> vertexArrayBolide; |
1394 | + QVector<Vec4f> colorArrayBolide; |
1395 | + Vec4f bolideColor = Vec4f(1,1,1,mm.mag); |
1396 | + |
1397 | + Vec3d topLeft = mm.position; |
1398 | + topLeft[1] -= bolideSize; |
1399 | + insertVertex(core, viewMatrix, vertexArrayBolide, topLeft); |
1400 | + colorArrayBolide.push_back(bolideColor); |
1401 | + |
1402 | + Vec3d topRight = mm.position; |
1403 | + topRight[0] -= bolideSize; |
1404 | + insertVertex(core, viewMatrix, vertexArrayBolide, topRight); |
1405 | + colorArrayBolide.push_back(bolideColor); |
1406 | + |
1407 | + Vec3d bottomRight = mm.position; |
1408 | + bottomRight[1] += bolideSize; |
1409 | + insertVertex(core, viewMatrix, vertexArrayBolide, bottomRight); |
1410 | + colorArrayBolide.push_back(bolideColor); |
1411 | + |
1412 | + Vec3d bottomLeft = mm.position; |
1413 | + bottomLeft[0] += bolideSize; |
1414 | + insertVertex(core, viewMatrix, vertexArrayBolide, bottomLeft); |
1415 | + colorArrayBolide.push_back(bolideColor); |
1416 | + |
1417 | + glEnable(GL_BLEND); |
1418 | + glBlendFunc(GL_ONE, GL_ONE); |
1419 | + sPainter.enableClientStates(true, true, true); |
1420 | + Meteor::bolideTexture->bind(); |
1421 | + static const float texCoordData[] = {1.,0., 0.,0., 0.,1., 1.,1.}; |
1422 | + sPainter.setTexCoordPointer(2, GL_FLOAT, texCoordData); |
1423 | + sPainter.setColorPointer(4, GL_FLOAT, colorArrayBolide.constData()); |
1424 | + sPainter.setVertexPointer(3, GL_DOUBLE, vertexArrayBolide.constData()); |
1425 | + sPainter.drawFromArray(StelPainter::TriangleFan, vertexArrayBolide.size(), 0, true); |
1426 | + |
1427 | + glDisable(GL_BLEND); |
1428 | + sPainter.enableClientStates(false); |
1429 | +} |
1430 | + |
1431 | +void Meteor::drawTrain(const StelCore *core, StelPainter& sPainter, const MeteorModel& mm, |
1432 | + const Mat4d& viewMatrix, const float thickness, const int segments, |
1433 | + QList<Vec4f> lineColorArray, QList<Vec4f> trainColorArray) |
1434 | +{ |
1435 | + if (segments != lineColorArray.size() || 2*segments != trainColorArray.size()) |
1436 | + { |
1437 | + qWarning() << "Meteor: color arrays have an inconsistent size!"; |
1438 | + return; |
1439 | + } |
1440 | + |
1441 | + // train (triangular prism) |
1442 | + // |
1443 | + QVector<Vec3d> vertexArrayLine; |
1444 | + QVector<Vec3d> vertexArrayL; |
1445 | + QVector<Vec3d> vertexArrayR; |
1446 | + QVector<Vec3d> vertexArrayTop; |
1447 | + |
1448 | + Vec3d posTrainB = mm.posTrain; |
1449 | + posTrainB[0] += thickness*0.7; |
1450 | + posTrainB[1] += thickness*0.7; |
1451 | + Vec3d posTrainL = mm.posTrain; |
1452 | + posTrainL[1] -= thickness; |
1453 | + Vec3d posTrainR = mm.posTrain; |
1454 | + posTrainR[0] -= thickness; |
1455 | + |
1456 | + for (int i=0; i<segments; i++) { |
1457 | + float mag = mm.mag * i/(3* (segments-1)); |
1458 | + if (i > mm.firstBrightSegment) { |
1459 | + mag *= 12/5; |
1460 | + } |
1461 | + |
1462 | + double height = mm.posTrain[2] + i*(mm.position[2] - mm.posTrain[2])/(segments-1); |
1463 | + Vec3d posi; |
1464 | + |
1465 | + posi = mm.posTrain; |
1466 | + posi[2] = height; |
1467 | + insertVertex(core, viewMatrix, vertexArrayLine, posi); |
1468 | + |
1469 | + posi = posTrainB; |
1470 | + posi[2] = height; |
1471 | + insertVertex(core, viewMatrix, vertexArrayL, posi); |
1472 | + insertVertex(core, viewMatrix, vertexArrayR, posi); |
1473 | + |
1474 | + posi = posTrainL; |
1475 | + posi[2] = height; |
1476 | + insertVertex(core, viewMatrix, vertexArrayL, posi); |
1477 | + insertVertex(core, viewMatrix, vertexArrayTop, posi); |
1478 | + |
1479 | + posi = posTrainR; |
1480 | + posi[2] = height; |
1481 | + insertVertex(core, viewMatrix, vertexArrayR, posi); |
1482 | + insertVertex(core, viewMatrix, vertexArrayTop, posi); |
1483 | + |
1484 | + lineColorArray[i][3] = mag; |
1485 | + trainColorArray[i*2][3] = mag; |
1486 | + trainColorArray[i*2+1][3] = mag; |
1487 | + } |
1488 | + |
1489 | + glEnable(GL_BLEND); |
1490 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
1491 | + sPainter.enableClientStates(true, false, true); |
1492 | + if (thickness) { |
1493 | + sPainter.setColorPointer(4, GL_FLOAT, trainColorArray.toVector().constData()); |
1494 | + |
1495 | + sPainter.setVertexPointer(3, GL_DOUBLE, vertexArrayL.constData()); |
1496 | + sPainter.drawFromArray(StelPainter::TriangleStrip, vertexArrayL.size(), 0, true); |
1497 | + |
1498 | + sPainter.setVertexPointer(3, GL_DOUBLE, vertexArrayR.constData()); |
1499 | + sPainter.drawFromArray(StelPainter::TriangleStrip, vertexArrayR.size(), 0, true); |
1500 | + |
1501 | + sPainter.setVertexPointer(3, GL_DOUBLE, vertexArrayTop.constData()); |
1502 | + sPainter.drawFromArray(StelPainter::TriangleStrip, vertexArrayTop.size(), 0, true); |
1503 | + } |
1504 | + sPainter.setColorPointer(4, GL_FLOAT, lineColorArray.toVector().constData()); |
1505 | + sPainter.setVertexPointer(3, GL_DOUBLE, vertexArrayLine.constData()); |
1506 | + sPainter.drawFromArray(StelPainter::LineStrip, vertexArrayLine.size(), 0, true); |
1507 | + |
1508 | + glDisable(GL_BLEND); |
1509 | + sPainter.enableClientStates(false); |
1510 | +} |
1511 | |
1512 | // returns true if visible |
1513 | // Assumes that we are in local frame |
1514 | void Meteor::draw(const StelCore* core, StelPainter& sPainter) |
1515 | { |
1516 | - if (!alive) |
1517 | + if (!m_alive) |
1518 | + { |
1519 | return; |
1520 | - |
1521 | - const StelProjectorP proj = sPainter.getProjector(); |
1522 | - |
1523 | - Vec3d spos = position; |
1524 | - Vec3d epos = posTrain; |
1525 | - |
1526 | - // convert to equ |
1527 | - spos.transfo4d(mmat); |
1528 | - epos.transfo4d(mmat); |
1529 | - |
1530 | - // convert to local and correct for earth radius [since equ and local coordinates in stellarium use same 0 point!] |
1531 | - spos = core->equinoxEquToAltAz( spos ); |
1532 | - epos = core->equinoxEquToAltAz( epos ); |
1533 | - spos[2] -= EARTH_RADIUS; |
1534 | - epos[2] -= EARTH_RADIUS; |
1535 | - // 1216 is to scale down under 1 for desktop version |
1536 | - spos/=1216; |
1537 | - epos/=1216; |
1538 | - |
1539 | - //qDebug("[%f %f %f]\n", position[0], position[1], position[2]); |
1540 | - |
1541 | - if (train) |
1542 | - { |
1543 | - // connect this point with last drawn point |
1544 | - double tmag = mag*distMultiplier; |
1545 | - |
1546 | - // compute an intermediate point so can curve slightly along projection distortions |
1547 | - Vec3d posi = posInternal; |
1548 | - posi[2] = position[2] + (posTrain[2] - position[2])/2; |
1549 | - posi.transfo4d(mmat); |
1550 | - posi = core->equinoxEquToAltAz( posi ); |
1551 | - posi[2] -= EARTH_RADIUS; |
1552 | - posi/=1216; |
1553 | - |
1554 | - // draw dark to light |
1555 | - Vec4f colorArray[3]; |
1556 | - colorArray[0].set(0,0,0,0); |
1557 | - colorArray[1].set(1,1,1,tmag*0.5); |
1558 | - colorArray[2].set(1,1,1,tmag); |
1559 | - Vec3d vertexArray[3]; |
1560 | - vertexArray[0]=epos; |
1561 | - vertexArray[1]=posi; |
1562 | - vertexArray[2]=spos; |
1563 | - sPainter.setColorPointer(4, GL_FLOAT, colorArray); |
1564 | - sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray); |
1565 | - sPainter.enableClientStates(true, false, true); |
1566 | - sPainter.drawFromArray(StelPainter::LineStrip, 3, 0, true); |
1567 | - sPainter.enableClientStates(false); |
1568 | - } |
1569 | - else |
1570 | - { |
1571 | - Vec3d start; |
1572 | - proj->project(spos, start); |
1573 | - sPainter.drawPoint2d(start[0],start[1]); |
1574 | - } |
1575 | - |
1576 | - train = 1; |
1577 | -} |
1578 | - |
1579 | -bool Meteor::isAlive(void) |
1580 | -{ |
1581 | - return(alive); |
1582 | + } |
1583 | + |
1584 | + float thickness, bolideSize; |
1585 | + calculateThickness(core, thickness, bolideSize); |
1586 | + |
1587 | + drawTrain(core, sPainter, meteor, m_viewMatrix, thickness, |
1588 | + m_segments, m_lineColorArray, m_trainColorArray); |
1589 | + |
1590 | + drawBolide(core, sPainter, meteor, m_viewMatrix, bolideSize); |
1591 | } |
1592 | |
1593 | === modified file 'src/core/modules/Meteor.hpp' |
1594 | --- src/core/modules/Meteor.hpp 2013-08-24 21:33:23 +0000 |
1595 | +++ src/core/modules/Meteor.hpp 2014-06-29 14:51:17 +0000 |
1596 | @@ -1,6 +1,7 @@ |
1597 | /* |
1598 | * Stellarium |
1599 | - * This file Copyright (C) 2004 Robert Spearman |
1600 | + * Copyright (C) 2004 Robert Spearman |
1601 | + * Copyright (C) 2014 Marcos Cardinot |
1602 | * |
1603 | * This program is free software; you can redistribute it and/or |
1604 | * modify it under the terms of the GNU General Public License |
1605 | @@ -20,7 +21,12 @@ |
1606 | #ifndef _METEOR_HPP_ |
1607 | #define _METEOR_HPP_ |
1608 | |
1609 | +#include "StelTextureTypes.hpp" |
1610 | #include "VecMath.hpp" |
1611 | + |
1612 | +#include <QList> |
1613 | +#include <QPair> |
1614 | + |
1615 | class StelCore; |
1616 | class StelPainter; |
1617 | |
1618 | @@ -34,14 +40,26 @@ |
1619 | //! Models a single meteor. |
1620 | //! Control of the meteor rate is performed in the MeteorMgr class. Once |
1621 | //! created, a meteor object only lasts for some amount of time, and then |
1622 | -//! "dies", after which, the update() member returns false. The live/dead |
1623 | -//! status of a meteor may also be determined using the isAlive member. |
1624 | +//! "dies", after which, the update() member returns false. |
1625 | class Meteor |
1626 | { |
1627 | public: |
1628 | + struct MeteorModel |
1629 | + { |
1630 | + Vec3d obs; //! observer position |
1631 | + Vec3d position; //! equatorial coordinate position |
1632 | + Vec3d posTrain; //! end of train |
1633 | + float xydistance; //! Distance in XY plane (orthogonal to meteor path) from observer to meteor |
1634 | + float minDist; //! Nearest point to observer along path |
1635 | + float startH; //! Start height above center of earth |
1636 | + float endH; //! End height |
1637 | + float mag; //! Apparent magnitude at head, 0-1 |
1638 | + int firstBrightSegment; //! First bright segment of the train |
1639 | + }; |
1640 | + |
1641 | //! Create a Meteor object. |
1642 | //! @param v the velocity of the meteor in km/s. |
1643 | - Meteor(const StelCore*, double v); |
1644 | + Meteor(const StelCore*, float v); |
1645 | virtual ~Meteor(); |
1646 | |
1647 | //! Updates the position of the meteor, and expires it if necessary. |
1648 | @@ -50,31 +68,55 @@ |
1649 | |
1650 | //! Draws the meteor. |
1651 | void draw(const StelCore* core, StelPainter& sPainter); |
1652 | - |
1653 | - //! Determine if a meteor is alive or has burned out. |
1654 | + |
1655 | + //! Draws the meteor train. (useful to be reused in MeteorShowers plugin) |
1656 | + static void drawTrain(const StelCore* core, StelPainter& sPainter, const MeteorModel& mm, |
1657 | + const Mat4d& viewMatrix, const float thickness, const int segments, |
1658 | + QList<Vec4f> lineColorArray, QList<Vec4f> trainColorArray); |
1659 | + |
1660 | + //! Draws the meteor bolide. (useful to be reused in MeteorShowers plugin) |
1661 | + static void drawBolide(const StelCore* core, StelPainter &sPainter, const MeteorModel& mm, |
1662 | + const Mat4d& viewMatrix, const float bolideSize); |
1663 | + |
1664 | + //! Calculates the train thickness and bolide size. |
1665 | + static void calculateThickness(const StelCore* core, float &thickness, float &bolideSize); |
1666 | + |
1667 | + //! <colorName, intensity> |
1668 | + typedef QPair<QString, int> colorPair; |
1669 | + |
1670 | + //! Updates parameters of meteor model. (useful to be reused in MeteorShowers plugin) |
1671 | + //! @return true of the meteor is still alive, else false. |
1672 | + static bool updateMeteorModel(double deltaTime, double speed, MeteorModel &mm); |
1673 | + |
1674 | + //! Builds Meteor Model |
1675 | //! @return true if alive, else false. |
1676 | - bool isAlive(void); |
1677 | - |
1678 | + static bool initMeteorModel(const StelCore *core, const int segments, |
1679 | + const Mat4d viewMatrix, MeteorModel &mm); |
1680 | + |
1681 | + //! Determine color arrays of line and prism used to draw meteor train. |
1682 | + static void buildColorArrays(const int segments, |
1683 | + const QList<colorPair> colors, |
1684 | + QList<Vec4f> &lineColorArray, |
1685 | + QList<Vec4f> &trainColorArray); |
1686 | + |
1687 | + static StelTextureSP bolideTexture; |
1688 | + |
1689 | private: |
1690 | - Mat4d mmat; // tranformation matrix to align radiant with earth direction of travel |
1691 | - Vec3d obs; // observer position in meteor coord. system |
1692 | - Vec3d position; // equatorial coordinate position |
1693 | - Vec3d posInternal; // middle of train |
1694 | - Vec3d posTrain; // end of train |
1695 | - bool train; // point or train visible? |
1696 | - double startH; // start height above center of earth |
1697 | - double endH; // end height |
1698 | - double velocity; // km/s |
1699 | - bool alive; // is it still visible? |
1700 | - float mag; // Apparent magnitude at head, 0-1 |
1701 | - float maxMag; // 0-1 |
1702 | - float absMag; // absolute magnitude |
1703 | - float visMag; // visual magnitude at observer |
1704 | - double xydistance; // distance in XY plane (orthogonal to meteor path) from observer to meteor |
1705 | - double initDist; // initial distance from observer |
1706 | - double minDist; // nearest point to observer along path |
1707 | - double distMultiplier; // scale magnitude due to changes in distance |
1708 | - |
1709 | + static void insertVertex(const StelCore* core, const Mat4d& viewMatrix, |
1710 | + QVector<Vec3d> &vertexArray, Vec3d vertex); |
1711 | + static Vec4f getColorFromName(QString colorName); |
1712 | + QList<colorPair> getRandColor(); |
1713 | + |
1714 | + bool m_alive; //! Indicate if the meteor it still visible |
1715 | + |
1716 | + float m_speed; //! Velocity of meteor in km/s |
1717 | + Mat4d m_viewMatrix; //! tranformation matrix to align radiant with earth direction of travel |
1718 | + MeteorModel meteor; //! Parameters of meteor model |
1719 | + double m_distMultiplier; //! Scale magnitude due to changes in distance |
1720 | + |
1721 | + QList<Vec4f> m_trainColorArray; |
1722 | + QList<Vec4f> m_lineColorArray; |
1723 | + const int m_segments; //! Number of segments along the train (useful to curve along projection distortions) |
1724 | }; |
1725 | |
1726 | |
1727 | |
1728 | === modified file 'src/core/modules/MeteorMgr.cpp' |
1729 | --- src/core/modules/MeteorMgr.cpp 2014-02-18 06:36:58 +0000 |
1730 | +++ src/core/modules/MeteorMgr.cpp 2014-06-29 14:51:17 +0000 |
1731 | @@ -1,7 +1,8 @@ |
1732 | /* |
1733 | * Stellarium |
1734 | - * This file Copyright (C) 2004 Robert Spearman |
1735 | - * |
1736 | + * Copyright (C) 2004 Robert Spearman |
1737 | + * Copyright (C) 2014 Marcos Cardinot |
1738 | + * |
1739 | * This program is free software; you can redistribute it and/or |
1740 | * modify it under the terms of the GNU General Public License |
1741 | * as published by the Free Software Foundation; either version 2 |
1742 | @@ -17,47 +18,42 @@ |
1743 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. |
1744 | */ |
1745 | |
1746 | -#include "StelProjector.hpp" |
1747 | - |
1748 | +#include "LandscapeMgr.hpp" |
1749 | +#include "Meteor.hpp" |
1750 | #include "MeteorMgr.hpp" |
1751 | +#include "SolarSystem.hpp" |
1752 | #include "StelApp.hpp" |
1753 | #include "StelCore.hpp" |
1754 | -#include "Meteor.hpp" |
1755 | -#include "LandscapeMgr.hpp" |
1756 | +#include "StelFileMgr.hpp" |
1757 | #include "StelModuleMgr.hpp" |
1758 | #include "StelPainter.hpp" |
1759 | +#include "StelTextureMgr.hpp" |
1760 | |
1761 | -#include <functional> |
1762 | -#include <cstdlib> |
1763 | #include <QSettings> |
1764 | |
1765 | -MeteorMgr::MeteorMgr(int zhr, int maxv ) : flagShow(true) |
1766 | +MeteorMgr::MeteorMgr(int zhr, int maxv ) |
1767 | + : ZHR(zhr) |
1768 | + , maxVelocity(maxv) |
1769 | + , flagShow(true) |
1770 | { |
1771 | setObjectName("MeteorMgr"); |
1772 | - |
1773 | - ZHR = zhr; |
1774 | - maxVelocity = maxv; |
1775 | - |
1776 | - // calculate factor for meteor creation rate per second since visible area ZHR is for |
1777 | - // estimated visible radius of 458km |
1778 | - // (calculated for average meteor magnitude of +2.5 and limiting magnitude of 5) |
1779 | - |
1780 | - // zhrToWsr = 1.0f/3600.f; |
1781 | - zhrToWsr = 1.6667f/3600.f; |
1782 | - // this is a correction factor to adjust for the model as programmed to match observed rates |
1783 | } |
1784 | |
1785 | MeteorMgr::~MeteorMgr() |
1786 | { |
1787 | - for(std::vector<Meteor*>::iterator iter = active.begin(); iter != active.end(); ++iter) |
1788 | + std::vector<Meteor*>::iterator iter; |
1789 | + for(iter = active.begin(); iter != active.end(); ++iter) |
1790 | { |
1791 | delete *iter; |
1792 | } |
1793 | active.clear(); |
1794 | + Meteor::bolideTexture.clear(); |
1795 | } |
1796 | |
1797 | void MeteorMgr::init() |
1798 | { |
1799 | + Meteor::bolideTexture = StelApp::getInstance().getTextureManager().createTextureThread(StelFileMgr::getInstallationDir()+"/textures/cometTail.png", StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE)); |
1800 | + |
1801 | setZHR(StelApp::getInstance().getSettings()->value("astro/meteor_rate", 10).toInt()); |
1802 | } |
1803 | |
1804 | @@ -67,7 +63,9 @@ |
1805 | double MeteorMgr::getCallOrder(StelModuleActionName actionName) const |
1806 | { |
1807 | if (actionName==StelModule::ActionDraw) |
1808 | - return StelApp::getInstance().getModuleMgr().getModule("SolarSystem")->getCallOrder(actionName)+10; |
1809 | + { |
1810 | + return GETSTELMODULE(SolarSystem)->getCallOrder(actionName)+10.; |
1811 | + } |
1812 | return 0; |
1813 | } |
1814 | |
1815 | @@ -93,78 +91,82 @@ |
1816 | return; |
1817 | #endif |
1818 | if (!flagShow) |
1819 | + { |
1820 | return; |
1821 | - |
1822 | + } |
1823 | + |
1824 | + StelCore* core = StelApp::getInstance().getCore(); |
1825 | + |
1826 | + double tspeed = core->getTimeRate()*86400; // sky seconds per actual second |
1827 | + if (!tspeed) { // is paused? |
1828 | + return; // freeze meteors at the current position |
1829 | + } |
1830 | + |
1831 | deltaTime*=1000; |
1832 | - StelCore* core = StelApp::getInstance().getCore(); |
1833 | + // if stellarium has been suspended, don't create |
1834 | + // huge number of meteors to make up for lost time! |
1835 | + if (deltaTime > 500) |
1836 | + { |
1837 | + deltaTime = 500; |
1838 | + } |
1839 | |
1840 | // step through and update all active meteors |
1841 | - for (std::vector<Meteor*>::iterator iter = active.begin(); iter != active.end(); ++iter) |
1842 | + std::vector<Meteor*>::iterator iter; |
1843 | + for (iter = active.begin(); iter != active.end(); ++iter) |
1844 | { |
1845 | if (!(*iter)->update(deltaTime)) |
1846 | { |
1847 | - // remove dead meteor |
1848 | - // qDebug("Meteor \tdied\n"); |
1849 | - |
1850 | delete *iter; |
1851 | - active.erase(iter); |
1852 | + iter = active.erase(iter); |
1853 | iter--; // important! |
1854 | } |
1855 | } |
1856 | |
1857 | // only makes sense given lifetimes of meteors to draw when timeSpeed is realtime |
1858 | // otherwise high overhead of large numbers of meteors |
1859 | - double tspeed = core->getTimeRate()*86400; // sky seconds per actual second |
1860 | - if (tspeed<=0 || fabs(tspeed)>1.) |
1861 | + if (tspeed<0 || fabs(tspeed)>1.) |
1862 | { |
1863 | // don't start any more meteors |
1864 | return; |
1865 | } |
1866 | |
1867 | - // if stellarium has been suspended, don't create huge number of meteors to |
1868 | - // make up for lost time! |
1869 | - if (deltaTime > 500) |
1870 | - { |
1871 | - deltaTime = 500; |
1872 | - } |
1873 | - |
1874 | // determine average meteors per frame needing to be created |
1875 | int mpf = (int)((double)ZHR*zhrToWsr*deltaTime/1000.0 + 0.5); |
1876 | if (mpf<1) |
1877 | + { |
1878 | mpf = 1; |
1879 | + } |
1880 | |
1881 | - int mlaunch = 0; |
1882 | for (int i=0; i<mpf; ++i) |
1883 | { |
1884 | // start new meteor based on ZHR time probability |
1885 | double prob = ((double)rand())/RAND_MAX; |
1886 | - if (ZHR>0 && prob<((double)ZHR*zhrToWsr*deltaTime/1000.0/(double)mpf) ) |
1887 | + if (ZHR>0 && prob<((double)ZHR*zhrToWsr*deltaTime/1000.0/(double)mpf)) |
1888 | { |
1889 | - Meteor *m = new Meteor(StelApp::getInstance().getCore(), maxVelocity); |
1890 | + Meteor *m = new Meteor(core, maxVelocity); |
1891 | active.push_back(m); |
1892 | - mlaunch++; |
1893 | } |
1894 | } |
1895 | - // qDebug("mpf: %d\tm launched: %d\t(mps: %f)\t%d\n", mpf, mlaunch, ZHR*zhrToWsr, deltaTime); |
1896 | } |
1897 | |
1898 | |
1899 | void MeteorMgr::draw(StelCore* core) |
1900 | { |
1901 | if (!flagShow) |
1902 | + { |
1903 | return; |
1904 | - |
1905 | - LandscapeMgr* landmgr = (LandscapeMgr*)StelApp::getInstance().getModuleMgr().getModule("LandscapeMgr"); |
1906 | + } |
1907 | + |
1908 | + LandscapeMgr* landmgr = GETSTELMODULE(LandscapeMgr); |
1909 | if (landmgr->getFlagAtmosphere() && landmgr->getLuminance()>5) |
1910 | + { |
1911 | return; |
1912 | + } |
1913 | |
1914 | + // step through and draw all active meteors |
1915 | StelPainter sPainter(core->getProjection(StelCore::FrameAltAz)); |
1916 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
1917 | - glEnable(GL_BLEND); |
1918 | - sPainter.enableTexture2d(false); |
1919 | - |
1920 | - // step through and draw all active meteors |
1921 | - for (std::vector<Meteor*>::iterator iter = active.begin(); iter != active.end(); ++iter) |
1922 | + std::vector<Meteor*>::iterator iter; |
1923 | + for (iter = active.begin(); iter != active.end(); ++iter) |
1924 | { |
1925 | (*iter)->draw(core, sPainter); |
1926 | } |
1927 | |
1928 | === modified file 'src/core/modules/MeteorMgr.hpp' |
1929 | --- src/core/modules/MeteorMgr.hpp 2013-08-24 21:33:23 +0000 |
1930 | +++ src/core/modules/MeteorMgr.hpp 2014-06-29 14:51:17 +0000 |
1931 | @@ -1,17 +1,18 @@ |
1932 | /* |
1933 | * Stellarium |
1934 | - * This file Copyright (C) 2004 Robert Spearman |
1935 | - * |
1936 | + * Copyright (C) 2004 Robert Spearman |
1937 | + * Copyright (C) 2014 Marcos Cardinot |
1938 | + * |
1939 | * This program is free software; you can redistribute it and/or |
1940 | * modify it under the terms of the GNU General Public License |
1941 | * as published by the Free Software Foundation; either version 2 |
1942 | * of the License, or (at your option) any later version. |
1943 | - * |
1944 | + * |
1945 | * This program is distributed in the hope that it will be useful, |
1946 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1947 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1948 | * GNU General Public License for more details. |
1949 | - * |
1950 | + * |
1951 | * You should have received a copy of the GNU General Public License |
1952 | * along with this program; if not, write to the Free Software |
1953 | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. |
1954 | @@ -20,7 +21,6 @@ |
1955 | #ifndef _METEORMGR_HPP_ |
1956 | #define _METEORMGR_HPP_ |
1957 | |
1958 | -#include <vector> |
1959 | #include "StelModule.hpp" |
1960 | |
1961 | class Meteor; |
1962 | @@ -59,6 +59,9 @@ |
1963 | |
1964 | //! Defines the order in which the various modules are drawn. |
1965 | virtual double getCallOrder(StelModuleActionName actionName) const; |
1966 | + |
1967 | + //! Factor to convert from zhr to whole earth per second rate |
1968 | + static const double zhrToWsr = 1.6667f / 3600.f; |
1969 | |
1970 | public slots: |
1971 | /////////////////////////////////////////////////////////////////////////// |
1972 | @@ -80,10 +83,9 @@ |
1973 | void zhrChanged(int); |
1974 | |
1975 | private: |
1976 | - std::vector<Meteor*> active; // Vector containing all active meteors |
1977 | + std::vector<Meteor*> active; // Vector containing all active meteors |
1978 | int ZHR; |
1979 | int maxVelocity; |
1980 | - double zhrToWsr; // factor to convert from zhr to whole earth per second rate |
1981 | bool flagShow; |
1982 | }; |
1983 |
Please update default showers.json file.