Added lunar eclipses back.

This commit is contained in:
Jonathas Costa
2017-10-19 11:41:36 -04:00
parent 6fdb587cca
commit a925d0646a
15 changed files with 308 additions and 59 deletions
@@ -1,4 +1,4 @@
/*****************************************************************************************
/*****************************************************************************************
* *
* OpenSpace *
* *
@@ -32,6 +32,11 @@
#include <modules/globebrowsing/rendering/layer/layergroup.h>
#include <modules/globebrowsing/tile/rawtiledatareader/rawtiledatareader.h>
#include <openspace/util/updatestructures.h>
#include <openspace/util/spicemanager.h>
namespace {
const double KM_TO_M = 1000.0;
}
namespace openspace::globebrowsing {
@@ -111,6 +116,93 @@ ghoul::opengl::ProgramObject* ChunkRenderer::getActivatedProgramWithTileData(
return programObject;
}
void ChunkRenderer::calculateEclipseShadows(const Chunk& chunk, ghoul::opengl::ProgramObject* programObject,
const RenderData& data) {
// Shadow calculations..
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
std::vector<RenderableGlobe::ShadowRenderingStruct> shadowDataArray;
std::vector<Ellipsoid::ShadowConfiguration> shadowConfArray = chunk.owner().ellipsoid().shadowConfigurationArray();
shadowDataArray.reserve(shadowConfArray.size());
double lt;
for (const auto & shadowConf : shadowConfArray) {
// TO REMEMBER: all distances and lengths in world coordinates are in meters!!! We need to move this to view space...
// Getting source and caster:
glm::dvec3 sourcePos = SpiceManager::ref().targetPosition(shadowConf.source.first, "SUN", "GALACTIC", {},
data.time.j2000Seconds(), lt);
sourcePos *= KM_TO_M; // converting to meters
glm::dvec3 casterPos = SpiceManager::ref().targetPosition(shadowConf.caster.first, "SUN", "GALACTIC", {},
data.time.j2000Seconds(), lt);
casterPos *= KM_TO_M; // converting to meters
psc caster_pos = PowerScaledCoordinate::CreatePowerScaledCoordinate(casterPos.x, casterPos.y, casterPos.z);
// First we determine if the caster is shadowing the current planet (all calculations in World Coordinates):
glm::dvec3 planetCasterVec = casterPos - data.position.dvec3();
glm::dvec3 sourceCasterVec = casterPos - sourcePos;
double sc_length = glm::length(sourceCasterVec);
glm::dvec3 planetCaster_proj = (glm::dot(planetCasterVec, sourceCasterVec) / (sc_length*sc_length)) * sourceCasterVec;
double d_test = glm::length(planetCasterVec - planetCaster_proj);
double xp_test = shadowConf.caster.second * sc_length / (shadowConf.source.second + shadowConf.caster.second);
double rp_test = shadowConf.caster.second * (glm::length(planetCaster_proj) + xp_test) / xp_test;
glm::dvec3 sunPos = SpiceManager::ref().targetPosition("SUN", "SUN", "GALACTIC", {}, data.time.j2000Seconds(), lt);
double casterDistSun = glm::length(casterPos - sunPos);
double planetDistSun = glm::length(data.position.dvec3() - sunPos);
RenderableGlobe::ShadowRenderingStruct shadowData;
shadowData.isShadowing = false;
// Eclipse shadows considers planets and moons as spheres
if (((d_test - rp_test) < (chunk.owner().ellipsoid().radii().x * KM_TO_M)) &&
(casterDistSun < planetDistSun)) {
// The current caster is shadowing the current planet
shadowData.isShadowing = true;
shadowData.rs = shadowConf.source.second;
shadowData.rc = shadowConf.caster.second;
shadowData.sourceCasterVec = glm::normalize(sourceCasterVec);
shadowData.xp = xp_test;
shadowData.xu = shadowData.rc * sc_length / (shadowData.rs - shadowData.rc);
shadowData.casterPositionVec = casterPos;
}
shadowDataArray.push_back(shadowData);
}
const std::string uniformVarName("shadowDataArray[");
unsigned int counter = 0;
for (const auto & sd : shadowDataArray) {
std::stringstream ss;
ss << uniformVarName << counter << "].isShadowing";
programObject->setUniform(ss.str(), sd.isShadowing);
if (sd.isShadowing) {
ss.str(std::string());
ss << uniformVarName << counter << "].xp";
programObject->setUniform(ss.str(), sd.xp);
ss.str(std::string());
ss << uniformVarName << counter << "].xu";
programObject->setUniform(ss.str(), sd.xu);
/*ss.str(std::string());
ss << uniformVarName << counter << "].rs";
programObject->setUniform(ss.str(), sd.rs);*/
ss.str(std::string());
ss << uniformVarName << counter << "].rc";
programObject->setUniform(ss.str(), sd.rc);
ss.str(std::string());
ss << uniformVarName << counter << "].sourceCasterVec";
programObject->setUniform(ss.str(), sd.sourceCasterVec);
ss.str(std::string());
ss << uniformVarName << counter << "].casterPositionVec";
programObject->setUniform(ss.str(), sd.casterPositionVec);
}
counter++;
}
programObject->setUniform("inverseViewTransform", glm::inverse(data.camera.combinedViewMatrix()));
programObject->setUniform("modelTransform", chunk.owner().modelTransform());
programObject->setUniform("hardShadows", chunk.owner().generalProperties().eclipseHardShadows);
programObject->setUniform("calculateEclipseShadows", true);
}
}
void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
const Chunk& chunk, const RenderData& data)
{
@@ -250,6 +342,10 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da
setCommonUniforms(*programObject, chunk, data);
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
calculateEclipseShadows(chunk, programObject, data);
}
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
@@ -341,7 +437,9 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat
setCommonUniforms(*programObject, chunk, data);
if (chunk.owner().ellipsoid().hasEclipseShadows()) {
calculateEclipseShadows(chunk, programObject, data);
}
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);