void Comet::drawComa(StelCore* core, StelProjector::ModelViewTranformP transfo) { // Find rotation matrix from 0/0/1 to viewdirection! crossproduct for axis (normal vector), dotproduct for angle. Vec3d eclposNrm=eclipticPos - core->getObserverHeliocentricEclipticPos() ; eclposNrm.normalize(); Mat4d comarot=Mat4d::rotation(Vec3d(0.0, 0.0, 1.0)^(eclposNrm), std::acos(Vec3d(0.0, 0.0, 1.0).dot(eclposNrm)) ); StelProjector::ModelViewTranformP transfo2 = transfo->clone(); transfo2->combine(comarot); StelPainter* sPainter = new StelPainter(core->getProjection(transfo2)); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_CULL_FACE); // GZ: For the coma, we can use extinction via atmosphere. // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. float minSkyMag=core->getSkyDrawer()->getLimitMagnitude(); float mag100pct=minSkyMag-6.0f; // should be 5, but let us draw it a bit brighter. float magDrop=getVMagnitudeWithExtinction(core)-mag100pct; float magFactor=std::pow(0.6f , magDrop); magFactor=qMin(magFactor, 2.0f); // Limit excessively bright display. comaTexture->bind(); sPainter->setColor(magFactor,magFactor,0.6f*magFactor); sPainter->setArrays((Vec3d*)comaVertexArr.constData(), (Vec2f*)comaTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, comaVertexArr.size()/3); glDisable(GL_BLEND); if (sPainter) delete sPainter; sPainter=NULL; }
void Comet::drawTail(StelCore* core, StelProjector::ModelViewTranformP transfo, bool gas) { // Find rotation matrix from 0/0/1 to eclipticPosition: crossproduct for axis (normal vector), dotproduct for angle. Vec3d eclposNrm=eclipticPos; eclposNrm.normalize(); Mat4d tailrot=Mat4d::rotation(Vec3d(0.0, 0.0, 1.0)^(eclposNrm), std::acos(Vec3d(0.0, 0.0, 1.0).dot(eclposNrm)) ); StelProjector::ModelViewTranformP transfo2 = transfo->clone(); transfo2->combine(tailrot); if (!gas) { CometOrbit* orbit=(CometOrbit*)userDataPtr; Vec3d velocity=orbit->getVelocity(); // [AU/d] // This was a try to rotate a straight parabola somewhat away from the antisolar direction. //Mat4d dustTailRot=Mat4d::rotation(eclposNrm^(-velocity), 0.15f*std::acos(eclposNrm.dot(-velocity))); // GZ: This scale factor of 0.15 is empirical from photos of Halley and Hale-Bopp. // The curved tail is curved towards positive X. We first rotate around the Z axis into a direction opposite of the motion vector, then again the antisolar rotation applies. Mat4d dustTailRot=Mat4d::zrotation(atan2(velocity[1], velocity[0]) + M_PI); transfo2->combine(dustTailRot); // In addition, we let the dust tail already start with a light tilt. Mat4d dustTailYrot=Mat4d::yrotation(5.0f*velocity.length()); // again, this is pretty ad-hoc, feel free to improve! transfo2->combine(dustTailYrot); } StelPainter* sPainter = new StelPainter(core->getProjection(transfo2)); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_CULL_FACE); // GZ: If we use getVMagnitudeWithExtinction(), a head extincted in the horizon mist can completely hide an otherwise frighteningly long tail. // we must use unextincted mag, but mix/dim with atmosphere/sky brightness. // In addition, light falloff is a bit reduced for better visibility. Power basis should be 0.4, we use 0.6. //float magfactor=std::pow(0.4f , getVMagnitudeWithExtinction(core)); float magFactor=std::pow(0.6f , getVMagnitude(core)); if (core->getSkyDrawer()->getFlagHasAtmosphere()) { // Mix with sky brightness and light pollution: This is very ad-hoc, if someone finds a better solution, please go ahead! // Light pollution: float bortleIndexFactor=0.1f * (11 - core->getSkyDrawer()->getBortleScaleIndex()); magFactor*= bortleIndexFactor*bortleIndexFactor; // GZ-Guesstimate for light pollution influence // sky brightness: This is about 10 for twilight where bright comet tails should already be visible. Dark night is close to 0. float avgAtmLum=GETSTELMODULE(LandscapeMgr)->getAtmosphereAverageLuminance(); float atmLumFactor=(15.0f-avgAtmLum)/15.0f; if (atmLumFactor<0.05f) atmLumFactor=0.05f; //atmLumFactor=std::sqrt(atmLumFactor); magFactor*=atmLumFactor*atmLumFactor; } magFactor*=(gas? 0.9 : dustTailBrightnessFactor); // TBD: empirical adjustment for texture brightness. magFactor=qMin(magFactor, 1.05f); // Limit excessively bright display. gasTailTexture->bind(); if (gas) { //gasTailTexture->bind(); sPainter->setColor(0.15f*magFactor,0.15f*magFactor,0.6f*magFactor); sPainter->setArrays((Vec3d*)gastailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } else { //dustTailTexture->bind(); sPainter->setColor(magFactor, magFactor,0.6f*magFactor); //sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)dusttailTexCoordArr.constData()); //sPainter->drawFromArray(StelPainter::Triangles, dusttailIndices.size(), 0, true, dusttailIndices.constData()); sPainter->setArrays((Vec3d*)dusttailVertexArr.constData(), (Vec2f*)gastailTexCoordArr.constData()); sPainter->drawFromArray(StelPainter::Triangles, gastailIndices.size(), 0, true, gastailIndices.constData()); } glDisable(GL_BLEND); if (sPainter) delete sPainter; sPainter=NULL; }