3
* Copyright (C) 2002 Fabien Chereau
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
// Class used to manage group of constellation
26
#include "constellation_mgr.h"
27
#include "constellation.h"
28
#include "hip_star_mgr.h"
30
#include "stel_utility.h"
32
// constructor which loads all data from appropriate files
33
ConstellationMgr::ConstellationMgr(HipStarMgr *_hip_stars) :
35
hipStarMgr(_hip_stars),
43
isolateSelected = false;
46
ConstellationMgr::~ConstellationMgr()
48
vector<Constellation *>::iterator iter;
49
for (iter = asterisms.begin(); iter != asterisms.end(); iter++)
54
if (asterFont) delete asterFont;
57
vector<vector<Vec3f> *>::iterator iter1;
58
for (iter1 = allBoundarySegments.begin(); iter1 != allBoundarySegments.end(); ++iter1)
62
allBoundarySegments.clear();
65
void ConstellationMgr::setFlagGravityLabel(bool g) {Constellation::gravityLabel = g;}
67
void ConstellationMgr::setLineColor(const Vec3f& c) {Constellation::lineColor = c;}
68
Vec3f ConstellationMgr::getLineColor() const {return Constellation::lineColor;}
70
void ConstellationMgr::setBoundaryColor(const Vec3f& c) {Constellation::boundaryColor = c;}
71
Vec3f ConstellationMgr::getBoundaryColor() const {return Constellation::boundaryColor;}
73
void ConstellationMgr::setLabelColor(const Vec3f& c) {Constellation::labelColor = c;}
74
Vec3f ConstellationMgr::getLabelColor() const {return Constellation::labelColor;}
76
void ConstellationMgr::setFont(float font_size, const string& ttfFileName)
78
if (asterFont) delete asterFont;
79
asterFont = new s_font(font_size, ttfFileName);
83
// Load line and art data from files
84
void ConstellationMgr::loadLinesAndArt(const string &fileName, const string &artfileName, const string &boundaryfileName, LoadingBar& lb)
87
std::ifstream inf(fileName.c_str());
91
printf("Can't open constellation data file %s\n", fileName.c_str());
95
// delete existing data, if any
96
vector < Constellation * >::iterator iter;
97
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
103
Constellation *cons = NULL;
107
while(!std::getline(inf, record).eof())
110
if (record.size()!=0 && record[0]=='#')
112
cons = new Constellation;
113
if(cons->read(record, hipStarMgr))
115
asterisms.push_back(cons);
118
cerr << "ERROR on line " << line << "of " << fileName.c_str() << endl;
124
// Set current states
126
setFlagLines(flagLines);
127
setFlagNames(flagNames);
128
setFlagBoundaries(flagBoundaries);
131
FILE *fic = fopen(artfileName.c_str(), "r");
134
cerr << "Can't open " << artfileName.c_str() << endl;
135
return; // no art, but still loaded constellation data
138
// Read the constellation art file with the following format :
139
// ShortName texture_file x1 y1 hp1 x2 y2 hp2
141
// shortname is the international short name (i.e "Lep" for Lepus)
142
// texture_file is the graphic file of the art texture
143
// x1 y1 are the x and y texture coordinates in pixels of the star of hipparcos number hp1
144
// x2 y2 are the x and y texture coordinates in pixels of the star of hipparcos number hp2
145
// The coordinate are taken with (0,0) at the top left corner of the image file
148
unsigned int x1, y1, x2, y2, x3, y3, hp1, hp2, hp3;
154
// determine total number to be loaded for percent complete display
155
while (fgets(tmpstr, 2000, fic)) {++total;}
162
if (fscanf(fic, "%s %s %u %u %u %u %u %u %u %u %u\n", shortname, texfile, &x1, &y1, &hp1, &x2, &y2, &hp2, &x3, &y3, &hp3) != 11)
166
// Empty constellation file
168
return; // no art is OK
170
cerr << "Error while loading art for constellation " << shortname << endl;;
175
lb.SetMessage(_("Loading Constellation Art: ") + StelUtility::intToWstring(current+1) + L"/" + StelUtility::intToWstring(total));
176
lb.Draw((float)(current+1)/total);
179
cons = findFromAbbreviation(shortname);
182
cerr << "ERROR : Can't find constellation called : " << shortname << endl;
186
cons->art_tex = new s_texture(texfile);
187
texSize = cons->art_tex->getSize();
189
Vec3f s1 = hipStarMgr->searchHP(hp1)->getObsJ2000Pos();
190
Vec3f s2 = hipStarMgr->searchHP(hp2)->getObsJ2000Pos();
191
Vec3f s3 = hipStarMgr->searchHP(hp3)->getObsJ2000Pos();
193
// To transform from texture coordinate to 2d coordinate we need to find X with XA = B
194
// A formed of 4 points in texture coordinate, B formed with 4 points in 3d coordinate
195
// We need 3 stars and the 4th point is deduced from the other to get an normal base
197
Vec3f s4 = s1 + (s2 - s1) ^ (s3 - s1);
198
Mat4f B(s1[0], s1[1], s1[2], 1, s2[0], s2[1], s2[2], 1, s3[0], s3[1], s3[2], 1, s4[0], s4[1], s4[2], 1);
199
Mat4f A(x1, texSize - y1, 0.f, 1.f, x2, texSize - y2, 0.f, 1.f, x3, texSize - y3, 0.f, 1.f, x1, texSize - y1, texSize, 1.f);
200
Mat4f X = B * A.inverse();
202
cons->art_vertex[0] = Vec3f(X * Vec3f(0, 0, 0));
203
cons->art_vertex[1] = Vec3f(X * Vec3f(texSize / 2, 0, 0));
204
cons->art_vertex[2] = Vec3f(X * Vec3f(texSize / 2, texSize / 2, 0));
205
cons->art_vertex[3] = Vec3f(X * Vec3f(0, texSize / 2, 0));
206
cons->art_vertex[4] = Vec3f(X * Vec3f(texSize / 2 + texSize / 2, 0, 0));
207
cons->art_vertex[5] = Vec3f(X * Vec3f(texSize / 2 + texSize / 2, texSize / 2, 0));
208
cons->art_vertex[6] = Vec3f(X * Vec3f(texSize / 2 + texSize / 2, texSize / 2 + texSize / 2, 0));
209
cons->art_vertex[7] = Vec3f(X * Vec3f(texSize / 2 + 0, texSize / 2 + texSize / 2, 0));
210
cons->art_vertex[8] = Vec3f(X * Vec3f(0, texSize / 2 + texSize / 2, 0));
217
loadBoundaries(boundaryfileName);
221
void ConstellationMgr::draw(Projector * prj, Navigator * nav) const
223
prj->set_orthographic_projection();
228
prj->reset_perspective_projection();
231
// Draw constellations art textures
232
void ConstellationMgr::draw_art(Projector * prj, Navigator * nav) const
234
glBlendFunc(GL_ONE, GL_ONE);
235
glEnable(GL_TEXTURE_2D);
237
glEnable(GL_CULL_FACE);
239
vector < Constellation * >::const_iterator iter;
240
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
242
(*iter)->draw_art_optim(prj, nav);
245
glDisable(GL_CULL_FACE);
248
// Draw constellations lines
249
void ConstellationMgr::draw_lines(Projector * prj) const
251
glDisable(GL_TEXTURE_2D);
254
vector < Constellation * >::const_iterator iter;
255
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
257
(*iter)->draw_optim(prj);
261
// Draw the names of all the constellations
262
void ConstellationMgr::draw_names(Projector * prj) const
265
glEnable(GL_TEXTURE_2D);
267
glBlendFunc(GL_ONE, GL_ONE);
268
// if (draw_mode == DM_NORMAL) glBlendFunc(GL_ONE, GL_ONE);
269
// else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // charting
271
vector < Constellation * >::const_iterator iter;
272
for (iter = asterisms.begin(); iter != asterisms.end(); iter++)
274
// Check if in the field of view
275
if (prj->project_j2000_check((*iter)->XYZname, (*iter)->XYname))
276
(*iter)->draw_name(asterFont, prj);
280
Constellation *ConstellationMgr::is_star_in(const HipStar * s) const
282
vector < Constellation * >::const_iterator iter;
283
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
285
// Check if the star is in one of the constellation
286
if ((*iter)->is_star_in(s))
292
Constellation *ConstellationMgr::findFromAbbreviation(const string & abbreviation) const
294
// search in uppercase only
295
string tname = abbreviation;
296
transform(tname.begin(), tname.end(), tname.begin(),::toupper);
298
vector < Constellation * >::const_iterator iter;
299
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
301
// Check if the star is in one of the constellation
302
if (string((*iter)->abbreviation) == tname)
310
* @brief Read constellation names from the given file
311
* @param namesFile Name of the file containing the constellation names in english
313
void ConstellationMgr::loadNames(const string& namesFile)
315
// Constellation not loaded yet
316
if (asterisms.empty()) return;
318
// clear previous names
319
vector < Constellation * >::const_iterator iter;
320
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
322
(*iter)->englishName.clear();
325
// read in translated common names from file
326
ifstream commonNameFile(namesFile.c_str());
327
if (!commonNameFile.is_open())
329
cerr << "Can't open file" << namesFile << endl;
333
// find matching constellation and update name
336
Constellation *aster;
337
while (!std::getline(commonNameFile, record).eof())
341
istringstream in(record);
344
// cout << "working on short name " << tmpShortName << endl;
346
aster = findFromAbbreviation(tmpShortName);
349
// Read the names in english
350
aster->englishName = record.substr(tmpShortName.length()+1,record.length()).c_str();
354
commonNameFile.close();
358
//! @brief Update i18 names from english names according to current locale
359
//! The translation is done using gettext with translated strings defined in translations.h
360
void ConstellationMgr::translateNames(Translator& trans)
362
vector < Constellation * >::const_iterator iter;
363
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
365
(*iter)->nameI18 = trans.translate((*iter)->englishName.c_str());
366
//cout << (*iter)->englishName.c_str() << " -> " << StelUtility::wstringToString((*iter)->nameI18) << endl;
371
void ConstellationMgr::update(int delta_time)
373
vector < Constellation * >::const_iterator iter;
374
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
376
(*iter)->update(delta_time);
381
void ConstellationMgr::setArtIntensity(float _max)
383
artMaxIntensity = _max;
384
vector < Constellation * >::const_iterator iter;
385
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
386
(*iter)->art_fader.set_max_value(_max);
389
void ConstellationMgr::setArtFadeDuration(float duration)
391
artFadeDuration = duration;
392
vector < Constellation * >::const_iterator iter;
393
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
394
(*iter)->art_fader.set_duration((int) (duration * 1000.f));
397
void ConstellationMgr::setFlagLines(bool b)
400
if (selected && isolateSelected)
402
selected->setFlagLines(b);
406
vector < Constellation * >::const_iterator iter;
407
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
408
(*iter)->setFlagLines(b);
412
void ConstellationMgr::setFlagBoundaries(bool b)
415
if (selected && isolateSelected)
417
selected->setFlagBoundaries(b);
421
vector < Constellation * >::const_iterator iter;
422
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
423
(*iter)->setFlagBoundaries(b);
427
void ConstellationMgr::setFlagArt(bool b)
430
if (selected && isolateSelected)
432
selected->setFlagArt(b);
436
vector < Constellation * >::const_iterator iter;
437
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
438
(*iter)->setFlagArt(b);
443
void ConstellationMgr::setFlagNames(bool b)
446
if (selected && isolateSelected)
448
selected->setFlagName(b);
452
vector < Constellation * >::const_iterator iter;
453
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
454
(*iter)->setFlagName(b);
458
void ConstellationMgr::setSelectedConst(Constellation * c)
460
// update states for other constellations to fade them out
464
// Propagate old parameters new newly selected constellation
465
if (selected) cc=selected;
466
else cc=*(asterisms.begin());
467
c->setFlagLines(cc->getFlagLines());
468
c->setFlagName(cc->getFlagName());
469
c->setFlagArt(cc->getFlagArt());
470
c->setFlagBoundaries(cc->getFlagBoundaries());
475
vector < Constellation * >::const_iterator iter;
476
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
478
if ((*iter) != selected)
480
(*iter)->setFlagLines(false);
481
(*iter)->setFlagName(false);
482
(*iter)->setFlagArt(false);
483
(*iter)->setFlagBoundaries(false);
486
Constellation::singleSelected = true;
490
vector < Constellation * >::const_iterator iter;
491
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
493
(*iter)->setFlagLines(c->getFlagLines());
494
(*iter)->setFlagName(c->getFlagName());
495
(*iter)->setFlagArt(c->getFlagArt());
496
(*iter)->setFlagBoundaries(c->getFlagBoundaries());
498
Constellation::singleSelected = false;
503
if (selected==NULL) return;
504
vector < Constellation * >::const_iterator iter;
505
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
507
if ((*iter) != selected)
509
(*iter)->setFlagLines(selected->getFlagLines());
510
(*iter)->setFlagName(selected->getFlagName());
511
(*iter)->setFlagArt(selected->getFlagArt());
512
(*iter)->setFlagBoundaries(selected->getFlagBoundaries());
520
bool ConstellationMgr::loadBoundaries(const string& boundaryFile)
522
Constellation *cons = NULL;
525
vector<vector<Vec3f> *>::iterator iter;
526
for (iter = allBoundarySegments.begin(); iter != allBoundarySegments.end(); ++iter)
530
allBoundarySegments.clear();
532
cout << "Loading Constellation boundary data...";
533
// Modified boundary file by Torsten Bronger with permission
534
// http://pp3.sourceforge.net
537
dataFile.open(boundaryFile.c_str());
538
if (!dataFile.is_open())
540
cerr << "Boundary file " << boundaryFile << " not found" << endl;
548
vector<Vec3f> *points = NULL;
551
while (!dataFile.eof())
553
points = new vector<Vec3f>;
557
if(num == 0) continue; // empty line
561
dataFile >> RA >> DE;
566
RA*=M_PI/12.; // Convert from hours to rad
567
DE*=M_PI/180.; // Convert from deg to rad
569
// Calc the Cartesian coord with RA and DE
570
sphe_to_rect(RA,DE,XYZ);
571
points->push_back(XYZ);
574
// this list is for the de-allocation
575
allBoundarySegments.push_back(points);
578
// there are 2 constellations per boundary
582
dataFile >> consname;
584
if (consname == "SER1" || consname == "SER2") consname = "SER";
586
cons = findFromAbbreviation(consname);
587
if (!cons) cout << "ERROR : Can't find constellation called : " << consname << endl;
588
else cons->isolatedBoundarySegments.push_back(points);
591
if (cons) cons->sharedBoundarySegments.push_back(points);
596
cout << "(" << i << " segments loaded)" << endl;
602
// Draw constellations lines
603
void ConstellationMgr::drawBoundaries(Projector * prj) const
605
glDisable(GL_TEXTURE_2D);
608
glLineStipple(2, 0x3333);
609
glEnable(GL_LINE_STIPPLE);
611
vector < Constellation * >::const_iterator iter;
612
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
614
(*iter)->draw_boundary_optim(prj);
616
glDisable(GL_LINE_STIPPLE);
619
unsigned int ConstellationMgr::getFirstSelectedHP(void) {
620
if (selected) return selected->asterism[0]->get_hp_number();
624
//! Return the matching constellation object's pointer if exists or NULL
625
//! @param nameI18n The case sensistive constellation name
626
Constellation* ConstellationMgr::searchByNameI18n(const wstring& nameI18n) const
628
wstring objw = nameI18n;
629
transform(objw.begin(), objw.end(), objw.begin(), ::toupper);
631
vector <Constellation*>::const_iterator iter;
632
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
634
wstring objwcap = (*iter)->nameI18;
635
transform(objwcap.begin(), objwcap.end(), objwcap.begin(), ::toupper);
636
if (objwcap==objw) return *iter;
641
//! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name
642
vector<wstring> ConstellationMgr::listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem) const
644
vector<wstring> result;
645
if (maxNbItem==0) return result;
647
wstring objw = objPrefix;
648
transform(objw.begin(), objw.end(), objw.begin(), ::toupper);
650
vector < Constellation * >::const_iterator iter;
651
for (iter = asterisms.begin(); iter != asterisms.end(); ++iter)
653
wstring constw = (*iter)->getNameI18().substr(0, objw.size());
654
transform(constw.begin(), constw.end(), constw.begin(), ::toupper);
657
result.push_back((*iter)->getNameI18());
658
if (result.size()==maxNbItem)