GridLinesMgr.cpp   GridLinesMgr.cpp 
skipping to change at line 24 skipping to change at line 24
* *
* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include <set> #include <set>
#include <QSettings> #include <QSettings>
#include <QDebug> #include <QDebug>
#include <QFontMetrics> #include <QFontMetrics>
#include <QtOpenGL>
#include "GridLinesMgr.hpp" #include "GridLinesMgr.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "renderer/StelCircleArcRenderer.hpp"
#include "renderer/StelRenderer.hpp"
#include "StelTranslator.hpp" #include "StelTranslator.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelFader.hpp" #include "StelFader.hpp"
#include "Planet.hpp" #include "Planet.hpp"
#include "StelLocaleMgr.hpp" #include "StelLocaleMgr.hpp"
#include "StelModuleMgr.hpp" #include "StelModuleMgr.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelPainter.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
//! @class SkyGrid //! @class SkyGrid
//! Class which manages a grid to display in the sky. //! Class which manages a grid to display in the sky.
//! TODO needs support for DMS/DMS labelling, not only HMS/DMS //! TODO needs support for DMS/DMS labelling, not only HMS/DMS
class SkyGrid class SkyGrid
{ {
public: public:
// Create and precompute positions of a SkyGrid // Create and precompute positions of a SkyGrid
SkyGrid(StelCore::FrameType frame); SkyGrid(StelCore::FrameType frame);
virtual ~SkyGrid(); virtual ~SkyGrid();
void draw(const StelCore* prj) const; //! Draw the grid.
//!
//! @param core The StelCore object.
//! @param renderer Renderer to draw with.
void draw(const StelCore* core, StelRenderer* renderer) const;
void setFontSize(double newFontSize); void setFontSize(double newFontSize);
void setColor(const Vec3f& c) {color = c;} void setColor(const Vec3f& c) {color = c;}
const Vec3f& getColor() {return color;} const Vec3f& getColor() {return color;}
void update(double deltaTime) {fader.update((int)(deltaTime*1000));} void update(double deltaTime) {fader.update((int)(deltaTime*1000));}
void setFadeDuration(float duration) {fader.setDuration((int)(durati on*1000.f));} void setFadeDuration(float duration) {fader.setDuration((int)(durati on*1000.f));}
void setDisplayed(const bool displayed){fader = displayed;} void setDisplayed(const bool displayed){fader = displayed;}
bool isDisplayed(void) const {return fader;} bool isDisplayed(void) const {return fader;}
private: private:
Vec3f color; Vec3f color;
StelCore::FrameType frameType; StelCore::FrameType frameType;
skipping to change at line 79 skipping to change at line 84
{ {
EQUATOR, EQUATOR,
ECLIPTIC, ECLIPTIC,
MERIDIAN, MERIDIAN,
HORIZON, HORIZON,
GALACTICPLANE GALACTICPLANE
}; };
// Create and precompute positions of a SkyGrid // Create and precompute positions of a SkyGrid
SkyLine(SKY_LINE_TYPE _line_type = EQUATOR); SkyLine(SKY_LINE_TYPE _line_type = EQUATOR);
virtual ~SkyLine(); virtual ~SkyLine();
void draw(StelCore* core) const; //! Draw the line.
//!
//! @param core The StelCore object.
//! @param renderer Renderer to draw with.
void draw(StelCore* core, StelRenderer* renderer) const;
void setColor(const Vec3f& c) {color = c;} void setColor(const Vec3f& c) {color = c;}
const Vec3f& getColor() {return color;} const Vec3f& getColor() {return color;}
void update(double deltaTime) {fader.update((int)(deltaTime*1000));} void update(double deltaTime) {fader.update((int)(deltaTime*1000));}
void setFadeDuration(float duration) {fader.setDuration((int)(durati on*1000.f));} void setFadeDuration(float duration) {fader.setDuration((int)(durati on*1000.f));}
void setDisplayed(const bool displayed){fader = displayed;} void setDisplayed(const bool displayed){fader = displayed;}
bool isDisplayed(void) const {return fader;} bool isDisplayed(void) const {return fader;}
void setFontSize(double newSize); void setFontSize(double newSize);
//! Re-translates the label. //! Re-translates the label.
void updateLabel(); void updateLabel();
private: private:
skipping to change at line 147 skipping to change at line 156
double minResolution = 80.; double minResolution = 80.;
double minSizeArcsec = minResolution/pixelPerRad*180./M_PI*3600; double minSizeArcsec = minResolution/pixelPerRad*180./M_PI*3600;
for (unsigned int i=0;i<11;++i) for (unsigned int i=0;i<11;++i)
if (STEP_SIZES_HMS[i]>minSizeArcsec) if (STEP_SIZES_HMS[i]>minSizeArcsec)
{ {
return STEP_SIZES_HMS[i]/3600.; return STEP_SIZES_HMS[i]/3600.;
} }
return 15.; return 15.;
} }
//! Data passed to viewportEdgeIntersectCallback.
struct ViewportEdgeIntersectCallbackData struct ViewportEdgeIntersectCallbackData
{ {
ViewportEdgeIntersectCallbackData(StelPainter* p) : sPainter(p) {;} //! Construct ViewportEdgeIntersectCallbackData with specified font
StelPainter* sPainter; metrics.
ViewportEdgeIntersectCallbackData(const QFontMetrics& metrics)
: fontMetrics(metrics){}
//! Renderer to draw the label with.
StelRenderer* renderer;
//! Projector to project 3D coordinates to viewport.
StelProjectorP projector;
//! Color of label text.
Vec4f textColor; Vec4f textColor;
QString text; // Label to display at the intersection of t //! Color of the sky line (or grid) being drawn.
he lines and screen side Vec4f skyLineColor;
double raAngle; // Used for meridians //! Metrics of the label font (so we know how to offset the label).
const QFontMetrics fontMetrics;
//! Label text.
QString text;
double raAngle;// Used for meridians
StelCore::FrameType frameType; StelCore::FrameType frameType;
}; };
// Callback which draws the label of the grid //! Callback which draws the label of the grid at the edge of the viewport.
//!
//! @param screenPos 2D position of the intersection on the screen.
//! @param direction Normalized direction of the arc toward the inside of t
he viewport.
//! @param userData ViewportEdgeIntersectCallbackData.
void viewportEdgeIntersectCallback(const Vec3d& screenPos, const Vec3d& dir ection, void* userData) void viewportEdgeIntersectCallback(const Vec3d& screenPos, const Vec3d& dir ection, void* userData)
{ {
ViewportEdgeIntersectCallbackData* d = static_cast<ViewportEdgeInter ViewportEdgeIntersectCallbackData* d =
sectCallbackData*>(userData); static_cast<ViewportEdgeIntersectCallbackData*>(userData);
Vec3d direc(direction); d->renderer->setGlobalColor(d->textColor);
direc.normalize();
const Vec4f tmpColor = d->sPainter->getColor();
d->sPainter->setColor(d->textColor[0], d->textColor[1], d->textColor
[2], d->textColor[3]);
QString text; QString text;
if (d->text.isEmpty()) if (d->text.isEmpty())
{ {
// We are in the case of meridians, we need to determine whi // We are in the case of meridians,
ch of the 2 labels (3h or 15h to use) // we need to determine which of the 2 labels (3h or 15h) to
use
Vec3d tmpV; Vec3d tmpV;
d->sPainter->getProjector()->unProject(screenPos, tmpV); d->projector->unProject(screenPos, tmpV);
double lon, lat; double lon, lat, raAngle;
StelUtils::rectToSphe(&lon, &lat, tmpV); StelUtils::rectToSphe(&lon, &lat, tmpV);
switch (d->frameType)
{
case StelCore::FrameAltAz:
{
double raAngle = M_PI-d->raAngle;
lon = M_PI-lon;
if (raAngle<0)
raAngle=+2.*M_PI;
if (lon<0)
lon=+2.*M_PI;
if (std::fabs(2.*M_PI-lon)<0.01)
{
// We are at meridian 0
lon = 0.;
}
if (std::fabs(lon-raAngle) < 0.01)
text = StelUtils::radToDmsStrAdapt(r
aAngle);
else
{
const double delta = raAngle<M_PI ?
M_PI : -M_PI;
if (raAngle==2*M_PI && delta==-M_PI)
{
text = StelUtils::radToDmsSt
rAdapt(0);
}
else
{
text = StelUtils::radToDmsSt
rAdapt(raAngle+delta);
}
}
break;
}
case StelCore::FrameGalactic:
{
double raAngle = M_PI-d->raAngle;
lon = M_PI-lon;
if (raAngle<0)
raAngle=+2.*M_PI;
if (lon<0)
lon=+2.*M_PI;
if (std::fabs(2.*M_PI-lon)<0.01) const bool altAzOrGalactic = d->frameType == StelCore::Frame
{ AltAz ||
// We are at meridian 0 d->frameType == StelCore::Frame
lon = 0.; Galactic;
} raAngle = d->raAngle;
if (std::fabs(lon-raAngle) < 0.01) if(altAzOrGalactic)
text = StelUtils::radToDmsStrAdapt(- {
raAngle+M_PI); raAngle = M_PI - raAngle;
else lon = M_PI - lon;
{ if (raAngle < 0) {raAngle += 2.0 * M_PI;}
const double delta = raAngle<M_PI ? if (lon < 0) {lon += 2.0 * M_PI;}
M_PI : -M_PI;
text = StelUtils::radToDmsStrAdapt(-
raAngle-delta+M_PI);
}
break;
}
default:
{
if (std::fabs(2.*M_PI-lon)<0.01)
{
// We are at meridian 0
lon = 0.;
}
if (std::fabs(lon-d->raAngle) < 0.01)
text = StelUtils::radToHmsStrAdapt(d
->raAngle);
else
{
const double delta = d->raAngle<M_PI
? M_PI : -M_PI;
text = StelUtils::radToHmsStrAdapt(d
->raAngle+delta);
}
}
} }
if (std::fabs(2.0 * M_PI - lon) < 0.01)
{
// We are at meridian 0
lon = 0.0;
}
const double delta = raAngle < M_PI ? M_PI : -M_PI;
double textAngle;
if (std::fabs(lon - raAngle) < 0.01)
{
textAngle =
(d->frameType == StelCore::FrameGalactic) ?
-raAngle + M_PI : raAngle;
}
else if(d->frameType == StelCore::FrameAltAz)
{
textAngle =
(std::fabs(raAngle - 2.0 * M_PI) < 0.01) ? 0
.0 : raAngle + delta;
}
else if(d->frameType == StelCore::FrameGalactic)
{
textAngle = -raAngle - delta + M_PI;
}
else
{
textAngle = raAngle + delta;
}
text = altAzOrGalactic ? StelUtils::radToDmsStrAdapt(textAng
le)
: StelUtils::radToHmsStrAdapt(textAng
le);
} }
else else
{
text = d->text; text = d->text;
}
double angleDeg = std::atan2(-direc[1], -direc[0])*180./M_PI; float angleDeg = std::atan2(-direction[1], -direction[0]) * 180.0 /
float xshift=6.f; M_PI;
if (angleDeg>90. || angleDeg<-90.) float xshift = 6.0f;
{ if (angleDeg > 90.0f || angleDeg < -90.0f)
angleDeg+=180.; {
xshift=-d->sPainter->getFontMetrics().width(text)-6.f; angleDeg += 180.0f;
xshift = -(d->fontMetrics.width(text)) - 6.0f;
} }
d->sPainter->drawText(screenPos[0], screenPos[1], text, angleDeg, xs d->renderer->drawText(TextParams(screenPos[0], screenPos[1], text)
hift, 3); .angleDegrees(angleDeg).shift(xshift, 3));
d->sPainter->setColor(tmpColor[0], tmpColor[1], tmpColor[2], tmpColo d->renderer->setGlobalColor(d->skyLineColor);
r[3]); d->renderer->setBlendMode(BlendMode_Alpha);
glDisable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} }
//! Draw the sky grid in the current frame //! Draw the sky grid in the current frame
void SkyGrid::draw(const StelCore* core) const void SkyGrid::draw(const StelCore* core, StelRenderer* renderer) const
{ {
const StelProjectorP prj = core->getProjection(frameType, frameType! =StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff) ; const StelProjectorP projector = core->getProjection(frameType, fram eType!=StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::Refracti onOff);
if (!fader.getInterstate()) if (!fader.getInterstate())
return; return;
// Look for all meridians and parallels intersecting with the disk b ounding the viewport // Look for all meridians and parallels intersecting with the disk b ounding the viewport
// Check whether the pole are in the viewport // Check whether the pole are in the viewport
bool northPoleInViewport = false; bool northPoleInViewport = false;
bool southPoleInViewport = false; bool southPoleInViewport = false;
Vec3f win; Vec3f win;
if (prj->project(Vec3f(0,0,1), win) && prj->checkInViewport(win)) if (projector->project(Vec3f(0,0,1), win) && projector->checkInViewp ort(win))
northPoleInViewport = true; northPoleInViewport = true;
if (prj->project(Vec3f(0,0,-1), win) && prj->checkInViewport(win)) if (projector->project(Vec3f(0,0,-1), win) && projector->checkInView port(win))
southPoleInViewport = true; southPoleInViewport = true;
// Get the longitude and latitude resolution at the center of the vi ewport // Get the longitude and latitude resolution at the center of the vi ewport
Vec3d centerV; Vec3d centerV;
prj->unProject(prj->getViewportPosX()+prj->getViewportWidth()/2, prj ->getViewportPosY()+prj->getViewportHeight()/2+1, centerV); projector->unProject(projector->getViewportPosX()+projector->getView portWidth()/2, projector->getViewportPosY()+projector->getViewportHeight()/ 2+1, centerV);
double lon2, lat2; double lon2, lat2;
StelUtils::rectToSphe(&lon2, &lat2, centerV); StelUtils::rectToSphe(&lon2, &lat2, centerV);
const double gridStepParallelRad = M_PI/180.*getClosestResolutionDMS (prj->getPixelPerRadAtCenter()); const double gridStepParallelRad = M_PI/180.*getClosestResolutionDMS (projector->getPixelPerRadAtCenter());
double gridStepMeridianRad; double gridStepMeridianRad;
if (northPoleInViewport || southPoleInViewport) if (northPoleInViewport || southPoleInViewport)
gridStepMeridianRad = (frameType==StelCore::FrameAltAz || fr ameType==StelCore::FrameGalactic) ? M_PI/180.* 10. : M_PI/180.* 15.; gridStepMeridianRad = (frameType==StelCore::FrameAltAz || fr ameType==StelCore::FrameGalactic) ? M_PI/180.* 10. : M_PI/180.* 15.;
else else
{ {
const double closetResLon = (frameType==StelCore::FrameAltAz || frameType==StelCore::FrameGalactic) ? getClosestResolutionDMS(prj->getP ixelPerRadAtCenter()*std::cos(lat2)) : getClosestResolutionHMS(prj->getPixe lPerRadAtCenter()*std::cos(lat2)); const double closetResLon = (frameType==StelCore::FrameAltAz || frameType==StelCore::FrameGalactic) ? getClosestResolutionDMS(projector ->getPixelPerRadAtCenter()*std::cos(lat2)) : getClosestResolutionHMS(projec tor->getPixelPerRadAtCenter()*std::cos(lat2));
gridStepMeridianRad = M_PI/180.* ((northPoleInViewport || so uthPoleInViewport) ? 15. : closetResLon); gridStepMeridianRad = M_PI/180.* ((northPoleInViewport || so uthPoleInViewport) ? 15. : closetResLon);
} }
// Get the bounding halfspace // Get the bounding halfspace
const SphericalCap& viewPortSphericalCap = prj->getBoundingCap(); const SphericalCap& viewPortSphericalCap = projector->getBoundingCap ();
// Compute the first grid starting point. This point is close to the center of the screen // Compute the first grid starting point. This point is close to the center of the screen
// and lays at the intersection of a meridien and a parallel // and lays at the intersection of a meridien and a parallel
lon2 = gridStepMeridianRad*((int)(lon2/gridStepMeridianRad+0.5)); lon2 = gridStepMeridianRad*((int)(lon2/gridStepMeridianRad+0.5));
lat2 = gridStepParallelRad*((int)(lat2/gridStepParallelRad+0.5)); lat2 = gridStepParallelRad*((int)(lat2/gridStepParallelRad+0.5));
Vec3d firstPoint; Vec3d firstPoint;
StelUtils::spheToRect(lon2, lat2, firstPoint); StelUtils::spheToRect(lon2, lat2, firstPoint);
firstPoint.normalize(); firstPoint.normalize();
// Q_ASSERT(viewPortSphericalCap.contains(firstPoint)); // Q_ASSERT(viewPortSphericalCap.contains(firstPoint));
// Initialize a painter and set openGL state // Prepare for drawing
StelPainter sPainter(prj); renderer->setBlendMode(BlendMode_Alpha);
glEnable(GL_BLEND); Vec4f textColor(color[0], color[1], color[2], 0.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transpa
rency mode Vec4f skyGridColor;
Vec4f textColor(color[0], color[1], color[2], 0);
if (StelApp::getInstance().getVisionModeNight()) if (StelApp::getInstance().getVisionModeNight())
{ {
// instead of a filter which just zeros G&B, set the red // instead of a filter which just zeros G&B, set the red
// value to the mean brightness of RGB. // value to the mean brightness of RGB.
float red = (color[0] + color[1] + color[2]) / 3.0; float red = (color[0] + color[1] + color[2]) / 3.0;
textColor[0] = red; textColor[0] = red;
textColor[1] = 0.; textColor[2] = 0.; textColor[1] = 0.; textColor[2] = 0.;
sPainter.setColor(red, 0, 0, fader.getInterstate()); skyGridColor = Vec4f(red, 0.0f, 0.0f, fader.getInterstate()) ;
} }
else else
{ {
sPainter.setColor(color[0],color[1],color[2], fader.getInter state()); skyGridColor = Vec4f(color[0], color[1], color[2], fader.get Interstate());
} }
renderer->setGlobalColor(skyGridColor);
textColor*=2; textColor *= 2;
textColor[3]=fader.getInterstate(); textColor[3] = fader.getInterstate();
sPainter.setFont(font); renderer->setFont(font);
ViewportEdgeIntersectCallbackData userData(&sPainter); ViewportEdgeIntersectCallbackData userData =
userData.textColor = textColor; ViewportEdgeIntersectCallbackData(QFontMetrics(font));
userData.frameType = frameType; userData.renderer = renderer;
userData.projector = projector;
userData.textColor = textColor;
userData.frameType = frameType;
userData.skyLineColor = skyGridColor;
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Draw all the meridians (great circles) // Draw all the meridians (great circles)
SphericalCap meridianSphericalCap(Vec3d(1,0,0), 0); SphericalCap meridianSphericalCap(Vec3d(1,0,0), 0);
Mat4d rotLon = Mat4d::zrotation(gridStepMeridianRad); Mat4d rotLon = Mat4d::zrotation(gridStepMeridianRad);
Vec3d fpt = firstPoint; Vec3d fpt = firstPoint;
Vec3d p1, p2; Vec3d p1, p2;
int maxNbIter = (int)(M_PI/gridStepMeridianRad); int maxNbIter = (int)(M_PI/gridStepMeridianRad);
int i; int i;
StelCircleArcRenderer circleRenderer(renderer, projector);
for (i=0; i<maxNbIter; ++i) for (i=0; i<maxNbIter; ++i)
{ {
StelUtils::rectToSphe(&lon2, &lat2, fpt); StelUtils::rectToSphe(&lon2, &lat2, fpt);
userData.raAngle = lon2; userData.raAngle = lon2;
meridianSphericalCap.n = fpt^Vec3d(0,0,1); meridianSphericalCap.n = fpt^Vec3d(0,0,1);
meridianSphericalCap.n.normalize(); meridianSphericalCap.n.normalize();
if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridianSphericalCap, p1, p2)) if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridianSphericalCap, p1, p2))
{ {
if (viewPortSphericalCap.d<meridianSphericalCap.d && viewPortSphericalCap.contains(meridianSphericalCap.n)) if (viewPortSphericalCap.d<meridianSphericalCap.d && viewPortSphericalCap.contains(meridianSphericalCap.n))
{ {
// The meridian is fully included in the vie wport, draw it in 3 sub-arcs to avoid length > 180. // The meridian is fully included in the vie wport, draw it in 3 sub-arcs to avoid length > 180.
const Mat4d& rotLon120 = Mat4d::rotation(mer idianSphericalCap.n, 120.*M_PI/180.); const Mat4d& rotLon120 = Mat4d::rotation(mer idianSphericalCap.n, 120.*M_PI/180.);
Vec3d rotFpt=fpt; Vec3d rotFpt=fpt;
rotFpt.transfo4d(rotLon120); rotFpt.transfo4d(rotLon120);
Vec3d rotFpt2=rotFpt; Vec3d rotFpt2=rotFpt;
rotFpt2.transfo4d(rotLon120); rotFpt2.transfo4d(rotLon120);
sPainter.drawGreatCircleArc(fpt, rotFpt, NUL circleRenderer.drawGreatCircleArc
L, viewportEdgeIntersectCallback, &userData); (fpt, rotFpt, NULL, viewportEdgeInte
sPainter.drawGreatCircleArc(rotFpt, rotFpt2, rsectCallback, &userData);
NULL, viewportEdgeIntersectCallback, &userData); circleRenderer.drawGreatCircleArc
sPainter.drawGreatCircleArc(rotFpt2, fpt, NU (rotFpt, rotFpt2, NULL, viewportEdge
LL, viewportEdgeIntersectCallback, &userData); IntersectCallback, &userData);
circleRenderer.drawGreatCircleArc
(rotFpt2, fpt, NULL, viewportEdgeInt
ersectCallback, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
continue; continue;
} }
else else
break; break;
} }
Vec3d middlePoint = p1+p2; Vec3d middlePoint = p1+p2;
middlePoint.normalize(); middlePoint.normalize();
if (!viewPortSphericalCap.contains(middlePoint)) if (!viewPortSphericalCap.contains(middlePoint))
middlePoint*=-1.; middlePoint*=-1.;
// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg // Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
sPainter.drawGreatCircleArc(p1, middlePoint, NULL, viewportE circleRenderer.drawGreatCircleArc
dgeIntersectCallback, &userData); (p1, middlePoint, NULL, viewportEdgeIntersectCallbac
sPainter.drawGreatCircleArc(p2, middlePoint, NULL, viewportE k, &userData);
dgeIntersectCallback, &userData); circleRenderer.drawGreatCircleArc
(p2, middlePoint, NULL, viewportEdgeIntersectCallbac
k, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
} }
if (i!=maxNbIter) if (i!=maxNbIter)
{ {
rotLon = Mat4d::zrotation(-gridStepMeridianRad); rotLon = Mat4d::zrotation(-gridStepMeridianRad);
fpt = firstPoint; fpt = firstPoint;
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
for (int j=0; j<maxNbIter-i; ++j) for (int j=0; j<maxNbIter-i; ++j)
skipping to change at line 402 skipping to change at line 408
meridianSphericalCap.n = fpt^Vec3d(0,0,1); meridianSphericalCap.n = fpt^Vec3d(0,0,1);
meridianSphericalCap.n.normalize(); meridianSphericalCap.n.normalize();
if (!SphericalCap::intersectionPoints(viewPortSpheri calCap, meridianSphericalCap, p1, p2)) if (!SphericalCap::intersectionPoints(viewPortSpheri calCap, meridianSphericalCap, p1, p2))
break; break;
Vec3d middlePoint = p1+p2; Vec3d middlePoint = p1+p2;
middlePoint.normalize(); middlePoint.normalize();
if (!viewPortSphericalCap.contains(middlePoint)) if (!viewPortSphericalCap.contains(middlePoint))
middlePoint*=-1; middlePoint*=-1;
sPainter.drawGreatCircleArc(p1, middlePoint, NULL, v circleRenderer.drawGreatCircleArc
iewportEdgeIntersectCallback, &userData); (p1, middlePoint, NULL, viewportEdgeIntersec
sPainter.drawGreatCircleArc(p2, middlePoint, NULL, v tCallback, &userData);
iewportEdgeIntersectCallback, &userData); circleRenderer.drawGreatCircleArc
(p2, middlePoint, NULL, viewportEdgeIntersec
tCallback, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
} }
} }
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Draw all the parallels (small circles) // Draw all the parallels (small circles)
SphericalCap parallelSphericalCap(Vec3d(0,0,1), 0); SphericalCap parallelSphericalCap(Vec3d(0,0,1), 0);
rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), gridStepParallelRa d); rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), gridStepParallelRa d);
fpt = firstPoint; fpt = firstPoint;
skipping to change at line 425 skipping to change at line 433
for (i=0; i<maxNbIter; ++i) for (i=0; i<maxNbIter; ++i)
{ {
StelUtils::rectToSphe(&lon2, &lat2, fpt); StelUtils::rectToSphe(&lon2, &lat2, fpt);
userData.text = StelUtils::radToDmsStrAdapt(lat2); userData.text = StelUtils::radToDmsStrAdapt(lat2);
parallelSphericalCap.d = fpt[2]; parallelSphericalCap.d = fpt[2];
if (parallelSphericalCap.d>0.9999999) if (parallelSphericalCap.d>0.9999999)
break; break;
const Vec3d rotCenter(0,0,parallelSphericalCap.d); const Vec3d rotCenter(0,0,parallelSphericalCap.d);
circleRenderer.setRotCenter(rotCenter);
if (!SphericalCap::intersectionPoints(viewPortSphericalCap, parallelSphericalCap, p1, p2)) if (!SphericalCap::intersectionPoints(viewPortSphericalCap, parallelSphericalCap, p1, p2))
{ {
if ((viewPortSphericalCap.d<parallelSphericalCap.d & & viewPortSphericalCap.contains(parallelSphericalCap.n)) if ((viewPortSphericalCap.d<parallelSphericalCap.d & & viewPortSphericalCap.contains(parallelSphericalCap.n))
|| (viewPortSphericalCap.d<-parallelSpherica lCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n))) || (viewPortSphericalCap.d<-parallelSpherica lCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n)))
{ {
// The parallel is fully included in the vie wport, draw it in 3 sub-arcs to avoid lengths >= 180 deg // The parallel is fully included in the vie wport, draw it in 3 sub-arcs to avoid lengths >= 180 deg
static const Mat4d rotLon120 = Mat4d::zrotat ion(120.*M_PI/180.); static const Mat4d rotLon120 = Mat4d::zrotat ion(120.*M_PI/180.);
Vec3d rotFpt=fpt; Vec3d rotFpt=fpt;
rotFpt.transfo4d(rotLon120); rotFpt.transfo4d(rotLon120);
Vec3d rotFpt2=rotFpt; Vec3d rotFpt2=rotFpt;
rotFpt2.transfo4d(rotLon120); rotFpt2.transfo4d(rotLon120);
sPainter.drawSmallCircleArc(fpt, rotFpt, rot
Center, viewportEdgeIntersectCallback, &userData); circleRenderer.drawSmallCircleArc
sPainter.drawSmallCircleArc(rotFpt, rotFpt2, (fpt, rotFpt, viewportEdgeIntersectC
rotCenter, viewportEdgeIntersectCallback, &userData); allback, &userData);
sPainter.drawSmallCircleArc(rotFpt2, fpt, ro circleRenderer.drawSmallCircleArc
tCenter, viewportEdgeIntersectCallback, &userData); (rotFpt, rotFpt2, viewportEdgeInters
ectCallback, &userData);
circleRenderer.drawSmallCircleArc
(rotFpt2, fpt, viewportEdgeIntersect
Callback, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
continue; continue;
} }
else else
break; break;
} }
// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg // Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
Vec3d middlePoint = p1-rotCenter+p2-rotCenter; Vec3d middlePoint = p1-rotCenter+p2-rotCenter;
middlePoint.normalize(); middlePoint.normalize();
middlePoint*=(p1-rotCenter).length(); middlePoint*=(p1-rotCenter).length();
middlePoint+=rotCenter; middlePoint+=rotCenter;
if (!viewPortSphericalCap.contains(middlePoint)) if (!viewPortSphericalCap.contains(middlePoint))
{ {
middlePoint-=rotCenter; middlePoint-=rotCenter;
middlePoint*=-1.; middlePoint*=-1.;
middlePoint+=rotCenter; middlePoint+=rotCenter;
} }
sPainter.drawSmallCircleArc(p1, middlePoint, rotCenter, view circleRenderer.drawSmallCircleArc
portEdgeIntersectCallback, &userData); (p1, middlePoint, viewportEdgeIntersectCallback, &us
sPainter.drawSmallCircleArc(p2, middlePoint, rotCenter, view erData);
portEdgeIntersectCallback, &userData); circleRenderer.drawSmallCircleArc
(p2, middlePoint, viewportEdgeIntersectCallback, &us
erData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
} }
if (i!=maxNbIter) if (i!=maxNbIter)
{ {
rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), -gridStepP arallelRad); rotLon = Mat4d::rotation(firstPoint^Vec3d(0,0,1), -gridStepP arallelRad);
fpt = firstPoint; fpt = firstPoint;
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
for (int j=0; j<maxNbIter-i; ++j) for (int j=0; j<maxNbIter-i; ++j)
{ {
StelUtils::rectToSphe(&lon2, &lat2, fpt); StelUtils::rectToSphe(&lon2, &lat2, fpt);
userData.text = StelUtils::radToDmsStrAdapt(lat2); userData.text = StelUtils::radToDmsStrAdapt(lat2);
parallelSphericalCap.d = fpt[2]; parallelSphericalCap.d = fpt[2];
const Vec3d rotCenter(0,0,parallelSphericalCap.d); const Vec3d rotCenter(0,0,parallelSphericalCap.d);
circleRenderer.setRotCenter(rotCenter);
if (!SphericalCap::intersectionPoints(viewPortSpheri calCap, parallelSphericalCap, p1, p2)) if (!SphericalCap::intersectionPoints(viewPortSpheri calCap, parallelSphericalCap, p1, p2))
{ {
if ((viewPortSphericalCap.d<parallelSpherica lCap.d && viewPortSphericalCap.contains(parallelSphericalCap.n)) if ((viewPortSphericalCap.d<parallelSpherica lCap.d && viewPortSphericalCap.contains(parallelSphericalCap.n))
|| (viewPortSphericalCap.d<-paralle lSphericalCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n))) || (viewPortSphericalCap.d<-paralle lSphericalCap.d && viewPortSphericalCap.contains(-parallelSphericalCap.n)))
{ {
// The parallel is fully included in the viewport, draw it in 3 sub-arcs to avoid lengths >= 180 deg // The parallel is fully included in the viewport, draw it in 3 sub-arcs to avoid lengths >= 180 deg
static const Mat4d rotLon120 = Mat4d ::zrotation(120.*M_PI/180.); static const Mat4d rotLon120 = Mat4d ::zrotation(120.*M_PI/180.);
Vec3d rotFpt=fpt; Vec3d rotFpt=fpt;
rotFpt.transfo4d(rotLon120); rotFpt.transfo4d(rotLon120);
Vec3d rotFpt2=rotFpt; Vec3d rotFpt2=rotFpt;
rotFpt2.transfo4d(rotLon120); rotFpt2.transfo4d(rotLon120);
sPainter.drawSmallCircleArc(fpt, rot circleRenderer.drawSmallCircleArc
Fpt, rotCenter, viewportEdgeIntersectCallback, &userData); (fpt, rotFpt, viewportEdgeIn
sPainter.drawSmallCircleArc(rotFpt, tersectCallback, &userData);
rotFpt2, rotCenter, viewportEdgeIntersectCallback, &userData); circleRenderer.drawSmallCircleArc
sPainter.drawSmallCircleArc(rotFpt2, (rotFpt, rotFpt2, viewportEd
fpt, rotCenter, viewportEdgeIntersectCallback, &userData); geIntersectCallback, &userData);
circleRenderer.drawSmallCircleArc
(rotFpt2, fpt, viewportEdgeI
ntersectCallback, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
continue; continue;
} }
else else
break; break;
} }
// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg // Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
Vec3d middlePoint = p1-rotCenter+p2-rotCenter; Vec3d middlePoint = p1-rotCenter+p2-rotCenter;
middlePoint.normalize(); middlePoint.normalize();
middlePoint*=(p1-rotCenter).length(); middlePoint*=(p1-rotCenter).length();
middlePoint+=rotCenter; middlePoint+=rotCenter;
if (!viewPortSphericalCap.contains(middlePoint)) if (!viewPortSphericalCap.contains(middlePoint))
{ {
middlePoint-=rotCenter; middlePoint-=rotCenter;
middlePoint*=-1.; middlePoint*=-1.;
middlePoint+=rotCenter; middlePoint+=rotCenter;
} }
sPainter.drawSmallCircleArc(p1, middlePoint, rotCent circleRenderer.drawSmallCircleArc
er, viewportEdgeIntersectCallback, &userData); (p1, middlePoint, viewportEdgeIntersectCallb
sPainter.drawSmallCircleArc(p2, middlePoint, rotCent ack, &userData);
er, viewportEdgeIntersectCallback, &userData); circleRenderer.drawSmallCircleArc
(p2, middlePoint, viewportEdgeIntersectCallb
ack, &userData);
fpt.transfo4d(rotLon); fpt.transfo4d(rotLon);
} }
} }
} }
SkyLine::SkyLine(SKY_LINE_TYPE _line_type) : color(0.f, 0.f, 1.f) SkyLine::SkyLine(SKY_LINE_TYPE _line_type) : color(0.f, 0.f, 1.f)
{ {
font.setPixelSize(14); font.setPixelSize(14);
line_type = _line_type; line_type = _line_type;
skipping to change at line 561 skipping to change at line 583
frameType = StelCore::FrameAltAz; frameType = StelCore::FrameAltAz;
label = q_("Horizon"); label = q_("Horizon");
break; break;
case GALACTICPLANE: case GALACTICPLANE:
frameType = StelCore::FrameGalactic; frameType = StelCore::FrameGalactic;
label = q_("Galactic Plane"); label = q_("Galactic Plane");
break; break;
} }
} }
void SkyLine::draw(StelCore *core) const void SkyLine::draw(StelCore *core, StelRenderer* renderer) const
{ {
if (!fader.getInterstate()) if (!fader.getInterstate())
return; return;
StelProjectorP prj = core->getProjection(frameType, frameType!=StelC ore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff); StelProjectorP projector = core->getProjection(frameType, frameType! =StelCore::FrameAltAz ? StelCore::RefractionAuto : StelCore::RefractionOff) ;
// Get the bounding halfspace // Get the bounding halfspace
const SphericalCap& viewPortSphericalCap = prj->getBoundingCap(); const SphericalCap& viewPortSphericalCap = projector->getBoundingCap
();
Vec4f textColor, skyLineColor;
if (StelApp::getInstance().getVisionModeNight())
{
// instead of a filter which just zeros G&B, set the red
// value to the mean brightness of RGB.
float red = (color[0] + color[1] + color[2]) / 3.0;
textColor = Vec4f(red, 0.0f, 0.0f, 0.0f);
skyLineColor = Vec4f(red, 0.0f, 0.0f, fader.getInterstate())
;
}
else
{
skyLineColor = Vec4f(color[0], color[1], color[2], fader.get
Interstate());
textColor = Vec4f(color[0], color[1], color[2], 0.0f);
}
renderer->setGlobalColor(skyLineColor);
renderer->setBlendMode(BlendMode_Alpha);
textColor *= 2;
textColor[3] = fader.getInterstate();
renderer->setFont(font);
ViewportEdgeIntersectCallbackData userData =
ViewportEdgeIntersectCallbackData(QFontMetrics(font));
userData.renderer = renderer;
userData.projector = projector;
userData.textColor = textColor;
userData.skyLineColor = skyLineColor;
userData.text = label;
// Initialize a painter and set openGL state
StelPainter sPainter(prj);
sPainter.setColor(color[0], color[1], color[2], fader.getInterstate(
));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transpa
rency mode
Vec4f textColor(color[0], color[1], color[2], 0);
textColor*=2;
textColor[3]=fader.getInterstate();
ViewportEdgeIntersectCallbackData userData(&sPainter);
sPainter.setFont(font);
userData.textColor = textColor;
userData.text = label;
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Draw the line // Draw the line
SphericalCap meridianSphericalCap(Vec3d(0,0,1), 0); SphericalCap meridianSphericalCap(Vec3d(0,0,1), 0);
Vec3d fpt(1,0,0); Vec3d fpt(1,0,0);
if (line_type==MERIDIAN) if (line_type==MERIDIAN)
{ {
meridianSphericalCap.n.set(0,1,0); meridianSphericalCap.n.set(0,1,0);
} }
StelCircleArcRenderer circleRenderer(renderer, projector);
Vec3d p1, p2; Vec3d p1, p2;
if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridian SphericalCap, p1, p2)) if (!SphericalCap::intersectionPoints(viewPortSphericalCap, meridian SphericalCap, p1, p2))
{ {
if ((viewPortSphericalCap.d<meridianSphericalCap.d && viewPo rtSphericalCap.contains(meridianSphericalCap.n)) if ((viewPortSphericalCap.d<meridianSphericalCap.d && viewPo rtSphericalCap.contains(meridianSphericalCap.n))
|| (viewPortSphericalCap.d<-meridianSphericalCap.d & & viewPortSphericalCap.contains(-meridianSphericalCap.n))) || (viewPortSphericalCap.d<-meridianSphericalCap.d & & viewPortSphericalCap.contains(-meridianSphericalCap.n)))
{ {
// The meridian is fully included in the viewport, d raw it in 3 sub-arcs to avoid length > 180. // The meridian is fully included in the viewport, d raw it in 3 sub-arcs to avoid length > 180.
const Mat4d& rotLon120 = Mat4d::rotation(meridianSph ericalCap.n, 120.*M_PI/180.); const Mat4d& rotLon120 = Mat4d::rotation(meridianSph ericalCap.n, 120.*M_PI/180.);
Vec3d rotFpt=fpt; Vec3d rotFpt=fpt;
rotFpt.transfo4d(rotLon120); rotFpt.transfo4d(rotLon120);
Vec3d rotFpt2=rotFpt; Vec3d rotFpt2=rotFpt;
rotFpt2.transfo4d(rotLon120); rotFpt2.transfo4d(rotLon120);
sPainter.drawGreatCircleArc(fpt, rotFpt, NULL, viewp
ortEdgeIntersectCallback, &userData); circleRenderer.drawGreatCircleArc
sPainter.drawGreatCircleArc(rotFpt, rotFpt2, NULL, v (fpt, rotFpt, NULL, viewportEdgeIntersectCal
iewportEdgeIntersectCallback, &userData); lback, &userData);
sPainter.drawGreatCircleArc(rotFpt2, fpt, NULL, view circleRenderer.drawGreatCircleArc
portEdgeIntersectCallback, &userData); (rotFpt, rotFpt2, NULL, viewportEdgeIntersec
return; tCallback, &userData);
circleRenderer.drawGreatCircleArc
(rotFpt2, fpt, NULL, viewportEdgeIntersectCa
llback, &userData);
} }
else return;
return;
} }
Vec3d middlePoint = p1+p2; Vec3d middlePoint = p1+p2;
middlePoint.normalize(); middlePoint.normalize();
if (!viewPortSphericalCap.contains(middlePoint)) if (!viewPortSphericalCap.contains(middlePoint))
middlePoint*=-1.; middlePoint*=-1.;
// Draw the arc in 2 sub-arcs to avoid lengths > 180 deg // Draw the arc in 2 sub-arcs to avoid lengths > 180 deg
sPainter.drawGreatCircleArc(p1, middlePoint, NULL, viewportEdgeInter circleRenderer.drawGreatCircleArc
sectCallback, &userData); (p1, middlePoint, NULL, viewportEdgeIntersectCallback, &user
sPainter.drawGreatCircleArc(p2, middlePoint, NULL, viewportEdgeInter Data);
sectCallback, &userData); circleRenderer.drawGreatCircleArc
(p2, middlePoint, NULL, viewportEdgeIntersectCallback, &user
Data);
// // Johannes: use a big radius as a dirty workaround for the bug that the // // Johannes: use a big radius as a dirty workaround for the bug that the
// // ecliptic line is not drawn around the observer, but around the su n: // // ecliptic line is not drawn around the observer, but around the su n:
// const Vec3d vv(1000000,0,0); // const Vec3d vv(1000000,0,0);
} }
GridLinesMgr::GridLinesMgr() GridLinesMgr::GridLinesMgr()
{ {
setObjectName("GridLinesMgr"); setObjectName("GridLinesMgr");
equGrid = new SkyGrid(StelCore::FrameEquinoxEqu); equGrid = new SkyGrid(StelCore::FrameEquinoxEqu);
equJ2000Grid = new SkyGrid(StelCore::FrameJ2000); equJ2000Grid = new SkyGrid(StelCore::FrameJ2000);
eclJ2000Grid = new SkyGrid(StelCore::FrameObservercentricEcliptic); eclJ2000Grid = new SkyGrid(StelCore::FrameObservercentricEclipt
galacticGrid = new SkyGrid(StelCore::FrameGalactic); ic);
aziGrid = new SkyGrid(StelCore::FrameAltAz); galacticGrid = new SkyGrid(StelCore::FrameGalactic);
equatorLine = new SkyLine(SkyLine::EQUATOR); aziGrid = new SkyGrid(StelCore::FrameAltAz);
eclipticLine = new SkyLine(SkyLine::ECLIPTIC); equatorLine = new SkyLine(SkyLine::EQUATOR);
meridianLine = new SkyLine(SkyLine::MERIDIAN); eclipticLine = new SkyLine(SkyLine::ECLIPTIC);
horizonLine = new SkyLine(SkyLine::HORIZON); meridianLine = new SkyLine(SkyLine::MERIDIAN);
horizonLine = new SkyLine(SkyLine::HORIZON);
galacticPlaneLine = new SkyLine(SkyLine::GALACTICPLANE); galacticPlaneLine = new SkyLine(SkyLine::GALACTICPLANE);
} }
GridLinesMgr::~GridLinesMgr() GridLinesMgr::~GridLinesMgr()
{ {
delete equGrid; delete equGrid;
delete equJ2000Grid; delete equJ2000Grid;
delete eclJ2000Grid; delete eclJ2000Grid;
delete galacticGrid; delete galacticGrid;
delete aziGrid; delete aziGrid;
skipping to change at line 705 skipping to change at line 747
eclJ2000Grid->update(deltaTime); eclJ2000Grid->update(deltaTime);
galacticGrid->update(deltaTime); galacticGrid->update(deltaTime);
aziGrid->update(deltaTime); aziGrid->update(deltaTime);
equatorLine->update(deltaTime); equatorLine->update(deltaTime);
eclipticLine->update(deltaTime); eclipticLine->update(deltaTime);
meridianLine->update(deltaTime); meridianLine->update(deltaTime);
horizonLine->update(deltaTime); horizonLine->update(deltaTime);
galacticPlaneLine->update(deltaTime); galacticPlaneLine->update(deltaTime);
} }
void GridLinesMgr::draw(StelCore* core) void GridLinesMgr::draw(StelCore* core, class StelRenderer* renderer)
{ {
equGrid->draw(core); equGrid->draw(core, renderer);
galacticGrid->draw(core); galacticGrid->draw(core, renderer);
equJ2000Grid->draw(core); equJ2000Grid->draw(core, renderer);
eclJ2000Grid->draw(core); eclJ2000Grid->draw(core, renderer);
aziGrid->draw(core); aziGrid->draw(core, renderer);
equatorLine->draw(core); equatorLine->draw(core, renderer);
eclipticLine->draw(core); eclipticLine->draw(core, renderer);
meridianLine->draw(core); meridianLine->draw(core, renderer);
horizonLine->draw(core); horizonLine->draw(core, renderer);
galacticPlaneLine->draw(core); galacticPlaneLine->draw(core, renderer);
} }
void GridLinesMgr::setStelStyle(const QString& section) void GridLinesMgr::setStelStyle(const QString& section)
{ {
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
// Load colors from config file // Load colors from config file
QString defaultColor = conf->value(section+"/default_color").toStrin g(); QString defaultColor = conf->value(section+"/default_color").toStrin g();
setColorEquatorGrid(StelUtils::strToVec3f(conf->value(section+"/equa torial_color", defaultColor).toString())); setColorEquatorGrid(StelUtils::strToVec3f(conf->value(section+"/equa torial_color", defaultColor).toString()));
setColorEquatorJ2000Grid(StelUtils::strToVec3f(conf->value(section+" /equatorial_J2000_color", defaultColor).toString())); setColorEquatorJ2000Grid(StelUtils::strToVec3f(conf->value(section+" /equatorial_J2000_color", defaultColor).toString()));
 End of changes. 55 change blocks. 
221 lines changed or deleted 258 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/