Landscape.cpp   Landscape.cpp 
skipping to change at line 267 skipping to change at line 267
} }
void LandscapeOldStyle::load(const QSettings& landscapeIni, const QString& landscapeId) void LandscapeOldStyle::load(const QSettings& landscapeIni, const QString& landscapeId)
{ {
// TODO: put values into hash and call create() method to consolidat e code // TODO: put values into hash and call create() method to consolidat e code
loadCommon(landscapeIni, landscapeId); loadCommon(landscapeIni, landscapeId);
// rows, cols have been loaded already, but with different defaults. // rows, cols have been loaded already, but with different defaults.
// GZ Hey, they are not used altogether! Resolution is constant, bel ow! // GZ Hey, they are not used altogether! Resolution is constant, bel ow!
//rows = landscapeIni.value("landscape/tesselate_rows", 8).toInt(); //rows = landscapeIni.value("landscape/tesselate_rows", 8).toInt();
//cols = landscapeIni.value("landscape/tesselate_cols", 16).toInt(); //cols = landscapeIni.value("landscape/tesselate_cols", 16).toInt();
QString type = landscapeIni.value("landscape/type").toString(); QString type = landscapeIni.value("landscape/type").toString();
if(type != "old_style") if(type != "old_style")
{ {
qWarning() << "Landscape type mismatch for landscape " << la ndscapeId qWarning() << "Landscape type mismatch for landscape " << la ndscapeId
<< ", expected old_style, found " << type << ". No landscape in use."; << ", expected old_style, found " << type << ". No landscape in use.";
validLandscape = 0; validLandscape = 0;
return; return;
} }
nbDecorRepeat = landscapeIni.value("landscape/nb_decor_repeat",
1).toInt();
fogAltAngle = landscapeIni.value("landscape/fog_alt_angle", 0
.).toFloat();
fogAngleShift = landscapeIni.value("landscape/fog_angle_shift",
0.).toFloat();
decorAltAngle = landscapeIni.value("landscape/decor_alt_angle",
0.).toFloat();
decorAngleShift = landscapeIni.value("landscape/decor_angle_shift
", 0.).toFloat();
angleRotateZ = landscapeIni.value("landscape/decor_angle_rotat
ez", 0.).toFloat() * M_PI/180.f;
groundAngleShift = landscapeIni.value("landscape/ground_angle_shif
t", 0.).toFloat() * M_PI/180.f;
groundAngleRotateZ = landscapeIni.value("landscape/ground_angle_rota
tez", 0.).toFloat() * M_PI/180.f;
drawGroundFirst = landscapeIni.value("landscape/draw_ground_first
", 0).toInt();
tanMode = landscapeIni.value("landscape/tan_mode", false)
.toBool();
calibrated = landscapeIni.value("landscape/calibrated", fals
e).toBool();
// Load sides textures // Load sides textures
nbSideTexs = landscapeIni.value("landscape/nbsidetex", 0).toInt(); nbSideTexs = landscapeIni.value("landscape/nbsidetex", 0).toInt();
sideTexs = new StelTextureSP[2*nbSideTexs]; // 0.14: allow upper hal f for light textures! sideTexs = new StelTextureSP[2*nbSideTexs]; // 0.14: allow upper hal f for light textures!
for (int i=0; i<nbSideTexs; ++i) for (int i=0; i<nbSideTexs; ++i)
{ {
QString textureKey = QString("landscape/tex%1").arg(i); QString textureKey = QString("landscape/tex%1").arg(i);
QString textureName = landscapeIni.value(textureKey).toStrin g(); QString textureName = landscapeIni.value(textureKey).toStrin g();
const QString texturePath = getTexturePath(textureName, land scapeId); const QString texturePath = getTexturePath(textureName, land scapeId);
sideTexs[i] = StelApp::getInstance().getTextureManager().cre ateTexture(texturePath); sideTexs[i] = StelApp::getInstance().getTextureManager().cre ateTexture(texturePath);
// GZ: To query the textures, also fill an array of QImage*, but only // GZ: To query the textures, also keep an array of QImage*, but only
// if that query is not going to be prevented by the polygon that already has been loaded at that point... // if that query is not going to be prevented by the polygon that already has been loaded at that point...
if ( (!horizonPolygon) && calibrated ) { // for uncalibrated landscapes the texture is currently never queried, so no need to store. if ( (!horizonPolygon) && calibrated ) { // for uncalibrated landscapes the texture is currently never queried, so no need to store.
QImage *image = new QImage(texturePath); QImage *image = new QImage(texturePath);
sidesImages.append(image); // indices identical to t hose in sideTexs sidesImages.append(image); // indices identical to t hose in sideTexs
} }
// Also allow light textures. The light textures must cover the same geometry as the sides. It is allowed that not all or even any ligh t textures are present! // Also allow light textures. The light textures must cover the same geometry as the sides. It is allowed that not all or even any ligh t textures are present!
textureKey = QString("landscape/light%1").arg(i); textureKey = QString("landscape/light%1").arg(i);
textureName = landscapeIni.value(textureKey).toString(); textureName = landscapeIni.value(textureKey).toString();
if (textureName.length()) if (textureName.length())
{ {
skipping to change at line 364 skipping to change at line 375
// GZ 2013/11: I don't see any use of this: // GZ 2013/11: I don't see any use of this:
// QString description = landscapeIni.value("landscape/fog").toString() ; // QString description = landscapeIni.value("landscape/fog").toString() ;
// //sscanf(description.toLocal8Bit(),"fogtex:%f:%f:%f:%f",&a,&b,&c,&d) ; // //sscanf(description.toLocal8Bit(),"fogtex:%f:%f:%f:%f",&a,&b,&c,&d) ;
// QStringList parameters = description.split(':'); // QStringList parameters = description.split(':');
// fogTexCoord.tex = fogTex; // fogTexCoord.tex = fogTex;
// fogTexCoord.texCoords[0] = parameters.at(1).toFloat(); // fogTexCoord.texCoords[0] = parameters.at(1).toFloat();
// fogTexCoord.texCoords[1] = parameters.at(2).toFloat(); // fogTexCoord.texCoords[1] = parameters.at(2).toFloat();
// fogTexCoord.texCoords[2] = parameters.at(3).toFloat(); // fogTexCoord.texCoords[2] = parameters.at(3).toFloat();
// fogTexCoord.texCoords[3] = parameters.at(4).toFloat(); // fogTexCoord.texCoords[3] = parameters.at(4).toFloat();
nbDecorRepeat = landscapeIni.value("landscape/nb_decor_repeat",
1).toInt();
fogAltAngle = landscapeIni.value("landscape/fog_alt_angle", 0
.).toFloat();
fogAngleShift = landscapeIni.value("landscape/fog_angle_shift",
0.).toFloat();
decorAltAngle = landscapeIni.value("landscape/decor_alt_angle",
0.).toFloat();
decorAngleShift = landscapeIni.value("landscape/decor_angle_shift
", 0.).toFloat();
angleRotateZ = landscapeIni.value("landscape/decor_angle_rotat
ez", 0.).toFloat() * M_PI/180.f;
groundAngleShift = landscapeIni.value("landscape/ground_angle_shif
t", 0.).toFloat() * M_PI/180.f;
groundAngleRotateZ = landscapeIni.value("landscape/ground_angle_rota
tez", 0.).toFloat() * M_PI/180.f;
drawGroundFirst = landscapeIni.value("landscape/draw_ground_first
", 0).toInt();
tanMode = landscapeIni.value("landscape/tan_mode", false)
.toBool();
calibrated = landscapeIni.value("landscape/calibrated", fals
e).toBool();
// Precompute the vertex arrays for ground display // Precompute the vertex arrays for ground display
// Make slices_per_side=(3<<K) so that the innermost polygon of the fandisk becomes a triangle: // Make slices_per_side=(3<<K) so that the innermost polygon of the fandisk becomes a triangle:
//const int slices_per_side = 3*64/(nbDecorRepeat*nbSide); //const int slices_per_side = 3*64/(nbDecorRepeat*nbSide);
//if (slices_per_side<=0) // GZ: How can negative ever happen? //if (slices_per_side<=0) // GZ: How can negative ever happen?
// slices_per_side = 1; // slices_per_side = 1;
const int slices_per_side = qMax(3*64/(nbDecorRepeat*nbSide), 1); const int slices_per_side = qMax(3*64/(nbDecorRepeat*nbSide), 1);
// draw a fan disk instead of a ordinary disk to that the inner slic es // draw a fan disk instead of a ordinary disk to that the inner slic es
// are not so slender. When they are too slender, culling errors occ ur // are not so slender. When they are too slender, culling errors occ ur
// in cylinder projection mode. // in cylinder projection mode.
skipping to change at line 398 skipping to change at line 397
while ((slices_inside&1)==0 && slices_inside > 4) while ((slices_inside&1)==0 && slices_inside > 4)
{ {
++level; ++level;
slices_inside>>=1; slices_inside>>=1;
} }
StelPainter::computeFanDisk(radius, slices_inside, level, groundVert exArr, groundTexCoordArr); StelPainter::computeFanDisk(radius, slices_inside, level, groundVert exArr, groundTexCoordArr);
// Precompute the vertex arrays for side display. The geometry of th e sides is always a cylinder. // Precompute the vertex arrays for side display. The geometry of th e sides is always a cylinder.
// The texture is split into regular quads. // The texture is split into regular quads.
// GZ: the old code for vertical placement makes unfortunately no se // GZ: the original code for vertical placement makes unfortunately
nse. There are many approximately-fitted landscapes, though. no sense. There are many approximately-fitted landscapes, though.
// I added a switch "calibrated" for the ini file. If true, it works // I added a switch "calibrated" for the ini file. If true, it works
as this landscape apparently was originally intended. as this landscape apparently was originally intended,
// if false (or missing) it uses the original code.
// So I corrected the texture coordinates so that decorAltAngle is t he total vertical angle, decorAngleShift the lower angle, // So I corrected the texture coordinates so that decorAltAngle is t he total vertical angle, decorAngleShift the lower angle,
// and the texture in between is correctly stretched. // and the texture in between is correctly stretched.
// I located an undocumented switch tan_mode, maybe tan_mode=true me ans cylindrical panorama projection. // I located an undocumented switch tan_mode, maybe tan_mode=true me ans cylindrical panorama projection.
// Since V0.13, calibrated&&tanMode also works! // Since V0.13, calibrated&&tanMode also works!
// In calibrated && !tan_mode, the vertical position is computed cor rectly, so that quads off the horizon are larger. // In calibrated && !tan_mode, the vertical position is computed cor rectly, so that quads off the horizon are larger.
// in calibrated && tan_mode, d_z can become a constant because the texture is already predistorted in cylindrical projection. // in calibrated && tan_mode, d_z can become a constant because the texture is already predistorted in cylindrical projection.
static const int stacks = (calibrated ? 16 : 8); // GZ: 8->16, I nee d better precision. static const int stacks = (calibrated ? 16 : 8); // GZ: 8->16, I nee d better precision.
float z0, d_z; float z0, d_z;
if (calibrated) if (calibrated)
{ {
skipping to change at line 606 skipping to change at line 606
{ {
if (!landFader.getInterstate()) if (!landFader.getInterstate())
return; return;
const float vshift = radius * ((tanMode || calibrated) ? std::tan(gr oundAngleShift) : std::sin(groundAngleShift)); const float vshift = radius * ((tanMode || calibrated) ? std::tan(gr oundAngleShift) : std::sin(groundAngleShift));
StelProjector::ModelViewTranformP transfo = core->getAltAzModelViewT ransform(StelCore::RefractionOff); StelProjector::ModelViewTranformP transfo = core->getAltAzModelViewT ransform(StelCore::RefractionOff);
transfo->combine(Mat4d::zrotation(groundAngleRotateZ-angleRotateZOff set) * Mat4d::translation(Vec3d(0,0,vshift))); transfo->combine(Mat4d::zrotation(groundAngleRotateZ-angleRotateZOff set) * Mat4d::translation(Vec3d(0,0,vshift)));
sPainter.setProjector(core->getProjection(transfo)); sPainter.setProjector(core->getProjection(transfo));
sPainter.setColor(landscapeBrightness, landscapeBrightness, landscap eBrightness, landFader.getInterstate()); sPainter.setColor(landscapeBrightness, landscapeBrightness, landscap eBrightness, landFader.getInterstate());
groundTex->bind(); if(groundTex.isNull())
{
qWarning()<<"LandscapeOldStyle groundTex is invalid!";
}
else
{
groundTex->bind();
}
sPainter.setArrays((Vec3d*)groundVertexArr.constData(), (Vec2f*)grou ndTexCoordArr.constData()); sPainter.setArrays((Vec3d*)groundVertexArr.constData(), (Vec2f*)grou ndTexCoordArr.constData());
sPainter.drawFromArray(StelPainter::Triangles, groundVertexArr.size( )/3); sPainter.drawFromArray(StelPainter::Triangles, groundVertexArr.size( )/3);
} }
float LandscapeOldStyle::getOpacity(Vec3d azalt) const float LandscapeOldStyle::getOpacity(Vec3d azalt) const
{ {
if (angleRotateZOffset!=0.0f) if (angleRotateZOffset!=0.0f)
azalt.transfo4d(Mat4d::zrotation(angleRotateZOffset)); azalt.transfo4d(Mat4d::zrotation(angleRotateZOffset));
// in case we also have a horizon polygon defined, this is trivial a nd fast. // in case we also have a horizon polygon defined, this is trivial a nd fast.
if (horizonPolygon) if (horizonPolygon)
{ {
if (horizonPolygon->contains(azalt) ) return 1.0f; else return 0.0f; if (horizonPolygon->contains(azalt) ) return 1.0f; else return 0.0f;
} }
// Else, sample the images... // Else, sample the images...
const float alt_rad = std::asin(azalt[2]); // sampled altitude, rad ians const float alt_rad = std::asin(azalt[2]); // sampled altitude, rad ians
if (alt_rad < decorAngleShift*M_PI/180.0f) return 1.0f; // below dec or, i.e. certainly opaque ground. if (alt_rad < decorAngleShift*M_PI/180.0f) return 1.0f; // below dec or, i.e. certainly opaque ground.
if (alt_rad > (decorAltAngle+decorAngleShift)*M_PI/180.0f) return 0. 0f; // above decor, i.e. certainly free sky. if (alt_rad > (decorAltAngle+decorAngleShift)*M_PI/180.0f) return 0. 0f; // above decor, i.e. certainly free sky.
if (!calibrated) // the result of this function has no real use here : just complain and return result for math. horizon. if (!calibrated) // the result of this function has no real use here : just complain and return result for math. horizon.
{ {
qDebug() << "Dubious result: Landscape \"" << name << "\" no static QString lastLandscapeName;
t calibrated. Result for mathematical horizon only."; if (lastLandscapeName != name)
{
qWarning() << "Dubious result: Landscape \"" << name
<< "\" not calibrated. Opacity test represents mathematical horizon only."
;
lastLandscapeName=name;
}
return (azalt[2] > 0 ? 0.0f : 1.0f); return (azalt[2] > 0 ? 0.0f : 1.0f);
} }
float az=atan2(azalt[0], azalt[1]) / M_PI + 0.5f; // -0.5..+1.5 float az=atan2(azalt[0], azalt[1]) / M_PI + 0.5f; // -0.5..+1.5
if (az<0) az+=2.0f; // 0..2 = N.E.S. W.N if (az<0) az+=2.0f; // 0..2 = N.E.S. W.N
// we go to 0..1 domain, it's easier to think. // we go to 0..1 domain, it's easier to think.
const float xShift=angleRotateZ /(2.0f*M_PI); // shift value in -1.. 1 const float xShift=angleRotateZ /(2.0f*M_PI); // shift value in -1.. 1
Q_ASSERT(xShift >= -1.0f);
Q_ASSERT(xShift <= 1.0f);
float az_phot=az*0.5f - 0.25f - xShift; // The 0.25 is caused b y regular pano left edge being East. The xShift compensates any configured angleRotateZ float az_phot=az*0.5f - 0.25f - xShift; // The 0.25 is caused b y regular pano left edge being East. The xShift compensates any configured angleRotateZ
az_phot=fmodf(az_phot, 1.0f); az_phot=fmodf(az_phot, 1.0f);
if (az_phot<0) az_phot+=1.0f; // 0.. 1 = image-X for a non-repeating pano photo if (az_phot<0) az_phot+=1.0f; // 0.. 1 = image-X for a non-repeating pano photo
float az_panel = nbSide*nbDecorRepeat * az_phot; // azimuth in "pan el space". Ex for nbS=4, nbDR=3: [0..[12, say 11.4 float az_panel = nbSide*nbDecorRepeat * az_phot; // azimuth in "pan el space". Ex for nbS=4, nbDR=3: [0..[12, say 11.4
float x_in_panel=fmodf(az_panel, 1.0f); float x_in_panel=fmodf(az_panel, 1.0f);
int currentSide = (int) floor(fmodf(az_panel, nbSide)); // must beco int currentSide = (int) floor(fmodf(az_panel, nbSide));
me 3 Q_ASSERT(currentSide>=0);
Q_ASSERT(currentSide<=nbSideTexs); Q_ASSERT(currentSide<nbSideTexs);
int x= (sides[currentSide].texCoords[0] + x_in_panel*(sides[currentS ide].texCoords[2]-sides[currentSide].texCoords[0])) int x= (sides[currentSide].texCoords[0] + x_in_panel*(sides[currentS ide].texCoords[2]-sides[currentSide].texCoords[0]))
* sidesImages[currentSide]->width(); // pixel X from left. * sidesImages[currentSide]->width(); // pixel X from left.
// QImage has pixel 0/0 in top left corner. We must find image Y for optionally cropped images. // QImage has pixel 0/0 in top left corner. We must find image Y for optionally cropped images.
// It should no longer be possible that sample position is outside c ropped texture. in this case, assert(0) but again assume full transparency and exit early. // It should no longer be possible that sample position is outside c ropped texture. in this case, assert(0) but again assume full transparency and exit early.
float y_img_1; // y of the sampled altitude in 0..1 visible image he ight from bottom float y_img_1; // y of the sampled altitude in 0..1 visible image he ight from bottom
if (tanMode) if (tanMode)
{ {
const float tanAlt=std::tan(alt_rad); const float tanAlt=std::tan(alt_rad);
skipping to change at line 669 skipping to change at line 680
else else
{ // adapted from spherical... { // adapted from spherical...
const float alt_pm1 = 2.0f * alt_rad / M_PI; // sampled al titude, -1...+1 linear in altitude angle const float alt_pm1 = 2.0f * alt_rad / M_PI; // sampled al titude, -1...+1 linear in altitude angle
const float img_top_pm1 = 1.0f-( (90.0f-decorAltAngle-decorA ngleShift) / 90.0f); // the top line in -1..+1 (angular) const float img_top_pm1 = 1.0f-( (90.0f-decorAltAngle-decorA ngleShift) / 90.0f); // the top line in -1..+1 (angular)
if (alt_pm1>img_top_pm1) { Q_ASSERT(0); return 0.0f; } // sh ould have been caught above with alt_rad tests if (alt_pm1>img_top_pm1) { Q_ASSERT(0); return 0.0f; } // sh ould have been caught above with alt_rad tests
const float img_bot_pm1 = 1.0f-((90.0f-decorAngleShift) / 90 .0f); // the bottom line in -1..+1 (angular) const float img_bot_pm1 = 1.0f-((90.0f-decorAngleShift) / 90 .0f); // the bottom line in -1..+1 (angular)
if (alt_pm1<img_bot_pm1) { Q_ASSERT(0); return 1.0f; } // sh ould have been caught above with alt_rad tests if (alt_pm1<img_bot_pm1) { Q_ASSERT(0); return 1.0f; } // sh ould have been caught above with alt_rad tests
y_img_1=(alt_pm1-img_bot_pm1)/(img_top_pm1-img_bot_pm1); // the sampled altitude in 0..1 visible image height from bottom y_img_1=(alt_pm1-img_bot_pm1)/(img_top_pm1-img_bot_pm1); // the sampled altitude in 0..1 visible image height from bottom
} }
// x0/y0 is lower left, x1/y1 upper right corner. // x0/y0 is lower left, x1/y1 upper right corner.
float y_baseImg_1 = sides[currentSide].texCoords[1]+ y_img_1*(sides[ currentSide].texCoords[3]-sides[currentSide].texCoords[1]); float y_baseImg_1 = sides[currentSide].texCoords[1]+ y_img_1*(sides[ currentSide].texCoords[3]-sides[currentSide].texCoords[1]);
int y=(1.0-y_baseImg_1)*sidesImages[currentSide]->height(); // pixel Y from top. int y=(1.0-y_baseImg_1)*sidesImages[currentSide]->height(); // pixel Y from top.
QRgb pixVal=sidesImages[currentSide]->pixel(x, y); QRgb pixVal=sidesImages[currentSide]->pixel(x, y);
#ifndef NDEBUG
// GZ: please leave the comment available for further development! // GZ: please leave the comment available for further development!
qDebug() << "Oldstyle Landscape sampling: az=" << az*180.0 << "° alt =" << alt_rad*180.0f/M_PI qDebug() << "Oldstyle Landscape sampling: az=" << az*180.0 << "° alt =" << alt_rad*180.0f/M_PI
<< "°, xShift[-1..+1]=" << xShift << " az_phot[0..1 ]=" << az_phot << "°, xShift[-1..+1]=" << xShift << " az_phot[0..1 ]=" << az_phot
<< " --> current side panel " << currentSide << " --> current side panel " << currentSide
<< ", w=" << sidesImages[currentSide]->width() << " h=" << sidesImages[currentSide]->height() << ", w=" << sidesImages[currentSide]->width() << " h=" << sidesImages[currentSide]->height()
<< " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f; << " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f;
#endif
return qAlpha(pixVal)/255.0f; return qAlpha(pixVal)/255.0f;
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////
LandscapePolygonal::LandscapePolygonal(float _radius) : Landscape(_radius) LandscapePolygonal::LandscapePolygonal(float _radius) : Landscape(_radius)
{} {}
LandscapePolygonal::~LandscapePolygonal() LandscapePolygonal::~LandscapePolygonal()
{} {}
skipping to change at line 885 skipping to change at line 896
if (M_PI/2-alt_rad > texFov/2.0 ) return 1.0; // outside fov, in the clamped texture zone: always opaque. if (M_PI/2-alt_rad > texFov/2.0 ) return 1.0; // outside fov, in the clamped texture zone: always opaque.
float radius=(M_PI/2-alt_rad)*2.0f/texFov; // radius in units of map Image.height/2 float radius=(M_PI/2-alt_rad)*2.0f/texFov; // radius in units of map Image.height/2
float az=atan2(azalt[0], azalt[1]) + M_PI/2 - angleRotateZ; // -pi/2 ..+3pi/2, real azimuth. NESW float az=atan2(azalt[0], azalt[1]) + M_PI/2 - angleRotateZ; // -pi/2 ..+3pi/2, real azimuth. NESW
// The texture map has south on top, east at right (if anglerotateZ =0) // The texture map has south on top, east at right (if anglerotateZ =0)
int x= mapImage->height()/2*(1 + radius*std::sin(az)); int x= mapImage->height()/2*(1 + radius*std::sin(az));
int y= mapImage->height()/2*(1 + radius*std::cos(az)); int y= mapImage->height()/2*(1 + radius*std::cos(az));
QRgb pixVal=mapImage->pixel(x, y); QRgb pixVal=mapImage->pixel(x, y);
#ifndef NDEBUG
// GZ: please leave the comment available for further development! // GZ: please leave the comment available for further development!
qDebug() << "Landscape sampling: az=" << (az+angleRotateZ)/M_PI*180. 0f << "° alt=" << alt_rad/M_PI*180.f qDebug() << "Landscape sampling: az=" << (az+angleRotateZ)/M_PI*180. 0f << "° alt=" << alt_rad/M_PI*180.f
<< "°, w=" << mapImage->width() << " h=" << mapImag e->height() << "°, w=" << mapImage->width() << " h=" << mapImag e->height()
<< " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f; << " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f;
#endif
return qAlpha(pixVal)/255.0f; return qAlpha(pixVal)/255.0f;
} }
/////////////////////////////////////////////////////////////////////////// ////////////////////// /////////////////////////////////////////////////////////////////////////// //////////////////////
// spherical panoramas // spherical panoramas
LandscapeSpherical::LandscapeSpherical(float _radius) LandscapeSpherical::LandscapeSpherical(float _radius)
: Landscape(_radius) : Landscape(_radius)
, mapTexTop(0.) , mapTexTop(0.)
, mapTexBottom(0.) , mapTexBottom(0.)
skipping to change at line 1068 skipping to change at line 1081
if (az<0) az+=2.0f; // 0..2 = N.E.S. W.N if (az<0) az+=2.0f; // 0..2 = N.E.S. W.N
const float xShift=(angleRotateZ) /M_PI; // shift value in -2..2 const float xShift=(angleRotateZ) /M_PI; // shift value in -2..2
float az_phot=az - 0.5f - xShift; // The 0.5 is caused by regul ar pano left edge being East. The xShift compensates any configured angleRo tateZ float az_phot=az - 0.5f - xShift; // The 0.5 is caused by regul ar pano left edge being East. The xShift compensates any configured angleRo tateZ
az_phot=fmodf(az_phot, 2.0f); az_phot=fmodf(az_phot, 2.0f);
if (az_phot<0) az_phot+=2.0f; // 0.. 2 = image-X if (az_phot<0) az_phot+=2.0f; // 0.. 2 = image-X
int x=(az_phot/2.0f) * mapImage->width(); // pixel X from left. int x=(az_phot/2.0f) * mapImage->width(); // pixel X from left.
QRgb pixVal=mapImage->pixel(x, y); QRgb pixVal=mapImage->pixel(x, y);
#ifndef NDEBUG
// GZ: please leave the comment available for further development! // GZ: please leave the comment available for further development!
qDebug() << "Landscape sampling: az=" << az*180.0 << "° alt=" << alt _pm1*90.0f qDebug() << "Landscape sampling: az=" << az*180.0 << "° alt=" << alt _pm1*90.0f
<< "°, xShift[-2..+2]=" << xShift << " az_phot[0..2 ]=" << az_phot << "°, xShift[-2..+2]=" << xShift << " az_phot[0..2 ]=" << az_phot
<< ", w=" << mapImage->width() << " h=" << mapImage ->height() << ", w=" << mapImage->width() << " h=" << mapImage ->height()
<< " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f; << " --> x:" << x << " y:" << y << " alpha:" << qAl pha(pixVal)/255.0f;
#endif
return qAlpha(pixVal)/255.0f; return qAlpha(pixVal)/255.0f;
} }
 End of changes. 21 change blocks. 
41 lines changed or deleted 56 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/