StelObjectP ConstellationMgr::setSelectedStar(const QString& abbreviation) { Constellation * c = findFromAbbreviation(abbreviation); if(c != NULL) { setSelectedConst(c); return c->getBrightestStarInConstellation(); } return NULL; }
/** * Calculates birate of the stream. * * @param bandwidth Bandwidth * @param codeRate Code rate * @param constellation Constellation * @param guardinterval Guard interval * @return Bitrate of the stream */ BitratePerPID PacketStream::calculateBitRate(const Bandwidth &bandwidth, const CodeRate &codeRate, const Constellation &constellation, const GuardInterval &guardinterval) { double maxBitRate = (423.0 / 544) * bandwidth.toValue() * codeRate.toValue(); maxBitRate *= constellation.toValue() * guardinterval.toValue(); BitratePerPID bitRatePerPID; bitRatePerPID.PID = PID; bitRatePerPID.bitrate = maxBitRate * ((double)_packetsInStream / _processedPackets) / 1000000; return bitRatePerPID; }
// Draw constellations art textures void ConstellationMgr::drawArt(StelRenderer* renderer, StelProjectorP projector) const { renderer->setBlendMode(BlendMode_Add); vector < Constellation * >::const_iterator iter; SphericalRegionP region = projector->getViewportConvexPolygon(); for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { Constellation* cons = *iter; if(NULL == cons->artTexture && !cons->artTexturePath.isEmpty()) { cons->artTexture = renderer->createTexture(cons->artTexturePath); } if(NULL == cons->artVertices) { // Tesselate on the plane assuming a tangential projection for the image const int resolution = 5; cons->generateArtVertices(renderer, resolution); } cons->drawArtOptim(renderer, projector, *region); } }
void ConstellationMgr::loadLinesAndArt(const QString &fileName, const QString &artfileName, const QString& cultureName) { QFile in(fileName); if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Can't open constellation data file" << fileName << "for culture" << cultureName; Q_ASSERT(0); } int totalRecords=0; QString record; QRegExp commentRx("^(\\s*#.*|\\s*)$"); while (!in.atEnd()) { record = QString::fromUtf8(in.readLine()); if (!commentRx.exactMatch(record)) totalRecords++; } in.seek(0); // delete existing data, if any vector < Constellation * >::iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) delete(*iter); asterisms.clear(); Constellation *cons = NULL; // read the file, adding a record per non-comment line int currentLineNumber = 0; // line in file int readOk = 0; // count of records processed OK while (!in.atEnd()) { record = QString::fromUtf8(in.readLine()); currentLineNumber++; if (commentRx.exactMatch(record)) continue; cons = new Constellation; if(cons->read(record, hipStarMgr)) { cons->artFader.setMaxValue(artIntensity); cons->setFlagArt(artDisplayed); cons->setFlagBoundaries(boundariesDisplayed); cons->setFlagLines(linesDisplayed); cons->setFlagLabels(namesDisplayed); asterisms.push_back(cons); ++readOk; } else { qWarning() << "ERROR reading constellation rec at line " << currentLineNumber << "for culture" << cultureName; delete cons; } } in.close(); qDebug() << "Loaded" << readOk << "/" << totalRecords << "constellation records successfully for culture" << cultureName; // Set current states setFlagArt(artDisplayed); setFlagLines(linesDisplayed); setFlagLabels(namesDisplayed); setFlagBoundaries(boundariesDisplayed); // It's possible to have no art - just constellations if (artfileName.isNull() || artfileName.isEmpty()) return; QFile fic(artfileName); if (!fic.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Can't open constellation art file" << fileName << "for culture" << cultureName; return; } totalRecords=0; while (!fic.atEnd()) { record = QString::fromUtf8(fic.readLine()); if (!commentRx.exactMatch(record)) totalRecords++; } fic.seek(0); // Read the constellation art file with the following format : // ShortName texture_file x1 y1 hp1 x2 y2 hp2 // Where : // shortname is the international short name (i.e "Lep" for Lepus) // texture_file is the graphic file of the art texture // x1 y1 are the x and y texture coordinates in pixels of the star of hipparcos number hp1 // x2 y2 are the x and y texture coordinates in pixels of the star of hipparcos number hp2 // The coordinate are taken with (0,0) at the top left corner of the image file QString shortname; QString texfile; unsigned int x1, y1, x2, y2, x3, y3, hp1, hp2, hp3; QString tmpstr; currentLineNumber = 0; // line in file readOk = 0; // count of records processed OK while (!fic.atEnd()) { ++currentLineNumber; record = QString::fromUtf8(fic.readLine()); if (commentRx.exactMatch(record)) continue; // prevent leaving zeros on numbers from being interpretted as octal numbers record.replace(" 0", " "); QTextStream rStr(&record); rStr >> shortname >> texfile >> x1 >> y1 >> hp1 >> x2 >> y2 >> hp2 >> x3 >> y3 >> hp3; if (rStr.status()!=QTextStream::Ok) { qWarning() << "ERROR parsing constellation art record at line" << currentLineNumber << "of art file for culture" << cultureName; continue; } // Draw loading bar // lb.SetMessage(q_("Loading Constellation Art: %1/%2").arg(currentLineNumber).arg(totalRecords)); // lb.Draw((float)(currentLineNumber)/totalRecords); cons = NULL; cons = findFromAbbreviation(shortname); if (!cons) { qWarning() << "ERROR in constellation art file at line" << currentLineNumber << "for culture" << cultureName << "constellation" << shortname << "unknown"; } else { QString texturePath(texfile); try { texturePath = StelFileMgr::findFile("skycultures/"+cultureName+"/"+texfile); } catch (std::runtime_error& e) { // if the texture isn't found in the skycultures/[culture] directory, // try the central textures diectory. qWarning() << "WARNING, could not locate texture file " << texfile << " in the skycultures/" << cultureName << " directory... looking in general textures/ directory..."; try { texturePath = StelFileMgr::findFile(QString("textures/")+texfile); } catch(exception& e2) { qWarning() << "ERROR: could not find texture, " << texfile << ": " << e2.what(); } } cons->artTexture = StelApp::getInstance().getTextureManager().createTextureThread(texturePath); int texSizeX, texSizeY; if (cons->artTexture==NULL || !cons->artTexture->getDimensions(texSizeX, texSizeY)) { qWarning() << "Texture dimension not available"; } StelCore* core = StelApp::getInstance().getCore(); Vec3d s1 = hipStarMgr->searchHP(hp1)->getJ2000EquatorialPos(core); Vec3d s2 = hipStarMgr->searchHP(hp2)->getJ2000EquatorialPos(core); Vec3d s3 = hipStarMgr->searchHP(hp3)->getJ2000EquatorialPos(core); // To transform from texture coordinate to 2d coordinate we need to find X with XA = B // A formed of 4 points in texture coordinate, B formed with 4 points in 3d coordinate // We need 3 stars and the 4th point is deduced from the other to get an normal base // X = B inv(A) Vec3d s4 = s1 + ((s2 - s1) ^ (s3 - s1)); Mat4d 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); Mat4d A(x1, texSizeY - y1, 0.f, 1.f, x2, texSizeY - y2, 0.f, 1.f, x3, texSizeY - y3, 0.f, 1.f, x1, texSizeY - y1, texSizeX, 1.f); Mat4d X = B * A.inverse(); // Tesselate on the plan assuming a tangential projection for the image static const int nbPoints=5; QVector<Vec2f> texCoords; texCoords.reserve(nbPoints*nbPoints*6); for (int j=0;j<nbPoints;++j) { for (int i=0;i<nbPoints;++i) { texCoords << Vec2f(((float)i)/nbPoints, ((float)j)/nbPoints); texCoords << Vec2f(((float)i+1.f)/nbPoints, ((float)j)/nbPoints); texCoords << Vec2f(((float)i)/nbPoints, ((float)j+1.f)/nbPoints); texCoords << Vec2f(((float)i+1.f)/nbPoints, ((float)j)/nbPoints); texCoords << Vec2f(((float)i+1.f)/nbPoints, ((float)j+1.f)/nbPoints); texCoords << Vec2f(((float)i)/nbPoints, ((float)j+1.f)/nbPoints); } } QVector<Vec3d> contour; contour.reserve(texCoords.size()); foreach (const Vec2f& v, texCoords) contour << X * Vec3d(v[0]*texSizeX, v[1]*texSizeY, 0.); cons->artPolygon.vertex=contour; cons->artPolygon.texCoords=texCoords; cons->artPolygon.primitiveType=StelVertexArray::Triangles; Vec3d tmp(X * Vec3d(0.5*texSizeX, 0.5*texSizeY, 0.)); tmp.normalize(); Vec3d tmp2(X * Vec3d(0., 0., 0.)); tmp2.normalize(); cons->boundingCap.n=tmp; cons->boundingCap.d=tmp*tmp2; ++readOk; } } qDebug() << "Loaded" << readOk << "/" << totalRecords << "constellation art records successfully for culture" << cultureName; fic.close(); }
// Load line and art data from files int ConstellationMgr::loadLinesAndArt(const string &skyCultureDir) { string fileName = skyCultureDir + "/constellationship.fab"; string artfileName = skyCultureDir + "/constellationsart.fab"; string boundaryfileName = skyCultureDir + "/boundaries.dat"; std::ifstream inf(fileName.c_str()); if (!inf.is_open()) { Log.write("Constellation_Mgr::loadLinesAndArt can't open constellation data file "+ fileName, cLog::eLOG_TYPE_ERROR); return -1; } // delete existing data, if any //~ if( SharedData::Instance()->DB() ) { //~ dbCursor<ObjectRecord> cursor(dbCursorForUpdate); //~ dbQuery q; //~ q = "type=",ObjectRecord::OBJECT_CONSTELLATION; //~ if( cursor.select(q) ) //~ cursor.removeAllSelected(); //~ SharedData::Instance()->DB()->commit(); //~ } vector < Constellation * >::iterator iter; for (iter = asterisms.begin(); iter != asterisms.end(); ++iter) { delete(*iter); } asterisms.clear(); selected.clear(); Constellation *cons = NULL; string record; int line=0; while (!inf.eof() && std::getline(inf, record)) { line++; if (record.size()!=0 && record[0]=='#') continue; cons = new Constellation; if (cons->read(record, hipStarMgr)) { asterisms.push_back(cons); } else { //cerr << "ERROR on line " << line << " of " << fileName.c_str() << endl; Log.write("ConstellationMgr::loadLinesAndArt on line " + Utility::intToString(line) + " of " + fileName, cLog::eLOG_TYPE_ERROR); delete cons; } } inf.close(); // Set current states setFlagArt(flagArt); setFlagLines(flagLines); setFlagNames(flagNames); setFlagBoundaries(flagBoundaries); FILE *fic = fopen(artfileName.c_str(), "r"); if (!fic) { // cerr << "Can't open " << artfileName.c_str() << endl; Log.write("ConstellationMgr::loadLinesAndArt Can't open " + artfileName, cLog::eLOG_TYPE_ERROR); return 0; // no art, but still loaded constellation data } fclose(fic); // Read the constellation art file with the following format : // ShortName texture_file x1 y1 hp1 x2 y2 hp2 // Where : // shortname is the international short name (i.e "Lep" for Lepus) // texture_file is the graphic file of the art texture // x1 y1 are the x and y texture coordinates in pixels of the star of hipparcos number hp1 // x2 y2 are the x and y texture coordinates in pixels of the star of hipparcos number hp2 // The coordinate are taken with (0,0) at the top left corner of the image file string shortname; string texfile; unsigned int x1, y1, x2, y2, x3, y3, hp1, hp2, hp3; float fx1, fy1, fx2, fy2, fx3, fy3; // read floats to allow proportional image points to allow image sizes to vary as needed int texW, texH; // art texture dimensions // Read in constellation art information // Note: Stellarium 0.10.3 allows more than 3 alignment points, here only first 3 are used. ifstream artFile(artfileName.c_str()); if (!artFile.is_open()) { //cerr << "Can't open file" << artFile << endl; Log.write("ConstellationMgr::loadLinesAndArt Can't open " + artfileName, cLog::eLOG_TYPE_ERROR); return 0; } while (!artFile.eof() && std::getline(artFile, record)) { if ( record != "") { stringstream in(record); in >> shortname >> texfile; if(in.fail()) { //cerr << "Error parsing constellation art record:\n" << record << endl; Log.write("ConstellationMgr::loadLinesAndArt Error parsing constellation art record " + record, cLog::eLOG_TYPE_ERROR); continue; } // TODO add better error checking if(shortname!="" && shortname[0]!='#') { in >> fx1 >> fy1 >> hp1; in >> fx2 >> fy2 >> hp2; in >> fx3 >> fy3 >> hp3; } else { continue;