ZoneArray.cpp   ZoneArray.cpp 
skipping to change at line 22 skipping to change at line 22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA.
*/ */
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#ifdef WIN32
#include <io.h>
#include <windows.h>
#endif
#include "ZoneArray.hpp" #include "ZoneArray.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "GeodesicGrid.hpp" #include "StelGeodesicGrid.hpp"
#include "StelObject.hpp" #include "StelObject.hpp"
namespace BigStarCatalogExtension { namespace BigStarCatalogExtension
{
static const Vec3d north(0,0,1); static const Vec3d north(0,0,1);
void ZoneArray::initTriangle(int index, void ZoneArray::initTriangle(int index, const Vec3d &c0, const Vec3d &c1,
const Vec3d &c0, const Vec3d &c2)
const Vec3d &c1, {
const Vec3d &c2) { // initialize center,axis0,axis1:
// initialize center,axis0,axis1: ZoneData &z(zones[index]);
ZoneData &z(zones[index]); z.center = c0+c1+c2;
z.center = c0+c1+c2; z.center.normalize();
z.center.normalize(); z.axis0 = north ^ z.center;
z.axis0 = north ^ z.center; z.axis0.normalize();
z.axis0.normalize(); z.axis1 = z.center ^ z.axis0;
z.axis1 = z.center ^ z.axis0; // initialize star_position_scale:
// initialize star_position_scale: double mu0,mu1,f,h;
double mu0,mu1,f,h; mu0 = (c0-z.center)*z.axis0;
mu0 = (c0-z.center)*z.axis0; mu1 = (c0-z.center)*z.axis1;
mu1 = (c0-z.center)*z.axis1; f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1);
f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); h = fabs(mu0)*f;
h = fabs(mu0)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h; h = fabs(mu1)*f;
h = fabs(mu1)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h; mu0 = (c1-z.center)*z.axis0;
mu0 = (c1-z.center)*z.axis0; mu1 = (c1-z.center)*z.axis1;
mu1 = (c1-z.center)*z.axis1; f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1);
f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); h = fabs(mu0)*f;
h = fabs(mu0)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h; h = fabs(mu1)*f;
h = fabs(mu1)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h; mu0 = (c2-z.center)*z.axis0;
mu0 = (c2-z.center)*z.axis0; mu1 = (c2-z.center)*z.axis1;
mu1 = (c2-z.center)*z.axis1; f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1);
f = 1.0/sqrt(1.0-mu0*mu0-mu1*mu1); h = fabs(mu0)*f;
h = fabs(mu0)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h; h = fabs(mu1)*f;
h = fabs(mu1)*f; if (star_position_scale < h) star_position_scale = h;
if (star_position_scale < h) star_position_scale = h;
} }
static inline static inline
int ReadInt(FILE *f,unsigned int &x) { int ReadInt(QFile& file, unsigned int &x)
const int rval = (4 == fread(&x,1,4,f)) ? 0 : -1; {
return rval; const int rval = (4 == file.read((char*)&x, 4))
? 0 : -1;
return rval;
} }
#define FILE_MAGIC 0x835f040a
#define FILE_MAGIC_OTHER_ENDIAN 0x0a045f83
#define FILE_MAGIC_NATIVE 0x835f040b
#define MAX_MAJOR_FILE_VERSION 0
#if (!defined(__GNUC__)) #if (!defined(__GNUC__))
#warning Star catalogue loading has only been tested with gcc #warning Star catalogue loading has only been tested with gcc
#endif #endif
ZoneArray *ZoneArray::create(const StarMgr &hip_star_mgr, ZoneArray *ZoneArray::create(const QString& extended_file_name, bool use_mm
const QString& extended_file_name, ap,
LoadingBar &lb) { StelLoadingBar &lb)
QString fname(extended_file_name); {
QString dbStr; // for debugging output. QString fname(extended_file_name);
bool use_mmap = false; QString dbStr; // for debugging output.
if (fname.contains("mmap:")) { try
fname.remove(0,5); {
use_mmap = true; fname = StelApp::getInstance().getFileMgr().findFile("stars/
} default/"+fname);
try { }
fname = StelApp::getInstance().getFileMgr().findFile("stars/default/"+f catch (std::runtime_error &e)
name); {
} catch (std::runtime_error &e) { qDebug() << "Loading" << extended_file_name << e.what();
qWarning() << "Loading" << extended_file_name << e.what(); return 0;
return 0; }
} QFile* file = new QFile(fname);
FILE *f = fopen(QFile::encodeName(fname).constData(),"rb"); if(!file->open(QIODevice::ReadOnly))
if (f == 0) { {
qWarning() << "Loading" << extended_file_name << "failed to open file." qDebug() << "Loading" << extended_file_name << "failed to op
; en file.";
return 0; return 0;
} }
dbStr = "Loading \"" + extended_file_name + "\": "; dbStr = "Loading \"" + extended_file_name + "\": ";
unsigned int magic,major,minor,type,level,mag_min,mag_range,mag_steps; unsigned int magic,major,minor,type,level,mag_min,mag_range,mag_step
if (ReadInt(f,magic) < 0 || s;
ReadInt(f,type) < 0 || if (ReadInt(*file,magic) < 0 ||
ReadInt(f,major) < 0 || ReadInt(*file,type) < 0 ||
ReadInt(f,minor) < 0 || ReadInt(*file,major) < 0 ||
ReadInt(f,level) < 0 || ReadInt(*file,minor) < 0 ||
ReadInt(f,mag_min) < 0 || ReadInt(*file,level) < 0 ||
ReadInt(f,mag_range) < 0 || ReadInt(*file,mag_min) < 0 ||
ReadInt(f,mag_steps) < 0) { ReadInt(*file,mag_range) < 0 ||
dbStr += "error - file format is bad."; ReadInt(*file,mag_steps) < 0)
qWarning(qPrintable(dbStr)); {
return 0; dbStr += "error - file format is bad.";
} qDebug() << dbStr;
const bool byte_swap = (magic == FILE_MAGIC_OTHER_ENDIAN); return 0;
if (byte_swap) { }
// ok, FILE_MAGIC_OTHER_ENDIAN, must swap const bool byte_swap = (magic == FILE_MAGIC_OTHER_ENDIAN);
if (use_mmap) { if (byte_swap)
dbStr += "warning - must convert catalogue "; {
// ok, FILE_MAGIC_OTHER_ENDIAN, must swap
if (use_mmap)
{
dbStr += "warning - must convert catalogue ";
#if (!defined(__GNUC__)) #if (!defined(__GNUC__))
dbStr += "to native format "; dbStr += "to native format ";
#endif #endif
dbStr += "before mmap loading"; dbStr += "before mmap loading";
qWarning(qPrintable(dbStr)); qDebug() << dbStr;
return 0; return 0;
} }
dbStr += "byteswap "; dbStr += "byteswap ";
type = bswap_32(type); type = bswap_32(type);
major = bswap_32(major); major = bswap_32(major);
minor = bswap_32(minor); minor = bswap_32(minor);
level = bswap_32(level); level = bswap_32(level);
mag_min = bswap_32(mag_min); mag_min = bswap_32(mag_min);
mag_range = bswap_32(mag_range); mag_range = bswap_32(mag_range);
mag_steps = bswap_32(mag_steps); mag_steps = bswap_32(mag_steps);
} else if (magic == FILE_MAGIC) { }
// ok, FILE_MAGIC else if (magic == FILE_MAGIC)
{
// ok, FILE_MAGIC
#if (!defined(__GNUC__)) #if (!defined(__GNUC__))
if (use_mmap) { if (use_mmap)
// mmap only with gcc: {
dbStr += "warning - you must convert catalogue " // mmap only with gcc:
+= "to native format before mmap loading"; dbStr += "warning - you must convert catalogue "
qWarning(qPrintable(dbStr)); += "to native format before mmap loading";
qDebug(qPrintable(dbStr));
return 0; return 0;
} }
#endif #endif
} else if (magic == FILE_MAGIC_NATIVE) { }
// ok, will work for any architecture and any compiler else if (magic == FILE_MAGIC_NATIVE)
} else { {
dbStr += "error - not a catalogue file."; // ok, will work for any architecture and any compiler
qWarning(qPrintable(dbStr)); }
return 0; else
} {
ZoneArray *rval = 0; dbStr += "error - not a catalogue file.";
dbStr += QString("%1_%2v%3_%4; ").arg(level) qDebug() << dbStr;
.arg(type) return 0;
.arg(major) }
.arg(minor); ZoneArray *rval = 0;
switch (type) { dbStr += QString("%1_%2v%3_%4; ").arg(level)
case 0: .arg(type)
if (major > MAX_MAJOR_FILE_VERSION) { .arg(major)
dbStr += "warning - unsupported version "; .arg(minor);
} else {
// When this assertion fails you must redefine Star1 switch (type)
// for your compiler. {
// Because your compiler does not pack the data, case 0:
// which is crucial for this application. if (major > MAX_MAJOR_FILE_VERSION)
assert(sizeof(Star1) == 28); {
rval = new ZoneArray1(f,byte_swap,use_mmap,lb,hip_star_mgr,level, dbStr += "warning - unsupported version ";
mag_min,mag_range,mag_steps); }
if (rval == 0) { else
dbStr += "error - no memory "; {
} // When this assertion fails you must redefine Star1
} // for your compiler.
break; // Because your compiler does not pack the data,
case 1: // which is crucial for this application.
if (major > MAX_MAJOR_FILE_VERSION) { Q_ASSERT(sizeof(Star1) == 28);
dbStr += "warning - unsupported version "; rval = new HipZoneArray(file, byte_swap, use_mmap, l
} else { b,
// When this assertion fails you must redefine Star2 level, mag_min, mag_range, m
// for your compiler. ag_steps);
// Because your compiler does not pack the data, if (rval == 0)
// which is crucial for this application. {
assert(sizeof(Star2) == 10); dbStr += "error - no memory ";
rval = new SpecialZoneArray<Star2>(f,byte_swap,use_mmap,lb,hip_star }
_mgr, }
level, break;
mag_min,mag_range,mag_steps); case 1:
if (rval == 0) { if (major > MAX_MAJOR_FILE_VERSION)
dbStr += "error - no memory "; {
} dbStr += "warning - unsupported version ";
} }
break; else
case 2: {
if (major > MAX_MAJOR_FILE_VERSION) { // When this assertion fails you must redefine Star2
dbStr += "warning - unsupported version "; // for your compiler.
} else { // Because your compiler does not pack the data,
// When this assertion fails you must redefine Star3 // which is crucial for this application.
// for your compiler. Q_ASSERT(sizeof(Star2) == 10);
// Because your compiler does not pack the data, rval = new SpecialZoneArray<Star2>(file, byte_swap,
// which is crucial for this application. use_mmap,
assert(sizeof(Star3) == 6); lb, level, mag_mi
rval = new SpecialZoneArray<Star3>(f,byte_swap,use_mmap,lb,hip_star n,
_mgr, mag_range, mag_st
level, eps);
mag_min,mag_range,mag_steps); if (rval == 0)
if (rval == 0) { {
dbStr += "error - no memory "; dbStr += "error - no memory ";
} }
} }
break; break;
default: case 2:
dbStr += "error - bad file type "; if (major > MAX_MAJOR_FILE_VERSION)
break; {
} dbStr += "warning - unsupported version ";
if (rval && rval->isInitialized()) { }
dbStr += QString("%1").arg(rval->getNrOfStars()); else
qDebug(qPrintable(dbStr)); {
// rval->generateNativeDebugFile((fname+".debug").c_str()); // When this assertion fails you must redefine Star3
} else { // for your compiler.
dbStr += " - initialization failed"; // Because your compiler does not pack the data,
qWarning(qPrintable(dbStr)); // which is crucial for this application.
if (rval) { Q_ASSERT(sizeof(Star3) == 6);
delete rval; rval = new SpecialZoneArray<Star3>(file, byte_swap,
rval = 0; use_mmap,
} lb, level, mag_mi
} n,
fclose(f); mag_range, mag_st
return rval; eps);
} if (rval == 0)
{
ZoneArray::ZoneArray(const StarMgr &hip_star_mgr,int level, dbStr += "error - no memory ";
int mag_min,int mag_range,int mag_steps) }
:level(level), }
mag_min(mag_min),mag_range(mag_range),mag_steps(mag_steps), break;
star_position_scale(0.0), //IntToDouble(scale_int)/Star::MaxPosV default:
al dbStr += "error - bad file type ";
hip_star_mgr(hip_star_mgr), break;
zones(0) { }
nr_of_zones = GeodesicGrid::nrOfZones(level); if (rval && rval->isInitialized())
nr_of_stars = 0; {
} dbStr += QString("%1").arg(rval->getNrOfStars());
qDebug() << qPrintable(dbStr);
bool ZoneArray::readFileWithLoadingBar(FILE *f,void *data,size_t size, }
LoadingBar &lb) { else
int parts = 256; {
size_t part_size = (size + (parts>>1)) / parts; dbStr += " - initialization failed";
if (part_size < 64*1024) { qDebug() << dbStr;
part_size = 64*1024; if (rval)
parts = (size + (part_size>>1)) / part_size; {
} delete rval;
float i = 0.f; rval = 0;
lb.Draw(i / parts); }
i += 1.f; }
while (size > 0) { return rval;
const size_t to_read = (part_size < size) ? part_size : size; }
const size_t read_rc = fread(data,1,to_read,f);
if (read_rc != to_read) return false; ZoneArray::ZoneArray(const QString& fname, QFile* file, int level, int mag_
size -= read_rc; min,
data = ((char*)data) + read_rc; int mag_range, int mag_steps)
lb.Draw(i / parts); : fname(fname), level(level), mag_min(mag_min),
i += 1.f; mag_range(mag_range), mag_steps(mag_steps),
} star_position_scale(0.0), zones(0), file(file)
return true; {
} nr_of_zones = StelGeodesicGrid::nrOfZones(level);
nr_of_stars = 0;
void ZoneArray1::updateHipIndex(HipIndexStruct hipIndex[]) const { }
for (const SpecialZoneData<Star1> *z=getZones()+(nr_of_zones-1);
z>=getZones();z--) { bool ZoneArray::readFileWithStelLoadingBar(QFile& file, void *data, qint64
for (const Star1 *s = z->getStars()+z->size-1;s>=z->getStars();s--) { size,
const int hip = s->hip; StelLoadingBar &lb)
if (hip < 0 || NR_OF_HIP < hip) { {
qDebug() << "ERROR: ZoneArray1::updateHipIndex: invalid HP number:" int parts = 256;
<< hip; int part_size = (size + (parts>>1)) / parts;
exit(1); if (part_size < 64*1024)
} {
if (hip != 0) { part_size = 64*1024;
hipIndex[hip].a = this; parts = (size + (part_size>>1)) / part_size;
hipIndex[hip].z = z; }
hipIndex[hip].s = s; float i = 0.f;
} lb.Draw(i / parts);
} i += 1.f;
} while (size > 0)
{
const int to_read = (part_size < size) ? part_size : size;
const int read_rc = file.read((char*)data, to_read);
if (read_rc != to_read) return false;
size -= read_rc;
data = ((char*)data) + read_rc;
lb.Draw(i / parts);
i += 1.f;
}
return true;
}
void HipZoneArray::updateHipIndex(HipIndexStruct hipIndex[]) const
{
for (const SpecialZoneData<Star1> *z=getZones()+(nr_of_zones-1);
z>=getZones();z--)
{
for (const Star1 *s = z->getStars()+z->size-1;s>=z->getStars
();s--)
{
const int hip = s->hip;
if (hip < 0 || NR_OF_HIP < hip)
{
qDebug() << "ERROR: HipZoneArray::updateHipI
ndex: invalid HP number:"
<< hip;
exit(1);
}
if (hip != 0)
{
hipIndex[hip].a = this;
hipIndex[hip].z = z;
hipIndex[hip].s = s;
}
}
}
}
template<class Star>
void SpecialZoneArray<Star>::scaleAxis(void)
{
star_position_scale /= Star::MaxPosVal;
for (ZoneData *z=zones+(nr_of_zones-1);z>=zones;z--)
{
z->axis0 *= star_position_scale;
z->axis1 *= star_position_scale;
}
}
template<class Star>
SpecialZoneArray<Star>::SpecialZoneArray(QFile* file, bool byte_swap,bool u
se_mmap,
StelLoadingBar &lb, int level, int
mag_min,
int mag_range, int mag_steps)
: ZoneArray(file->fileName(), file, level, mag_min, mag_rang
e, mag_steps),
stars(0), mmap_start(0)
{
if (nr_of_zones > 0)
{
lb.Draw(0.f);
zones = new SpecialZoneData<Star>[nr_of_zones];
if (zones == 0)
{
qDebug() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: no memory (1)";
exit(1);
}
unsigned int *zone_size = new unsigned int[nr_of_zones];
if (zone_size == 0)
{
qDebug() << "ERROR: SpecialZoneArray(" << level
<< ")::SpecialZoneArray: no memory (2)";
exit(1);
}
if ((qint64)(sizeof(unsigned int)*nr_of_zones) != file->read
((char*)zone_size, sizeof(unsigned int)*nr_of_zones))
{
qDebug() << "Error reading zones from catalog:"
<< file->fileName();
delete[] getZones();
zones = 0;
nr_of_zones = 0;
}
else
{
const unsigned int *tmp = zone_size;
for (unsigned int z=0;z<nr_of_zones;z++,tmp++)
{
const unsigned int tmp_spu_int32 = byte_swap
?bswap_32(*tmp):*tmp;
nr_of_stars += tmp_spu_int32;
getZones()[z].size = tmp_spu_int32;
}
}
// delete zone_size before allocating stars
// in order to avoid memory fragmentation:
delete[] zone_size;
if (nr_of_stars == 0)
{
// no stars ?
if (zones) delete[] getZones();
zones = 0;
nr_of_zones = 0;
}
else
{
if (use_mmap)
{
mmap_start = file->map(file->pos(), sizeof(S
tar)*nr_of_stars);
if (mmap_start == 0)
{
qDebug() << "ERROR: SpecialZoneArray
(" << level
<< ")::SpecialZoneArray: QF
ile(" << file->fileName()
<< ".map(" << file->pos()
<< ',' << sizeof(Star)*nr_o
f_stars
<< ") failed: " << file->er
rorString();
stars = 0;
nr_of_stars = 0;
delete[] getZones();
zones = 0;
nr_of_zones = 0;
}
else
{
stars = (Star*)mmap_start;
Star *s = stars;
for (unsigned int z=0;z<nr_of_zones;
z++)
{
getZones()[z].stars = s;
s += getZones()[z].size;
}
}
file->close();
}
else
{
stars = new Star[nr_of_stars];
if (stars == 0)
{
qDebug() << "ERROR: SpecialZoneArray
(" << level
<< ")::SpecialZoneArray: no
memory (3)";
exit(1);
}
if (!readFileWithStelLoadingBar(*file,stars,
sizeof(Star)*nr_of_stars,lb))
{
delete[] stars;
stars = 0;
nr_of_stars = 0;
delete[] getZones();
zones = 0;
nr_of_zones = 0;
}
else
{
Star *s = stars;
for (unsigned int z=0;z<nr_of_zones;
z++)
{
getZones()[z].stars = s;
s += getZones()[z].size;
}
if (
#if (!defined(__GNUC__))
true
#else
byte_swap
#endif
)
{
s = stars;
for (unsigned int i=0;i<nr_o
f_stars;i++,s++)
{
s->repack(
#ifdef WORDS_BIGENDIAN
// need for byte
_swap on a BE machine means that catalog is LE
!byte_swap
#else
// need for byte
_swap on a LE machine means that catalog is BE
byte_swap
#endif
);
}
}
}
file->close();
}
}
lb.Draw(1.f);
}
}
template<class Star>
SpecialZoneArray<Star>::~SpecialZoneArray(void)
{
if (stars)
{
if (mmap_start != 0)
{
file->unmap(mmap_start);
}
else
{
delete[] stars;
}
delete file;
stars = 0;
}
if (zones)
{
delete[] getZones();
zones = NULL;
}
nr_of_zones = 0;
nr_of_stars = 0;
}
template<class Star>
void SpecialZoneArray<Star>::draw(int index, bool is_inside, const float *r
cmag_table,
const StelProjectorP& prj, unsigned int ma
xMagStarName,
float names_brightness, StelFont *starFont
) const
{
StelSkyDrawer* drawer = StelApp::getInstance().getCore()->getSkyDraw
er();
SpecialZoneData<Star> *const z = getZones() + index;
Vec3d xy;
const Star *const end = z->getStars() + z->size;
const double d2000 = 2451545.0;
const double movementFactor = (M_PI/180)*(0.0001/3600) * ((StarMgr::
getCurrentJDay()-d2000)/365.25) / star_position_scale;
for (const Star *s=z->getStars();s<end;++s)
{
if (is_inside ? prj->project(s->getJ2000Pos(z,movementFactor
),xy) : prj->projectCheck(s->getJ2000Pos(z,movementFactor),xy))
{
if (drawer->drawPointSource(xy[0],xy[1],rcmag_table
+ 2*(s->mag),s->bV)==false)
{
break;
}
if (s->mag < maxMagStarName)
{
const QString& starname = s->getNameI18n();
if (!starname.isEmpty())
{
const float offset = (rcmag_table +
2*(s->mag))[0]*0.7;
const Vec3f& colorr = (StelApp::getI
nstance().getVisionModeNight() ? Vec3f(0.8, 0.2, 0.2) : StelSkyDrawer::inde
xToColor(s->bV))*0.75;
glColor4f(colorr[0], colorr[1], colo
rr[2],names_brightness);
drawer->getPainter()->drawText(starF
ont,xy[0],xy[1], starname, 0, offset, offset, false);
}
}
}
}
}
template<class Star>
void SpecialZoneArray<Star>::searchAround(int index, const Vec3d &v, double
cosLimFov,
QList<StelObjectP > &result)
{
const double d2000 = 2451545.0;
const double movementFactor = (M_PI/180)*(0.0001/3600)
* ((StarMgr::getCurrentJDay()-d2000)/3
65.25)
/ star_position_scale;
const SpecialZoneData<Star> *const z = getZones()+index;
Vec3d tmp;
for (int i=0;i<z->size;i++)
{
tmp = z->getStars()[i].getJ2000Pos(z,movementFactor);
tmp.normalize();
if (tmp*v >= cosLimFov)
{
// TODO: do not select stars that are too faint to d
isplay
result.push_back(z->getStars()[i].createStelObject(t
his,z));
}
}
} }
} // namespace BigStarCatalogExtension } // namespace BigStarCatalogExtension
 End of changes. 12 change blocks. 
245 lines changed or deleted 556 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/