bool SkyQPainter::drawPlanet(KSPlanetBase* planet) { if( !m_proj->checkVisibility(planet) ) return false; bool visible = false; QPointF pos = m_proj->toScreen(planet,true,&visible); if( !visible || !m_proj->onScreen(pos) ) return false; float fakeStarSize = ( 10.0 + log10( Options::zoomFactor() ) - log10( MINZOOM ) ) * ( 10 - planet->mag() ) / 10; if( fakeStarSize > 15.0 ) fakeStarSize = 15.0; float size = planet->angSize() * dms::PI * Options::zoomFactor()/10800.0; if( size < fakeStarSize && planet->name() != "Sun" && planet->name() != "Moon" ) { // Draw them as bright stars of appropriate color instead of images char spType; //FIXME: do these need i18n? if( planet->name() == i18n("Mars") ) { spType = 'K'; } else if( planet->name() == i18n("Jupiter") || planet->name() == i18n("Mercury") || planet->name() == i18n("Saturn") ) { spType = 'F'; } else { spType = 'B'; } drawPointSource(pos,fakeStarSize,spType); } else { float sizemin = 1.0; if( planet->name() == "Sun" || planet->name() == "Moon" ) sizemin = 8.0; float size = planet->angSize() * dms::PI * Options::zoomFactor()/10800.0; if( size < sizemin ) size = sizemin; if( Options::showPlanetImages() && !planet->image().isNull() ) { //Because Saturn has rings, we inflate its image size by a factor 2.5 if( planet->name() == "Saturn" ) size = int(2.5*size); // Scale size exponentially so it is visible at large zooms else if (planet->name() == "Pluto") size = int(size*exp(1.5*size)); save(); translate(pos); rotate( m_proj->findPA( planet, pos.x(), pos.y() ) ); drawImage( QRect(-0.5*size, -0.5*size, size, size), planet->image() ); restore(); } else { //Otherwise, draw a simple circle. drawEllipse( pos, size, size ); } } return true; }
bool SkyQPainter::drawPointSource(SkyPoint* loc, float mag, char sp) { //Check if it's even visible before doing anything if( !m_proj->checkVisibility(loc) ) return false; bool visible = false; QPointF pos = m_proj->toScreen(loc,true,&visible); if( visible && m_proj->onScreen(pos) ) { // FIXME: onScreen here should use canvas size rather than SkyMap size, especially while printing in portrait mode! drawPointSource(pos, starWidth(mag), sp); return true; } else { return false; } }
// Terminate drawing of a 3D model, draw the halo void StelSkyDrawer::postDrawSky3dModel(StelPainter* painter, const Vec3f& v, float illuminatedArea, float mag, const Vec3f& color) { const float pixPerRad = painter->getProjector()->getPixelPerRadAtCenter(); // Assume a disk shape float pixRadius = std::sqrt(illuminatedArea/(60.*60.)*M_PI/180.*M_PI/180.*(pixPerRad*pixPerRad))/M_PI; bool noStarHalo = false; if (mag<-15.f) { // Sun, halo size varies in function of the magnitude because sun as seen from pluto should look dimmer // as the sun as seen from earth texSunHalo->bind(); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); painter->enableTexture2d(true); float rmag = big3dModelHaloRadius*(mag+15.f)/-11.f; float cmag = 1.f; if (rmag<pixRadius*3.f+100.) cmag = qMax(0.f, 1.f-(pixRadius*3.f+100-rmag)/100); Vec3f win; painter->getProjector()->project(v, win); painter->setColor(color[0]*cmag, color[1]*cmag, color[2]*cmag); painter->drawSprite2dModeNoDeviceScale(win[0], win[1], rmag); noStarHalo = true; } // Now draw the halo according the object brightness bool save = flagStarTwinkle; flagStarTwinkle = false; RCMag rcm; computeRCMag(mag, &rcm); // We now have the radius and luminosity of the small halo // If the disk of the planet is big enough to be visible, we should adjust the eye adaptation luminance // so that the radius of the halo is small enough to be not visible (so that we see the disk) float tStart = 2.f; float tStop = 6.f; bool truncated=false; float maxHaloRadius = qMax(tStart*3., pixRadius*3.); if (rcm.radius>maxHaloRadius) { truncated = true; rcm.radius=maxHaloRadius+std::sqrt(rcm.radius-maxHaloRadius); } // Fade the halo away when the disk is too big if (pixRadius>=tStop) { rcm.luminance=0.f; } if (pixRadius>tStart && pixRadius<tStop) { rcm.luminance=(tStop-pixRadius)/(tStop-tStart); } if (truncated && flagLuminanceAdaptation) { float wl = findWorldLumForMag(mag, rcm.radius); if (wl>0) { const float f = core->getMovementMgr()->getCurrentFov(); reportLuminanceInFov(qMin(700.f, qMin(wl/50, (60.f*60.f)/(f*f)*6.f))); } } if (!noStarHalo) { preDrawPointSource(painter); drawPointSource(painter, v, rcm, color); postDrawPointSource(painter); } flagStarTwinkle=save; }