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 groups of Stars
23
#include "hip_star_mgr.h"
25
#include "s_texture.h"
28
#include "stellarium.h"
29
#include "navigator.h"
30
#include "stel_utility.h"
31
#include "translator.h"
33
#define RADIUS_STAR 1.
35
// construct and load all data
36
HipStarMgr::HipStarMgr() :
40
starArraySize(0), // This is the full data array including HP, HP SAO (not duplicated)
43
starZones = new vector<HipStar*>[HipGrid.getNbPoints()];
47
HipStarMgr::~HipStarMgr()
52
/// delete starcTexture;
53
/// starcTexture=NULL;
55
delete HipStar::starFont;
56
HipStar::starFont=NULL;
64
delete [] StarFlatArray;
68
void HipStarMgr::setLabelColor(const Vec3f& c) {HipStar::label_color = c;}
69
Vec3f HipStarMgr::getLabelColor(void) {return HipStar::label_color;}
71
void HipStarMgr::setCircleColor(const Vec3f& c) {HipStar::circle_color = c;}
72
Vec3f HipStarMgr::getCircleColor(void) {return HipStar::circle_color;}
74
void HipStarMgr::init(float font_size, const string& font_name, const string& hipCatFile,
75
const string& commonNameFile, const string& sciNameFile, LoadingBar& lb)
77
load_data(hipCatFile, lb);
78
load_double(hipCatFile);
79
load_variable(hipCatFile);
81
load_common_names(commonNameFile);
82
load_sci_names(sciNameFile);
84
/// starcTexture = new s_texture("starc64x64.png",TEX_LOAD_TYPE_PNG_BLEND3); // Load star chart texture
85
starTexture = new s_texture("star16x16.png",TEX_LOAD_TYPE_PNG_SOLID); // Load star texture
87
HipStar::starFont = new s_font(font_size, font_name);
88
if (!HipStar::starFont)
90
printf("Can't create starFont\n");
95
// Load from file ( create the stream and call the Read function )
96
void HipStarMgr::load_data(const string& hipCatFile, LoadingBar& lb)
98
cout << "Loading Hipparcos star data...";
102
hipFile=fopen(hipCatFile.c_str(),"rb");
105
cerr << "ERROR " << hipCatFile << " NOT FOUND" << endl;
109
// Read number of stars in the Hipparcos catalog
110
unsigned int catalogSize=0;
111
fread((char*)&catalogSize,4,1,hipFile);
112
LE_TO_CPU_INT32(catalogSize,catalogSize);
114
starArraySize = catalogSize;//120417;
116
// Create the sequential array
117
StarArray = new HipStar[starArraySize];
119
StarFlatArray = new HipStar*[starArraySize];
120
for (int i=0;i<starArraySize;++i)
122
StarFlatArray[i] = NULL;
125
// Read binary file Hipparcos catalog
126
unsigned int data_drop =0;
128
for(int i=0;i<starArraySize;i++)
130
if (!(i%2000) || (i == starArraySize-1))
133
lb.SetMessage(_("Loading Hipparcos catalog:") + StelUtility::intToWstring((i == starArraySize-1 ? starArraySize: i)) +
134
L"/" + StelUtility::intToWstring(starArraySize));
135
lb.Draw((float)i/starArraySize);
139
e->HP=(unsigned int)i;
140
if (!e->read(hipFile))
145
starZones[HipGrid.GetNearest(e->XYZ)].push_back(e);
146
StarFlatArray[e->HP]=e;
150
printf("(%d stars loaded [%d dropped]).\n", starArraySize-data_drop,data_drop);
152
// sort stars by magnitude for faster rendering
153
for(int i=0;i < HipGrid.getNbPoints();i++) {
154
std::sort( starZones[i].begin(), starZones[i].end(), std::not2(HipStarMagComparer()));
158
// Load common names from file
159
int HipStarMgr::load_common_names(const string& commonNameFile)
161
cout << "Load star names from " << commonNameFile << endl;
163
// clear existing names (would be faster if they were in separate array
164
// since relatively few are named)
165
for (int i=0; i<starArraySize; ++i)
167
StarArray[i].englishCommonName = "";
168
StarArray[i].commonNameI18 = L"";
172
cnFile=fopen(commonNameFile.c_str(),"r");
175
cerr << "Warning " << commonNameFile << " not found." << endl;
179
common_names_map.clear();
180
// if (!lstCommonNames.empty())
182
// lstCommonNames.clear();
183
// lstCommonNamesHP.clear();
185
// Assign names to the matching stars, now support spaces in names
189
fgets(line, 256, cnFile);
192
sscanf(line,"%u",&tmp);
193
star = searchHP(tmp);
198
while(c!='|' && i<256){c=line[i];++i;}
199
star->englishCommonName = &(line[i]);
201
star->englishCommonName.erase(star->englishCommonName.length()-1, 1);
203
// remove underscores
204
for (string::size_type j=0;j<star->englishCommonName.length();++j) {
205
if (star->englishCommonName[j]=='_') star->englishCommonName[j]=' ';
207
star->commonNameI18 = _(star->englishCommonName.c_str());
208
common_names_map.push_back(star);
210
} while(fgets(line, 256, cnFile));
217
// Load scientific names from file
218
void HipStarMgr::load_sci_names(const string& sciNameFile)
220
// clear existing names (would be faster if they were in separate arrays
221
// since relatively few are named)
222
for (int i=0; i<starArraySize; i++)
224
StarArray[i].sciName = L"";
228
snFile=fopen(sciNameFile.c_str(),"r");
231
cerr << "Warning " << sciNameFile.c_str() << " not found" << endl;
235
sci_names_map.clear();
237
// Assign names to the matching stars, now support spaces in names
241
fgets(line, 256, snFile);
244
sscanf(line,"%u",&tmp);
245
star = searchHP(tmp);
246
if (star && star->sciName==L"")
250
while(c!='|' && i<256){c=line[i];++i;}
251
char* tempc = &(line[i]);
252
while(c!='_' && i<256){c=line[i];++i;}
254
string sciName = tempc;
255
sciName.erase(sciName.length()-1, 1);
256
star->sciName = Translator::UTF8stringToWstring(sciName);
257
sci_names_map.push_back(star);
259
} while(fgets(line, 256, snFile));
264
// Draw all the stars
265
void HipStarMgr::draw(Vec3f equ_vision, ToneReproductor* eye, Projector* prj)
268
// If stars are turned off don't waste time below
269
// projecting all stars just to draw disembodied labels
270
if(!starsFader.getInterstate()) return;
272
// Set temporary static variable for optimization
273
if (flagStarTwinkle) HipStar::twinkle_amount = twinkleAmount;
274
else HipStar::twinkle_amount = 0;
275
HipStar::star_scale = starScale * starsFader.getInterstate();
276
HipStar::star_mag_scale = starMagScale;
277
HipStar::gravity_label = gravityLabel;
278
HipStar::names_brightness = names_fader.getInterstate()
279
* starsFader.getInterstate();
284
// TODO: fade on/off with starsFader
285
if( starsFader.getInterstate())
286
drawPoint(equ_vision, eye, prj);
290
glEnable(GL_TEXTURE_2D);
293
// Find the star zones which are in the screen
296
// FOV is currently measured vertically, so need to adjust for wide screens
297
// TODO: projector should probably use largest measurement itself
298
float max_fov = MY_MAX( prj->get_fov(), prj->get_fov()*prj->getViewportWidth()/prj->getViewportHeight());
300
nbZones = HipGrid.Intersect(equ_vision, max_fov*M_PI/180.f*1.2f);
301
static int * zoneList = HipGrid.getResult();
302
// float maxMag = limiting_mag-1 + 60.f/prj->get_fov();
303
float maxMag = limitingMag-1 + 60.f/max_fov;
305
prj->set_orthographic_projection(); // set 2D coordinate
307
// Print all the stars of all the selected zones
308
static vector<HipStar *>::iterator end;
309
static vector<HipStar *>::iterator iter;
312
// Bind the star texture
313
//if (draw_mode == DM_NORMAL)
314
glBindTexture (GL_TEXTURE_2D, starTexture->getID());
315
//else glBindTexture (GL_TEXTURE_2D, starcTexture->getID());
318
//if (draw_mode == DM_NORMAL)
319
glBlendFunc(GL_ONE, GL_ONE);
320
//else glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // charting
323
for(int i=0;i<nbZones;++i)
325
end = starZones[zoneList[i]].end();
326
for(iter = starZones[zoneList[i]].begin(); iter!=end; ++iter)
329
// If too small, skip and Compute the 2D position and check if in screen
330
if(h->Mag > maxMag) break;
331
if(!prj->project_j2000_check(h->XYZ, XY)) continue;
333
// if (draw_mode == DM_NORMAL)
336
if (names_fader.getInterstate() && h->Mag < maxMagStarName)
338
if (h->draw_name(XY))
339
glBindTexture (GL_TEXTURE_2D, starTexture->getID());
344
// h->draw_chart(XY);
345
// if (names_fader.getInterstate() && h->Mag < maxMagStarName)
347
// // need to rebind the star texture after font printing
348
// if (h->draw_name(XY))
349
// glBindTexture (GL_TEXTURE_2D, starcTexture->getID());
356
prj->reset_perspective_projection();
359
// Draw all the stars
360
void HipStarMgr::drawPoint(Vec3f equ_vision, ToneReproductor* _eye, Projector* prj)
362
glEnable(GL_TEXTURE_2D);
364
glBindTexture (GL_TEXTURE_2D, starTexture->getID());
365
glBlendFunc(GL_ONE, GL_ONE);
367
// Find the star zones which are in the screen
369
nbZones = HipGrid.Intersect(equ_vision, prj->get_fov()*M_PI/180.f*1.2f);
370
int * zoneList = HipGrid.getResult();
371
float maxMag = 5.5f+60.f/prj->get_fov();
373
prj->set_orthographic_projection(); // set 2D coordinate
375
// Print all the stars of all the selected zones
376
static vector<HipStar *>::iterator end;
377
static vector<HipStar *>::iterator iter;
380
for(int i=0;i<nbZones;++i)
382
end = starZones[zoneList[i]].end();
383
for(iter = starZones[zoneList[i]].begin(); iter!=end; ++iter)
386
// If too small, skip and Compute the 2D position and check if in screen
387
if(h->Mag>maxMag) break;
388
if(!prj->project_j2000_check(h->XYZ, XY)) continue;
390
if (!h->commonNameI18.empty() && names_fader.getInterstate() && h->Mag<maxMagStarName)
393
// glBindTexture (GL_TEXTURE_2D, starTexture->getID());
398
prj->reset_perspective_projection();
401
// Look for a star by XYZ coords
402
HipStar * HipStarMgr::search(Vec3f Pos) const
405
HipStar * nearest=NULL;
406
float angleNearest=0.;
408
for(int i=0; i<starArraySize; i++)
410
if (!StarFlatArray[i]) continue;
411
if (StarFlatArray[i]->XYZ[0]*Pos[0] + StarFlatArray[i]->XYZ[1]*Pos[1] +
412
StarFlatArray[i]->XYZ[2]*Pos[2]>angleNearest)
414
angleNearest = StarFlatArray[i]->XYZ[0]*Pos[0] +
415
StarFlatArray[i]->XYZ[1]*Pos[1] + StarFlatArray[i]->XYZ[2]*Pos[2];
416
nearest=StarFlatArray[i];
419
if (angleNearest>RADIUS_STAR*0.9999)
426
// Return a stl vector containing the nebulas located inside the lim_fov circle around position v
427
vector<StelObject*> HipStarMgr::search_around(Vec3d v, double lim_fov) const
429
vector<StelObject*> result;
431
double cos_lim_fov = cos(lim_fov * M_PI/180.);
433
for(int i=0; i<starArraySize; i++)
435
if (!StarFlatArray[i]) continue;
436
if (StarFlatArray[i]->XYZ[0]*v[0] + StarFlatArray[i]->XYZ[1]*v[1] + StarFlatArray[i]->XYZ[2]*v[2]>=cos_lim_fov)
438
result.push_back(StarFlatArray[i]);
445
// Load the double stars from the double star file
446
bool HipStarMgr::load_double(const string& hipCatFile)
449
string dataDir = hipCatFile;
455
unsigned int loc = dataDir.rfind("/");
457
if (loc != string::npos)
458
dataDir = dataDir.substr(0,loc+1);
460
cout << "Loading Hipparcos double stars...";
461
string hipData = dataDir + "double_txt.dat";
463
dataFile = fopen(hipData.c_str(),"r");
466
cerr << "Hipparcos double star data file " << hipData << " not found" << endl;
470
while (fgets(record,1024,dataFile))
472
sscanf(record,"%u", &HP);
473
e = StarFlatArray[HP];
476
e->doubleStar = true;
483
cout << "(" << i << " stars loaded)" << endl;
487
// Load the variable stars from the raw hip file
488
bool HipStarMgr::load_variable(const string& hipCatFile)
491
string dataDir = hipCatFile;
497
unsigned int loc = dataDir.rfind("/");
499
if (loc != string::npos)
500
dataDir = dataDir.substr(0,loc+1);
502
cout << "Loading Hipparcos periodic variable stars...";
503
string hipData = dataDir+"variable_txt.dat";
504
dataFile = fopen(hipData.c_str(),"r");
507
cerr << "Hipparcos variable star data file " << hipData << " not found" << endl;
511
while (fgets(record,1024,dataFile))
513
sscanf(record,"%u", &HP);
514
e = StarFlatArray[HP];
517
e->variableStar = true;
524
cout << "(" << i << " stars loaded)" << endl;
528
//! @brief Update i18 names from english names according to passed translator
529
//! The translation is done using gettext with translated strings defined in translations.h
530
void HipStarMgr::translateNames(Translator& trans)
533
// TODO: separate common names vector would be more efficient
534
for (int i=0; i<starArraySize; ++i)
536
StarArray[i].commonNameI18 = trans.translate(StarArray[i].englishCommonName);
542
HipStar *HipStarMgr::search(const string& name) const
544
const string catalogs("HP HD SAO");
547
for (string::size_type i=0;i<n.length();++i)
549
if (n[i]=='_') n[i]=' ';
558
// check if a valid catalog reference
559
if (catalogs.find(cat,0) == string::npos)
561
// try see if the string is a HP number
562
istringstream cat_to_num(cat);
564
if (!cat_to_num.fail()) return searchHP(num);
569
if (ss.fail()) return NULL;
571
if (cat == "HP") return searchHP(num);
576
// Search the star by HP number
577
HipStar *HipStarMgr::searchHP(unsigned int _HP) const
579
if (_HP != 0 && _HP < (unsigned int)starArraySize && StarFlatArray[_HP]
580
&& StarFlatArray[_HP]->HP == _HP)
581
return StarFlatArray[_HP];
585
HipStar* HipStarMgr::searchByNameI18n(const wstring& nameI18n) const
587
wstring objw = nameI18n;
588
transform(objw.begin(), objw.end(), objw.begin(), ::toupper);
590
// Search by HP number if it's an HP formated number
591
// Please help, if you know a better way to do this:
592
if (nameI18n.length() >= 2 && nameI18n[0]==L'H' && nameI18n[1]==L'P')
595
wstring::size_type i=2;
597
for (;i<nameI18n.length();i++)
599
if (nameI18n[i] != L' ') break;
603
for (;i<nameI18n.length();i++)
605
if (hp_ok = (L'0' <= nameI18n[i] && nameI18n[i] <= L'9'))
607
nr = 10*nr+(nameI18n[i]-L'0');
620
// Search by I18n common name
621
std::vector<HipStar*>::const_iterator iter;
622
for (iter=common_names_map.begin();iter!=common_names_map.end();++iter)
624
wstring objwcap = (*iter)->commonNameI18;
625
transform(objwcap.begin(), objwcap.end(), objwcap.begin(), ::toupper);
626
if (objwcap==objw) return *iter;
629
// Search by sci name
630
for (iter=sci_names_map.begin();iter!=sci_names_map.end();++iter)
632
wstring objwcap = (*iter)->sciName;
633
transform(objwcap.begin(), objwcap.end(), objwcap.begin(), ::toupper);
634
if (objwcap==objw) return *iter;
640
//! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name
641
vector<wstring> HipStarMgr::listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem) const
643
vector<wstring> result;
644
if (maxNbItem==0) return result;
646
wstring objw = objPrefix;
647
transform(objw.begin(), objw.end(), objw.begin(), ::toupper);
649
// Search by common names
650
std::vector<HipStar*>::const_iterator iter;
651
for (iter = common_names_map.begin(); iter != common_names_map.end(); ++iter)
653
wstring constw = (*iter)->commonNameI18.substr(0, objw.size());
654
transform(constw.begin(), constw.end(), constw.begin(), ::toupper);
657
result.push_back((*iter)->commonNameI18);
661
// Search by sci names
662
for (iter = sci_names_map.begin(); iter != sci_names_map.end(); ++iter)
664
wstring constw = (*iter)->sciName.substr(0, objw.size());
665
transform(constw.begin(), constw.end(), constw.begin(), ::toupper);
668
result.push_back((*iter)->sciName);
672
sort(result.begin(), result.end());
673
if (result.size()>maxNbItem) result.erase(result.begin()+maxNbItem, result.end());
679
//! Define font file name and size to use for star names display
680
void HipStarMgr::setFont(float font_size, const string& font_name) {
682
if (HipStar::starFont) delete HipStar::starFont;
683
HipStar::starFont = new s_font(font_size, font_name);
684
assert(HipStar::starFont);