ZodiacalLight.cpp   ZodiacalLight.cpp 
/* /*
* Stellarium * Stellarium
* Copyright (C) 2002 Fabien Chereau (MilkyWay class) * Copyright (C) 2002 Fabien Chereau (MilkyWay class)
* Copyright (C) 2014 Georg Zotti (followed pattern for ZodiacalLight) * Copyright (C) 2014-17 Georg Zotti (followed pattern for ZodiacalLight)
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
skipping to change at line 75 skipping to change at line 75
Q_ASSERT(conf); Q_ASSERT(conf);
// The Paper describes brightness values over the complete sky, so a lso the texture covers the full sky. // The Paper describes brightness values over the complete sky, so a lso the texture covers the full sky.
// The data hole around the sun has been filled by useful values. // The data hole around the sun has been filled by useful values.
tex = StelApp::getInstance().getTextureManager().createTexture(StelF ileMgr::getInstallationDir()+"/textures/zodiacallight_2004.png"); tex = StelApp::getInstance().getTextureManager().createTexture(StelF ileMgr::getInstallationDir()+"/textures/zodiacallight_2004.png");
setFlagShow(conf->value("astro/flag_zodiacal_light", true).toBool()) ; setFlagShow(conf->value("astro/flag_zodiacal_light", true).toBool()) ;
setIntensity(conf->value("astro/zodiacal_light_intensity",1.f).toFlo at()); setIntensity(conf->value("astro/zodiacal_light_intensity",1.f).toFlo at());
vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight( 1.f,1.f,60,30,1, true)); // 6x6 degree quads vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight( 1.f,1.f,60,30,1, true)); // 6x6 degree quads
vertexArray->colors.resize(vertexArray->vertex.length()); vertexArray->colors.resize(vertexArray->vertex.length());
vertexArray->colors.fill(Vec3f(1.0, 0.3, 0.9)); vertexArray->colors.fill(color);
eclipticalVertices=vertexArray->vertex; eclipticalVertices=vertexArray->vertex;
// This vector is used to keep original vertices, these will be modi fied in update(). // This vector is used to keep original vertices, these will be modi fied in update().
QString displayGroup = N_("Display Options"); QString displayGroup = N_("Display Options");
addAction("actionShow_ZodiacalLight", displayGroup, N_("Zodiacal Lig ht"), "flagZodiacalLightDisplayed", "Ctrl+Shift+Z"); addAction("actionShow_ZodiacalLight", displayGroup, N_("Zodiacal Lig ht"), "flagZodiacalLightDisplayed", "Ctrl+Shift+Z");
StelCore* core=StelApp::getInstance().getCore();
connect(core, SIGNAL(locationChanged(StelLocation)), this, SLOT(hand
leLocationChanged(StelLocation)));
}
void ZodiacalLight::handleLocationChanged(StelLocation loc)
{
// This just forces update() to re-compute longitude.
Q_UNUSED(loc);
lastJD=-1e12;
} }
void ZodiacalLight::update(double deltaTime) void ZodiacalLight::update(double deltaTime)
{ {
fader->update((int)(deltaTime*1000)); fader->update((int)(deltaTime*1000));
if (!getFlagShow() || (getIntensity()<0.01) ) if (!getFlagShow() || (getIntensity()<0.01) )
return; return;
StelCore* core=StelApp::getInstance().getCore(); StelCore* core=StelApp::getInstance().getCore();
// Test if we are not on Earth. Texture would not fit, so don't draw // Test if we are not on Earth or Moon. Texture would not fit, so do
then. n't draw then.
if (core->getCurrentLocation().planetName != "Earth") return; if (! QString("Earth Moon").contains(core->getCurrentLocation().plan
etName)) return;
double currentJD=core->getJD(); double currentJD=core->getJD();
if (qAbs(currentJD - lastJD) > 0.25f) // should be enough to update position every 6 hours. if (qAbs(currentJD - lastJD) > 0.25f) // should be enough to update position every 6 hours.
{ {
// update vertices // Allowed locations are only Earth or Moon. For Earth, we c
Vec3d obsPos=core->getObserverHeliocentricEclipticPos(); an compute ZL along ecliptic of date.
// For solar-centered texture, take minus, else plus: // For the Moon, we can only show ZL along J2000 ecliptic.
double solarLongitude=atan2(obsPos[1], obsPos[0]) - 0.5*M_PI // In draw() we have different projector frames. But we also
; need separate solar longitude computations here.
Mat4d transMat=StelCore::matVsop87ToJ2000 * Mat4d::zrotation // The ZL texture has its bright spot in the winter solstice
(solarLongitude); point.
// The computation here returns solar longitude for Earth, a
nd antilongitude for the Moon, therefore we either add or subtract pi/2.
double lambdaSun;
if (core->getCurrentLocation().planetName=="Earth")
{
double eclJDE = GETSTELMODULE(SolarSystem)->getEarth
()->getRotObliquity(core->getJDE());
double ra_equ, dec_equ, betaJDE;
StelUtils::rectToSphe(&ra_equ,&dec_equ,GETSTELMODULE
(SolarSystem)->getSun()->getEquinoxEquatorialPos(core));
StelUtils::equToEcl(ra_equ, dec_equ, eclJDE, &lambda
Sun, &betaJDE);
lambdaSun+= M_PI*0.5;
}
else
{
Vec3d obsPos=core->getObserverHeliocentricEclipticPo
s();
lambdaSun=atan2(obsPos[1], obsPos[0]) -M_PI*0.5;
}
Mat4d rotMat=Mat4d::zrotation(lambdaSun);
for (int i=0; i<eclipticalVertices.size(); ++i) for (int i=0; i<eclipticalVertices.size(); ++i)
{ {
Vec3d tmp=eclipticalVertices.at(i); Vec3d tmp=eclipticalVertices.at(i);
vertexArray->vertex.replace(i, transMat * tmp); vertexArray->vertex.replace(i, rotMat * tmp);
} }
lastJD=currentJD; lastJD=currentJD;
} }
} }
/************************************************************************* /*************************************************************************
Reimplementation of the getCallOrder method Reimplementation of the getCallOrder method
*************************************************************************/ *************************************************************************/
double ZodiacalLight::getCallOrder(StelModuleActionName actionName) const double ZodiacalLight::getCallOrder(StelModuleActionName actionName) const
{ {
skipping to change at line 139 skipping to change at line 166
{ {
return *fader; return *fader;
} }
void ZodiacalLight::draw(StelCore* core) void ZodiacalLight::draw(StelCore* core)
{ {
if (!getFlagShow() || (getIntensity()<0.01) ) if (!getFlagShow() || (getIntensity()<0.01) )
return; return;
// Test if we are not on Earth. Texture would not fit, so don't draw then. // Test if we are not on Earth. Texture would not fit, so don't draw then.
if (core->getCurrentLocation().planetName != "Earth") return; if (! QString("Earth Moon").contains(core->getCurrentLocation().plan etName)) return;
StelSkyDrawer *drawer=core->getSkyDrawer(); StelSkyDrawer *drawer=core->getSkyDrawer();
int bortle=drawer->getBortleScaleIndex(); int bortle=drawer->getBortleScaleIndex();
// Test for light pollution, return if too bad. // Test for light pollution, return if too bad.
if ( (drawer->getFlagHasAtmosphere()) && (bortle > 5) ) return; if ( (drawer->getFlagHasAtmosphere()) && (bortle > 5) ) return;
StelProjector::ModelViewTranformP transfo = core->getJ2000ModelViewT // The ZL is best observed from Earth only. On the Moon, we must be
ransform(); happy with ZL along the J2000 ecliptic. (Sorry for LP:1628765, I don't find
a general solution.)
StelProjector::ModelViewTranformP transfo;
if (core->getCurrentLocation().planetName == "Earth")
transfo = core->getObservercentricEclipticOfDateModelViewTra
nsform();
else
transfo = core->getObservercentricEclipticJ2000ModelViewTran
sform();
const StelProjectorP prj = core->getProjection(transfo); const StelProjectorP prj = core->getProjection(transfo);
StelToneReproducer* eye = core->getToneReproducer(); StelToneReproducer* eye = core->getToneReproducer();
Q_ASSERT(tex); // A texture must be loaded before calling this Q_ASSERT(tex); // A texture must be loaded before calling this
// Default ZL color is white (sunlight) // Default ZL color is white (sunlight), or whatever has been set e.
Vec3f c = Vec3f(1.0f, 1.0f, 1.0f); g. by script.
Vec3f c = color;
// ZL is quite sensitive to light pollution. I scale to make it less visible. // ZL is quite sensitive to light pollution. I scale to make it less visible.
float lum = drawer->surfacebrightnessToLuminance(13.5f + 0.5f*bortle ); // (8.0f + 0.5*bortle); float lum = drawer->surfacebrightnessToLuminance(13.5f + 0.5f*bortle ); // (8.0f + 0.5*bortle);
// Get the luminance scaled between 0 and 1 // Get the luminance scaled between 0 and 1
float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate()); float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate());
// Bound a maximum luminance // Bound a maximum luminance
aLum = qMin(0.15f, aLum*2.f); // 2*aLum at dark sky with mag13.5 at Bortle=1 gives 0.13 aLum = qMin(0.15f, aLum*2.f); // 2*aLum at dark sky with mag13.5 at Bortle=1 gives 0.13
//qDebug() << "aLum=" << aLum; //qDebug() << "aLum=" << aLum;
// intensity of 1.0 is "proper", but allow boost for dim screens // intensity of 1.0 is "proper", but allow boost for dim screens
c*=aLum*intensity; c*=aLum*intensity;
// // In brighter twilight we should tune brightness down. So for sun a
bove -18 degrees, we must tweak here:
// const Vec3d& sunPos = GETSTELMODULE(SolarSystem)->getSun()->getAltAz
PosGeometric(core);
// if (drawer->getFlagHasAtmosphere())
// {
// if (sunPos[2] > -0.1) return; // Make ZL invisible during ci
vil twilight and daylight.
// if (sunPos[2] > -0.3)
// { // scale twilight down for sun altitude -18..-6, i.e. scal
e -0.3..-0.1 to 1..0,
// float twilightScale= -5.0f* (sunPos[2]+0.1) ; // 0(
if bright)..1(dark)
// c*=twilightScale;
// }
// }
// Better: adapt brightness by atmospheric brightness // Better: adapt brightness by atmospheric brightness
const float atmLum = GETSTELMODULE(LandscapeMgr)->getAtmosphereAvera geLuminance(); const float atmLum = GETSTELMODULE(LandscapeMgr)->getAtmosphereAvera geLuminance();
if (atmLum>0.05f) return; // 10cd/m^2 at sunset, 3.3 at civil twilig ht (sun at -6deg). 0.0145 sun at -12, 0.0004 sun at -18, 0.01 at Full Moon !? if (atmLum>0.05f) return; // 10cd/m^2 at sunset, 3.3 at civil twilig ht (sun at -6deg). 0.0145 sun at -12, 0.0004 sun at -18, 0.01 at Full Moon !?
//qDebug() << "AtmLum: " << atmLum; //qDebug() << "AtmLum: " << atmLum;
float atmFactor=20.0f*(0.05f-atmLum); float atmFactor=20.0f*(0.05f-atmLum);
Q_ASSERT(atmFactor<=1.0f); Q_ASSERT(atmFactor<=1.0f);
Q_ASSERT(atmFactor>=0.0f); Q_ASSERT(atmFactor>=0.0f);
c*=atmFactor*atmFactor; c*=atmFactor*atmFactor;
if (c[0]<0) c[0]=0; if (c[0]<0) c[0]=0;
skipping to change at line 218 skipping to change at line 238
extinction.forward(vertAltAz, &oneMag); extinction.forward(vertAltAz, &oneMag);
float extinctionFactor=std::pow(0.4f , oneMag)/bortl e; // drop of one magnitude: factor 2.5 or 40%, and further reduced by ligh t pollution float extinctionFactor=std::pow(0.4f , oneMag)/bortl e; // drop of one magnitude: factor 2.5 or 40%, and further reduced by ligh t pollution
Vec3f thisColor=Vec3f(c[0]*extinctionFactor, c[1]*ex tinctionFactor, c[2]*extinctionFactor); Vec3f thisColor=Vec3f(c[0]*extinctionFactor, c[1]*ex tinctionFactor, c[2]*extinctionFactor);
vertexArray->colors.append(thisColor); vertexArray->colors.append(thisColor);
} }
} }
else else
vertexArray->colors.fill(Vec3f(c[0], c[1], c[2])); vertexArray->colors.fill(Vec3f(c[0], c[1], c[2]));
StelPainter sPainter(prj); StelPainter sPainter(prj);
glEnable(GL_CULL_FACE); sPainter.setCullFace(true);
sPainter.enableTexture2d(true); sPainter.setBlending(true, GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
tex->bind(); tex->bind();
sPainter.drawStelVertexArray(*vertexArray); sPainter.drawStelVertexArray(*vertexArray);
glDisable(GL_CULL_FACE); sPainter.setCullFace(false);
} }
 End of changes. 12 change blocks. 
40 lines changed or deleted 65 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/