From d2ebde282ba583675158d96956652c89b14aa0e2 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sat, 18 May 2019 15:34:42 -0400 Subject: [PATCH 001/214] Bring back stars to the Earth's night. --- .../shaders/atmosphere_deferred_fs.glsl | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index 74a4282642..d384406668 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -294,7 +294,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor const vec3 v, const vec3 s, out float r, out float mu, out vec3 attenuation, const vec3 fragPosObj, out bool groundHit, const double maxLength, const double pixelDepth, - const vec4 spaceColor, const float sunIntensity) { + const vec4 spaceColor, const float sunIntensity, const vec3 normal) { const float INTERPOLATION_EPS = 0.004f; // precision const from Brunetton @@ -315,8 +315,8 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor // through the atmosphere. If this ray hits something inside the atmosphere, // we will subtract the attenuated scattering light from that path in the // current path. - vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0); - + vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0); + // After removing the initial path from camera pos to top of atmosphere (for an // observer in the space) we test if the light ray is hitting the atmosphere vec3 x0 = fragPosObj; @@ -363,7 +363,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if (abs(mu - muHorizon) < INTERPOLATION_EPS) { // We want an interpolation value close to 1/2, so the // contribution of each radiance value is almost the same - // or it has a havey weight if from above or below horizon + // or it has a hevy weight if from above or below horizon float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS); //float t2 = t * t; @@ -427,7 +427,14 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if (groundHit) { return finalScatteringRadiance; } else { - return ((r-Rg) * invRtMinusRg)*spaceColor.rgb * backgroundConstant + finalScatteringRadiance; + // Linearizing the stars contribution based on the observer's position (height) + float cosTheta = dot(normalize(x0), normalize(s)); + float cosPhi = dot(normalize(v), normalize(s)); + if (cosTheta == 0.0 && cosPhi < 0.6) { + return spaceColor.rgb * backgroundConstant + finalScatteringRadiance; + } else { + return ((r-Rg) * invRtMinusRg) * spaceColor.rgb * backgroundConstant + finalScatteringRadiance; + } } } @@ -564,7 +571,6 @@ void main() { //float Rt2 = Rt * Rt; // in Km //float Rg2 = Rg * Rg; // in Km - for (int i = 0; i < nSamples; i++) { // Color from G-Buffer //vec4 color = texelFetch(mainColorTexture, fragCoords, i); @@ -667,7 +673,8 @@ void main() { s, r, mu, attenuation, vec3(positionObjectsCoords.xyz), groundHit, maxLength, pixelDepth, - color, sunIntensityInscatter); + color, sunIntensityInscatter, + normal.xyz); vec3 groundColorV = vec3(0.0); vec3 sunColorV = vec3(0.0); if (groundHit) { @@ -712,7 +719,6 @@ void main() { discard; } //renderTarget = vec4(1.0, 0.0, 0.0, 1.0); - } } From 447f68c3d61d7d3972d233b29a12c185f31f85a8 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sun, 19 May 2019 14:41:55 -0400 Subject: [PATCH 002/214] Physically attenuated night light. --- .../atmosphere/shaders/atmosphere_deferred_fs.glsl | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index d384406668..cb654122dd 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -427,14 +427,9 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if (groundHit) { return finalScatteringRadiance; } else { - // Linearizing the stars contribution based on the observer's position (height) - float cosTheta = dot(normalize(x0), normalize(s)); - float cosPhi = dot(normalize(v), normalize(s)); - if (cosTheta == 0.0 && cosPhi < 0.6) { - return spaceColor.rgb * backgroundConstant + finalScatteringRadiance; - } else { - return ((r-Rg) * invRtMinusRg) * spaceColor.rgb * backgroundConstant + finalScatteringRadiance; - } + // The final color is given by the attenuated light arriving at the observer's eye + // plus the scattered light in the atmosphere (only inscattered light taken into account here) + return attenuation * (spaceColor.rgb * backgroundConstant) + finalScatteringRadiance; } } From 5c65801bd93a073628b71afadc4c67eedb29078b Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 20 Aug 2019 23:03:49 -0400 Subject: [PATCH 003/214] Testing new AA algorithm for current lines. --- modules/base/rendering/renderabletrail.cpp | 10 ++++++++-- modules/base/rendering/renderabletrail.h | 3 ++- modules/base/shaders/renderabletrail_fs.glsl | 13 +++++++++++++ modules/base/shaders/renderabletrail_vs.glsl | 6 ++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 4ff75279d2..fef6669dc5 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -38,10 +38,10 @@ namespace { constexpr const char* ProgramName = "EphemerisProgram"; constexpr const char* KeyTranslation = "Translation"; - constexpr const std::array UniformNames = { + constexpr const std::array UniformNames = { "opacity", "modelViewTransform", "projectionTransform", "color", "useLineFade", "lineFade", "vertexSortingMethod", "idOffset", "nVertices", "stride", "pointSize", - "renderPhase" + "renderPhase", "resolution" }; // The possible values for the _renderingModes property @@ -301,6 +301,9 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { _programObject->setUniform(_uniformCache.lineFade, _appearance.lineFade); } + /*glm::ivec2 resolution = global::renderEngine.renderingResolution(); + _programObject->setUniform(_uniformCache.resolution, resolution);*/ + static std::map SortingMapping = { // Fragile! Keep in sync with shader { RenderInformation::VertexSorting::NewestFirst, 0 }, @@ -352,6 +355,9 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { p->setUniform(c.nVertices, nVertices); + glm::ivec2 resolution = global::renderEngine.renderingResolution(); + p->setUniform(c.resolution, resolution); + if (renderPoints) { // The stride parameter determines the distance between larger points and // smaller ones diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index 68adcf8e8b..3704f186af 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -182,7 +182,8 @@ private: ghoul::opengl::ProgramObject* _programObject = nullptr; UniformCache(opacity, modelView, projection, color, useLineFade, lineFade, - vertexSorting, idOffset, nVertices, stride, pointSize, renderPhase) _uniformCache; + vertexSorting, idOffset, nVertices, stride, pointSize, renderPhase, + resolution) _uniformCache; }; } // namespace openspace diff --git a/modules/base/shaders/renderabletrail_fs.glsl b/modules/base/shaders/renderabletrail_fs.glsl index 4482761a7e..54d20c21e6 100644 --- a/modules/base/shaders/renderabletrail_fs.glsl +++ b/modules/base/shaders/renderabletrail_fs.glsl @@ -28,6 +28,7 @@ in vec4 vs_positionScreenSpace; in vec4 vs_gPosition; in float fade; in float v_pointSize; +in vec2 lineCenterArray; uniform vec3 color; uniform int renderPhase; @@ -60,6 +61,18 @@ Fragment getFragment() { frag.color.a = transparencyCorrection; } + double distanceCenter = length(lineCenterArray - vec2(gl_FragCoord.xy)); + double lineWidth = 1E20;//4.0; + float blendFactor = 1.5; + //if (distanceCenter > lineWidth) { + // if (distanceCenter > 1E20) { + // frag.color = vec4(1.0, 0.0, 0.0, 1.0); + // //frag.color.w = 0; + // } else { + frag.color.w = pow( float((lineWidth - distanceCenter) / lineWidth), blendFactor); + //frag.color.w = 1.0; + //} + frag.gPosition = vs_gPosition; // There is no normal here diff --git a/modules/base/shaders/renderabletrail_vs.glsl b/modules/base/shaders/renderabletrail_vs.glsl index 49af45b2ce..b4b6e44bf4 100644 --- a/modules/base/shaders/renderabletrail_vs.glsl +++ b/modules/base/shaders/renderabletrail_vs.glsl @@ -32,6 +32,7 @@ out vec4 vs_positionScreenSpace; out vec4 vs_gPosition; out float fade; out float v_pointSize; +out vec2 lineCenterArray; uniform dmat4 modelViewTransform; uniform mat4 projectionTransform; @@ -43,6 +44,8 @@ uniform int vertexSortingMethod; uniform int pointSize; uniform int stride; +uniform ivec2 resolution; + // Fragile! Keep in sync with RenderableTrail::render #define VERTEX_SORTING_NEWESTFIRST 0 #define VERTEX_SORTING_OLDESTFIRST 1 @@ -78,4 +81,7 @@ void main() { gl_PointSize = (stride == 1 || int(modId) % stride == 0) ? float(pointSize) : float(pointSize) / 2; v_pointSize = gl_PointSize; gl_Position = vs_positionScreenSpace; + + vec2 vp = vec2(resolution); + lineCenterArray = 0.5 * (vs_positionScreenSpace.xy + vec2(1.0)) * vp; } From 805401c40961df067f9e36f85f264a3a5953e315 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 22 Aug 2019 11:18:21 -0400 Subject: [PATCH 004/214] Testing... --- modules/base/rendering/renderabletrail.cpp | 16 +++++----- modules/base/rendering/renderabletrail.h | 2 +- modules/base/shaders/renderabletrail_fs.glsl | 30 ++++++++++--------- modules/base/shaders/renderabletrail_vs.glsl | 20 ++++++------- .../digitaluniverse/shaders/billboard_fs.glsl | 3 +- 5 files changed, 36 insertions(+), 35 deletions(-) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 049736d998..14386c35d2 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -38,10 +38,10 @@ namespace { constexpr const char* ProgramName = "EphemerisProgram"; constexpr const char* KeyTranslation = "Translation"; - constexpr const std::array UniformNames = { + constexpr const std::array UniformNames = { "opacity", "modelViewTransform", "projectionTransform", "color", "useLineFade", "lineFade", "vertexSortingMethod", "idOffset", "nVertices", "stride", "pointSize", - "renderPhase", "resolution" + "renderPhase", "resolution", "lineWidth" }; // The possible values for the _renderingModes property @@ -327,14 +327,15 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { (_appearance.renderingModes == RenderingModeLinesPoints); if (renderLines) { - glLineWidth(_appearance.lineWidth); + glLineWidth(ceil((2.f * 1.f + _appearance.lineWidth) * std::sqrt(2.f))); } if (renderPoints) { glEnable(GL_PROGRAM_POINT_SIZE); } auto render = [renderLines, renderPoints, p = _programObject, &data, - &modelTransform, pointSize = _appearance.pointSize.value(), c = _uniformCache] + &modelTransform, pointSize = _appearance.pointSize.value(), + c = _uniformCache, lw = _appearance.lineWidth] (RenderInformation& info, int nVertices, int offset) { // We pass in the model view transformation matrix as double in order to maintain @@ -357,7 +358,9 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { glm::ivec2 resolution = global::renderEngine.renderingResolution(); p->setUniform(c.resolution, resolution); - + + p->setUniform(c.lineWidth, ceil((2.f * 1.f + lw) * std::sqrt(2.f))); + if (renderPoints) { // The stride parameter determines the distance between larger points and // smaller ones @@ -373,8 +376,6 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { glBindVertexArray(info._vaoID); if (renderLines) { - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); p->setUniform(c.renderPhase, RenderPhaseLines); // Subclasses of this renderer might be using the index array or might now be // so we check if there is data available and if there isn't, we use the @@ -394,7 +395,6 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { reinterpret_cast(info.first * sizeof(unsigned int)) ); } - glDisable(GL_LINE_SMOOTH); } if (renderPoints) { // Subclasses of this renderer might be using the index array or might now be diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index 3704f186af..1507f7e4a8 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -183,7 +183,7 @@ private: UniformCache(opacity, modelView, projection, color, useLineFade, lineFade, vertexSorting, idOffset, nVertices, stride, pointSize, renderPhase, - resolution) _uniformCache; + resolution, lineWidth) _uniformCache; }; } // namespace openspace diff --git a/modules/base/shaders/renderabletrail_fs.glsl b/modules/base/shaders/renderabletrail_fs.glsl index 54d20c21e6..a89c32adb0 100644 --- a/modules/base/shaders/renderabletrail_fs.glsl +++ b/modules/base/shaders/renderabletrail_fs.glsl @@ -24,15 +24,15 @@ #include "fragment.glsl" -in vec4 vs_positionScreenSpace; +in float vs_positionDepth; in vec4 vs_gPosition; in float fade; -in float v_pointSize; -in vec2 lineCenterArray; +in vec2 mathLine; uniform vec3 color; uniform int renderPhase; uniform float opacity = 1.0; +uniform float lineWidth; // Fragile! Keep in sync with RenderableTrail::render::RenderPhase #define RenderPhaseLines 0 @@ -44,7 +44,7 @@ uniform float opacity = 1.0; Fragment getFragment() { Fragment frag; frag.color = vec4(color * fade, fade * opacity); - frag.depth = vs_positionScreenSpace.w; + frag.depth = vs_positionDepth; frag.blend = BLEND_MODE_ADDITIVE; if (renderPhase == RenderPhasePoints) { @@ -61,17 +61,19 @@ Fragment getFragment() { frag.color.a = transparencyCorrection; } - double distanceCenter = length(lineCenterArray - vec2(gl_FragCoord.xy)); - double lineWidth = 1E20;//4.0; + double distanceCenter = length(mathLine - vec2(gl_FragCoord.xy)); + double dLW = double(lineWidth); float blendFactor = 1.5; - //if (distanceCenter > lineWidth) { - // if (distanceCenter > 1E20) { - // frag.color = vec4(1.0, 0.0, 0.0, 1.0); - // //frag.color.w = 0; - // } else { - frag.color.w = pow( float((lineWidth - distanceCenter) / lineWidth), blendFactor); - //frag.color.w = 1.0; - //} + if (distanceCenter > dLW) { + frag.color = vec4(1.0, 0.0, 0.0, 1.0); + //frag.color.a = 0; + } else { + frag.color.a *= pow(float((dLW - distanceCenter) / dLW), blendFactor); + //frag.color.a = 1.0; + } + + // if (distanceCenter > 3.0) + // frag.color = vec4(0.0, 1.0, 0.0, 1.0); frag.gPosition = vs_gPosition; diff --git a/modules/base/shaders/renderabletrail_vs.glsl b/modules/base/shaders/renderabletrail_vs.glsl index b4b6e44bf4..d0b3ece155 100644 --- a/modules/base/shaders/renderabletrail_vs.glsl +++ b/modules/base/shaders/renderabletrail_vs.glsl @@ -28,11 +28,10 @@ layout(location = 0) in vec3 in_point_position; -out vec4 vs_positionScreenSpace; +out float vs_positionDepth; out vec4 vs_gPosition; out float fade; -out float v_pointSize; -out vec2 lineCenterArray; +noperspective out vec2 mathLine; uniform dmat4 modelViewTransform; uniform mat4 projectionTransform; @@ -76,12 +75,13 @@ void main() { } vs_gPosition = vec4(modelViewTransform * dvec4(in_point_position, 1)); - vs_positionScreenSpace = z_normalization(projectionTransform * vs_gPosition); + vec4 vs_positionClipSpace = projectionTransform * vs_gPosition; + vec4 vs_positionNDC = vs_positionClipSpace / vs_positionClipSpace.w; + vs_positionDepth = vs_positionClipSpace.w; + + gl_PointSize = (stride == 1 || int(modId) % stride == 0) ? + float(pointSize) : float(pointSize) / 2; + gl_Position = z_normalization(vs_positionClipSpace); - gl_PointSize = (stride == 1 || int(modId) % stride == 0) ? float(pointSize) : float(pointSize) / 2; - v_pointSize = gl_PointSize; - gl_Position = vs_positionScreenSpace; - - vec2 vp = vec2(resolution); - lineCenterArray = 0.5 * (vs_positionScreenSpace.xy + vec2(1.0)) * vp; + mathLine = 0.5 * (vs_positionNDC.xy + vec2(1.0)) * vec2(resolution); } diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 975f76a7be..ecbc3d3a17 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -64,7 +64,6 @@ Fragment getFragment() { // with the ATM. frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); - - + return frag; } \ No newline at end of file From 5708bf84161e4cb75420e6bc1d4c2d088cbc7341 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 23 Aug 2019 16:56:30 -0400 Subject: [PATCH 005/214] New fast AA for lines is working. --- modules/base/rendering/renderabletrail.cpp | 2 +- modules/base/shaders/renderabletrail_fs.glsl | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 0137a5c16c..ef0cea3264 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -178,7 +178,7 @@ RenderableTrail::Appearance::Appearance() , lineColor(LineColorInfo, glm::vec3(1.0f, 1.0f, 0.f), glm::vec3(0.f), glm::vec3(1.f)) , useLineFade(EnableFadeInfo, true) , lineFade(FadeInfo, 1.f, 0.f, 30.f) - , lineWidth(LineWidthInfo, 2.f, 1.f, 20.f) + , lineWidth(LineWidthInfo, 10.f, 1.f, 20.f) , pointSize(PointSizeInfo, 1, 1, 64) , renderingModes( RenderingModeInfo, diff --git a/modules/base/shaders/renderabletrail_fs.glsl b/modules/base/shaders/renderabletrail_fs.glsl index a89c32adb0..d5499dd1bf 100644 --- a/modules/base/shaders/renderabletrail_fs.glsl +++ b/modules/base/shaders/renderabletrail_fs.glsl @@ -27,7 +27,7 @@ in float vs_positionDepth; in vec4 vs_gPosition; in float fade; -in vec2 mathLine; +noperspective in vec2 mathLine; uniform vec3 color; uniform int renderPhase; @@ -63,18 +63,14 @@ Fragment getFragment() { double distanceCenter = length(mathLine - vec2(gl_FragCoord.xy)); double dLW = double(lineWidth); - float blendFactor = 1.5; + float blendFactor = 20; + if (distanceCenter > dLW) { - frag.color = vec4(1.0, 0.0, 0.0, 1.0); - //frag.color.a = 0; + frag.color.a = 0.0; } else { frag.color.a *= pow(float((dLW - distanceCenter) / dLW), blendFactor); - //frag.color.a = 1.0; } - // if (distanceCenter > 3.0) - // frag.color = vec4(0.0, 1.0, 0.0, 1.0); - frag.gPosition = vs_gPosition; // There is no normal here From ee800cee89c92ae9abebe57a4bf205310bc67aa1 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 23 Sep 2019 13:08:23 -0400 Subject: [PATCH 006/214] Fixed star rendering cuts on cubemap borders. --- .../digitaluniverse/shaders/billboard_fs.glsl | 2 +- .../digitaluniverse/shaders/billboard_gs.glsl | 19 +-- modules/space/shaders/star_ge.glsl | 109 ++++-------------- 3 files changed, 38 insertions(+), 92 deletions(-) diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 3ca590e5a5..d2859f1162 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -25,7 +25,7 @@ #include "fragment.glsl" flat in vec4 gs_colorMap; -in float vs_screenSpaceDepth; +flat in float vs_screenSpaceDepth; in vec2 texCoord; in float ta; diff --git a/modules/digitaluniverse/shaders/billboard_gs.glsl b/modules/digitaluniverse/shaders/billboard_gs.glsl index cb955fbc33..4ee3047d28 100644 --- a/modules/digitaluniverse/shaders/billboard_gs.glsl +++ b/modules/digitaluniverse/shaders/billboard_gs.glsl @@ -55,7 +55,7 @@ flat in float dvarScaling[]; flat out vec4 gs_colorMap; out vec2 texCoord; -out float vs_screenSpaceDepth; +flat out float vs_screenSpaceDepth; out float ta; const double PARSEC = 0.308567756e17LF; @@ -171,17 +171,22 @@ void main() { // Build primitive - texCoord = corners[3]; - gl_Position = thirdPosition; - EmitVertex(); + texCoord = corners[0]; gl_Position = initialPosition; EmitVertex(); - texCoord = corners[2]; - gl_Position = crossCorner; - EmitVertex(); + texCoord = corners[1]; gl_Position = secondPosition; EmitVertex(); + + texCoord = corners[3]; + gl_Position = thirdPosition; + EmitVertex(); + + texCoord = corners[2]; + gl_Position = crossCorner; + EmitVertex(); + EndPrimitive(); } \ No newline at end of file diff --git a/modules/space/shaders/star_ge.glsl b/modules/space/shaders/star_ge.glsl index dcb36a5711..d12d51d146 100644 --- a/modules/space/shaders/star_ge.glsl +++ b/modules/space/shaders/star_ge.glsl @@ -83,13 +83,7 @@ void main() { dvec4 dpos = modelMatrix * dvec4(vs_position); dvec4 clipTestPos = cameraViewProjectionMatrix * dpos; - clipTestPos /= clipTestPos.w; - if ((clipTestPos.x < -1.0 || clipTestPos.x > 1.0) || - (clipTestPos.y < -1.0 || clipTestPos.y > 1.0)) - { - return; - } - + ge_bvLumAbsMagAppMag = vs_bvLumAbsMagAppMag[0]; ge_velocity = vs_velocity[0]; ge_speed = vs_speed[0]; @@ -156,96 +150,43 @@ void main() { dvec3 scaledUp = dvec3(0.0); vec4 bottomLeftVertex, bottomRightVertex, topLeftVertex, topRightVertex; - // if (distanceToStarInParsecs > 1800.0) { - // scaledRight = scaleMultiply * invariantRight * 0.5f; - // scaledUp = scaleMultiply * invariantUp * 0.5f; - // } else { - dvec3 normal = normalize(eyePosition - dpos.xyz); - dvec3 newRight = normalize(cross(cameraUp, normal)); - dvec3 newUp = cross(normal, newRight); - scaledRight = scaleMultiply * newRight; - scaledUp = scaleMultiply * newUp; - //} - + dvec3 normal = normalize(eyePosition - dpos.xyz); + dvec3 newRight = normalize(cross(cameraUp, normal)); + dvec3 newUp = cross(normal, newRight); + scaledRight = scaleMultiply * newRight; + scaledUp = scaleMultiply * newUp; + bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); gs_screenSpaceDepth = bottomLeftVertex.w; - topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); + topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * + dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); - // Testing size: - // vec3 tmpPos = vec3(eyePositionDelta); - // vec4 falseBottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(tmpPos - scaledRight - scaledUp, dpos.w))); + bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * + dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - // vec4 falseTopRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(tmpPos + scaledUp + scaledRight, dpos.w))); - // vec2 halfViewSize = vec2(screenSize.x, screenSize.y) * 0.5f; - // vec2 topRight = falseTopRightVertex.xy/falseTopRightVertex.w; - // vec2 bottomLeft = falseBottomLeftVertex.xy/falseBottomLeftVertex.w; - - // Complete algebra - // topRight = ((topRight + vec2(1.0)) * halfViewSize) - vec2(0.5); - // bottomLeft = ((bottomLeft + vec2(1.0)) * halfViewSize) - vec2(0.5); - //vec2 sizes = abs(topRight - bottomLeft); - - // Optimized version - // vec2 sizes = abs(halfViewSize * (topRight - bottomLeft)); - - // float height = sizes.y; - // float width = sizes.x; - - // if ((height > billboardSize) || - // (width > billboardSize)) { - // float correctionScale = height > billboardSize ? billboardSize / height : - // billboardSize / width; - - // scaledRight *= correctionScale; - // scaledUp *= correctionScale; - // bottomLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); - // gs_screenSpaceDepth = bottomLeftVertex.w; - // topRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); - - - // bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - - // topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); - - // } else { - // if (width < 2.0f) { - // float maxVar = 2.0f; - // float minVar = 1.0f; - // float var = (height + width); - // float ta = ( (var - minVar)/(maxVar - minVar) ); - // if (ta == 0.0f) - // return; - // } - // float minSize = 30.f; - // if ((width < minSize) || (height < minSize)) - // return; - bottomRightVertex = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * + topLeftVertex = z_normalization(vec4(cameraViewProjectionMatrix * dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); - // } - + // Build primitive - gl_Position = topLeftVertex; - psfCoords = vec2(-1.0, 1.0); - EmitVertex(); + gl_Position = bottomLeftVertex; psfCoords = vec2(-1.0, -1.0); EmitVertex(); - gl_Position = topRightVertex; - psfCoords = vec2(1.0, 1.0); - EmitVertex(); + gl_Position = bottomRightVertex; psfCoords = vec2(1.0, -1.0); EmitVertex(); + + gl_Position = topLeftVertex; + psfCoords = vec2(-1.0, 1.0); + EmitVertex(); + + gl_Position = topRightVertex; + psfCoords = vec2(1.0, 1.0); + EmitVertex(); + EndPrimitive(); + } From 2694810e27a50ca34319e21f140794ddf9d3ef39 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 23 Sep 2019 13:12:07 -0400 Subject: [PATCH 007/214] Clean up. --- modules/space/shaders/star_ge.glsl | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/space/shaders/star_ge.glsl b/modules/space/shaders/star_ge.glsl index d12d51d146..80ba2dd4f1 100644 --- a/modules/space/shaders/star_ge.glsl +++ b/modules/space/shaders/star_ge.glsl @@ -82,8 +82,6 @@ void main() { vs_position = gl_in[0].gl_Position; // in object space dvec4 dpos = modelMatrix * dvec4(vs_position); - dvec4 clipTestPos = cameraViewProjectionMatrix * dpos; - ge_bvLumAbsMagAppMag = vs_bvLumAbsMagAppMag[0]; ge_velocity = vs_velocity[0]; ge_speed = vs_speed[0]; From f205a82cb103a5a64555d22f2dbc11584b26338f Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Tue, 24 Sep 2019 09:22:41 +0200 Subject: [PATCH 008/214] Minor cleanup --- modules/touch/src/touchinteraction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index de3d78b6bd..1653b13248 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -1372,7 +1372,7 @@ void TouchInteraction::step(double dt) { #ifdef TOUCH_DEBUG_PROPERTIES LINFO(fmt::format( "{}: Zoom In Limit should be larger than anchor center to surface, setting it to {}", - _loggerCat, zoomInBounds); + _loggerCat, zoomInBounds)); #endif _zoomInLimit.setValue(zoomInBounds); } @@ -1396,7 +1396,7 @@ void TouchInteraction::step(double dt) { bool willNewPositionViolateZoomOutLimit = (newPosDistance >= _zoomOutLimit.value()); bool willNewPositionViolateZoomInLimit = (newPosDistance < _zoomInLimit.value()); - if(!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){ + if (!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){ camPos += zoomDistanceIncrement; } else if (currentPosViolatingZoomOutLimit) { From 94097588185ad22f0efebb220b69a46d86db121b Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Tue, 24 Sep 2019 09:23:24 +0200 Subject: [PATCH 009/214] Updating frontend hash to latest including gui for touch --- data/assets/util/webgui.asset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index 5a052ed12b..aa33c1e6ed 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -3,7 +3,7 @@ asset.require('./static_server') local guiCustomization = asset.require('customization/gui') -- Select which commit hashes to use for the frontend and backend -local frontendHash = "785d6fe3416b2e30bed0a04313ef61b0e2729645" +local frontendHash = "7f464f7ede73b0e9edd1869eeb90465a5194dd29" local dataProvider = "data.openspaceproject.com/files/webgui" local frontend = asset.syncedResource({ From f9cece3e995e5a14fd1a88a1fc9d8893f56189b6 Mon Sep 17 00:00:00 2001 From: Ingela Rossing Date: Tue, 24 Sep 2019 17:12:42 +0200 Subject: [PATCH 010/214] Fix case sensitivity issue --- src/rendering/framebufferrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index a0db067e32..2007f13a53 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -804,7 +804,7 @@ void FramebufferRenderer::updateHDRAndFiltering() { _hdrFilteringProgram = ghoul::opengl::ProgramObject::Build( "HDR and Filtering Program", absPath("${SHADERS}/framebuffer/hdrAndFiltering.vert"), - absPath("${SHADERS}/framebuffer/hdrAndfiltering.frag") + absPath("${SHADERS}/framebuffer/hdrAndFiltering.frag") ); using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; //_hdrFilteringProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); From ab52b812f9ae98e4d273bca4a25cf7637770f2a1 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 25 Sep 2019 16:03:34 -0400 Subject: [PATCH 011/214] Improved geometry shader performance. --- .../digitaluniverse/shaders/billboard_fs.glsl | 4 +++ .../digitaluniverse/shaders/billboard_gs.glsl | 28 +++++++++++++------ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 3ca590e5a5..4d08f6e912 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -39,6 +39,10 @@ Fragment getFragment() { vec4 textureColor = texture(spriteTexture, texCoord); + if (textureColor.a == 0.f || gs_colorMap.a == 0.f) { + discard; + } + vec4 fullColor = vec4(1.0); if (hasColorMap) { diff --git a/modules/digitaluniverse/shaders/billboard_gs.glsl b/modules/digitaluniverse/shaders/billboard_gs.glsl index cb955fbc33..d83e53b10f 100644 --- a/modules/digitaluniverse/shaders/billboard_gs.glsl +++ b/modules/digitaluniverse/shaders/billboard_gs.glsl @@ -159,16 +159,26 @@ void main() { } } - initialPosition = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); - vs_screenSpaceDepth = initialPosition.w; - secondPosition = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - crossCorner = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); - thirdPosition = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); + // initialPosition = z_normalization(vec4(cameraViewProjectionMatrix * + // dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); + // vs_screenSpaceDepth = initialPosition.w; + // secondPosition = z_normalization(vec4(cameraViewProjectionMatrix * + // dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); + // crossCorner = z_normalization(vec4(cameraViewProjectionMatrix * + // dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); + // thirdPosition = z_normalization(vec4(cameraViewProjectionMatrix * + // dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); + // Saving one matrix multiplication: + dvec4 dposClip = cameraViewProjectionMatrix * dpos; + dvec4 scaledRightClip = cameraViewProjectionMatrix * dvec4(scaledRight, 0.0); + dvec4 scaledUpClip = cameraViewProjectionMatrix * dvec4(scaledUp, 0.0); + + initialPosition = z_normalization(vec4(dposClip - scaledRightClip - scaledUpClip)); + vs_screenSpaceDepth = initialPosition.w; + secondPosition = z_normalization(vec4(dposClip + scaledRightClip - scaledUpClip)); + crossCorner = z_normalization(vec4(dposClip + scaledUpClip + scaledRightClip)); + thirdPosition = z_normalization(vec4(dposClip + scaledUpClip - scaledRightClip)); // Build primitive texCoord = corners[3]; From 5eb99492931df807fa60fe28f61dc63829b23347 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 26 Sep 2019 11:38:41 -0400 Subject: [PATCH 012/214] Improved performance of RenderableBillboardsClod. --- data/assets/scene/digitaluniverse/2dF.asset | 4 +- data/assets/scene/digitaluniverse/2mass.asset | 4 +- data/assets/scene/digitaluniverse/6dF.asset | 4 +- data/assets/scene/digitaluniverse/abell.asset | 4 +- .../scene/digitaluniverse/quasars.asset | 4 +- data/assets/scene/digitaluniverse/sdss.asset | 4 +- .../scene/digitaluniverse/superclusters.asset | 4 +- data/assets/scene/digitaluniverse/tully.asset | 4 +- .../rendering/renderablebillboardscloud.cpp | 10 ++-- .../digitaluniverse/shaders/billboard_fs.glsl | 3 +- .../digitaluniverse/shaders/billboard_gs.glsl | 58 ++++++++----------- 11 files changed, 49 insertions(+), 54 deletions(-) diff --git a/data/assets/scene/digitaluniverse/2dF.asset b/data/assets/scene/digitaluniverse/2dF.asset index 2b09ab91ff..2da1fb619d 100644 --- a/data/assets/scene/digitaluniverse/2dF.asset +++ b/data/assets/scene/digitaluniverse/2dF.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "2dF Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_2dF_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -24,7 +24,7 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 1.0, File = speck .. "/2dF.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", ColorMap = speck .. "/2dF.cmap", ColorOption = { "redshift", "proximity" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 25.0 } }, diff --git a/data/assets/scene/digitaluniverse/2mass.asset b/data/assets/scene/digitaluniverse/2mass.asset index b27311229a..c27557c282 100644 --- a/data/assets/scene/digitaluniverse/2mass.asset +++ b/data/assets/scene/digitaluniverse/2mass.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "2MASS Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_2mass_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -24,7 +24,7 @@ local object = { Color = { 1.0, 0.4, 0.2 }, Opacity = 1.0, File = speck .. "/2MASS.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", ColorMap = speck .. "/lss.cmap", ColorOption = { "redshift", "prox5Mpc" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } }, diff --git a/data/assets/scene/digitaluniverse/6dF.asset b/data/assets/scene/digitaluniverse/6dF.asset index 3f9b74256c..2843b142d4 100644 --- a/data/assets/scene/digitaluniverse/6dF.asset +++ b/data/assets/scene/digitaluniverse/6dF.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "6dF Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_6dF_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -24,7 +24,7 @@ local object = { Color = { 1.0, 1.0, 0.0 }, Opacity = 1.0, File = speck .. "/6dF.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", ColorMap = speck .. "/6dF.cmap", ColorOption = { "redshift", "proximity" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 10.0 } }, diff --git a/data/assets/scene/digitaluniverse/abell.asset b/data/assets/scene/digitaluniverse/abell.asset index 673f2f57ac..287eab6c52 100644 --- a/data/assets/scene/digitaluniverse/abell.asset +++ b/data/assets/scene/digitaluniverse/abell.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "Abell Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_abell_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -25,7 +25,7 @@ local object = { Opacity = 1.0, --ColorMap = speck .. "/abell.cmap", File = speck .. "/abell.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", LabelFile = speck .. "/abell.label", TextColor = { 0.0, 0.8, 0.0, 1.0 }, TextSize = 22, diff --git a/data/assets/scene/digitaluniverse/quasars.asset b/data/assets/scene/digitaluniverse/quasars.asset index b24f034f7d..be9b11e59b 100644 --- a/data/assets/scene/digitaluniverse/quasars.asset +++ b/data/assets/scene/digitaluniverse/quasars.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "Quasars Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_quasars_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -24,7 +24,7 @@ local object = { Color = { 1.0, 0.4, 0.2 }, Opacity = 0.95, File = speck .. "/quasars.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", Unit = "Mpc", ScaleFactor = 540.9, -- Fade in value in the same unit as "Unit" diff --git a/data/assets/scene/digitaluniverse/sdss.asset b/data/assets/scene/digitaluniverse/sdss.asset index 38563ed859..56d92df264 100644 --- a/data/assets/scene/digitaluniverse/sdss.asset +++ b/data/assets/scene/digitaluniverse/sdss.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "Sloan Digital Sky Survey Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_sloandss_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -28,7 +28,7 @@ local object = { ColorMap = speck .. "/SDSSgals.cmap", ColorOption = { "redshift", "proximity" }, ColorRange = { { 0.0, 0.075 }, { 1.0, 50.0 } }, - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", Unit = "Mpc", -- Fade in value in the same unit as "Unit" FadeInDistances = { 220.0, 650.0 }, diff --git a/data/assets/scene/digitaluniverse/superclusters.asset b/data/assets/scene/digitaluniverse/superclusters.asset index d51868d921..5ce754caa7 100644 --- a/data/assets/scene/digitaluniverse/superclusters.asset +++ b/data/assets/scene/digitaluniverse/superclusters.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "Galaxy Superclusters Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_superclusters_textures", - Version = 1 + Version = 2 }) local speck = asset.syncedResource({ @@ -25,7 +25,7 @@ local object = { Color = { 1.0, 1.0, 1.0 }, Opacity = 0.65, File = speck .. "/superclust.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", LabelFile = speck .. "/superclust.label", TextColor = { 0.9, 0.9, 0.9, 1.0 }, ScaleFactor = 531.0, diff --git a/data/assets/scene/digitaluniverse/tully.asset b/data/assets/scene/digitaluniverse/tully.asset index 59d750c728..e8e515e22b 100644 --- a/data/assets/scene/digitaluniverse/tully.asset +++ b/data/assets/scene/digitaluniverse/tully.asset @@ -6,7 +6,7 @@ local textures = asset.syncedResource({ Name = "Tully Textures", Type = "HttpSynchronization", Identifier = "digitaluniverse_tully_textures", - Version = 2 + Version = 3 }) local speck = asset.syncedResource({ @@ -25,7 +25,7 @@ local tullyPoints = { Opacity = 0.99, ScaleFactor = 500.0, File = speck .. "/tully.speck", - Texture = textures .. "/point3.png", + Texture = textures .. "/point3A.png", --ColorMap = speck .. "/tully.cmap", ColorMap = speck .. "/lss.cmap", --ColorOption = { "proximity" }, diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index da42b36210..00b27c1516 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -814,21 +814,23 @@ void RenderableBillboardsCloud::renderBillboards(const RenderData& data, _program->setUniform(_uniformCache.cameraPos, data.camera.positionVec3()); _program->setUniform( _uniformCache.cameraLookup, - data.camera.lookUpVectorWorldSpace() + glm::vec3(data.camera.lookUpVectorWorldSpace()) ); _program->setUniform(_uniformCache.renderOption, _renderOption.value()); _program->setUniform(_uniformCache.modelMatrix, modelMatrix); _program->setUniform( _uniformCache.cameraViewProjectionMatrix, - glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() + glm::mat4( + glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() + ) ); _program->setUniform(_uniformCache.minBillboardSize, _billboardMinSize); // in pixels _program->setUniform(_uniformCache.maxBillboardSize, _billboardMaxSize); // in pixels _program->setUniform(_uniformCache.color, _pointColor); _program->setUniform(_uniformCache.alphaValue, _opacity); _program->setUniform(_uniformCache.scaleFactor, _scaleFactor); - _program->setUniform(_uniformCache.up, orthoUp); - _program->setUniform(_uniformCache.right, orthoRight); + _program->setUniform(_uniformCache.up, glm::vec3(orthoUp)); + _program->setUniform(_uniformCache.right, glm::vec3(orthoRight)); _program->setUniform(_uniformCache.fadeInValue, fadeInVariable); _program->setUniform( diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 4d08f6e912..0db1fa3fe4 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -39,7 +39,8 @@ Fragment getFragment() { vec4 textureColor = texture(spriteTexture, texCoord); - if (textureColor.a == 0.f || gs_colorMap.a == 0.f) { + if (textureColor.a == 0.f || gs_colorMap.a == 0.f || + ta == 0.f || fadeInValue == 0.f) { discard; } diff --git a/modules/digitaluniverse/shaders/billboard_gs.glsl b/modules/digitaluniverse/shaders/billboard_gs.glsl index d83e53b10f..a534d0f29f 100644 --- a/modules/digitaluniverse/shaders/billboard_gs.glsl +++ b/modules/digitaluniverse/shaders/billboard_gs.glsl @@ -30,16 +30,16 @@ layout(points) in; layout(triangle_strip, max_vertices = 4) out; uniform float scaleFactor; -uniform dvec3 up; -uniform dvec3 right; +uniform vec3 up; +uniform vec3 right; uniform dvec3 cameraPosition; // in world space (no SGCT View was considered) -uniform dvec3 cameraLookUp; // in world space (no SGCT View was considered) +uniform vec3 cameraLookUp; // in world space (no SGCT View was considered) uniform int renderOption; uniform vec2 screenSize; uniform float maxBillboardSize; uniform float minBillboardSize; -uniform dmat4 cameraViewProjectionMatrix; +uniform mat4 cameraViewProjectionMatrix; uniform dmat4 modelMatrix; uniform float correctionSizeFactor; @@ -94,11 +94,11 @@ void main() { dvec4 dpos = dvec4(dvec3(pos.xyz) * unit, 1.0); dpos = modelMatrix * dpos; - double scaleMultiply = exp(scaleFactor * 0.10); + float scaleMultiply = exp(scaleFactor * 0.10f); scaleMultiply = hasDvarScaling ? dvarScaling[0] * scaleMultiply : scaleMultiply; - dvec3 scaledRight = dvec3(0.0); - dvec3 scaledUp = dvec3(0.0); + vec3 scaledRight = vec3(0.f); + vec3 scaledUp = vec3(0.f); vec4 initialPosition, secondPosition, thirdPosition, crossCorner; @@ -106,15 +106,15 @@ void main() { scaledRight = scaleMultiply * right * 0.5f; scaledUp = scaleMultiply * up * 0.5f; } else if (renderOption == 1) { - dvec3 normal = normalize(cameraPosition - dpos.xyz); - dvec3 newRight = normalize(cross(cameraLookUp, normal)); - dvec3 newUp = cross(normal, newRight); + vec3 normal = vec3(normalize(cameraPosition - dpos.xyz)); + vec3 newRight = normalize(cross(cameraLookUp, normal)); + vec3 newUp = cross(normal, newRight); if (!enabledRectSizeControl) { double distCamera = length(cameraPosition - dpos.xyz); float expVar = float(-distCamera) / pow(10.f, correctionSizeEndDistance); - double factorVar = double(pow(10, correctionSizeFactor)); - scaleMultiply *= 1.0 / (1.0 + factorVar * double(exp(expVar))); + float factorVar = pow(10.f, correctionSizeFactor); + scaleMultiply *= 1.f / (1.f + factorVar * exp(expVar)); } scaledRight = scaleMultiply * newRight * 0.5f; @@ -122,11 +122,13 @@ void main() { } if (enabledRectSizeControl) { - initialPosition = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); + initialPosition = z_normalization(cameraViewProjectionMatrix * + vec4(vec3(dpos.xyz) - scaledRight - scaledUp, dpos.w)); + vs_screenSpaceDepth = initialPosition.w; - crossCorner = z_normalization(vec4(cameraViewProjectionMatrix * - dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); + + crossCorner = z_normalization(cameraViewProjectionMatrix * + vec4(vec3(dpos.xyz) + scaledUp + scaledRight, dpos.w)); // Testing size for rectangular viewport: vec2 halfViewSize = vec2(screenSize.x, screenSize.y) * 0.5f; @@ -158,27 +160,17 @@ void main() { } } } - - // initialPosition = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz - scaledRight - scaledUp, dpos.w))); - // vs_screenSpaceDepth = initialPosition.w; - // secondPosition = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledRight - scaledUp, dpos.w))); - // crossCorner = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledUp + scaledRight, dpos.w))); - // thirdPosition = z_normalization(vec4(cameraViewProjectionMatrix * - // dvec4(dpos.xyz + scaledUp - scaledRight, dpos.w))); // Saving one matrix multiplication: - dvec4 dposClip = cameraViewProjectionMatrix * dpos; - dvec4 scaledRightClip = cameraViewProjectionMatrix * dvec4(scaledRight, 0.0); - dvec4 scaledUpClip = cameraViewProjectionMatrix * dvec4(scaledUp, 0.0); + vec4 dposClip = cameraViewProjectionMatrix * vec4(dpos); + vec4 scaledRightClip = cameraViewProjectionMatrix * vec4(scaledRight, 0.0); + vec4 scaledUpClip = cameraViewProjectionMatrix * vec4(scaledUp, 0.0); - initialPosition = z_normalization(vec4(dposClip - scaledRightClip - scaledUpClip)); + initialPosition = z_normalization(dposClip - scaledRightClip - scaledUpClip); vs_screenSpaceDepth = initialPosition.w; - secondPosition = z_normalization(vec4(dposClip + scaledRightClip - scaledUpClip)); - crossCorner = z_normalization(vec4(dposClip + scaledUpClip + scaledRightClip)); - thirdPosition = z_normalization(vec4(dposClip + scaledUpClip - scaledRightClip)); + secondPosition = z_normalization(dposClip + scaledRightClip - scaledUpClip); + crossCorner = z_normalization(dposClip + scaledUpClip + scaledRightClip); + thirdPosition = z_normalization(dposClip + scaledUpClip - scaledRightClip); // Build primitive texCoord = corners[3]; From a84ef147cbf293f021cc07be76f6d2adff3dfff2 Mon Sep 17 00:00:00 2001 From: Micah Acinapura Date: Fri, 27 Sep 2019 10:23:58 -0400 Subject: [PATCH 013/214] fix for gui projector config --- config/gui_projector.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/gui_projector.xml b/config/gui_projector.xml index 3429edb9d6..42c3971235 100644 --- a/config/gui_projector.xml +++ b/config/gui_projector.xml @@ -17,7 +17,7 @@ - + From 5d1a217936bf4a64afbf14bf0dc5a90ceaebceac Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 27 Sep 2019 15:30:19 -0400 Subject: [PATCH 014/214] Changed star speck file reading to work with problematic getline function in Windows. --- modules/space/rendering/renderablestars.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/modules/space/rendering/renderablestars.cpp b/modules/space/rendering/renderablestars.cpp index f5ba7cf51c..56fbc1c0c7 100644 --- a/modules/space/rendering/renderablestars.cpp +++ b/modules/space/rendering/renderablestars.cpp @@ -1384,7 +1384,7 @@ void RenderableStars::readSpeckFile() { std::string line; while (true) { std::streampos position = file.tellg(); - std::getline(file, line); + std::getline(file, line, '\n'); if (line[0] == '#' || line.empty()) { continue; @@ -1399,9 +1399,6 @@ void RenderableStars::readSpeckFile() { if (_enableTestGrid) { file.seekg(position - std::streamoff(8)); } - else { - file.seekg(position); - } break; } @@ -1450,22 +1447,14 @@ void RenderableStars::readSpeckFile() { float minLumValue = std::numeric_limits::max(); float maxLumValue = std::numeric_limits::min(); - bool first = true; do { std::vector values(_nValuesPerStar); - - if (!first) { - std::getline(file, line); - } - else { - first = false; - } - std::stringstream str(line); for (int i = 0; i < _nValuesPerStar; ++i) { str >> values[i]; } + bool nullArray = true; for (float v : values) { if (v != 0.0) { @@ -1480,6 +1469,9 @@ void RenderableStars::readSpeckFile() { if (!nullArray) { _fullData.insert(_fullData.end(), values.begin(), values.end()); } + + std::getline(file, line, '\n'); + } while (!file.eof()); // Normalize Luminosity: From cbc8845ddfadf8159c4d29c3539048920a87e56c Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Tue, 1 Oct 2019 10:15:13 +0200 Subject: [PATCH 015/214] Fixed layer name for Sea Ice concentration --- data/assets/scene/solarsystem/planets/earth/earth.asset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index f934b499bd..3c90956e24 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -126,7 +126,7 @@ local Earth = { Name = "AMSR2 GCOM W1 Sea Ice Concentration (Temporal)", Type = "TemporalTileLayer", FilePath = openspace.globebrowsing.createTemporalGibsGdalXml( - "AMSR2_Sea_Ice_Concentration_12km", + "AMSRU2_Sea_Ice_Concentration_12km", "2012-05-08", "Yesterday", "1d", From ab076fd3d2f1c994f622322d5870bfdbefe58458 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 8 Oct 2019 16:38:12 -0400 Subject: [PATCH 016/214] Added shadow and ring components to Globebrowsing and shaders for shadows. --- data/assets/default.scene | 4 +- .../solarsystem/planets/saturn/saturn.asset | 40 +- modules/globebrowsing/CMakeLists.txt | 8 + modules/globebrowsing/shaders/rings_fs.glsl | 129 ++++ .../globebrowsing/shaders/rings_geom_fs.glsl | 75 ++ .../globebrowsing/shaders/rings_geom_vs.glsl | 51 ++ modules/globebrowsing/shaders/rings_vs.glsl | 67 ++ modules/globebrowsing/src/renderableglobe.cpp | 99 ++- modules/globebrowsing/src/renderableglobe.h | 16 +- modules/globebrowsing/src/ringscomponent.cpp | 445 +++++++++++ modules/globebrowsing/src/ringscomponent.h | 115 +++ modules/globebrowsing/src/shadowcomponent.cpp | 708 ++++++++++++++++++ modules/globebrowsing/src/shadowcomponent.h | 160 ++++ 13 files changed, 1885 insertions(+), 32 deletions(-) create mode 100644 modules/globebrowsing/shaders/rings_fs.glsl create mode 100644 modules/globebrowsing/shaders/rings_geom_fs.glsl create mode 100644 modules/globebrowsing/shaders/rings_geom_vs.glsl create mode 100644 modules/globebrowsing/shaders/rings_vs.glsl create mode 100644 modules/globebrowsing/src/ringscomponent.cpp create mode 100644 modules/globebrowsing/src/ringscomponent.h create mode 100644 modules/globebrowsing/src/shadowcomponent.cpp create mode 100644 modules/globebrowsing/src/shadowcomponent.h diff --git a/data/assets/default.scene b/data/assets/default.scene index c6d3e2523c..4cdd560715 100644 --- a/data/assets/default.scene +++ b/data/assets/default.scene @@ -9,9 +9,9 @@ asset.onInitialize(function () openspace.globebrowsing.goToGeo("Earth", 58.5877, 16.1924, 20000000) - openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun" }) + openspace.markInterestingNodes({ "Saturn", "Mars", "Moon", "Sun", "Saturn" }) end) asset.onDeinitialize(function () - openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun" }) + openspace.removeInterestingNodes({ "Earth", "Mars", "Moon", "Sun", "Saturn" }) end) diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 77b45972f2..49748b1bf7 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -34,6 +34,15 @@ local Saturn = { Enabled = true } } + }, + Rings = { + Texture = textures .. "/saturn_rings.png", + Size = 140445000, + Offset = { 74500 / 140445.100671159, 1.0 }, -- min / max extend + Shadows = { + Enabled = true, + DistanceFraction = 50.0 + } } }, Tag = { "planet_solarSystem", "planet_giants" }, @@ -42,21 +51,22 @@ local Saturn = { } } -local SaturnRings = { - Identifier = "SaturnRings", - Parent = Saturn.Identifier, - Renderable = { - Type = "RenderableRings", - Texture = textures .. "/saturn_rings.png", - Size = 140445000, - Offset = { 74500 / 140445.100671159, 1.0 } -- min / max extend - }, - GUI = { - Name = "Saturn Rings", - Path = "/Solar System/Planets/Saturn" - } -} +-- local SaturnRings = { +-- Identifier = "SaturnRings", +-- Parent = Saturn.Identifier, +-- Renderable = { +-- Type = "RenderableRings", +-- Texture = textures .. "/saturn_rings.png", +-- Size = 140445000, +-- Offset = { 74500 / 140445.100671159, 1.0 } -- min / max extend +-- }, +-- GUI = { +-- Name = "Saturn Rings", +-- Path = "/Solar System/Planets/Saturn" +-- } +-- } -assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings }) +--assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn }) diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 7d46e40e1a..7f8550c9e7 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -51,6 +51,8 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/rawtile.h ${CMAKE_CURRENT_SOURCE_DIR}/src/rawtiledatareader.h ${CMAKE_CURRENT_SOURCE_DIR}/src/renderableglobe.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/ringscomponent.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/shadowcomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/skirtedgrid.h ${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.h ${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.h @@ -80,6 +82,8 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/rawtile.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rawtiledatareader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/renderableglobe.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ringscomponent.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/shadowcomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/skirtedgrid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/tileindex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/tileloadjob.cpp @@ -94,6 +98,10 @@ set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/globalrenderer_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/localrenderer_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/renderer_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_geom_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/rings_geom_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetilemapping.hglsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/tileheight.hglsl diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl new file mode 100644 index 0000000000..dfaab354a4 --- /dev/null +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -0,0 +1,129 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +in vec2 vs_st; +in float vs_screenSpaceDepth; +in vec4 vs_positionViewSpace; +in flat vec4 shadowCoords; + +uniform sampler2D shadowPositionTexture; + +uniform sampler2DShadow shadowMap; +uniform sampler1D texture1; +uniform vec2 textureOffset; +uniform float transparency; + +uniform bool hasSunPosition; +uniform vec3 sunPosition; +uniform float _nightFactor; + +// temp +in vec4 fragPosInLightSpace; + +Fragment getFragment() { + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; + + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); + + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) + discard; + + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.f || texCoord > 1.f) { + discard; + } + + vec4 diffuse = texture(texture1, texCoord); + float colorValue = length(diffuse.rgb); + // times 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want + // to normalize the transparency value to [0,1] + if (colorValue < 3.0 * transparency) { + diffuse.a = pow(colorValue / (3.0 * transparency), 1); + } + + // shadow == 1.0 means it is not in shadow + float shadow = 1.0; + if ( shadowCoords.z >= 0 ) { + shadow = textureProj(shadowMap, shadowCoords); + } + + // shadow = 1.0; + // vec4 depthInTexture = vec4(0.0, 0.0, 0.0, 1.0); + // //if (shadowCoords.z >= 0) { + // if (true) { + // vec4 byHandCoords = shadowCoords / shadowCoords.w; + // // Distance of the current pixel from the light source + // depthInTexture = texture(shadowPositionTexture, byHandCoords.xy); + // //depthInTexture = texture(shadowPositionTexture, vec2(0.5, 0.5)); + // // if (depthInTexture.x < byHandCoords.z) { + // // shadow = 0.0; + // // } + // if (length(fragPosInLightSpace) > depthInTexture.x) { + // shadow = 0.2; + // } + // //shadow = length(fragPosInLightSpace); + // } + + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + vec3 normal; + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + if (gl_FrontFacing) { + normal = vec3(-1.0, 0.0, 0.0); + } + else { + normal = vec3(1.0, 0.0, 0.0); + } + + // Reduce the color of the fragment by the user factor + // if we are facing away from the Sun + if (dot(sunPosition, normal) < 0) { + diffuse.xyz *= _nightFactor; + } + + Fragment frag; + //frag.color = depthInTexture; + frag.color = (0.55 * diffuse * shadow) + diffuse * 0.45; + //frag.color = vec4(shadow * vec3(1.0, 1.0, 1.0), 1.0); + //frag.depth = vs_position.w; + frag.depth = vs_screenSpaceDepth; + if (diffuse.a < 1.0) + frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); + else + frag.gPosition = vs_positionViewSpace; + frag.gNormal = vec4(normal, 1.0); + + return frag; +} diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl new file mode 100644 index 0000000000..0c167298b9 --- /dev/null +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -0,0 +1,75 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +layout (location = 3) out vec4 renderedPosition; + +in vec2 vs_st; +in float vs_screenSpaceDepth; +in vec4 vs_positionViewSpace; + +uniform vec2 textureOffset; + +Fragment getFragment() { + // Moving the origin to the center + vec2 st = (vs_st - vec2(0.5)) * 2.0; + + // The length of the texture coordinates vector is our distance from the center + float radius = length(st); + + // We only want to consider ring-like objects so we need to discard everything else + if (radius > 1.0) + discard; + + // Remapping the texture coordinates + // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] + // textureOffset.x -> 0 + // textureOffset.y -> 1 + float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x); + if (texCoord < 0.f || texCoord > 1.f) { + discard; + } + + // The normal for the one plane depends on whether we are dealing + // with a front facing or back facing fragment + //vec3 normal; + // The plane is oriented on the xz plane + // WARNING: This might not be the case for Uranus + // if (gl_FrontFacing) { + // normal = vec3(-1.0, 0.0, 0.0); + // } + // else { + // normal = vec3(1.0, 0.0, 0.0); + // } + + Fragment frag; + frag.color = vec4(1.0);; + frag.depth = vs_screenSpaceDepth; + renderedPosition = vec4(vec3(length(vs_positionViewSpace.xyz)), 1.0);//vec4(vs_positionViewSpace.xyz, 1.0); + //renderedPosition = vec4(vec3(vs_screenSpaceDepth.w)/10.0, 1.0); + + return frag; +} diff --git a/modules/globebrowsing/shaders/rings_geom_vs.glsl b/modules/globebrowsing/shaders/rings_geom_vs.glsl new file mode 100644 index 0000000000..1b287f29d3 --- /dev/null +++ b/modules/globebrowsing/shaders/rings_geom_vs.glsl @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +#include "PowerScaling/powerScalingMath.hglsl" + +layout(location = 0) in vec2 in_position; +layout(location = 1) in vec2 in_st; + +out vec2 vs_st; +out float vs_screenSpaceDepth; +out vec4 vs_positionViewSpace; + +uniform dmat4 modelViewMatrix; +uniform dmat4 projectionMatrix; + +void main() { + vs_st = in_st; + + dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace); + vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace); + + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + vs_positionViewSpace = vec4(positionViewSpace); + + //gl_Position = positionClipSpaceZNorm; + gl_Position = positionClipSpace; +} \ No newline at end of file diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl new file mode 100644 index 0000000000..729e8615a1 --- /dev/null +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -0,0 +1,67 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +#include "PowerScaling/powerScaling_vs.hglsl" + +layout(location = 0) in vec2 in_position; +layout(location = 1) in vec2 in_st; + +out vec2 vs_st; +out float vs_screenSpaceDepth; +out vec4 vs_positionViewSpace; +out vec4 shadowCoords; + +// temp +out vec4 fragPosInLightSpace; +uniform dmat4 objectToLightSpaceMatrix; + +uniform dmat4 modelViewMatrix; +uniform dmat4 projectionMatrix; + +// ShadowMatrix is the matrix defined by: +// textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix +// where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] +uniform dmat4 shadowMatrix; + + +void main() { + vs_st = in_st; + + dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace); + vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace); + + shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); + // temp + fragPosInLightSpace = vec4(objectToLightSpaceMatrix * + dvec4(in_position.xy, 0.0, 1.0)); + + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + vs_positionViewSpace = vec4(positionViewSpace); + + //gl_Position = positionClipSpaceZNorm; + gl_Position = positionClipSpace; +} diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 2a9dabcea7..e1c8278561 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -505,6 +505,8 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) , _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments) , _leftRoot(Chunk(LeftHemisphereIndex)) , _rightRoot(Chunk(RightHemisphereIndex)) + , _ringsComponent(dictionary) + , _shadowComponent(dictionary) { _generalProperties.currentLodScaleFactor.setReadOnly(true); @@ -656,6 +658,20 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _labelsDictionary = dictionary.value(KeyLabels); } + // Components + if (dictionary.hasKey("Rings")) { + _ringsComponent.initialize(); + addPropertySubOwner(_ringsComponent); + _hasRings = true; + + ghoul::Dictionary ringsDic; + dictionary.getValue("Rings", ringsDic); + if (ringsDic.hasKey("Shadows")) { + _shadowComponent.initialize(); + addPropertySubOwner(_shadowComponent); + } + } + #ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION _module = global::moduleEngine.module(); #endif // OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION @@ -670,6 +686,11 @@ void RenderableGlobe::initializeGL() { _layerManager.update(); _grid.initializeGL(); + + _ringsComponent.initializeGL(); + + _shadowComponent.initializeGL(); + // Recompile the shaders directly so that it is not done the first time the render // function is called. recompileShaders(); @@ -691,6 +712,10 @@ void RenderableGlobe::deinitializeGL() { } _grid.deinitializeGL(); + + _ringsComponent.deinitializeGL(); + + _shadowComponent.deinitializeGL(); } bool RenderableGlobe::isReady() const { @@ -713,8 +738,49 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask if (distanceToCamera < distance) { try { - renderChunks(data, rendererTask); - _globeLabelsComponent.draw(data); + // Before Shadows + //renderChunks(data, rendererTask); + //_globeLabelsComponent.draw(data); + + + if (_hasRings && _ringsComponent.isEnabled()) { + if (_shadowComponent.isEnabled()) { + + glDisablei(GL_BLEND, 3); + //glEnablei(GL_DEPTH_TEST, 3); + _shadowComponent.begin(data); + + //_ringsComponent.draw(data, RingsComponent::GeometryOnly); + //RenderData tmpRD = data; + //tmpRD.modelTransform.rotation = tmpRD.modelTransform.rotation * glm::dmat3(glm::rotate(glm::dmat4(1), 90.0, glm::dvec3(1.0, 0.0, 0.0))); + //_ringsComponent.draw(tmpRD, RingsComponent::GeometryOnly); + renderChunks(data, rendererTask, true); + + _shadowComponent.end(data); + glEnablei(GL_BLEND, 3); + + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(2.5f, 10.0f); + + _ringsComponent.draw( + data, + RingsComponent::GeometryAndShading, + _shadowComponent.shadowMapData() + ); + renderChunks(data, rendererTask); + + glDisable(GL_POLYGON_OFFSET_FILL); + } + else { + renderChunks(data, rendererTask); + _ringsComponent.draw(data, RingsComponent::GeometryAndShading); + } + } + else { + renderChunks(data, rendererTask); + } + + } catch (const ghoul::opengl::TextureUnit::TextureUnitError&) { std::string layer = _lastChangedLayer ? _lastChangedLayer->guiName() : ""; @@ -852,7 +918,8 @@ const glm::dmat4& RenderableGlobe::modelTransform() const { // Rendering code ////////////////////////////////////////////////////////////////////////////////////////// -void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) { +void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, + const bool renderGeomOnly) { if (_shadersNeedRecompilation) { recompileShaders(); } @@ -1086,7 +1153,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) { // Render all chunks that want to be rendered globally _globalRenderer.program->activate(); for (int i = 0; i < std::min(globalCount, ChunkBufferSize); ++i) { - renderChunkGlobally(*global[i], data); + renderChunkGlobally(*global[i], data, renderGeomOnly); } _globalRenderer.program->deactivate(); @@ -1094,7 +1161,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) { // Render all chunks that need to be rendered locally _localRenderer.program->activate(); for (int i = 0; i < std::min(localCount, ChunkBufferSize); ++i) { - renderChunkLocally(*local[i], data); + renderChunkLocally(*local[i], data, renderGeomOnly); } _localRenderer.program->deactivate(); @@ -1151,7 +1218,8 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&) { } } -void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data) { +void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data, + const bool renderGeomOnly) { //PerfMeasure("globally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_globalRenderer.program; @@ -1199,16 +1267,21 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& } glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + + if (!renderGeomOnly) { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } _grid.drawUsingActiveProgram(); + for (GPULayerGroup& l : _globalRenderer.gpuLayerGroups) { l.deactivate(); } } -void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data) { +void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data, + const bool renderGeomOnly) { //PerfMeasure("locally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_localRenderer.program; @@ -1301,9 +1374,11 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d } glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - + if (!renderGeomOnly) { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + } + _grid.drawUsingActiveProgram(); for (GPULayerGroup& l : _localRenderer.gpuLayerGroups) { diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index a15d671704..87fe7aa30b 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -181,7 +183,8 @@ private: */ float getHeight(const glm::dvec3& position) const; - void renderChunks(const RenderData& data, RendererTasks& rendererTask); + void renderChunks(const RenderData& data, RendererTasks& rendererTask, + const bool renderGeomOnly = false); /** * Chunks can be rendered either globally or locally. Global rendering is performed @@ -191,7 +194,8 @@ private: * point precision by doing this which means that the camera too close to a global * tile will lead to jagging. We only render global chunks for lower chunk levels. */ - void renderChunkGlobally(const Chunk& chunk, const RenderData& data); + void renderChunkGlobally(const Chunk& chunk, const RenderData& data, + const bool renderGeomOnly = false); /** * Local rendering of chunks are done using linear interpolation in camera space. @@ -204,7 +208,8 @@ private: * levels) the better the approximation becomes. This is why we only render local * chunks for higher chunk levels. */ - void renderChunkLocally(const Chunk& chunk, const RenderData& data); + void renderChunkLocally(const Chunk& chunk, const RenderData& data, + const bool renderGeomOnly = false); void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp, bool renderBounds, bool renderAABB) const; @@ -275,6 +280,11 @@ private: size_t _iterationsOfUnavailableData = 0; Layer* _lastChangedLayer = nullptr; + // Components + RingsComponent _ringsComponent; + ShadowComponent _shadowComponent; + bool _hasRings = false; + // Labels GlobeLabelsComponent _globeLabelsComponent; ghoul::Dictionary _labelsDictionary; diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp new file mode 100644 index 0000000000..9c7e2003f2 --- /dev/null +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -0,0 +1,445 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +namespace { + constexpr const std::array UniformNames = { + "modelViewMatrix", "projectionMatrix", "textureOffset", + "transparency", "_nightFactor", "sunPosition", "texture1" + }; + + constexpr const std::array GeomUniformNames = { + "modelViewMatrix", "projectionMatrix", "textureOffset" + }; + + constexpr openspace::properties::Property::PropertyInfo TextureInfo = { + "Texture", + "Texture", + "This value is the path to a texture on disk that contains a one-dimensional " + "texture which is used for these rings." + }; + + constexpr openspace::properties::Property::PropertyInfo SizeInfo = { + "Size", + "Size", + "This value specifies the radius of the rings in meter." + }; + + constexpr openspace::properties::Property::PropertyInfo OffsetInfo = { + "Offset", + "Offset", + "This value is used to limit the width of the rings.Each of the two values is a " + "value between 0 and 1, where 0 is the center of the ring and 1 is the maximum " + "extent at the radius. If this value is, for example {0.5, 1.0}, the ring is " + "only shown between radius/2 and radius. It defaults to {0.0, 1.0}." + }; + + constexpr openspace::properties::Property::PropertyInfo NightFactorInfo = { + "NightFactor", + "Night Factor", + "This value is a multiplicative factor that is applied to the side of the rings " + "that is facing away from the Sun. If this value is equal to '1', no darkening " + "of the night side occurs." + }; + + constexpr openspace::properties::Property::PropertyInfo TransparencyInfo = { + "Transparency", + "Transparency", + "This value determines the transparency of part of the rings depending on the " + "color values. For this value v, the transparency is equal to length(color) / v." + }; +} // namespace + +namespace openspace { + + documentation::Documentation RingsComponent::Documentation() { + using namespace documentation; + return { + "Rings Component", + "globebrowsing_rings_component", + { + { + TextureInfo.identifier, + new StringVerifier, + Optional::Yes, + TextureInfo.description + }, + { + SizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + SizeInfo.description + }, + { + OffsetInfo.identifier, + new DoubleVector2Verifier, + Optional::Yes, + OffsetInfo.description + }, + { + NightFactorInfo.identifier, + new DoubleVerifier, + Optional::Yes, + NightFactorInfo.description + }, + { + TransparencyInfo.identifier, + new DoubleVerifier, + Optional::Yes, + TransparencyInfo.description + } + } + }; + } + + RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) + : properties::PropertyOwner({ "Rings" }) + , _texturePath(TextureInfo) + , _size(SizeInfo, 1.f, 0.f, 1e25f) + , _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f)) + , _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f) + , _transparency(TransparencyInfo, 0.15f, 0.f, 1.f) + , _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true) + , _ringsDictionary(dictionary) + { + using ghoul::filesystem::File; + + if (dictionary.hasKey("Rings")) { + dictionary.getValue("Rings", _ringsDictionary); + } + + documentation::testSpecificationAndThrow( + Documentation(), + _ringsDictionary, + "RingsComponent" + ); + } + + void RingsComponent::initialize() + { + using ghoul::filesystem::File; + + addProperty(_enabled); + + _size = static_cast(_ringsDictionary.value(SizeInfo.identifier)); + //setBoundingSphere(_size); + _size.onChange([&]() { _planeIsDirty = true; }); + addProperty(_size); + + _texturePath = absPath(_ringsDictionary.value(TextureInfo.identifier)); + _textureFile = std::make_unique(_texturePath); + + if (_ringsDictionary.hasKeyAndValue(OffsetInfo.identifier)) { + _offset = _ringsDictionary.value(OffsetInfo.identifier); + } + addProperty(_offset); + + _texturePath.onChange([&]() { loadTexture(); }); + addProperty(_texturePath); + + _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); + + if (_ringsDictionary.hasKeyAndValue(NightFactorInfo.identifier)) { + _nightFactor = static_cast( + _ringsDictionary.value(NightFactorInfo.identifier) + ); + } + addProperty(_nightFactor); + + if (_ringsDictionary.hasKeyAndValue(TransparencyInfo.identifier)) { + _transparency = static_cast( + _ringsDictionary.value(TransparencyInfo.identifier) + ); + } + addProperty(_transparency); + } + + bool RingsComponent::isReady() const { + return (_shader || _geometryOnlyShader) && _texture; + } + + void RingsComponent::initializeGL() { + _shader = global::renderEngine.buildRenderProgram( + "RingsProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl") + ); + + _geometryOnlyShader = global::renderEngine.buildRenderProgram( + "RingsGeomOnlyProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_fs.glsl") + ); + + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + ghoul::opengl::updateUniformLocations( + *_geometryOnlyShader, + _geomUniformCache, + GeomUniformNames + ); + + glGenVertexArrays(1, &_quad); + glGenBuffers(1, &_vertexPositionBuffer); + + createPlane(); + loadTexture(); + } + + void RingsComponent::deinitializeGL() { + glDeleteVertexArrays(1, &_quad); + _quad = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + _textureFile = nullptr; + _texture = nullptr; + + global::renderEngine.removeRenderProgram(_shader.get()); + _shader = nullptr; + + global::renderEngine.removeRenderProgram(_geometryOnlyShader.get()); + _geometryOnlyShader = nullptr; + } + + void RingsComponent::draw( + const RenderData& data, + const RingsComponent::RenderPass renderPass, + const ShadowComponent::ShadowMapData& shadowData + ) { + + if (renderPass == GeometryAndShading) { + _shader->activate(); + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->activate(); + } + + const glm::dmat4 modelTransform = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; + const glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); + + ghoul::opengl::TextureUnit unit; + if (renderPass == GeometryAndShading) { + _shader->setUniform(_uniformCache.modelViewMatrix, modelViewTransform); + _shader->setUniform(_uniformCache.projectionMatrix, projectionMatrix); + _shader->setUniform(_uniformCache.textureOffset, _offset); + _shader->setUniform(_uniformCache.transparency, _transparency); + _shader->setUniform(_uniformCache.nightFactor, _nightFactor); + _shader->setUniform(_uniformCache.sunPosition, _sunPosition); + + unit.activate(); + _texture->bind(); + _shader->setUniform(_uniformCache.texture, unit); + + // Adding the model transformation to the final shadow matrix so we have a + // complete transformation from the model coordinates to the clip space of + // the light position. + _shader->setUniform("shadowMatrix", shadowData.shadowMatrix * modelTransform); + + ghoul::opengl::TextureUnit shadowMapUnit; + shadowMapUnit.activate(); + glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); + + _shader->setUniform("shadowMap", shadowMapUnit); + + // DEBUGGING + ghoul::opengl::TextureUnit shadowTextureUnit; + shadowTextureUnit.activate(); + glBindTexture(GL_TEXTURE_2D, shadowData.positionInLightSpaceTexture); + _shader->setUniform("shadowPositionTexture", shadowTextureUnit); + _shader->setUniform("objectToLightSpaceMatrix", + shadowData.worldToLightSpaceMatrix * modelTransform); + + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->setUniform( + _geomUniformCache.modelViewMatrix, + modelViewTransform + ); + _geometryOnlyShader->setUniform( + _geomUniformCache.projectionMatrix, + projectionMatrix + ); + _geometryOnlyShader->setUniform( + _geomUniformCache.textureOffset, + _offset + ); + } + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glBindVertexArray(_quad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + glEnable(GL_CULL_FACE); + + if (renderPass == GeometryAndShading) { + _shader->deactivate(); + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->deactivate(); + } + } + + void RingsComponent::update(const UpdateData& data) { + if (_shader->isDirty()) { + _shader->rebuildFromFile(); + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + } + + if (_geometryOnlyShader->isDirty()) { + _geometryOnlyShader->rebuildFromFile(); + ghoul::opengl::updateUniformLocations( + *_geometryOnlyShader, + _geomUniformCache, + GeomUniformNames + ); + } + + if (_planeIsDirty) { + createPlane(); + _planeIsDirty = false; + } + + if (_textureIsDirty) { + loadTexture(); + _textureIsDirty = false; + } + + _sunPosition = glm::normalize( + global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition() - + data.modelTransform.translation + ); + } + + void RingsComponent::loadTexture() { + if (!_texturePath.value().empty()) { + using namespace ghoul::io; + using namespace ghoul::opengl; + std::unique_ptr texture = TextureReader::ref().loadTexture( + absPath(_texturePath) + ); + + if (texture) { + LDEBUGC( + "RingsComponent", + fmt::format("Loaded texture from '{}'", absPath(_texturePath)) + ); + _texture = std::move(texture); + + _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + + _textureFile = std::make_unique(_texturePath); + _textureFile->setCallback( + [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + ); + } + } + } + + void RingsComponent::createPlane() { + const GLfloat size = _size; + + struct VertexData { + GLfloat x; + GLfloat y; + GLfloat s; + GLfloat t; + }; + + VertexData data[] = { + { -size, -size, 0.f, 0.f }, + { size, size, 1.f, 1.f }, + { -size, size, 0.f, 1.f }, + { -size, -size, 0.f, 0.f }, + { size, -size, 1.f, 0.f }, + { size, size, 1.f, 1.f }, + }; + + glBindVertexArray(_quad); + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer( + 0, + 2, + GL_FLOAT, + GL_FALSE, + sizeof(VertexData), + nullptr + ); + glEnableVertexAttribArray(1); + glVertexAttribPointer( + 1, + 2, + GL_FLOAT, + GL_FALSE, + sizeof(VertexData), + reinterpret_cast(offsetof(VertexData, s)) // NOLINT + ); + } + + bool RingsComponent::isEnabled() const { + return _enabled; + } +} // namespace openspace diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h new file mode 100644 index 0000000000..4ebb05b963 --- /dev/null +++ b/modules/globebrowsing/src/ringscomponent.h @@ -0,0 +1,115 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__ +#define __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace ghoul { + class Dictionary; +} + +namespace ghoul::filesystem { class File; } + +namespace ghoul::opengl { + class ProgramObject; +} // namespace ghoul::opengl + +namespace openspace { + struct RenderData; + struct UpdateData; + + namespace documentation { struct Documentation; } + + class RingsComponent : public properties::PropertyOwner { + public: + enum RenderPass { + GeometryOnly, + GeometryAndShading + }; + public: + RingsComponent(const ghoul::Dictionary& dictionary); + + void initialize(); + void initializeGL(); + void deinitializeGL(); + + bool isReady() const; + + void draw( + const RenderData& data, + const RingsComponent::RenderPass renderPass, + const ShadowComponent::ShadowMapData& shadowData = {} + ); + void update(const UpdateData& data); + + static documentation::Documentation Documentation(); + + bool isEnabled() const; + + private: + void loadTexture(); + void createPlane(); + + properties::StringProperty _texturePath; + properties::FloatProperty _size; + properties::Vec2Property _offset; + properties::FloatProperty _nightFactor; + properties::FloatProperty _transparency; + properties::BoolProperty _enabled; + + std::unique_ptr _shader; + std::unique_ptr _geometryOnlyShader; + UniformCache(modelViewMatrix, projectionMatrix, textureOffset, + transparency, nightFactor, sunPosition, texture) _uniformCache; + UniformCache(modelViewMatrix, projectionMatrix, textureOffset) _geomUniformCache; + std::unique_ptr _texture; + std::unique_ptr _textureFile; + + ghoul::Dictionary _ringsDictionary; + bool _textureIsDirty = false; + GLuint _quad = 0; + GLuint _vertexPositionBuffer = 0; + bool _planeIsDirty = false; + + glm::vec3 _sunPosition; + }; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__ diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp new file mode 100644 index 0000000000..6f51887b2a --- /dev/null +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -0,0 +1,708 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "ShadowComponent"; + + constexpr openspace::properties::Property::PropertyInfo SaveDepthTextureInfo = { + "SaveDepthTextureInfo", + "Save Depth Texture", + "Debug" + }; + + constexpr openspace::properties::Property::PropertyInfo DistanceFractionInfo = { + "DistanceFraction", + "Distance Fraction", + "Distance fraction of original distance from light source to the globe to be " + "considered as the new light source distance." + }; + + void checkFrameBufferState(const std::string& codePosition) + { + if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Framework not built. " + codePosition); + GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch (fbErr) { + case GL_FRAMEBUFFER_UNDEFINED: + LERROR("Indefined framebuffer."); + break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + LERROR("Incomplete, missing attachement."); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + LERROR("Framebuffer doesn't have at least one image attached to it."); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + LERROR( + "Returned if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is " + "GL_NONE for any color attachment point(s) named by GL_DRAW_BUFFERi." + ); + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + LERROR( + "Returned if GL_READ_BUFFER is not GL_NONE and the value of " + "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color " + "attachment point named by GL_READ_BUFFER."); + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + LERROR( + "Returned if the combination of internal formats of the attached " + "images violates an implementation - dependent set of restrictions." + ); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + LERROR( + "Returned if the value of GL_RENDERBUFFE_r_samples is not the same " + "for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES " + "is the not same for all attached textures; or , if the attached " + "images are a mix of renderbuffers and textures, the value of " + "GL_RENDERBUFFE_r_samples does not match the value of " + "GL_TEXTURE_SAMPLES." + ); + LERROR( + "Returned if the value of GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not " + "the same for all attached textures; or , if the attached images are " + "a mix of renderbuffers and textures, the value of " + "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS is not GL_TRUE for all attached " + "textures." + ); + break; + case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + LERROR( + "Returned if any framebuffer attachment is layered, and any " + "populated attachment is not layered, or if all populated color " + "attachments are not from textures of the same target." + ); + break; + default: + LDEBUG("No error found checking framebuffer: " + codePosition); + break; + } + } + } +} // namespace + +namespace openspace { + + documentation::Documentation ShadowComponent::Documentation() { + using namespace documentation; + return { + "ShadowsRing Component", + "globebrowsing_shadows_component", + { + { + DistanceFractionInfo.identifier, + new DoubleVerifier, + Optional::Yes, + DistanceFractionInfo.description + } + } + }; + } + + ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) + : properties::PropertyOwner({ "Shadows" }) + , _saveDepthTexture(SaveDepthTextureInfo) + , _distanceFraction(DistanceFractionInfo, 30, 1, 100000) + , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) + , _shadowMapDictionary(dictionary) + , _shadowDepthTextureHeight(1024) + , _shadowDepthTextureWidth(1024) + , _shadowDepthTexture(-1) + , _positionInLightSpaceTexture(-1) + , _shadowFBO(-1) + , _firstPassSubroutine(-1) + , _secondPassSubroutine(1) + , _defaultFBO(-1) + , _sunPosition(0.0) + , _shadowMatrix(1.0) + , _executeDepthTextureSave(false) + { + using ghoul::filesystem::File; + + if (dictionary.hasKey("Rings")) { + ghoul::Dictionary ringsDic; + dictionary.getValue("Rings", ringsDic); + if (ringsDic.hasKey("Shadows")) { + ringsDic.getValue("Shadows", _shadowMapDictionary); + } + } + + documentation::testSpecificationAndThrow( + Documentation(), + _shadowMapDictionary, + "ShadowComponent" + ); + + if (_shadowMapDictionary.hasKey(DistanceFractionInfo.identifier)) { + _distanceFraction = static_cast( + _shadowMapDictionary.value(DistanceFractionInfo.identifier) + ); + } + + _saveDepthTexture.onChange([&]() { + _executeDepthTextureSave = true; + }); + + addProperty(_enabled); + addProperty(_saveDepthTexture); + addProperty(_distanceFraction); + } + + void ShadowComponent::initialize() + { + using ghoul::filesystem::File; + } + + bool ShadowComponent::isReady() const { + return true; + } + + void ShadowComponent::initializeGL() { + createDepthTexture(); + createShadowFBO(); + } + + void ShadowComponent::deinitializeGL() { + glDeleteTextures(1, &_shadowDepthTexture); + glDeleteTextures(1, &_positionInLightSpaceTexture); + glDeleteFramebuffers(1, &_shadowFBO); + checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer"); + } + + void ShadowComponent::begin(const RenderData& data) { + // =========================================== + // Builds light's ModelViewProjectionMatrix: + // =========================================== + + glm::dvec3 diffVector = glm::dvec3(_sunPosition) - data.modelTransform.translation; + double originalLightDistance = glm::length(diffVector); + glm::dvec3 lightDirection = glm::normalize(diffVector); + + // Percentage of the original light source distance (to avoid artifacts) + double multiplier = originalLightDistance * + (static_cast(_distanceFraction)/1.0E5); + + // New light source position + glm::dvec3 lightPosition = data.modelTransform.translation + + (lightDirection * multiplier); + + // Saving current Camera parameters + _cameraPos = data.camera.positionVec3(); + // JCC: We have aim and ancor nodes and position now. Need to fix this. + //_cameraFocus = data.camera.focusPositionVec3(); + _cameraRotation = data.camera.rotationQuaternion(); + + //=============== Automatically Created Camera Matrix =================== + //======================================================================= + //glm::dmat4 lightViewMatrix = glm::lookAt( + // //lightPosition, + // glm::dvec3(0.0), + // //glm::dvec3(_sunPosition), // position + // glm::dvec3(data.modelTransform.translation), // focus + // data.camera.lookUpVectorWorldSpace() // up + // //glm::dvec3(0.0, 1.0, 0.0) + //); + + //camera->setPositionVec3(lightPosition); + //camera->setFocusPositionVec3(data.modelTransform.translation); + //camera->setRotation(glm::dquat(glm::inverse(lightViewMatrix))); + + //======================================================================= + //======================================================================= + + + //=============== Manually Created Camera Matrix =================== + //================================================================== + // camera Z + glm::dvec3 cameraZ = lightDirection; + + // camera X + glm::dvec3 upVector = glm::dvec3(0.0, -1.0, 0.0); + glm::dvec3 cameraX = glm::normalize(glm::cross(upVector, cameraZ)); + + // camera Y + glm::dvec3 cameraY = glm::cross(cameraZ, cameraX); + + // init 4x4 matrix + glm::dmat4 cameraRotationMatrix(1.0); + + double* matrix = glm::value_ptr(cameraRotationMatrix); + matrix[0] = cameraX.x; + matrix[4] = cameraX.y; + matrix[8] = cameraX.z; + matrix[1] = cameraY.x; + matrix[5] = cameraY.y; + matrix[9] = cameraY.z; + matrix[2] = cameraZ.x; + matrix[6] = cameraZ.y; + matrix[10] = cameraZ.z; + + // set translation part + // We aren't setting the position here because it is set in + // the camera->setPosition() + //matrix[12] = -glm::dot(cameraX, lightPosition); + //matrix[13] = -glm::dot(cameraY, lightPosition); + //matrix[14] = -glm::dot(cameraZ, lightPosition); + + /*Scene* scene = camera->parent()->scene(); + global::navigationHandler.setFocusNode(data.); + */ + + Camera camera(data.camera); + camera.setPositionVec3(lightPosition); + // JCC: We have aim and ancor nodes and position now. Need to fix this. + //camera.setFocusPositionVec3(data.modelTransform.translation); + camera.setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); + + //======================================================================= + //======================================================================= + + + //============= Light Matrix by Camera Matrices Composition ============= + //======================================================================= + glm::dmat4 lightProjectionMatrix = glm::dmat4(camera.projectionMatrix()); + //glm::dmat4 lightProjectionMatrix = glm::ortho(-1000.0, 1000.0, -1000.0, 1000.0, 0.0010, 1000.0); + //glm::dmat4 lightProjectionMatrix = glm::frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000000.0); + + // The model transformation missing in the final shadow matrix is add when rendering each + // object (using its transformations provided by the RenderData structure) + _shadowData.shadowMatrix = + _toTextureCoordsMatrix * + lightProjectionMatrix * + camera.combinedViewMatrix(); + + // temp + _shadowData.worldToLightSpaceMatrix = glm::dmat4(camera.combinedViewMatrix()); + + checkGLError("begin() -- Saving Current GL State"); + // Saves current state + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + glGetIntegerv(GL_VIEWPORT, _mViewport); + _faceCulling = glIsEnabled(GL_CULL_FACE); + glGetIntegerv(GL_CULL_FACE_MODE, &_faceToCull); + _polygonOffSet = glIsEnabled(GL_POLYGON_OFFSET_FILL); + glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &_polygonOffSetFactor); + glGetFloatv(GL_POLYGON_OFFSET_UNITS, &_polygonOffSetUnits); + glGetFloatv(GL_COLOR_CLEAR_VALUE, _colorClearValue); + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &_depthClearValue); + _depthIsEnabled = glIsEnabled(GL_DEPTH_TEST); + glGetIntegerv(GL_DEPTH_FUNC, &_depthFunction); + _blendIsEnabled = glIsEnabled(GL_BLEND); + + + checkGLError("begin() -- before binding FBO"); + glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); + checkGLError("begin() -- after binding FBO"); + glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight); + checkGLError("begin() -- set new viewport"); + glClearDepth(1.0f); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + checkGLError("begin() -- after cleanning Depth buffer"); + + + /*glEnable(GL_CULL_FACE); + checkGLError("begin() -- enabled cull face"); + glCullFace(GL_FRONT); + checkGLError("begin() -- set cullface to front");*/ + /*glEnable(GL_POLYGON_OFFSET_FILL); + checkGLError("begin() -- enabled polygon offset fill"); + glPolygonOffset(2.5f, 10.0f); + checkGLError("begin() -- set values for polygon offset");*/ + + checkGLError("begin() finished"); + + } + + void ShadowComponent::end(const RenderData& data) { + checkGLError("end() -- Flushing"); + //glFlush(); + if (_executeDepthTextureSave) { + saveDepthBuffer(); + _executeDepthTextureSave = false; + } + + // Restores Camera Parameters + Camera camera = data.camera; + camera.setPositionVec3(_cameraPos); + // JCC: We have aim and ancor nodes and position now. Need to fix this. + //camera.setFocusPositionVec3(_cameraFocus); + camera.setRotation(_cameraRotation); + + // Restores system state + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + checkGLError("end() -- Rebinding default FBO"); + glViewport( + _mViewport[0], + _mViewport[1], + _mViewport[2], + _mViewport[3] + ); + + if (_faceCulling) { + glEnable(GL_CULL_FACE); + glCullFace(_faceToCull); + } + else { + glDisable(GL_CULL_FACE); + } + + if (_depthIsEnabled) { + glEnable(GL_DEPTH_TEST); + } + else { + glDisable(GL_DEPTH_TEST); + } + + glDepthFunc(_depthFunction); + + if (_polygonOffSet) { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(_polygonOffSetFactor, _polygonOffSetUnits); + } + else { + glDisable(GL_POLYGON_OFFSET_FILL); + } + + glClearColor( + _colorClearValue[0], + _colorClearValue[1], + _colorClearValue[2], + _colorClearValue[3] + ); + glClearDepth(_depthClearValue); + + if (_blendIsEnabled) { + glEnable(GL_BLEND); + } + + checkGLError("end() finished"); + } + + void ShadowComponent::update(const UpdateData& /*data*/) { + _sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition(); + } + + void ShadowComponent::createDepthTexture() { + checkGLError("createDepthTexture() -- Starting configuration"); + glGenTextures(1, &_shadowDepthTexture); + glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); + glTexStorage2D( + GL_TEXTURE_2D, + 1, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight + ); + + /*glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + 0 + );*/ + checkGLError("createDepthTexture() -- Depth testure created"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorder); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + checkGLError("createdDepthTexture"); + + glGenTextures(1, &_positionInLightSpaceTexture); + glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); + //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + checkGLError("createDepthTexture() -- Position/Distance buffer created"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + checkGLError("createdPositionTexture"); + + glBindTexture(GL_TEXTURE_2D, 0); + + _shadowData.shadowDepthTexture = _shadowDepthTexture; + _shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; + } + + void ShadowComponent::createShadowFBO() { + // Saves current FBO first + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + + /*GLint _mViewport[4]; + glGetIntegerv(GL_VIEWPORT, _mViewport);*/ + + glGenFramebuffers(1, &_shadowFBO); + glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, + _shadowDepthTexture, + 0 + ); + + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT3, + _positionInLightSpaceTexture, + 0 + ); + checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); + //GLenum drawBuffers[] = { GL_NONE }; + GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT3 }; + glDrawBuffers(4, drawBuffers); + + checkFrameBufferState("createShadowFBO()"); + + // Restores system state + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + /*glViewport( + _mViewport[0], + _mViewport[1], + _mViewport[2], + _mViewport[3] + );*/ + checkGLError("createShadowFBO() -- createdShadowFBO"); + } + + void ShadowComponent::saveDepthBuffer() { + int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight; + GLubyte * buffer = new GLubyte[size]; + + glReadPixels( + 0, + 0, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, + buffer + ); + + checkGLError("readDepthBuffer To buffer"); + std::fstream ppmFile; + + ppmFile.open("depthBufferShadowMapping.ppm", std::fstream::out); + if (ppmFile.is_open()) { + + ppmFile << "P3" << std::endl; + ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight + << std::endl; + ppmFile << "255" << std::endl; + + std::cout << "\n\nSaving depth texture to file depthBufferShadowMapping.ppm\n\n"; + int k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++, k++) { + unsigned int val = static_cast(buffer[k]); + ppmFile << val << " " << val << " " << val << " "; + } + ppmFile << std::endl; + } + + ppmFile.close(); + + std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n"; + } + + delete[] buffer; + + GLfloat * bBuffer = new GLfloat[size * 4]; + + glReadBuffer(GL_COLOR_ATTACHMENT3); + glReadPixels( + 0, + 0, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + GL_RGBA, + GL_FLOAT, + bBuffer + ); + + checkGLError("readPositionBuffer To buffer"); + ppmFile.clear(); + + ppmFile.open("positionBufferShadowMapping.ppm", std::fstream::out); + if (ppmFile.is_open()) { + + ppmFile << "P3" << std::endl; + ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight + << std::endl; + ppmFile << "255" << std::endl; + + std::cout << "\n\nSaving texture position to positionBufferShadowMapping.ppm\n\n"; + + float biggestValue = 0.f; + + int k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++) { + biggestValue = bBuffer[k] > biggestValue ? + bBuffer[k] : biggestValue; + k += 4; + } + } + + biggestValue /= 255.f; + + k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++) { + ppmFile << static_cast(bBuffer[k] / biggestValue) << " " + << static_cast(bBuffer[k + 1] / biggestValue) << " " + << static_cast(bBuffer[k + 2] / biggestValue) << " "; + k += 4; + } + ppmFile << std::endl; + } + + ppmFile.close(); + + std::cout << "Texture saved to file positionBufferShadowMapping.ppm\n\n"; + } + + delete[] bBuffer; + } + + void ShadowComponent::checkGLError(const std::string & where) const { + const GLenum error = glGetError(); + switch (error) { + case GL_NO_ERROR: + break; + case GL_INVALID_ENUM: + LERRORC( + "OpenGL Invalid State", + fmt::format("Function {}: GL_INVALID_ENUM", where) + ); + break; + case GL_INVALID_VALUE: + LERRORC( + "OpenGL Invalid State", + fmt::format("Function {}: GL_INVALID_VALUE", where) + ); + break; + case GL_INVALID_OPERATION: + LERRORC( + "OpenGL Invalid State", + fmt::format( + "Function {}: GL_INVALID_OPERATION", where + )); + break; + case GL_INVALID_FRAMEBUFFER_OPERATION: + LERRORC( + "OpenGL Invalid State", + fmt::format( + "Function {}: GL_INVALID_FRAMEBUFFER_OPERATION", + where + ) + ); + break; + case GL_OUT_OF_MEMORY: + LERRORC( + "OpenGL Invalid State", + fmt::format("Function {}: GL_OUT_OF_MEMORY", where) + ); + break; + default: + LERRORC( + "OpenGL Invalid State", + fmt::format("Unknown error code: {0:x}", static_cast(error)) + ); + } + } + + bool ShadowComponent::isEnabled() const { + return _enabled; + } + + ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const { + return _shadowData; + } +} // namespace openspace diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h new file mode 100644 index 0000000000..95208c59b9 --- /dev/null +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -0,0 +1,160 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014-2018 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ +#define __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace ghoul { + class Dictionary; +} + +namespace ghoul::filesystem { class File; } + +namespace ghoul::opengl { + class ProgramObject; +} // namespace ghoul::opengl + +namespace openspace { + struct RenderData; + struct UpdateData; + + namespace documentation { struct Documentation; } + + static const GLfloat shadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; + + class ShadowComponent : public properties::PropertyOwner { + public: + struct ShadowMapData { + glm::dmat4 shadowMatrix; + // temp + glm::dmat4 worldToLightSpaceMatrix; + GLuint shadowDepthTexture; + GLuint positionInLightSpaceTexture; + }; + public: + ShadowComponent(const ghoul::Dictionary& dictionary); + + void initialize(); + void initializeGL(); + void deinitializeGL(); + //bool deinitialize(); + + bool isReady() const; + + void begin(const RenderData& data); + void end(const RenderData& data); + void update(const UpdateData& data); + + static documentation::Documentation Documentation(); + + bool isEnabled() const; + + ShadowComponent::ShadowMapData shadowMapData() const; + + private: + void createDepthTexture(); + void createShadowFBO(); + + // Debug + void saveDepthBuffer(); + void checkGLError(const std::string & where) const; + + private: + + ShadowMapData _shadowData; + + // Texture coords in [0, 1], while clip coords in [-1, 1] + const glm::dmat4 _toTextureCoordsMatrix = glm::dmat4( + glm::dvec4(0.5, 0.0, 0.0, 0.0), + glm::dvec4(0.0, 0.5, 0.0, 0.0), + glm::dvec4(0.0, 0.0, 0.5, 0.0), + glm::dvec4(0.5, 0.5, 0.5, 1.0) + ); + + // DEBUG + properties::TriggerProperty _saveDepthTexture; + properties::IntProperty _distanceFraction; + properties::BoolProperty _enabled; + + ghoul::Dictionary _shadowMapDictionary; + + int _shadowDepthTextureHeight; + int _shadowDepthTextureWidth; + + GLuint _shadowDepthTexture; + GLuint _positionInLightSpaceTexture; + GLuint _shadowFBO; + GLuint _firstPassSubroutine; + GLuint _secondPassSubroutine; + GLint _defaultFBO; + GLint _mViewport[4]; + + GLboolean _faceCulling; + GLboolean _polygonOffSet; + GLboolean _depthIsEnabled; + GLboolean _blendIsEnabled = false; + + GLenum _faceToCull; + GLenum _depthFunction; + + GLfloat _polygonOffSetFactor; + GLfloat _polygonOffSetUnits; + GLfloat _colorClearValue[4]; + GLfloat _depthClearValue; + + glm::vec3 _sunPosition; + + glm::dmat4 _shadowMatrix; + + glm::dvec3 _cameraPos; + glm::dvec3 _cameraFocus; + glm::dquat _cameraRotation; + + std::stringstream _serializedCamera; + + // DEBUG + bool _executeDepthTextureSave; + + }; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ From 992a618e8669b32a3236b49310eee4de5a4a26e0 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Wed, 9 Oct 2019 10:52:18 -0600 Subject: [PATCH 017/214] Added asset file for new C2019 Q4 "Borisov" interstellar object --- .../interstellar/c-2019_q4_borisov.asset | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset diff --git a/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset b/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset new file mode 100644 index 0000000000..7d41e166ec --- /dev/null +++ b/data/assets/scene/solarsystem/interstellar/c-2019_q4_borisov.asset @@ -0,0 +1,46 @@ +local assetHelper = asset.require('util/asset_helper') +local sunTransforms = asset.require('scene/solarsystem/sun/transforms') + +local trajectory = asset.syncedResource({ + Name = "C-2019 Q4 Borisov Trajectory", + Type = "HttpSynchronization", + Identifier = "borisov_horizons", + Version = 1 +}) + +local C2019Q4BorisovTrail = { + Identifier = "C2019Q4BorisovTrail", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableTrailTrajectory", + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = trajectory .. "/horizons_c2019q4borisov.dat" + }, + Color = { 0.9, 0.9, 0.0 }, + StartTime = "2015 JAN 01 00:00:00", + EndTime = "2024 JAN 01 00:00:00", + SampleInterval = 60 + }, + GUI = { + Name = "C-2019 Q4 Borisov Trail", + Path = "/Solar System/Interstellar" + } +} + +local C2019Q4BorisovPosition = { + Identifier = "C2019Q4BorisovPosition", + Parent = sunTransforms.SolarSystemBarycenter.Identifier, + Transform = { + Translation = { + Type = "HorizonsTranslation", + HorizonsTextFile = trajectory .. "/horizons_c2019q4borisov.dat" + }, + }, + GUI = { + Name = "C-2019 Q4 Borisov", + Path = "/Solar System/Interstellar" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { C2019Q4BorisovPosition, C2019Q4BorisovTrail }) From e8d623053b9bed4ff0d578298bc787137e867e7e Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 9 Oct 2019 17:10:13 -0400 Subject: [PATCH 018/214] Improved code. --- modules/globebrowsing/shaders/rings_fs.glsl | 9 ++- .../globebrowsing/shaders/rings_geom_fs.glsl | 6 +- modules/globebrowsing/src/renderableglobe.cpp | 31 ++++---- modules/globebrowsing/src/shadowcomponent.cpp | 72 ++++++++++++------- modules/globebrowsing/src/shadowcomponent.h | 4 +- 5 files changed, 70 insertions(+), 52 deletions(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index dfaab354a4..9cb82f01eb 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -74,9 +74,12 @@ Fragment getFragment() { // shadow == 1.0 means it is not in shadow float shadow = 1.0; - if ( shadowCoords.z >= 0 ) { - shadow = textureProj(shadowMap, shadowCoords); - } + //if ( shadowCoords.z >= 0 ) { + vec4 normalizedShadowCoords = shadowCoords; + //normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.z); + normalizedShadowCoords.w = 1.0/normalizeFloat(normalizedShadowCoords.z); + shadow = textureProj(shadowMap, normalizedShadowCoords); + //} // shadow = 1.0; // vec4 depthInTexture = vec4(0.0, 0.0, 0.0, 1.0); diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 0c167298b9..aa50efc94a 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -25,8 +25,6 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" -layout (location = 3) out vec4 renderedPosition; - in vec2 vs_st; in float vs_screenSpaceDepth; in vec4 vs_positionViewSpace; @@ -66,9 +64,9 @@ Fragment getFragment() { // } Fragment frag; - frag.color = vec4(1.0);; + frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); frag.depth = vs_screenSpaceDepth; - renderedPosition = vec4(vec3(length(vs_positionViewSpace.xyz)), 1.0);//vec4(vs_positionViewSpace.xyz, 1.0); + //renderedPosition = vec4(vec3(length(vs_positionViewSpace.xyz)), 1.0);//vec4(vs_positionViewSpace.xyz, 1.0); //renderedPosition = vec4(vec3(vs_screenSpaceDepth.w)/10.0, 1.0); return frag; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index e1c8278561..c595a5b8c8 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -746,30 +746,29 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask if (_hasRings && _ringsComponent.isEnabled()) { if (_shadowComponent.isEnabled()) { - glDisablei(GL_BLEND, 3); - //glEnablei(GL_DEPTH_TEST, 3); - _shadowComponent.begin(data); - - //_ringsComponent.draw(data, RingsComponent::GeometryOnly); - //RenderData tmpRD = data; - //tmpRD.modelTransform.rotation = tmpRD.modelTransform.rotation * glm::dmat3(glm::rotate(glm::dmat4(1), 90.0, glm::dvec3(1.0, 0.0, 0.0))); - //_ringsComponent.draw(tmpRD, RingsComponent::GeometryOnly); - renderChunks(data, rendererTask, true); - - _shadowComponent.end(data); - glEnablei(GL_BLEND, 3); - + // Render from light source point of view + RenderData lightRenderData(_shadowComponent.begin(data)); + + glDisable(GL_BLEND); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(2.5f, 10.0f); + renderChunks(lightRenderData, rendererTask, true); + _ringsComponent.draw(lightRenderData, RingsComponent::GeometryOnly); + + glEnable(GL_BLEND); + glDisable(GL_POLYGON_OFFSET_FILL); + + _shadowComponent.end(data); + + + // Render again from original point of view + renderChunks(data, rendererTask); _ringsComponent.draw( data, RingsComponent::GeometryAndShading, _shadowComponent.shadowMapData() ); - renderChunks(data, rendererTask); - - glDisable(GL_POLYGON_OFFSET_FILL); } else { renderChunks(data, rendererTask); diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 6f51887b2a..118666680a 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -232,7 +232,7 @@ namespace openspace { checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer"); } - void ShadowComponent::begin(const RenderData& data) { + RenderData ShadowComponent::begin(const RenderData& data) { // =========================================== // Builds light's ModelViewProjectionMatrix: // =========================================== @@ -253,6 +253,10 @@ namespace openspace { _cameraPos = data.camera.positionVec3(); // JCC: We have aim and ancor nodes and position now. Need to fix this. //_cameraFocus = data.camera.focusPositionVec3(); + + //const SceneGraphNode * origAimNode = global::navigationHandler.orbitalNavigator().aimNode(); + //const SceneGraphNode * origAnchorNode = global::navigationHandler.orbitalNavigator().anchorNode(); + _cameraRotation = data.camera.rotationQuaternion(); //=============== Automatically Created Camera Matrix =================== @@ -290,14 +294,14 @@ namespace openspace { glm::dmat4 cameraRotationMatrix(1.0); double* matrix = glm::value_ptr(cameraRotationMatrix); - matrix[0] = cameraX.x; - matrix[4] = cameraX.y; - matrix[8] = cameraX.z; - matrix[1] = cameraY.x; - matrix[5] = cameraY.y; - matrix[9] = cameraY.z; - matrix[2] = cameraZ.x; - matrix[6] = cameraZ.y; + matrix[0] = cameraX.x; + matrix[4] = cameraX.y; + matrix[8] = cameraX.z; + matrix[1] = cameraY.x; + matrix[5] = cameraY.y; + matrix[9] = cameraY.z; + matrix[2] = cameraZ.x; + matrix[6] = cameraZ.y; matrix[10] = cameraZ.z; // set translation part @@ -310,8 +314,8 @@ namespace openspace { /*Scene* scene = camera->parent()->scene(); global::navigationHandler.setFocusNode(data.); */ - - Camera camera(data.camera); + + Camera camera = data.camera; camera.setPositionVec3(lightPosition); // JCC: We have aim and ancor nodes and position now. Need to fix this. //camera.setFocusPositionVec3(data.modelTransform.translation); @@ -355,6 +359,8 @@ namespace openspace { checkGLError("begin() -- before binding FBO"); glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + glDrawBuffers(3, drawBuffers); checkGLError("begin() -- after binding FBO"); glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight); checkGLError("begin() -- set new viewport"); @@ -376,10 +382,19 @@ namespace openspace { checkGLError("begin() -- set values for polygon offset");*/ checkGLError("begin() finished"); - + + RenderData lightRenderData{ + camera, + data.time, + data.doPerformanceMeasurement, + data.renderBinMask, + data.modelTransform + }; + + return lightRenderData; } - void ShadowComponent::end(const RenderData& data) { + void ShadowComponent::end(const RenderData& dataOrig) { checkGLError("end() -- Flushing"); //glFlush(); if (_executeDepthTextureSave) { @@ -388,7 +403,7 @@ namespace openspace { } // Restores Camera Parameters - Camera camera = data.camera; + Camera camera = dataOrig.camera; camera.setPositionVec3(_cameraPos); // JCC: We have aim and ancor nodes and position now. Need to fix this. //camera.setFocusPositionVec3(_cameraFocus); @@ -396,6 +411,10 @@ namespace openspace { // Restores system state glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + GLenum drawBuffers[] = { + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 + }; + glDrawBuffers(3, drawBuffers); checkGLError("end() -- Rebinding default FBO"); glViewport( _mViewport[0], @@ -452,15 +471,15 @@ namespace openspace { checkGLError("createDepthTexture() -- Starting configuration"); glGenTextures(1, &_shadowDepthTexture); glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - glTexStorage2D( + /*glTexStorage2D( GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, _shadowDepthTextureWidth, _shadowDepthTextureHeight - ); + );*/ - /*glTexImage2D( + glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, @@ -470,15 +489,15 @@ namespace openspace { GL_DEPTH_COMPONENT, GL_FLOAT, 0 - );*/ + ); checkGLError("createDepthTexture() -- Depth testure created"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorder); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); checkGLError("createdDepthTexture"); @@ -519,24 +538,23 @@ namespace openspace { glGenFramebuffers(1, &_shadowFBO); glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); - glFramebufferTexture2D( + glFramebufferTexture( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_TEXTURE_2D, _shadowDepthTexture, 0 ); glFramebufferTexture( GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT3, + GL_COLOR_ATTACHMENT0, _positionInLightSpaceTexture, 0 ); checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); //GLenum drawBuffers[] = { GL_NONE }; - GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT3 }; - glDrawBuffers(4, drawBuffers); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + glDrawBuffers(3, drawBuffers); checkFrameBufferState("createShadowFBO()"); diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 95208c59b9..53c8d1f677 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -79,8 +79,8 @@ namespace openspace { bool isReady() const; - void begin(const RenderData& data); - void end(const RenderData& data); + RenderData begin(const RenderData& data); + void end(const RenderData& dataOrig); void update(const UpdateData& data); static documentation::Documentation Documentation(); From 0c0e3e47f30913a0ccacabc25ce153b6d62c0b62 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 10 Oct 2019 18:02:19 -0400 Subject: [PATCH 019/214] Fixing acne. --- modules/globebrowsing/shaders/rings_fs.glsl | 12 +++--- modules/globebrowsing/src/shadowcomponent.cpp | 43 ++++++++++++------- modules/globebrowsing/src/shadowcomponent.h | 4 ++ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 9cb82f01eb..41b5b11dca 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -28,7 +28,7 @@ in vec2 vs_st; in float vs_screenSpaceDepth; in vec4 vs_positionViewSpace; -in flat vec4 shadowCoords; +in vec4 shadowCoords; uniform sampler2D shadowPositionTexture; @@ -74,12 +74,14 @@ Fragment getFragment() { // shadow == 1.0 means it is not in shadow float shadow = 1.0; - //if ( shadowCoords.z >= 0 ) { + if ( shadowCoords.z >= 0 ) { vec4 normalizedShadowCoords = shadowCoords; - //normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.z); - normalizedShadowCoords.w = 1.0/normalizeFloat(normalizedShadowCoords.z); + normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; shadow = textureProj(shadowMap, normalizedShadowCoords); - //} + //shadow = textureProj(shadowMap, shadowCoords); + } // shadow = 1.0; // vec4 depthInTexture = vec4(0.0, 0.0, 0.0, 1.0); diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 118666680a..d0fdae7d66 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -248,6 +248,9 @@ namespace openspace { // New light source position glm::dvec3 lightPosition = data.modelTransform.translation + (lightDirection * multiplier); + + //// Light Position + //glm::dvec3 lightPosition = glm::dvec3(_sunPosition); // Saving current Camera parameters _cameraPos = data.camera.positionVec3(); @@ -284,7 +287,7 @@ namespace openspace { glm::dvec3 cameraZ = lightDirection; // camera X - glm::dvec3 upVector = glm::dvec3(0.0, -1.0, 0.0); + glm::dvec3 upVector = glm::dvec3(0.0, 1.0, 0.0); glm::dvec3 cameraX = glm::normalize(glm::cross(upVector, cameraZ)); // camera Y @@ -315,11 +318,11 @@ namespace openspace { global::navigationHandler.setFocusNode(data.); */ - Camera camera = data.camera; - camera.setPositionVec3(lightPosition); + _lightCamera = new Camera(data.camera); + _lightCamera->setPositionVec3(lightPosition); // JCC: We have aim and ancor nodes and position now. Need to fix this. //camera.setFocusPositionVec3(data.modelTransform.translation); - camera.setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); + _lightCamera->setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); //======================================================================= //======================================================================= @@ -327,7 +330,7 @@ namespace openspace { //============= Light Matrix by Camera Matrices Composition ============= //======================================================================= - glm::dmat4 lightProjectionMatrix = glm::dmat4(camera.projectionMatrix()); + glm::dmat4 lightProjectionMatrix = glm::dmat4(_lightCamera->projectionMatrix()); //glm::dmat4 lightProjectionMatrix = glm::ortho(-1000.0, 1000.0, -1000.0, 1000.0, 0.0010, 1000.0); //glm::dmat4 lightProjectionMatrix = glm::frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000000.0); @@ -336,10 +339,10 @@ namespace openspace { _shadowData.shadowMatrix = _toTextureCoordsMatrix * lightProjectionMatrix * - camera.combinedViewMatrix(); + _lightCamera->combinedViewMatrix(); // temp - _shadowData.worldToLightSpaceMatrix = glm::dmat4(camera.combinedViewMatrix()); + _shadowData.worldToLightSpaceMatrix = glm::dmat4(_lightCamera->combinedViewMatrix()); checkGLError("begin() -- Saving Current GL State"); // Saves current state @@ -383,12 +386,20 @@ namespace openspace { checkGLError("begin() finished"); - RenderData lightRenderData{ + /*RenderData lightRenderData{ camera, data.time, data.doPerformanceMeasurement, data.renderBinMask, data.modelTransform + };*/ + + RenderData lightRenderData{ + *_lightCamera, + data.time, + data.doPerformanceMeasurement, + data.renderBinMask, + data.modelTransform }; return lightRenderData; @@ -471,15 +482,15 @@ namespace openspace { checkGLError("createDepthTexture() -- Starting configuration"); glGenTextures(1, &_shadowDepthTexture); glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - /*glTexStorage2D( + glTexStorage2D( GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, _shadowDepthTextureWidth, _shadowDepthTextureHeight - );*/ + ); - glTexImage2D( + /*glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, @@ -489,15 +500,15 @@ namespace openspace { GL_DEPTH_COMPONENT, GL_FLOAT, 0 - ); + );*/ checkGLError("createDepthTexture() -- Depth testure created"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorder); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); checkGLError("createdDepthTexture"); diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 53c8d1f677..819e1289a0 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -35,6 +35,8 @@ #include #include +#include + #include #include #include @@ -150,6 +152,8 @@ namespace openspace { std::stringstream _serializedCamera; + Camera *_lightCamera; + // DEBUG bool _executeDepthTextureSave; From d4ad7c3394979aa5ae70792cbe45231206fb1430 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 11 Oct 2019 17:17:06 -0400 Subject: [PATCH 020/214] Improved performance. Clean up. --- modules/globebrowsing/shaders/rings_fs.glsl | 40 ++---- .../globebrowsing/shaders/rings_geom_fs.glsl | 3 - .../globebrowsing/shaders/rings_geom_vs.glsl | 16 +-- modules/globebrowsing/shaders/rings_vs.glsl | 24 ++-- modules/globebrowsing/src/renderableglobe.cpp | 29 +++-- modules/globebrowsing/src/ringscomponent.cpp | 50 ++++---- modules/globebrowsing/src/ringscomponent.h | 7 +- modules/globebrowsing/src/shadowcomponent.cpp | 119 +++--------------- modules/globebrowsing/src/shadowcomponent.h | 10 +- 9 files changed, 85 insertions(+), 213 deletions(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 41b5b11dca..34337c7fa8 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -27,13 +27,10 @@ in vec2 vs_st; in float vs_screenSpaceDepth; -in vec4 vs_positionViewSpace; in vec4 shadowCoords; -uniform sampler2D shadowPositionTexture; - -uniform sampler2DShadow shadowMap; -uniform sampler1D texture1; +uniform sampler2DShadow shadowMapTexture; +uniform sampler1D ringTexture; uniform vec2 textureOffset; uniform float transparency; @@ -64,7 +61,7 @@ Fragment getFragment() { discard; } - vec4 diffuse = texture(texture1, texCoord); + vec4 diffuse = texture(ringTexture, texCoord); float colorValue = length(diffuse.rgb); // times 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want // to normalize the transparency value to [0,1] @@ -76,30 +73,12 @@ Fragment getFragment() { float shadow = 1.0; if ( shadowCoords.z >= 0 ) { vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w); + normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - shadow = textureProj(shadowMap, normalizedShadowCoords); - //shadow = textureProj(shadowMap, shadowCoords); + shadow = textureProj(shadowMapTexture, normalizedShadowCoords); } - // shadow = 1.0; - // vec4 depthInTexture = vec4(0.0, 0.0, 0.0, 1.0); - // //if (shadowCoords.z >= 0) { - // if (true) { - // vec4 byHandCoords = shadowCoords / shadowCoords.w; - // // Distance of the current pixel from the light source - // depthInTexture = texture(shadowPositionTexture, byHandCoords.xy); - // //depthInTexture = texture(shadowPositionTexture, vec2(0.5, 0.5)); - // // if (depthInTexture.x < byHandCoords.z) { - // // shadow = 0.0; - // // } - // if (length(fragPosInLightSpace) > depthInTexture.x) { - // shadow = 0.2; - // } - // //shadow = length(fragPosInLightSpace); - // } - // The normal for the one plane depends on whether we are dealing // with a front facing or back facing fragment vec3 normal; @@ -119,15 +98,10 @@ Fragment getFragment() { } Fragment frag; - //frag.color = depthInTexture; + frag.color = (0.55 * diffuse * shadow) + diffuse * 0.45; - //frag.color = vec4(shadow * vec3(1.0, 1.0, 1.0), 1.0); - //frag.depth = vs_position.w; frag.depth = vs_screenSpaceDepth; - if (diffuse.a < 1.0) - frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); - else - frag.gPosition = vs_positionViewSpace; + frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); frag.gNormal = vec4(normal, 1.0); return frag; diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index aa50efc94a..4fc09ad60f 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -27,7 +27,6 @@ in vec2 vs_st; in float vs_screenSpaceDepth; -in vec4 vs_positionViewSpace; uniform vec2 textureOffset; @@ -66,8 +65,6 @@ Fragment getFragment() { Fragment frag; frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); frag.depth = vs_screenSpaceDepth; - //renderedPosition = vec4(vec3(length(vs_positionViewSpace.xyz)), 1.0);//vec4(vs_positionViewSpace.xyz, 1.0); - //renderedPosition = vec4(vec3(vs_screenSpaceDepth.w)/10.0, 1.0); return frag; } diff --git a/modules/globebrowsing/shaders/rings_geom_vs.glsl b/modules/globebrowsing/shaders/rings_geom_vs.glsl index 1b287f29d3..6eb0ca2390 100644 --- a/modules/globebrowsing/shaders/rings_geom_vs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_vs.glsl @@ -31,21 +31,17 @@ layout(location = 1) in vec2 in_st; out vec2 vs_st; out float vs_screenSpaceDepth; -out vec4 vs_positionViewSpace; -uniform dmat4 modelViewMatrix; -uniform dmat4 projectionMatrix; +uniform dmat4 modelViewProjectionMatrix; void main() { vs_st = in_st; - dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0); - vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace); - vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace); + dvec4 positionClipSpace = modelViewProjectionMatrix * + dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); vs_screenSpaceDepth = positionClipSpaceZNorm.w; - vs_positionViewSpace = vec4(positionViewSpace); - - //gl_Position = positionClipSpaceZNorm; - gl_Position = positionClipSpace; + + gl_Position = positionClipSpaceZNorm; } \ No newline at end of file diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl index 729e8615a1..5fb7d0fbeb 100644 --- a/modules/globebrowsing/shaders/rings_vs.glsl +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -34,12 +34,7 @@ out float vs_screenSpaceDepth; out vec4 vs_positionViewSpace; out vec4 shadowCoords; -// temp -out vec4 fragPosInLightSpace; -uniform dmat4 objectToLightSpaceMatrix; - -uniform dmat4 modelViewMatrix; -uniform dmat4 projectionMatrix; +uniform dmat4 modelViewProjectionMatrix; // ShadowMatrix is the matrix defined by: // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix @@ -50,18 +45,13 @@ uniform dmat4 shadowMatrix; void main() { vs_st = in_st; - dvec4 positionViewSpace = modelViewMatrix * dvec4(in_position, 0.0, 1.0); - vec4 positionClipSpace = vec4(projectionMatrix * positionViewSpace); - vec4 positionClipSpaceZNorm = z_normalization(positionClipSpace); + dvec4 positionClipSpace = modelViewProjectionMatrix * + dvec4(in_position, 0.0, 1.0); + vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); - // temp - fragPosInLightSpace = vec4(objectToLightSpaceMatrix * - dvec4(in_position.xy, 0.0, 1.0)); - - vs_screenSpaceDepth = positionClipSpaceZNorm.w; - vs_positionViewSpace = vec4(positionViewSpace); - //gl_Position = positionClipSpaceZNorm; - gl_Position = positionClipSpace; + vs_screenSpaceDepth = positionClipSpaceZNorm.w; + + gl_Position = positionClipSpaceZNorm; } diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index c595a5b8c8..ba838ea5ce 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -687,9 +687,10 @@ void RenderableGlobe::initializeGL() { _grid.initializeGL(); - _ringsComponent.initializeGL(); - - _shadowComponent.initializeGL(); + if (_hasRings) { + _ringsComponent.initializeGL(); + _shadowComponent.initializeGL(); + } // Recompile the shaders directly so that it is not done the first time the render // function is called. @@ -713,9 +714,10 @@ void RenderableGlobe::deinitializeGL() { _grid.deinitializeGL(); - _ringsComponent.deinitializeGL(); - - _shadowComponent.deinitializeGL(); + if (_hasRings) { + _ringsComponent.deinitializeGL(); + _shadowComponent.deinitializeGL(); + } } bool RenderableGlobe::isReady() const { @@ -746,21 +748,18 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask if (_hasRings && _ringsComponent.isEnabled()) { if (_shadowComponent.isEnabled()) { - // Render from light source point of view + // Set matrices and other GL states RenderData lightRenderData(_shadowComponent.begin(data)); glDisable(GL_BLEND); - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(2.5f, 10.0f); - + + // Render from light source point of view renderChunks(lightRenderData, rendererTask, true); _ringsComponent.draw(lightRenderData, RingsComponent::GeometryOnly); - - glEnable(GL_BLEND); - glDisable(GL_POLYGON_OFFSET_FILL); - _shadowComponent.end(data); - + glEnable(GL_BLEND); + + _shadowComponent.end(); // Render again from original point of view renderChunks(data, rendererTask); diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 9c7e2003f2..37b91e8233 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -56,13 +56,13 @@ #include namespace { - constexpr const std::array UniformNames = { - "modelViewMatrix", "projectionMatrix", "textureOffset", - "transparency", "_nightFactor", "sunPosition", "texture1" + constexpr const std::array UniformNames = { + "modelViewProjectionMatrix", "textureOffset", "transparency", "_nightFactor", + "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture" }; - constexpr const std::array GeomUniformNames = { - "modelViewMatrix", "projectionMatrix", "textureOffset" + constexpr const std::array GeomUniformNames = { + "modelViewProjectionMatrix", "textureOffset" }; constexpr openspace::properties::Property::PropertyInfo TextureInfo = { @@ -273,50 +273,44 @@ namespace openspace { glm::dmat4(data.modelTransform.rotation) * glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); - const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; - const glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); + const glm::dmat4 modelViewProjectionTransform = + glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() + * modelTransform; - ghoul::opengl::TextureUnit unit; if (renderPass == GeometryAndShading) { - _shader->setUniform(_uniformCache.modelViewMatrix, modelViewTransform); - _shader->setUniform(_uniformCache.projectionMatrix, projectionMatrix); + _shader->setUniform( + _uniformCache.modelViewProjectionMatrix, + modelViewProjectionTransform + ); _shader->setUniform(_uniformCache.textureOffset, _offset); _shader->setUniform(_uniformCache.transparency, _transparency); _shader->setUniform(_uniformCache.nightFactor, _nightFactor); _shader->setUniform(_uniformCache.sunPosition, _sunPosition); - unit.activate(); + ghoul::opengl::TextureUnit ringTextureUnit; + ringTextureUnit.activate(); _texture->bind(); - _shader->setUniform(_uniformCache.texture, unit); + _shader->setUniform(_uniformCache.ringTexture, ringTextureUnit); // Adding the model transformation to the final shadow matrix so we have a // complete transformation from the model coordinates to the clip space of // the light position. - _shader->setUniform("shadowMatrix", shadowData.shadowMatrix * modelTransform); + _shader->setUniform( + _uniformCache.shadowMatrix, + shadowData.shadowMatrix * modelTransform + ); ghoul::opengl::TextureUnit shadowMapUnit; shadowMapUnit.activate(); glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); - _shader->setUniform("shadowMap", shadowMapUnit); - - // DEBUGGING - ghoul::opengl::TextureUnit shadowTextureUnit; - shadowTextureUnit.activate(); - glBindTexture(GL_TEXTURE_2D, shadowData.positionInLightSpaceTexture); - _shader->setUniform("shadowPositionTexture", shadowTextureUnit); - _shader->setUniform("objectToLightSpaceMatrix", - shadowData.worldToLightSpaceMatrix * modelTransform); + _shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit); } else if (renderPass == GeometryOnly) { _geometryOnlyShader->setUniform( - _geomUniformCache.modelViewMatrix, - modelViewTransform - ); - _geometryOnlyShader->setUniform( - _geomUniformCache.projectionMatrix, - projectionMatrix + _geomUniformCache.modelViewProjectionMatrix, + modelViewProjectionTransform ); _geometryOnlyShader->setUniform( _geomUniformCache.textureOffset, diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index 4ebb05b963..9c24eecdd3 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -95,9 +95,10 @@ namespace openspace { std::unique_ptr _shader; std::unique_ptr _geometryOnlyShader; - UniformCache(modelViewMatrix, projectionMatrix, textureOffset, - transparency, nightFactor, sunPosition, texture) _uniformCache; - UniformCache(modelViewMatrix, projectionMatrix, textureOffset) _geomUniformCache; + UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, + sunPosition, ringTexture, shadowMatrix, shadowMapTexture + ) _uniformCache; + UniformCache(modelViewProjectionMatrix, textureOffset) _geomUniformCache; std::unique_ptr _texture; std::unique_ptr _textureFile; diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index d0fdae7d66..2c308b04aa 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -165,11 +165,11 @@ namespace openspace { ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) : properties::PropertyOwner({ "Shadows" }) , _saveDepthTexture(SaveDepthTextureInfo) - , _distanceFraction(DistanceFractionInfo, 30, 1, 100000) + , _distanceFraction(DistanceFractionInfo, 30, 1, 1000) , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) , _shadowMapDictionary(dictionary) - , _shadowDepthTextureHeight(1024) - , _shadowDepthTextureWidth(1024) + , _shadowDepthTextureHeight(4096) + , _shadowDepthTextureWidth(4096) , _shadowDepthTexture(-1) , _positionInLightSpaceTexture(-1) , _shadowFBO(-1) @@ -252,35 +252,6 @@ namespace openspace { //// Light Position //glm::dvec3 lightPosition = glm::dvec3(_sunPosition); - // Saving current Camera parameters - _cameraPos = data.camera.positionVec3(); - // JCC: We have aim and ancor nodes and position now. Need to fix this. - //_cameraFocus = data.camera.focusPositionVec3(); - - //const SceneGraphNode * origAimNode = global::navigationHandler.orbitalNavigator().aimNode(); - //const SceneGraphNode * origAnchorNode = global::navigationHandler.orbitalNavigator().anchorNode(); - - _cameraRotation = data.camera.rotationQuaternion(); - - //=============== Automatically Created Camera Matrix =================== - //======================================================================= - //glm::dmat4 lightViewMatrix = glm::lookAt( - // //lightPosition, - // glm::dvec3(0.0), - // //glm::dvec3(_sunPosition), // position - // glm::dvec3(data.modelTransform.translation), // focus - // data.camera.lookUpVectorWorldSpace() // up - // //glm::dvec3(0.0, 1.0, 0.0) - //); - - //camera->setPositionVec3(lightPosition); - //camera->setFocusPositionVec3(data.modelTransform.translation); - //camera->setRotation(glm::dquat(glm::inverse(lightViewMatrix))); - - //======================================================================= - //======================================================================= - - //=============== Manually Created Camera Matrix =================== //================================================================== // camera Z @@ -314,16 +285,10 @@ namespace openspace { //matrix[13] = -glm::dot(cameraY, lightPosition); //matrix[14] = -glm::dot(cameraZ, lightPosition); - /*Scene* scene = camera->parent()->scene(); - global::navigationHandler.setFocusNode(data.); - */ - _lightCamera = new Camera(data.camera); + _lightCamera = std::move(std::unique_ptr(new Camera(data.camera))); _lightCamera->setPositionVec3(lightPosition); - // JCC: We have aim and ancor nodes and position now. Need to fix this. - //camera.setFocusPositionVec3(data.modelTransform.translation); _lightCamera->setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); - //======================================================================= //======================================================================= @@ -331,9 +296,7 @@ namespace openspace { //============= Light Matrix by Camera Matrices Composition ============= //======================================================================= glm::dmat4 lightProjectionMatrix = glm::dmat4(_lightCamera->projectionMatrix()); - //glm::dmat4 lightProjectionMatrix = glm::ortho(-1000.0, 1000.0, -1000.0, 1000.0, 0.0010, 1000.0); - //glm::dmat4 lightProjectionMatrix = glm::frustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000000.0); - + // The model transformation missing in the final shadow matrix is add when rendering each // object (using its transformations provided by the RenderData structure) _shadowData.shadowMatrix = @@ -341,10 +304,7 @@ namespace openspace { lightProjectionMatrix * _lightCamera->combinedViewMatrix(); - // temp - _shadowData.worldToLightSpaceMatrix = glm::dmat4(_lightCamera->combinedViewMatrix()); - - checkGLError("begin() -- Saving Current GL State"); + // Saves current state glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); glGetIntegerv(GL_VIEWPORT, _mViewport); @@ -360,19 +320,15 @@ namespace openspace { _blendIsEnabled = glIsEnabled(GL_BLEND); - checkGLError("begin() -- before binding FBO"); glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; glDrawBuffers(3, drawBuffers); - checkGLError("begin() -- after binding FBO"); glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight); - checkGLError("begin() -- set new viewport"); glClearDepth(1.0f); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - checkGLError("begin() -- after cleanning Depth buffer"); /*glEnable(GL_CULL_FACE); @@ -384,16 +340,6 @@ namespace openspace { glPolygonOffset(2.5f, 10.0f); checkGLError("begin() -- set values for polygon offset");*/ - checkGLError("begin() finished"); - - /*RenderData lightRenderData{ - camera, - data.time, - data.doPerformanceMeasurement, - data.renderBinMask, - data.modelTransform - };*/ - RenderData lightRenderData{ *_lightCamera, data.time, @@ -405,28 +351,18 @@ namespace openspace { return lightRenderData; } - void ShadowComponent::end(const RenderData& dataOrig) { - checkGLError("end() -- Flushing"); - //glFlush(); + void ShadowComponent::end() { if (_executeDepthTextureSave) { saveDepthBuffer(); _executeDepthTextureSave = false; } - // Restores Camera Parameters - Camera camera = dataOrig.camera; - camera.setPositionVec3(_cameraPos); - // JCC: We have aim and ancor nodes and position now. Need to fix this. - //camera.setFocusPositionVec3(_cameraFocus); - camera.setRotation(_cameraRotation); - // Restores system state glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; glDrawBuffers(3, drawBuffers); - checkGLError("end() -- Rebinding default FBO"); glViewport( _mViewport[0], _mViewport[1], @@ -470,8 +406,6 @@ namespace openspace { if (_blendIsEnabled) { glEnable(GL_BLEND); } - - checkGLError("end() finished"); } void ShadowComponent::update(const UpdateData& /*data*/) { @@ -479,7 +413,6 @@ namespace openspace { } void ShadowComponent::createDepthTexture() { - checkGLError("createDepthTexture() -- Starting configuration"); glGenTextures(1, &_shadowDepthTexture); glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); glTexStorage2D( @@ -501,21 +434,19 @@ namespace openspace { GL_FLOAT, 0 );*/ - checkGLError("createDepthTexture() -- Depth testure created"); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, shadowBorder); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, ShadowBorder); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - checkGLError("createdDepthTexture"); + + checkGLError("createDepthTexture() -- Depth testure created"); - glGenTextures(1, &_positionInLightSpaceTexture); + /*glGenTextures(1, &_positionInLightSpaceTexture); glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); - //glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glTexImage2D( GL_TEXTURE_2D, 0, @@ -527,13 +458,11 @@ namespace openspace { GL_FLOAT, nullptr ); - checkGLError("createDepthTexture() -- Position/Distance buffer created"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - checkGLError("createdPositionTexture"); - + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ + glBindTexture(GL_TEXTURE_2D, 0); _shadowData.shadowDepthTexture = _shadowDepthTexture; @@ -544,9 +473,7 @@ namespace openspace { // Saves current FBO first glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); - /*GLint _mViewport[4]; - glGetIntegerv(GL_VIEWPORT, _mViewport);*/ - + glGenFramebuffers(1, &_shadowFBO); glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); glFramebufferTexture( @@ -556,28 +483,22 @@ namespace openspace { 0 ); - glFramebufferTexture( + /*glFramebufferTexture( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _positionInLightSpaceTexture, 0 - ); + );*/ + checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); - //GLenum drawBuffers[] = { GL_NONE }; - GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE }; glDrawBuffers(3, drawBuffers); checkFrameBufferState("createShadowFBO()"); // Restores system state glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); - /*glViewport( - _mViewport[0], - _mViewport[1], - _mViewport[2], - _mViewport[3] - );*/ - checkGLError("createShadowFBO() -- createdShadowFBO"); } void ShadowComponent::saveDepthBuffer() { diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 819e1289a0..ddb5752af5 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -60,7 +60,7 @@ namespace openspace { namespace documentation { struct Documentation; } - static const GLfloat shadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; + static const GLfloat ShadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; class ShadowComponent : public properties::PropertyOwner { public: @@ -82,7 +82,7 @@ namespace openspace { bool isReady() const; RenderData begin(const RenderData& data); - void end(const RenderData& dataOrig); + void end(); void update(const UpdateData& data); static documentation::Documentation Documentation(); @@ -107,8 +107,8 @@ namespace openspace { const glm::dmat4 _toTextureCoordsMatrix = glm::dmat4( glm::dvec4(0.5, 0.0, 0.0, 0.0), glm::dvec4(0.0, 0.5, 0.0, 0.0), - glm::dvec4(0.0, 0.0, 0.5, 0.0), - glm::dvec4(0.5, 0.5, 0.5, 1.0) + glm::dvec4(0.0, 0.0, 1.0, 0.0), + glm::dvec4(0.5, 0.5, 0.0, 1.0) ); // DEBUG @@ -152,7 +152,7 @@ namespace openspace { std::stringstream _serializedCamera; - Camera *_lightCamera; + std::unique_ptr _lightCamera; // DEBUG bool _executeDepthTextureSave; From b591af3c2a1697b919c73e5ecc7dceddb24ea044 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 11 Oct 2019 18:11:22 -0400 Subject: [PATCH 021/214] Initial tests for performance improvements. --- modules/galaxy/shaders/galaxyraycast.glsl | 19 ++++++++------- shaders/framebuffer/raycastframebuffer.frag | 26 ++++++++++----------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index a16188aa5d..dab687e3ca 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -29,17 +29,18 @@ uniform float absorptionMultiply#{id} = 50.0; uniform float emissionMultiply#{id} = 1500.0; uniform sampler3D galaxyTexture#{id}; -void sample#{id}(vec3 samplePos, +void sample#{id}( + vec3 samplePos, vec3 dir, inout vec3 accumulatedColor, inout vec3 accumulatedAlpha, - inout float stepSize) - { + inout float stepSize + ) { vec3 aspect = aspect#{id}; stepSize = maxStepSize#{id} / length(dir / aspect); //Early ray termination on black parts of the data - vec3 normalizedPos = samplePos*2.0 - 1.0; + vec3 normalizedPos = samplePos * 2.f - 1.f; if (normalizedPos.x * normalizedPos.x + normalizedPos.y * normalizedPos.y > 0.7) { return; } @@ -51,12 +52,12 @@ void sample#{id}(vec3 samplePos, sampledColor = sampledColor*sampledColor; // Fudge for the dust "spreading" - sampledColor.a = clamp(sampledColor.a, 0.0, 1.0); - sampledColor.a = pow(sampledColor.a, 0.7); + sampledColor.a = clamp(sampledColor.a, 0.f, 1.f); + sampledColor.a = pow(sampledColor.a, 0.7f); // Absorption probability float scaledDensity = sampledColor.a * stepSize * absorptionMultiply#{id}; - vec3 alphaTint = vec3(0.3, 0.54, 0.85); + vec3 alphaTint = vec3(0.3f, 0.54f, 0.85f); vec3 absorption = alphaTint * scaledDensity; // Extinction @@ -67,10 +68,10 @@ void sample#{id}(vec3 samplePos, accumulatedColor.rgb += sampledColor.rgb * stepSize * emissionMultiply#{id} * opacityCoefficient#{id}; - vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + vec3 oneMinusFrontAlpha = vec3(1.f) - accumulatedAlpha; accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb * opacityCoefficient#{id}; } float stepSize#{id}(vec3 samplePos, vec3 dir) { - return maxStepSize#{id} * length(dir * 1.0 / aspect#{id}); + return maxStepSize#{id} * length(dir * 1.f / aspect#{id}); } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 6a949b4cc9..b5a972cff8 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -45,7 +45,7 @@ uniform vec2 windowSize; out vec4 finalColor; #define ALPHA_LIMIT 0.99 -#define RAYCAST_MAX_STEPS 1000 +#define RAYCAST_MAX_STEPS 480 #include <#{getEntryPath}> @@ -55,7 +55,7 @@ void main() { vec4 exitColorTexture = texture(exitColorTexture, texCoord); // If we don't have an exit, discard the ray - if (exitColorTexture.a < 1.0 || exitColorTexture.rgb == vec3(0.0)) { + if (exitColorTexture.a < 1.f || exitColorTexture.rgb == vec3(0.f)) { discard; } @@ -63,13 +63,13 @@ void main() { vec3 exitPos = exitColorTexture.rgb; float exitDepth = denormalizeFloat(texture(exitDepthTexture, texCoord).x); - float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 + float jitterFactor = 0.5f + 0.5f * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 vec3 entryPos; float entryDepth; getEntry(entryPos, entryDepth); // If we don't have an entry, discard the ray - if (entryPos == vec3(0.0)) { + if (entryPos == vec3(0.f)) { discard; } @@ -80,21 +80,21 @@ void main() { float raycastDepth = length(diff); float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); - float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0); + float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.f, 1.f); raycastDepth = geoRatio * raycastDepth; - float currentDepth = 0.0; + float currentDepth = 0.f; float nextStepSize = stepSize#{id}(position, direction); float currentStepSize; - float previousJitterDistance = 0.0; + float previousJitterDistance = 0.f; int nSteps = 0; int sampleIndex = 0; - float opacityDecay = 1.0; + float opacityDecay = 1.f; - vec3 accumulatedColor = vec3(0.0); - vec3 accumulatedAlpha = vec3(0.0); + vec3 accumulatedColor = vec3(0.f); + vec3 accumulatedAlpha = vec3(0.f); for (nSteps = 0; @@ -102,7 +102,7 @@ void main() { accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < RAYCAST_MAX_STEPS; ++nSteps) { - if (nextStepSize < raycastDepth / 10000000000.0) { + if (nextStepSize < raycastDepth / 10000000000.f) { break; } @@ -110,7 +110,7 @@ void main() { currentDepth += currentStepSize; float jitteredStepSize = currentStepSize * jitterFactor; - vec3 jitteredPosition = position + direction*jitteredStepSize; + vec3 jitteredPosition = position + direction * jitteredStepSize; position += direction * currentStepSize; sample#{id}(jitteredPosition, direction, accumulatedColor, accumulatedAlpha, nextStepSize); @@ -122,7 +122,7 @@ void main() { nextStepSize = min(nextStepSize, maxStepSize); } - finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3); + finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3.f); finalColor.rgb /= finalColor.a ; gl_FragDepth = normalizeFloat(entryDepth); From 2df5a4c9bcb8f9b5e3df58f40937224518f9cba6 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 14 Oct 2019 12:17:14 -0400 Subject: [PATCH 022/214] Improved shadows quality and added planet shadows. --- .../shaders/globalrenderer_vs.glsl | 12 ++++ .../shaders/localrenderer_vs.glsl | 12 ++++ .../globebrowsing/shaders/renderer_fs.glsl | 17 +++++ .../globebrowsing/shaders/rings_geom_fs.glsl | 5 +- .../shaders/texturetilemapping.hglsl | 1 + modules/globebrowsing/src/renderableglobe.cpp | 62 ++++++++++++++++--- modules/globebrowsing/src/renderableglobe.h | 13 +++- modules/globebrowsing/src/ringscomponent.cpp | 10 ++- modules/globebrowsing/src/ringscomponent.h | 3 +- modules/globebrowsing/src/shadowcomponent.cpp | 11 ++-- modules/globebrowsing/src/shadowcomponent.h | 3 - 11 files changed, 126 insertions(+), 23 deletions(-) diff --git a/modules/globebrowsing/shaders/globalrenderer_vs.glsl b/modules/globebrowsing/shaders/globalrenderer_vs.glsl index 8e91e2e6a4..84c0edbc7f 100644 --- a/modules/globebrowsing/shaders/globalrenderer_vs.glsl +++ b/modules/globebrowsing/shaders/globalrenderer_vs.glsl @@ -48,6 +48,14 @@ out vec3 positionCameraSpace; uniform dmat4 modelTransform; #endif +#if SHADOW_MAPPING_ENABLED + // ShadowMatrix is the matrix defined by: + // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix + // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] + uniform dmat4 shadowMatrix; + out vec4 shadowCoords; +#endif + uniform mat4 modelViewProjectionTransform; uniform mat4 modelViewTransform; uniform vec3 radiiSquared; @@ -130,4 +138,8 @@ void main() { #if USE_ECLIPSE_SHADOWS positionWorldSpace = vec3(modelTransform * dvec4(pair.position, 1.0)); #endif + +#if SHADOW_MAPPING_ENABLED + shadowCoords = vec4(shadowMatrix * dvec4(pair.position, 1.0)); +#endif } diff --git a/modules/globebrowsing/shaders/localrenderer_vs.glsl b/modules/globebrowsing/shaders/localrenderer_vs.glsl index 5e6ef0e12b..cdafdef007 100644 --- a/modules/globebrowsing/shaders/localrenderer_vs.glsl +++ b/modules/globebrowsing/shaders/localrenderer_vs.glsl @@ -48,6 +48,14 @@ out vec3 positionWorldSpace; uniform dmat4 inverseViewTransform; #endif +#if SHADOW_MAPPING_ENABLED + // ShadowMatrix is the matrix defined by: + // textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix + // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] + uniform dmat4 shadowMatrix; + out vec4 shadowCoords; +#endif + uniform mat4 projectionTransform; // Input points in camera space uniform vec3 p00; @@ -113,4 +121,8 @@ void main() { #if USE_ECLIPSE_SHADOWS positionWorldSpace = vec3(inverseViewTransform * dvec4(p, 1.0)); #endif + +#if SHADOW_MAPPING_ENABLED + shadowCoords = vec4(shadowMatrix * dvec4(p, 1.0)); +#endif } diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index f0408f7941..ad2334bf55 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -59,6 +59,11 @@ uniform vec3 lightDirectionCameraSpace; uniform float orenNayarRoughness; #endif +#if SHADOW_MAPPING_ENABLED +in vec4 shadowCoords; +uniform sampler2DShadow shadowMapTexture; +#endif + #if USE_ECLIPSE_SHADOWS /******************************************************************************* @@ -258,5 +263,17 @@ Fragment getFragment() { } #endif // SHOW_CHUNK_EDGES +#if SHADOW_MAPPING_ENABLED + float shadow = 1.0; + if ( shadowCoords.z >= 0 ) { + vec4 normalizedShadowCoords = shadowCoords; + normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; + shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + } + frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow; +#endif + return frag; } diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 4fc09ad60f..88e43984a9 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -28,6 +28,7 @@ in vec2 vs_st; in float vs_screenSpaceDepth; +uniform sampler1D ringTexture; uniform vec2 textureOffset; Fragment getFragment() { @@ -49,6 +50,8 @@ Fragment getFragment() { if (texCoord < 0.f || texCoord > 1.f) { discard; } + + float diffuse = length(texture(ringTexture, texCoord).rgb); // The normal for the one plane depends on whether we are dealing // with a front facing or back facing fragment @@ -64,7 +67,7 @@ Fragment getFragment() { Fragment frag; frag.color = vec4(vec3(vs_screenSpaceDepth), 1.0); - frag.depth = vs_screenSpaceDepth; + frag.depth = (diffuse < 0.5) ? 1E30 : vs_screenSpaceDepth; return frag; } diff --git a/modules/globebrowsing/shaders/texturetilemapping.hglsl b/modules/globebrowsing/shaders/texturetilemapping.hglsl index 24820242c7..cf94053125 100644 --- a/modules/globebrowsing/shaders/texturetilemapping.hglsl +++ b/modules/globebrowsing/shaders/texturetilemapping.hglsl @@ -64,6 +64,7 @@ #define SHOW_CHUNK_EDGES #{showChunkEdges} #define SHOW_HEIGHT_RESOLUTION #{showHeightResolution} #define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities} +#define SHADOW_MAPPING_ENABLED #{enableShadowMapping} const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0); diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index ba838ea5ce..9b226dd9ca 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -184,6 +184,12 @@ namespace { "Enables the rendering of eclipse shadows using hard shadows" }; + constexpr openspace::properties::Property::PropertyInfo ShadowMappingInfo = { + "ShadowMapping", + "Shadow Mapping", + "Enables shadow mapping algorithm. Used by renderable rings too." + }; + constexpr openspace::properties::Property::PropertyInfo TargetLodScaleFactorInfo = { "TargetLodScaleFactor", "Target Level of Detail Scale Factor", @@ -495,6 +501,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) BoolProperty(AccurateNormalsInfo, false), BoolProperty(EclipseInfo, false), BoolProperty(EclipseHardShadowsInfo, false), + BoolProperty(ShadowMappingInfo, false), FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f), @@ -537,6 +544,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) addProperty(_generalProperties.useAccurateNormals); addProperty(_generalProperties.eclipseShadowsEnabled); addProperty(_generalProperties.eclipseHardShadows); + addProperty(_generalProperties.shadowMapping); _generalProperties.targetLodScaleFactor.onChange([this]() { float sf = _generalProperties.targetLodScaleFactor; _generalProperties.currentLodScaleFactor = sf; @@ -566,6 +574,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _generalProperties.eclipseShadowsEnabled.onChange(notifyShaderRecompilation); _generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation); _generalProperties.performShading.onChange(notifyShaderRecompilation); + _generalProperties.shadowMapping.onChange(notifyShaderRecompilation); _debugProperties.showChunkEdges.onChange(notifyShaderRecompilation); _debugProperties.showHeightResolution.onChange(notifyShaderRecompilation); _debugProperties.showHeightIntensities.onChange(notifyShaderRecompilation); @@ -747,14 +756,13 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask if (_hasRings && _ringsComponent.isEnabled()) { if (_shadowComponent.isEnabled()) { - // Set matrices and other GL states RenderData lightRenderData(_shadowComponent.begin(data)); glDisable(GL_BLEND); // Render from light source point of view - renderChunks(lightRenderData, rendererTask, true); + renderChunks(lightRenderData, rendererTask, {}, true); _ringsComponent.draw(lightRenderData, RingsComponent::GeometryOnly); glEnable(GL_BLEND); @@ -762,7 +770,7 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask _shadowComponent.end(); // Render again from original point of view - renderChunks(data, rendererTask); + renderChunks(data, rendererTask, _shadowComponent.shadowMapData()); _ringsComponent.draw( data, RingsComponent::GeometryAndShading, @@ -917,7 +925,7 @@ const glm::dmat4& RenderableGlobe::modelTransform() const { ////////////////////////////////////////////////////////////////////////////////////////// void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, - const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { if (_shadersNeedRecompilation) { recompileShaders(); } @@ -1151,7 +1159,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, // Render all chunks that want to be rendered globally _globalRenderer.program->activate(); for (int i = 0; i < std::min(globalCount, ChunkBufferSize); ++i) { - renderChunkGlobally(*global[i], data, renderGeomOnly); + renderChunkGlobally(*global[i], data, shadowData, renderGeomOnly); } _globalRenderer.program->deactivate(); @@ -1159,7 +1167,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, // Render all chunks that need to be rendered locally _localRenderer.program->activate(); for (int i = 0; i < std::min(localCount, ChunkBufferSize); ++i) { - renderChunkLocally(*local[i], data, renderGeomOnly); + renderChunkLocally(*local[i], data, shadowData, renderGeomOnly); } _localRenderer.program->deactivate(); @@ -1217,7 +1225,7 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, } void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data, - const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { //PerfMeasure("globally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_globalRenderer.program; @@ -1264,6 +1272,23 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& calculateEclipseShadows(program, data, ShadowCompType::GLOBAL_SHADOW); } + // Shadow Mapping + ghoul::opengl::TextureUnit shadowMapUnit; + if (_generalProperties.shadowMapping && shadowData.shadowDepthTexture != 0) { + // Adding the model transformation to the final shadow matrix so we have a + // complete transformation from the model coordinates to the clip space of + // the light position. + program.setUniform( + "shadowMatrix", + shadowData.shadowMatrix * modelTransform() + ); + + shadowMapUnit.activate(); + glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); + + program.setUniform("shadowMapTexture", shadowMapUnit); + } + glEnable(GL_DEPTH_TEST); if (!renderGeomOnly) { @@ -1279,7 +1304,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& } void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data, - const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { //PerfMeasure("locally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_localRenderer.program; @@ -1371,6 +1396,23 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d calculateEclipseShadows(program, data, ShadowCompType::LOCAL_SHADOW); } + // Shadow Mapping + ghoul::opengl::TextureUnit shadowMapUnit; + if (_generalProperties.shadowMapping && shadowData.shadowDepthTexture != 0) { + // Adding the model transformation to the final shadow matrix so we have a + // complete transformation from the model coordinates to the clip space of + // the light position. + program.setUniform( + "shadowMatrix", + shadowData.shadowMatrix * modelTransform() + ); + + shadowMapUnit.activate(); + glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); + + program.setUniform("shadowMapTexture", shadowMapUnit); + } + glEnable(GL_DEPTH_TEST); if (!renderGeomOnly) { glEnable(GL_CULL_FACE); @@ -1538,6 +1580,10 @@ void RenderableGlobe::recompileShaders() { "useEclipseHardShadows", std::to_string(_generalProperties.eclipseHardShadows) ); + pairs.emplace_back( + "enableShadowMapping", + std::to_string(_generalProperties.shadowMapping) + ); pairs.emplace_back("showChunkEdges", std::to_string(_debugProperties.showChunkEdges)); pairs.emplace_back("showHeightResolution", std::to_string(_debugProperties.showHeightResolution) diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 87fe7aa30b..240f281736 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -138,6 +138,7 @@ private: properties::BoolProperty useAccurateNormals; properties::BoolProperty eclipseShadowsEnabled; properties::BoolProperty eclipseHardShadows; + properties::BoolProperty shadowMapping; properties::FloatProperty targetLodScaleFactor; properties::FloatProperty currentLodScaleFactor; properties::FloatProperty cameraMinHeight; @@ -184,7 +185,9 @@ private: float getHeight(const glm::dvec3& position) const; void renderChunks(const RenderData& data, RendererTasks& rendererTask, - const bool renderGeomOnly = false); + const ShadowComponent::ShadowMapData& shadowData = {}, + const bool renderGeomOnly = false + ); /** * Chunks can be rendered either globally or locally. Global rendering is performed @@ -195,7 +198,9 @@ private: * tile will lead to jagging. We only render global chunks for lower chunk levels. */ void renderChunkGlobally(const Chunk& chunk, const RenderData& data, - const bool renderGeomOnly = false); + const ShadowComponent::ShadowMapData& shadowData = {}, + const bool renderGeomOnly = false + ); /** * Local rendering of chunks are done using linear interpolation in camera space. @@ -209,7 +214,9 @@ private: * chunks for higher chunk levels. */ void renderChunkLocally(const Chunk& chunk, const RenderData& data, - const bool renderGeomOnly = false); + const ShadowComponent::ShadowMapData& shadowData = {}, + const bool renderGeomOnly = false + ); void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp, bool renderBounds, bool renderAABB) const; diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 37b91e8233..699201e654 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -61,8 +61,8 @@ namespace { "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture" }; - constexpr const std::array GeomUniformNames = { - "modelViewProjectionMatrix", "textureOffset" + constexpr const std::array GeomUniformNames = { + "modelViewProjectionMatrix", "textureOffset", "ringTexture" }; constexpr openspace::properties::Property::PropertyInfo TextureInfo = { @@ -277,6 +277,7 @@ namespace openspace { glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() * modelTransform; + ghoul::opengl::TextureUnit ringTextureUnit; if (renderPass == GeometryAndShading) { _shader->setUniform( _uniformCache.modelViewProjectionMatrix, @@ -287,7 +288,6 @@ namespace openspace { _shader->setUniform(_uniformCache.nightFactor, _nightFactor); _shader->setUniform(_uniformCache.sunPosition, _sunPosition); - ghoul::opengl::TextureUnit ringTextureUnit; ringTextureUnit.activate(); _texture->bind(); _shader->setUniform(_uniformCache.ringTexture, ringTextureUnit); @@ -316,6 +316,10 @@ namespace openspace { _geomUniformCache.textureOffset, _offset ); + + ringTextureUnit.activate(); + _texture->bind(); + _shader->setUniform(_geomUniformCache.ringTexture, ringTextureUnit); } glEnable(GL_DEPTH_TEST); diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index 9c24eecdd3..0b4d796bf9 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -98,7 +98,8 @@ namespace openspace { UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, sunPosition, ringTexture, shadowMatrix, shadowMapTexture ) _uniformCache; - UniformCache(modelViewProjectionMatrix, textureOffset) _geomUniformCache; + UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture) + _geomUniformCache; std::unique_ptr _texture; std::unique_ptr _textureFile; diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 2c308b04aa..acea310fa5 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -165,7 +165,7 @@ namespace openspace { ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) : properties::PropertyOwner({ "Shadows" }) , _saveDepthTexture(SaveDepthTextureInfo) - , _distanceFraction(DistanceFractionInfo, 30, 1, 1000) + , _distanceFraction(DistanceFractionInfo, 3, 1, 10000) , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) , _shadowMapDictionary(dictionary) , _shadowDepthTextureHeight(4096) @@ -242,8 +242,11 @@ namespace openspace { glm::dvec3 lightDirection = glm::normalize(diffVector); // Percentage of the original light source distance (to avoid artifacts) - double multiplier = originalLightDistance * - (static_cast(_distanceFraction)/1.0E5); + /*double multiplier = originalLightDistance * + (static_cast(_distanceFraction)/1.0E5);*/ + + double multiplier = originalLightDistance * + (static_cast(_distanceFraction) / 10000.0); // New light source position glm::dvec3 lightPosition = data.modelTransform.translation + @@ -466,7 +469,7 @@ namespace openspace { glBindTexture(GL_TEXTURE_2D, 0); _shadowData.shadowDepthTexture = _shadowDepthTexture; - _shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; + //_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; } void ShadowComponent::createShadowFBO() { diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index ddb5752af5..bfdbb7c0b5 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -66,10 +66,7 @@ namespace openspace { public: struct ShadowMapData { glm::dmat4 shadowMatrix; - // temp - glm::dmat4 worldToLightSpaceMatrix; GLuint shadowDepthTexture; - GLuint positionInLightSpaceTexture; }; public: ShadowComponent(const ghoul::Dictionary& dictionary); From eee55bc68f53dcd0bc7e28b612d3fa07aa3376dc Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 16 Oct 2019 18:06:02 -0400 Subject: [PATCH 023/214] Added Percentage Closer Filter. --- modules/globebrowsing/shaders/renderer_fs.glsl | 18 ++++++++++++++++-- modules/globebrowsing/shaders/rings_fs.glsl | 14 +++++++++++++- modules/globebrowsing/src/shadowcomponent.cpp | 8 +++++--- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index ad2334bf55..77926c9ce8 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -265,12 +265,26 @@ Fragment getFragment() { #if SHADOW_MAPPING_ENABLED float shadow = 1.0; - if ( shadowCoords.z >= 0 ) { + if ( shadowCoords.w > 1 ) { vec4 normalizedShadowCoords = shadowCoords; normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + float sum = 0; + int fStep = 5; + for (int i = 0; i < fStep; ++i) { + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, -fStep + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, fStep - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, -fStep + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, fStep - i)); + } + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0)); + shadow = sum / (8.f * fStep + 1.f); } frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow; #endif diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 34337c7fa8..551f1ebb01 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -76,7 +76,19 @@ Fragment getFragment() { normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + float sum = 0; + int fStep = 2; + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, -fStep)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, fStep)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, -fStep)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, fStep)); + shadow = sum / 9.f; } // The normal for the one plane depends on whether we are dealing diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index acea310fa5..1a64a0836f 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -246,11 +246,13 @@ namespace openspace { (static_cast(_distanceFraction)/1.0E5);*/ double multiplier = originalLightDistance * - (static_cast(_distanceFraction) / 10000.0); + (static_cast(_distanceFraction) / 1E17); // New light source position - glm::dvec3 lightPosition = data.modelTransform.translation + - (lightDirection * multiplier); + /*glm::dvec3 lightPosition = data.modelTransform.translation + + (lightDirection * multiplier);*/ + glm::dvec3 lightPosition = data.modelTransform.translation + + (diffVector * multiplier); //// Light Position //glm::dvec3 lightPosition = glm::dvec3(_sunPosition); From 18810384dc88d13ba170793f23e26bb6be91a2e4 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 18 Oct 2019 17:12:57 -0600 Subject: [PATCH 024/214] Initial commit of profiles, containing convert-to-scene script --- apps/OpenSpace/main.cpp | 18 +- include/openspace/engine/configuration.h | 1 + scripts/_makeAsset.lua | 176 +++++++++++++ scripts/_parser.lua | 299 +++++++++++++++++++++++ scripts/convertProfileToScene.lua | 7 + src/engine/configuration.cpp | 11 + 6 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 scripts/_makeAsset.lua create mode 100644 scripts/_parser.lua create mode 100644 scripts/convertProfileToScene.lua diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 1be2584abe..9d9fa49ba8 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -1172,7 +1172,7 @@ int main(int argc, char** argv) { configurationFilePath ); - // If the user requested a commandline-based configuation script that should + // If the user requested a commandline-based configuration script that should // overwrite some of the values, this is the time to do it if (!commandlineArguments.configurationOverride.empty()) { LDEBUG("Executing Lua script passed through the commandline:"); @@ -1184,6 +1184,22 @@ int main(int argc, char** argv) { parseLuaState(global::configuration); } + // Convert profile to scene file (if was provided in configuration file) + if (!global::configuration.profile.empty()) { + LINFO(fmt::format("Run Lua script to convert {}.profile to scene", + global::configuration.profile)); + std::string setProfileFilenameInLuaState = "local ProfileFilename = \"" + + global::configuration.profile + ".profile\""; + ghoul::lua::runScript( + global::configuration.state, + setProfileFilenameInLuaState + ); + ghoul::lua::runScript( + global::configuration.state, + absPath(ProfileToSceneConverter) + ); + } + // Determining SGCT configuration file LDEBUG("SGCT Configuration file: " + global::configuration.windowConfiguration); diff --git a/include/openspace/engine/configuration.h b/include/openspace/engine/configuration.h index 0c8139f8c9..46ceb35780 100644 --- a/include/openspace/engine/configuration.h +++ b/include/openspace/engine/configuration.h @@ -44,6 +44,7 @@ struct Configuration { std::string windowConfiguration = "${CONFIG}/single.xml"; std::string asset; + std::string profile; std::vector globalCustomizationScripts; std::map pathTokens = { { "CACHE" , "CACHE = \"${BASE}/cache\"" } diff --git a/scripts/_makeAsset.lua b/scripts/_makeAsset.lua new file mode 100644 index 0000000000..1f3948f896 --- /dev/null +++ b/scripts/_makeAsset.lua @@ -0,0 +1,176 @@ +local M = {} + +ModuleStr = "" +AssetStr = "" +KeyStr = "" +TimeStr = "" +MarkNodesStr = "" +PropertyStr = "" +CameraStr = "" + +function tableSize(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function generateAsset(T, fileOut) + file = io.open(fileOut, "w") + io.output(file) + + --Module section + for i,j in pairs(T["Module"]) do + if not isBlank(j[2]) and not isBlank(j[3]) then + ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[2].."\nelse\n".." "..j[3].."\nend\n" + elseif not isBlank(j[3]) then + ModuleStr = ModuleStr.."if not openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[3].."\nend\n" + elseif not isBlank(j[2]) then + ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[2].."\nend\n" + end + end + + --Asset section + AssetStr = AssetStr.."asset.require('./base');\n" + AssetStr = AssetStr.."local assetHelper = asset.require('util/asset_helper')\n" + AssetStr = AssetStr.."local propertyHelper = asset.require('util/property_helper')\n" + AssetStr = AssetStr.."local sceneHelper = asset.require('util/scene_helper')\n" + AssetStr = AssetStr.."local renderableHelper = asset.require('util/renderable_helper')\n" + local assetType = "" + for i,j in pairs(T["Asset"]) do + if isBlank(j[2]) then + assetType = "required" + else + if not (j[2] == "required") and not (j[2] == "requested") then + printError("Asset arg 2/2 must be either 'required' or 'requested'.") + os.exit() + else + assetType = j[2] + end + end + AssetStr = AssetStr.."asset."..assetType.."('"..j[1].."')\n" + end + + --Keybindings section + if not (tableSize(T["Keybinding"]) == 0) then + KeyStr = KeyStr.."local Keybindings = {\n" + for i,j in pairs(T["Keybinding"]) do + KeyStr = KeyStr.." {\n" + KeyStr = KeyStr.." Key = \""..j[1].."\",\n" + KeyStr = KeyStr.." Documentation = \""..j[2].."\",\n" + KeyStr = KeyStr.." Name = \""..j[3].."\",\n" + KeyStr = KeyStr.." GuiPath = \""..j[4].."\",\n" + KeyStr = KeyStr.." Local = "..j[5]..",\n" + KeyStr = KeyStr.." Command = \""..j[6].."\"\n" + KeyStr = KeyStr.." },\n" + end + KeyStr = KeyStr.."}\n" + end + + --Time section + for i,j in pairs(T["Time"]) do + if not (j[1] == "absolute") and not (j[1] == "relative") then + printError("Time arg 1/1 must be either 'absolute' or 'relative'.") + os.exit() + elseif (j[1] == "absolute") then + TimeStr = TimeStr.." openspace.time.setTime(\""..j[2].."\")\n" + elseif (j[1] == "relative") then + TimeStr = TimeStr.." openspace.time.setTime(" + TimeStr = TimeStr.."openspace.time.advancedTime(now, \"" + TimeStr = TimeStr..j[2].."\"))\n" + end + end + + --MarkNodes section + mkNodLen = tableSize(T["MarkNodes"]) + if not (mkNodLen == 0) then + MarkNodesStr = MarkNodesStr.." openspace.markInterestingNodes({" + for i,j in pairs(T["MarkNodes"]) do + MarkNodesStr = MarkNodesStr.."\""..j.."\"" + if (i < mkNodLen) then + MarkNodesStr = MarkNodesStr..", " + end + end + MarkNodesStr = MarkNodesStr.."})\n" + end + + --Property section + for i,j in pairs(T["Property"]) do + if not (j[1] == "setPropertyValue") and not (j[1] == "setPropertyValueSingle") then + printError("Property arg 1/1 must be 'setPropertyValue[Single]'.") + os.exit() + else + PropertyStr = PropertyStr.." openspace."..j[1].."('"..j[2].."', "..j[3]..")\n" + end + end + + --Camera section + for i,j in pairs(T["Camera"]) do + if (j[1] == "setNavigationState") then + CameraStr = CameraStr.." openspace.navigation.setNavigationState({" + CameraStr = CameraStr.."Anchor = "..j[2]..", " + if not isBlank(j[3]) then + CameraStr = CameraStr.."Aim = "..j[3]..", " + end + if not isBlank(j[4]) then + CameraStr = CameraStr.."ReferenceFrame = "..j[4]..", " + end + CameraStr = CameraStr.."Position = {"..j[5].."}, " + if not isBlank(j[6]) then + CameraStr = CameraStr.."Up = {"..j[6].."}, " + end + if not isBlank(j[7]) then + CameraStr = CameraStr.."Yaw = "..j[7]..", " + end + if not isBlank(j[8]) then + CameraStr = CameraStr.."Pitch = "..j[8] + end + CameraStr = CameraStr.."})\n" + elseif (j[1] == "goToGeo") then + CameraStr = CameraStr.." openspace.navigation.goToGeo(" + if not isBlank(j[2]) then + CameraStr = CameraStr..j[2]..", " + end + CameraStr = CameraStr..j[3]..", "..j[4] + if not isBlank(j[5]) then + CameraStr = CameraStr..", "..j[5] + end + CameraStr = CameraStr..")\n" + else + printError("Camera arg 1/1 must be 'setNavigationState' or 'goToGeo'.") + os.exit() + end + end + + + --Write the file + io.write(ModuleStr) + io.write("\n") + io.write(AssetStr) + io.write("\n") + io.write(KeyStr) + io.write("\n") + io.write("asset.onInitialize(function ()\n") + io.write(TimeStr) + io.write("\n") + if not (tableSize(T["Keybinding"]) == 0) then + io.write(" sceneHelper.bindKeys(Keybindings)") + io.write("\n") + end + io.write(MarkNodesStr) + io.write("\n") + io.write(PropertyStr) + io.write("\n") + io.write(CameraStr) + io.write("\n") + io.write("end)\n") + + io.close(file) +end +M.generateAsset = generateAsset + +return M diff --git a/scripts/_parser.lua b/scripts/_parser.lua new file mode 100644 index 0000000000..76103abc17 --- /dev/null +++ b/scripts/_parser.lua @@ -0,0 +1,299 @@ +local M = {} + + +local version +local modulesTable = {} +local assetsTable = {} +local propertiesTable = {} +local timeTable = {} +local cameraTable = {} +local markNodesTable = {} +local keybindingsTable = {} +local resultTable = {} +local insideSection = false +local currFunction = "None" +local currSection = "None" +local numLinesVersion = 0 +local lineIndex = 1 + +function printError(message) + print("Error @ line "..lineIndex..": "..message) +end + +function splitByTab (inputstr) + sep = "\t" + t = {} + for match in (inputstr..sep):gmatch("(.-)"..sep) do + table.insert(t, match) + end + return t; +end + +function parseVersion(line) + numLinesVersion = numLinesVersion + 1 + if numLinesVersion > 1 then + printError("Too many lines in Version section.") + os.exit() + else + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError("No tabs allowed in version entry.") + os.exit() + else + version = line + end + end +end + +function parseMarkNodes(line) + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError("No tabs allowed in MarkNodes entry.") + os.exit() + else + table.insert(markNodesTable, line) + end +end + +function parseModule(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError("3 fields requried in a Module entry.") + os.exit() + else + table.insert(modulesTable, t) + end +end + +function parseAsset(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError("2 fields required in a Asset entry.") + os.exit() + else + local req = "required" + if t[2] == "requested" then + req = "requested" + end + table.insert(assetsTable, {t[1], req}) + end +end + +function parseProperty(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError("3 fields required in a Property entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Property set command (arg 1/3) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Property name (arg 2/3) is required.") + os.exit() + elseif isBlank(t[3]) then + printError("Property value to set (arg 3/3) is required.") + os.exit() + end + + if t[1] ~= "setPropertyValue" and t[1] ~= "setPropertyValueSingle" then + printError("Property set command '"..t[1].."' is not supported.") + os.exit() + end + + table.insert(propertiesTable, t) +end + +function parseKeybinding(line) + local numReqFields = 6 + t = {} + t = splitByTab(line) + if tableLen(t) < numReqFields then + printError(numReqFields.." fields required in a Keybinding entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Keybinding key (arg 1/6) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Keybinding documentation (arg 2/6) is required.") + os.exit() + elseif isBlank(t[3]) then + printError("Keybinding name (arg 3/6) is required.") + os.exit() + elseif isBlank(t[4]) then + printError("Keybinding GuiPath (arg 4/6) is required.") + os.exit() + elseif isBlank(t[5]) then + printError("Keybinding local(T/F) (arg 5/6) is required.") + os.exit() + elseif isBlank(t[6]) then + printError("Keybinding script to execute (arg 6/6) is required.") + os.exit() + end + + --If there are more than 6 fields then combine the final fields together + --assuming that this is a lua script that contains tabs + if tableLen(t) > numReqFields then + for i=(numReqFields + 1),tableLen(t) do + t[numReqFields] = t[numReqFields]..t[i] + end + end + + if t[5] ~= "true" and t[5] ~= "false" then + printError("Keybinding local arg must be true or false.") + os.exit() + end + + table.insert(keybindingsTable, {t[1], t[2], t[3], t[4], t[5], t[6]}) +end + +function parseTime(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError("2 fields required in a Time entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Time set type (arg 1/2) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Time value to set (arg 2/2) is required.") + os.exit() + end + + if t[1] ~= "absolute" and t[1] ~= "relative" then + printError("Time set type '"..t[1].."' is not supported.") + os.exit() + end + + table.insert(timeTable, t) +end + +function parseCamera(line) + t = {} + t = splitByTab(line) + + local cmd = t[1] + if cmd == "setNavigationState" then + if tableLen(t) ~= 8 then + printError("8 fields required in camera 'setNavigationState' line.") + os.exit() + elseif isBlank(t[2]) then + printError("Camera setNavigationState Anchor (arg 1/7) is required.") + os.exit() + elseif isBlank(t[5]) then + printError("Camera setNavigationState position vector (arg 4/7) is required.") + os.exit() + end + elseif cmd == "goToGeo" then + if tableLen(t) ~= 5 then + printError("5 fields required in camera 'goToGeo' line.") + os.exit() + elseif isBlank(t[3]) then + printError("Camera goToGeo Latitude (arg 2/4) is required.") + os.exit() + elseif isBlank(t[4]) then + printError("Camera goToGeo Longitude (arg 3/4) is required.") + os.exit() + end + else + printError("Camera position command '"..cmd.."' is not supported.") + os.exit() + end + + table.insert(cameraTable, t) +end + + +local parsingSections = { + {section = "Version", func = parseVersion}, + {section = "Module", func = parseModule}, + {section = "Asset", func = parseAsset}, + {section = "Property", func = parseProperty}, + {section = "Keybinding", func = parseKeybinding}, + {section = "Time", func = parseTime}, + {section = "Camera", func = parseCamera}, + {section = "MarkNodes", func = parseMarkNodes} +} + +function file_exists(file) + local f = io.open(file, "rb") + if f then + f:close() + end + return f ~= nil +end + +function lines_from(file) + if not file_exists(file) then + return {} + end + lines = {} + for line in io.lines(file) do + lines[#lines + 1] = line + end + return lines +end + +function determineSection(header) + header = header:sub(2) + for _,i in pairs(parsingSections) do + if i.section == header then + currSection = i.section + currFunction = i.func + return true + end + end + return false +end + +function isBlank(line) + return line:match("%S") == nil +end + +function parseCurrentSection(line) + currFunction(line) +end + +function tableLen(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function parseProfile(fileIn) + local lines = lines_from(fileIn) + + for k,v in pairs(lines) do + if insideSection then + if isBlank(v) then + insideSection = false + else + parseCurrentSection(v) + end + elseif v:sub(1, 1) == "#" then + if determineSection(v) then + insideSection = true + end + end + lineIndex = lineIndex + 1 + end + + resultTable["Version"] = version + resultTable["Module"] = modulesTable + resultTable["Asset"] = assetsTable + resultTable["Property"] = propertiesTable + resultTable["Time"] = timeTable + resultTable["Camera"] = cameraTable + resultTable["MarkNodes"] = markNodesTable + resultTable["Keybinding"] = keybindingsTable + + return resultTable +end + +M.parseProfile = parseProfile +return M diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua new file mode 100644 index 0000000000..a2e94d37b4 --- /dev/null +++ b/scripts/convertProfileToScene.lua @@ -0,0 +1,7 @@ +local parser = require("_parser") +local makeAsset = require("_makeAsset") + +profileOut = ProfileFilename:match("^.+%.").."asset" + +local resultTable = parser.parseProfile(ProfileFilename) +makeAsset.generateAsset(resultTable, profileOut) diff --git a/src/engine/configuration.cpp b/src/engine/configuration.cpp index 8912f488a8..dbb1e2e438 100644 --- a/src/engine/configuration.cpp +++ b/src/engine/configuration.cpp @@ -36,11 +36,14 @@ namespace { // We can't use ${SCRIPTS} here as that hasn't been defined by this point constexpr const char* InitialConfigHelper = "${BASE}/scripts/configuration_helper.lua"; + constexpr const char* ProfileToSceneConverter = + "${BASE}/scripts/convertProfileToScene.lua"; // Variable names for the openspace.cfg file // These are also used in the _doc include file constexpr const char* KeySGCTConfig = "SGCTConfig"; constexpr const char* KeyAsset = "Asset"; + constexpr const char* KeyProfile = "Profile"; constexpr const char* KeyGlobalCustomizationScripts = "GlobalCustomizationScripts"; constexpr const char* KeyPaths = "Paths"; constexpr const char* KeyFonts = "Fonts"; @@ -277,6 +280,7 @@ void parseLuaState(Configuration& configuration) { getValue(s, KeySGCTConfig, c.windowConfiguration); getValue(s, KeyAsset, c.asset); + getValue(s, KeyProfile, c.profile); getValue(s, KeyGlobalCustomizationScripts, c.globalCustomizationScripts); getValue(s, KeyPaths, c.pathTokens); getValue(s, KeyFonts, c.fonts); @@ -356,6 +360,13 @@ Configuration loadConfigurationFromFile(const std::string& filename) { parseLuaState(result); + // Set asset name to that of the profile because a new scene file will be + // created with that name, and also because the profile name will override + // an asset name if both are provided. + if (!result.profile.empty()) { + result.asset = result.profile; + } + return result; } From ad97cd93eefd9a9436c2dc0e940e8cfd90fce829 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 21 Oct 2019 13:57:53 -0600 Subject: [PATCH 025/214] Created new renderable class for JPL Small Body DataBase telemetry --- .../space/rendering/renderablesmallbody.cpp | 539 ++++++++++++++++++ modules/space/rendering/renderablesmallbody.h | 131 +++++ 2 files changed, 670 insertions(+) create mode 100644 modules/space/rendering/renderablesmallbody.cpp create mode 100644 modules/space/rendering/renderablesmallbody.h diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp new file mode 100644 index 0000000000..f9bfd88f0d --- /dev/null +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -0,0 +1,539 @@ + /**************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char* ProgramName = "RenderableSmallBody"; + constexpr const char* _loggerCat = "Satellites"; + + static const openspace::properties::Property::PropertyInfo PathInfo = { + "Path", + "Path", + "The file path to the SBDB file to read" + }; + + static const openspace::properties::Property::PropertyInfo SegmentsInfo = { + "Segments", + "Segments", + "The number of segments to use for each orbit ellipse" + }; + constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = { + "LineWidth", + "Line Width", + "This value specifies the line width of the trail if the selected rendering " + "method includes lines. If the rendering mode is set to Points, this value is " + "ignored." + }; + constexpr openspace::properties::Property::PropertyInfo FadeInfo = { + "Fade", + "Line fade", + "The fading factor that is applied to the trail if the 'EnableFade' value is " + "'true'. If it is 'false', this setting has no effect. The higher the number, " + "the less fading is applied." + }; + constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { + "Color", + "Color", + "This value determines the RGB main color for the lines and points of the trail." + }; + + constexpr const char* KeyFile = "Path"; + constexpr const char* KeyLineNum = "LineNumber"; +} + +namespace openspace { + + // The list of leap years only goes until 2056 as we need to touch this file then + // again anyway ;) + const std::vector LeapYears = { + 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, + 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, + 2044, 2048, 2052, 2056 + }; + + // Count the number of full days since the beginning of 2000 to the beginning of + // the parameter 'year' + int countDays(int year) { + // Find the position of the current year in the vector, the difference + // between its position and the position of 2000 (for J2000) gives the + // number of leap years + constexpr const int Epoch = 2000; + constexpr const int DaysRegularYear = 365; + constexpr const int DaysLeapYear = 366; + + if (year == Epoch) { + return 0; + } + + // Get the position of the most recent leap year + const auto lb = std::lower_bound(LeapYears.begin(), LeapYears.end(), year); + + // Get the position of the epoch + const auto y2000 = std::find(LeapYears.begin(), LeapYears.end(), Epoch); + + // The distance between the two iterators gives us the number of leap years + const int nLeapYears = static_cast(std::abs(std::distance(y2000, lb))); + + const int nYears = std::abs(year - Epoch); + const int nRegularYears = nYears - nLeapYears; + + // Get the total number of days as the sum of leap years + non leap years + const int result = nRegularYears * DaysRegularYear + nLeapYears * DaysLeapYear; + return result; + } + + // Returns the number of leap seconds that lie between the {year, dayOfYear} + // time point and { 2000, 1 } + int countLeapSeconds(int year, int dayOfYear) { + // Find the position of the current year in the vector; its position in + // the vector gives the number of leap seconds + struct LeapSecond { + int year; + int dayOfYear; + bool operator<(const LeapSecond& rhs) const { + return std::tie(year, dayOfYear) < std::tie(rhs.year, rhs.dayOfYear); + } + }; + + const LeapSecond Epoch = { 2000, 1 }; + + // List taken from: https://www.ietf.org/timezones/data/leap-seconds.list + static const std::vector LeapSeconds = { + { 1972, 1 }, + { 1972, 183 }, + { 1973, 1 }, + { 1974, 1 }, + { 1975, 1 }, + { 1976, 1 }, + { 1977, 1 }, + { 1978, 1 }, + { 1979, 1 }, + { 1980, 1 }, + { 1981, 182 }, + { 1982, 182 }, + { 1983, 182 }, + { 1985, 182 }, + { 1988, 1 }, + { 1990, 1 }, + { 1991, 1 }, + { 1992, 183 }, + { 1993, 182 }, + { 1994, 182 }, + { 1996, 1 }, + { 1997, 182 }, + { 1999, 1 }, + { 2006, 1 }, + { 2009, 1 }, + { 2012, 183 }, + { 2015, 182 }, + { 2017, 1 } + }; + + // Get the position of the last leap second before the desired date + LeapSecond date { year, dayOfYear }; + const auto it = std::lower_bound(LeapSeconds.begin(), LeapSeconds.end(), date); + + // Get the position of the Epoch + const auto y2000 = std::lower_bound( + LeapSeconds.begin(), + LeapSeconds.end(), + Epoch + ); + + // The distance between the two iterators gives us the number of leap years + const int nLeapSeconds = static_cast(std::abs(std::distance(y2000, it))); + return nLeapSeconds; + } + +double epochFromSubstring(const std::string& epochString) { + // The epochString is in the form: + // YYDDD.DDDDDDDD + // With YY being the last two years of the launch epoch, the first DDD the day + // of the year and the remaning a fractional part of the day + + // The main overview of this function: + // 1. Reconstruct the full year from the YY part + // 2. Calculate the number of seconds since the beginning of the year + // 2.a Get the number of full days since the beginning of the year + // 2.b If the year is a leap year, modify the number of days + // 3. Convert the number of days to a number of seconds + // 4. Get the number of leap seconds since January 1st, 2000 and remove them + // 5. Adjust for the fact the epoch starts on 1st Januaray at 12:00:00, not + // midnight + + // According to https://celestrak.com/columns/v04n03/ + // Apparently, US Space Command sees no need to change the two-line element + // set format yet since no artificial earth satellites existed prior to 1957. + // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and + // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! + + // 1. Get the full year + std::string yearPrefix = [y = epochString.substr(0, 2)](){ + int year = std::atoi(y.c_str()); + return year >= 57 ? "19" : "20"; + }(); + const int year = std::atoi((yearPrefix + epochString.substr(0, 2)).c_str()); + const int daysSince2000 = countDays(year); + + // 2. + // 2.a + double daysInYear = std::atof(epochString.substr(2).c_str()); + + // 2.b + const bool isInLeapYear = std::find( + LeapYears.begin(), + LeapYears.end(), + year + ) != LeapYears.end(); + if (isInLeapYear && daysInYear >= 60) { + // We are in a leap year, so we have an effective day more if we are + // beyond the end of february (= 31+29 days) + --daysInYear; + } + + // 3 + using namespace std::chrono; + const int SecondsPerDay = static_cast(seconds(hours(24)).count()); + //Need to subtract 1 from daysInYear since it is not a zero-based count + const double nSecondsSince2000 = (daysSince2000 + daysInYear - 1) * SecondsPerDay; + + // 4 + // We need to remove additional leap seconds past 2000 and add them prior to + // 2000 to sync up the time zones + const double nLeapSecondsOffset = -countLeapSeconds( + year, + static_cast(std::floor(daysInYear)) + ); + + // 5 + const double nSecondsEpochOffset = static_cast( + seconds(hours(12)).count() + ); + + // Combine all of the values + const double epoch = nSecondsSince2000 + nLeapSecondsOffset - nSecondsEpochOffset; + return epoch; + } + +documentation::Documentation RenderableSmallBody::Documentation() { + using namespace documentation; + return { + "RenderableSmallBody", + "space_renderable_satellites", + { + { + SegmentsInfo.identifier, + new DoubleVerifier, + Optional::No, + SegmentsInfo.description + }, + { + PathInfo.identifier, + new StringVerifier, + Optional::No, + PathInfo.description + }, + { + LineWidthInfo.identifier, + new DoubleVerifier, + Optional::Yes, + LineWidthInfo.description + }, + { + FadeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FadeInfo.description + }, + { + LineColorInfo.identifier, + new DoubleVector3Verifier, + Optional::No, + LineColorInfo.description + } + } + }; +} + +RenderableSmallBody::RenderableSmallBody(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _path(PathInfo) + , _nSegments(SegmentsInfo) + , _lineFade(FadeInfo) + +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableSmallBody" + ); + + _path = dictionary.value(PathInfo.identifier); + _nSegments = static_cast(dictionary.value(SegmentsInfo.identifier)); + _lineFade = static_cast(dictionary.value(FadeInfo.identifier)); + + if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) { + _appearance.lineColor = dictionary.value(LineColorInfo.identifier); + } + + addPropertySubOwner(_appearance); + addProperty(_path); + addProperty(_nSegments); + addProperty(_lineFade); +} + + +void RenderableSmallBody::readJplSbDb(const std::string& filename) { + if (!FileSys.fileExists(filename)) { + throw ghoul::RuntimeError(fmt::format( + "JPL SBDB file {} does not exist.", filename + )); + } + + std::ifstream file; + file.exceptions(std::ifstream::failbit | std::ifstream::badbit); + file.open(filename); + + std::streamoff numberOfLines = std::count(std::istreambuf_iterator(file), + std::istreambuf_iterator(), '\n' ); + file.seekg(std::ios_base::beg); // reset iterator to beginning of file + + std::string line; + std::string name; + std::string ignore; + std::getline(file, line); // get rid of first line (header) + for (std::streamoff i = 0; i < numberOfLines; i++) { + KeplerParameters keplerElements; + // Object designator string + std::getline(file, name, ','); + // (Ignore object status for NEO, PHA, diameter) + std::getline(file, ignore, ','); + std::getline(file, ignore, ','); + std::getline(file, ignore, ','); + // Eccentricity (unit-less) + std::getline(file, ignore, ','); + keplerElements.eccentricity = std::stod(ignore); + // Semi-major axis (astronomical units - au) + std::getline(file, ignore, ','); + keplerElements.semiMajorAxis = std::stod(ignore); + // Inclination (degrees) + std::getline(file, ignore, ','); + keplerElements.inclination = std::stod(ignore); + // Longitude of ascending node (degrees) + std::getline(file, ignore, ','); + keplerElements.ascendingNode = std::stod(ignore); + // Argument of Periapsis (degrees) + std::getline(file, ignore, ','); + keplerElements.argumentOfPeriapsis = std::std(ignore); + // Mean Anomaly (degrees) + std::getline(file, ignore, ','); + keplerElements.meanAnomaly = std::std(ignore); + // Epoch (MJD) + std::getline(file, ignore, ','); + keplerElements.epoch = std::std(ignore); + // Period (days) + std::getline(file, ignore, ','); + keplerElements.period = std::std(ignore); + + _sbData.push_back(keplerElements); + _sbNames.push_back(name); + } + file.close(); +} + +void RenderableSmallBody::initializeGL() { + glGenVertexArrays(1, &_vertexArray); + glGenBuffers(1, &_vertexBuffer); + + _programObject = SpaceModule::ProgramObjectManager.request( + ProgramName, + []() -> std::unique_ptr { + return global::renderEngine.buildRenderProgram( + ProgramName, + absPath("${MODULE_SPACE}/shaders/debrisViz_vs.glsl"), + absPath("${MODULE_SPACE}/shaders/debrisViz_fs.glsl") + ); + } + ); + + _uniformCache.modelView = _programObject->uniformLocation("modelViewTransform"); + _uniformCache.projection = _programObject->uniformLocation("projectionTransform"); + _uniformCache.lineFade = _programObject->uniformLocation("lineFade"); + _uniformCache.inGameTime = _programObject->uniformLocation("inGameTime"); + _uniformCache.color = _programObject->uniformLocation("color"); + _uniformCache.opacity = _programObject->uniformLocation("opacity"); + + updateBuffers(); + setRenderBin(Renderable::RenderBin::Overlay); +} + +void RenderableSmallBody::deinitializeGL() { + glDeleteBuffers(1, &_vertexBuffer); + glDeleteVertexArrays(1, &_vertexArray); + + SpaceModule::ProgramObjectManager.release( + ProgramName, + [](ghoul::opengl::ProgramObject* p) { + global::renderEngine.removeRenderProgram(p); + } + ); + _programObject = nullptr; +} + +bool RenderableSmallBody::isReady() const { + return _programObject != nullptr; +} + +void RenderableSmallBody::render(const RenderData& data, RendererTasks&) { + if (_sbData.empty()) + return; + + _programObject->activate(); + _programObject->setUniform(_uniformCache.opacity, _opacity); + _programObject->setUniform(_uniformCache.inGameTime, data.time.j2000Seconds()); + + + glm::dmat4 modelTransform = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + _programObject->setUniform( + _uniformCache.modelView, + data.camera.combinedViewMatrix() * modelTransform + ); + + _programObject->setUniform(_uniformCache.projection, data.camera.projectionMatrix()); + _programObject->setUniform(_uniformCache.color, _appearance.lineColor); + _programObject->setUniform(_uniformCache.lineFade, _appearance.lineFade); + + glLineWidth(_appearance.lineWidth); + + const size_t nrOrbits = _sbData.size(); + gl::GLint vertices = 0; + + //glDepthMask(false); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE) + + glBindVertexArray(_vertexArray); + for (size_t i = 0; i < nrOrbits; ++i) { + glDrawArrays(GL_LINE_STRIP, vertices, _nSegments + 1); + vertices = vertices + _nSegments + 1; + } + glBindVertexArray(0); + + _programObject->deactivate(); + +} + +void RenderableSmallBody::updateBuffers() { + readJplSbDb(_path); + + const size_t nVerticesPerOrbit = _nSegments + 1; + _vertexBufferData.resize(_sbData.size() * nVerticesPerOrbit); + size_t orbitindex = 0; + + for (const auto& orbit : _sbData) { + _keplerTranslator.setKeplerElements( + orbit.eccentricity, + orbit.semiMajorAxis, + orbit.inclination, + orbit.ascendingNode, + orbit.argumentOfPeriapsis, + orbit.meanAnomaly, + orbit.period, + orbit.epoch + ); + + for (size_t i=0 ; i < nVerticesPerOrbit; ++i) { + size_t index = orbitindex * nVerticesPerOrbit + i; + + double timeOffset = orbit.period * + static_cast(i)/ static_cast(_nSegments); + + glm::dvec3 position = _keplerTranslator.position({ + {}, + Time(timeOffset + orbit.epoch), + Time(0.0), + false + }); + + double positionX = position.x; + double positionY = position.y; + double positionZ = position.z; + + _vertexBufferData[index].x = static_cast(positionX); + _vertexBufferData[index].y = static_cast(positionY); + _vertexBufferData[index].z = static_cast(positionZ); + _vertexBufferData[index].time = static_cast(timeOffset); + _vertexBufferData[index].epoch = orbit.epoch; + _vertexBufferData[index].period = orbit.period; + } + + ++orbitindex; + } + + glBindVertexArray(_vertexArray); + + glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); + glBufferData( + GL_ARRAY_BUFFER, + _vertexBufferData.size() * sizeof(TrailVBOLayout), + _vertexBufferData.data(), + GL_STATIC_DRAW + ); + + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)0); // stride : 4*sizeof(GL_FLOAT) + 2*sizeof(GL_DOUBLE) + + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4*sizeof(GL_FLOAT)) ); + + + glBindVertexArray(0); + +} + +} diff --git a/modules/space/rendering/renderablesmallbody.h b/modules/space/rendering/renderablesmallbody.h new file mode 100644 index 0000000000..17b1b9df3d --- /dev/null +++ b/modules/space/rendering/renderablesmallbody.h @@ -0,0 +1,131 @@ +/**************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ +#define __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace openspace { + +class RenderableSmallBody : public Renderable { +public: + RenderableSmallBody(const ghoul::Dictionary& dictionary); + + void initializeGL() override; + void deinitializeGL() override; + + bool isReady() const override; + void render(const RenderData& data, RendererTasks& rendererTask) override; + + static documentation::Documentation Documentation(); + /** + * Reads the provided file downloaded from the JPL Small Body Database and calls + * the KeplerTranslation::setKeplerElments method with the correct values. + * If \p filename is a valid JPL SBDB file but contains + * disallowed values (see KeplerTranslation::setKeplerElements), a + * KeplerTranslation::RangeError is thrown. + * + * \param filename The path to the file that contains the file. + * + * \throw ghoul::RuntimeError if the file does not exist or there is a + * problem with its format. + * \pre The \p filename must exist + */ + void readJplSbDb(const std::string& filename); + +private: + struct Vertex { + glm::vec3 position; + glm::vec3 color; + glm::vec2 texcoord; + }; + + struct KeplerParameters { + double inclination = 0.0; + double semiMajorAxis = 0.0; + double ascendingNode = 0.0; + double eccentricity = 0.0; + double argumentOfPeriapsis = 0.0; + double meanAnomaly = 0.0; + double meanMotion = 0.0; + double epoch = 0.0; + double period = 0.0; + }; + + /// The layout of the VBOs + struct TrailVBOLayout { + float x, y, z, time; + double epoch, period; + }; + + KeplerTranslation _keplerTranslator; + std::vector _sbData; + std::vector _sbNames; + + /// The backend storage for the vertex buffer object containing all points for this + /// trail. + std::vector _vertexBufferData; + + /// The index array that is potentially used in the draw call. If this is empty, no + /// element draw call is used. + std::vector _indexBufferData; + + GLuint _vertexArray; + GLuint _vertexBuffer; + GLuint _indexBuffer; + + //GLuint _vaoTest; // vertexArrayObject + //GLuint _vboTest; // vertextBufferObject + //GLuint _eboTest; // elementBufferObject/ indexBufferObject + + void updateBuffers(); + + ghoul::opengl::ProgramObject* _programObject; + + properties::StringProperty _path; + properties::UIntProperty _nSegments; + + properties::DoubleProperty _lineFade; + + RenderableTrail::Appearance _appearance; + + glm::vec3 _position; + + UniformCache(modelView, projection, lineFade, inGameTime, color, opacity, + numberOfSegments) _uniformCache; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ + From 37679d4104b843353c870ca7c9331ee05d73e470 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 21 Oct 2019 14:01:20 -0600 Subject: [PATCH 026/214] Formatting changes (indent) only --- .../space/rendering/renderablesmallbody.cpp | 316 +++++++++--------- 1 file changed, 157 insertions(+), 159 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index f9bfd88f0d..eaef22af7e 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -85,178 +85,178 @@ namespace { namespace openspace { - // The list of leap years only goes until 2056 as we need to touch this file then - // again anyway ;) - const std::vector LeapYears = { - 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, - 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, - 2044, 2048, 2052, 2056 +// The list of leap years only goes until 2056 as we need to touch this file then +// again anyway ;) +const std::vector LeapYears = { + 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, + 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, + 2044, 2048, 2052, 2056 +}; + +// Count the number of full days since the beginning of 2000 to the beginning of +// the parameter 'year' +int countDays(int year) { + // Find the position of the current year in the vector, the difference + // between its position and the position of 2000 (for J2000) gives the + // number of leap years + constexpr const int Epoch = 2000; + constexpr const int DaysRegularYear = 365; + constexpr const int DaysLeapYear = 366; + + if (year == Epoch) { + return 0; + } + + // Get the position of the most recent leap year + const auto lb = std::lower_bound(LeapYears.begin(), LeapYears.end(), year); + + // Get the position of the epoch + const auto y2000 = std::find(LeapYears.begin(), LeapYears.end(), Epoch); + + // The distance between the two iterators gives us the number of leap years + const int nLeapYears = static_cast(std::abs(std::distance(y2000, lb))); + + const int nYears = std::abs(year - Epoch); + const int nRegularYears = nYears - nLeapYears; + + // Get the total number of days as the sum of leap years + non leap years + const int result = nRegularYears * DaysRegularYear + nLeapYears * DaysLeapYear; + return result; +} + +// Returns the number of leap seconds that lie between the {year, dayOfYear} +// time point and { 2000, 1 } +int countLeapSeconds(int year, int dayOfYear) { + // Find the position of the current year in the vector; its position in + // the vector gives the number of leap seconds + struct LeapSecond { + int year; + int dayOfYear; + bool operator<(const LeapSecond& rhs) const { + return std::tie(year, dayOfYear) < std::tie(rhs.year, rhs.dayOfYear); + } }; - // Count the number of full days since the beginning of 2000 to the beginning of - // the parameter 'year' - int countDays(int year) { - // Find the position of the current year in the vector, the difference - // between its position and the position of 2000 (for J2000) gives the - // number of leap years - constexpr const int Epoch = 2000; - constexpr const int DaysRegularYear = 365; - constexpr const int DaysLeapYear = 366; + const LeapSecond Epoch = { 2000, 1 }; - if (year == Epoch) { - return 0; - } + // List taken from: https://www.ietf.org/timezones/data/leap-seconds.list + static const std::vector LeapSeconds = { + { 1972, 1 }, + { 1972, 183 }, + { 1973, 1 }, + { 1974, 1 }, + { 1975, 1 }, + { 1976, 1 }, + { 1977, 1 }, + { 1978, 1 }, + { 1979, 1 }, + { 1980, 1 }, + { 1981, 182 }, + { 1982, 182 }, + { 1983, 182 }, + { 1985, 182 }, + { 1988, 1 }, + { 1990, 1 }, + { 1991, 1 }, + { 1992, 183 }, + { 1993, 182 }, + { 1994, 182 }, + { 1996, 1 }, + { 1997, 182 }, + { 1999, 1 }, + { 2006, 1 }, + { 2009, 1 }, + { 2012, 183 }, + { 2015, 182 }, + { 2017, 1 } + }; - // Get the position of the most recent leap year - const auto lb = std::lower_bound(LeapYears.begin(), LeapYears.end(), year); + // Get the position of the last leap second before the desired date + LeapSecond date { year, dayOfYear }; + const auto it = std::lower_bound(LeapSeconds.begin(), LeapSeconds.end(), date); - // Get the position of the epoch - const auto y2000 = std::find(LeapYears.begin(), LeapYears.end(), Epoch); + // Get the position of the Epoch + const auto y2000 = std::lower_bound( + LeapSeconds.begin(), + LeapSeconds.end(), + Epoch + ); - // The distance between the two iterators gives us the number of leap years - const int nLeapYears = static_cast(std::abs(std::distance(y2000, lb))); - - const int nYears = std::abs(year - Epoch); - const int nRegularYears = nYears - nLeapYears; - - // Get the total number of days as the sum of leap years + non leap years - const int result = nRegularYears * DaysRegularYear + nLeapYears * DaysLeapYear; - return result; - } - - // Returns the number of leap seconds that lie between the {year, dayOfYear} - // time point and { 2000, 1 } - int countLeapSeconds(int year, int dayOfYear) { - // Find the position of the current year in the vector; its position in - // the vector gives the number of leap seconds - struct LeapSecond { - int year; - int dayOfYear; - bool operator<(const LeapSecond& rhs) const { - return std::tie(year, dayOfYear) < std::tie(rhs.year, rhs.dayOfYear); - } - }; - - const LeapSecond Epoch = { 2000, 1 }; - - // List taken from: https://www.ietf.org/timezones/data/leap-seconds.list - static const std::vector LeapSeconds = { - { 1972, 1 }, - { 1972, 183 }, - { 1973, 1 }, - { 1974, 1 }, - { 1975, 1 }, - { 1976, 1 }, - { 1977, 1 }, - { 1978, 1 }, - { 1979, 1 }, - { 1980, 1 }, - { 1981, 182 }, - { 1982, 182 }, - { 1983, 182 }, - { 1985, 182 }, - { 1988, 1 }, - { 1990, 1 }, - { 1991, 1 }, - { 1992, 183 }, - { 1993, 182 }, - { 1994, 182 }, - { 1996, 1 }, - { 1997, 182 }, - { 1999, 1 }, - { 2006, 1 }, - { 2009, 1 }, - { 2012, 183 }, - { 2015, 182 }, - { 2017, 1 } - }; - - // Get the position of the last leap second before the desired date - LeapSecond date { year, dayOfYear }; - const auto it = std::lower_bound(LeapSeconds.begin(), LeapSeconds.end(), date); - - // Get the position of the Epoch - const auto y2000 = std::lower_bound( - LeapSeconds.begin(), - LeapSeconds.end(), - Epoch - ); - - // The distance between the two iterators gives us the number of leap years - const int nLeapSeconds = static_cast(std::abs(std::distance(y2000, it))); - return nLeapSeconds; - } + // The distance between the two iterators gives us the number of leap years + const int nLeapSeconds = static_cast(std::abs(std::distance(y2000, it))); + return nLeapSeconds; +} double epochFromSubstring(const std::string& epochString) { - // The epochString is in the form: - // YYDDD.DDDDDDDD - // With YY being the last two years of the launch epoch, the first DDD the day - // of the year and the remaning a fractional part of the day + // The epochString is in the form: + // YYDDD.DDDDDDDD + // With YY being the last two years of the launch epoch, the first DDD the day + // of the year and the remaning a fractional part of the day - // The main overview of this function: - // 1. Reconstruct the full year from the YY part - // 2. Calculate the number of seconds since the beginning of the year - // 2.a Get the number of full days since the beginning of the year - // 2.b If the year is a leap year, modify the number of days - // 3. Convert the number of days to a number of seconds - // 4. Get the number of leap seconds since January 1st, 2000 and remove them - // 5. Adjust for the fact the epoch starts on 1st Januaray at 12:00:00, not - // midnight + // The main overview of this function: + // 1. Reconstruct the full year from the YY part + // 2. Calculate the number of seconds since the beginning of the year + // 2.a Get the number of full days since the beginning of the year + // 2.b If the year is a leap year, modify the number of days + // 3. Convert the number of days to a number of seconds + // 4. Get the number of leap seconds since January 1st, 2000 and remove them + // 5. Adjust for the fact the epoch starts on 1st Januaray at 12:00:00, not + // midnight - // According to https://celestrak.com/columns/v04n03/ - // Apparently, US Space Command sees no need to change the two-line element - // set format yet since no artificial earth satellites existed prior to 1957. - // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and - // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! + // According to https://celestrak.com/columns/v04n03/ + // Apparently, US Space Command sees no need to change the two-line element + // set format yet since no artificial earth satellites existed prior to 1957. + // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and + // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! - // 1. Get the full year - std::string yearPrefix = [y = epochString.substr(0, 2)](){ - int year = std::atoi(y.c_str()); - return year >= 57 ? "19" : "20"; - }(); - const int year = std::atoi((yearPrefix + epochString.substr(0, 2)).c_str()); - const int daysSince2000 = countDays(year); + // 1. Get the full year + std::string yearPrefix = [y = epochString.substr(0, 2)](){ + int year = std::atoi(y.c_str()); + return year >= 57 ? "19" : "20"; + }(); + const int year = std::atoi((yearPrefix + epochString.substr(0, 2)).c_str()); + const int daysSince2000 = countDays(year); - // 2. - // 2.a - double daysInYear = std::atof(epochString.substr(2).c_str()); + // 2. + // 2.a + double daysInYear = std::atof(epochString.substr(2).c_str()); - // 2.b - const bool isInLeapYear = std::find( - LeapYears.begin(), - LeapYears.end(), - year - ) != LeapYears.end(); - if (isInLeapYear && daysInYear >= 60) { - // We are in a leap year, so we have an effective day more if we are - // beyond the end of february (= 31+29 days) - --daysInYear; - } - - // 3 - using namespace std::chrono; - const int SecondsPerDay = static_cast(seconds(hours(24)).count()); - //Need to subtract 1 from daysInYear since it is not a zero-based count - const double nSecondsSince2000 = (daysSince2000 + daysInYear - 1) * SecondsPerDay; - - // 4 - // We need to remove additional leap seconds past 2000 and add them prior to - // 2000 to sync up the time zones - const double nLeapSecondsOffset = -countLeapSeconds( - year, - static_cast(std::floor(daysInYear)) - ); - - // 5 - const double nSecondsEpochOffset = static_cast( - seconds(hours(12)).count() - ); - - // Combine all of the values - const double epoch = nSecondsSince2000 + nLeapSecondsOffset - nSecondsEpochOffset; - return epoch; + // 2.b + const bool isInLeapYear = std::find( + LeapYears.begin(), + LeapYears.end(), + year + ) != LeapYears.end(); + if (isInLeapYear && daysInYear >= 60) { + // We are in a leap year, so we have an effective day more if we are + // beyond the end of february (= 31+29 days) + --daysInYear; } + // 3 + using namespace std::chrono; + const int SecondsPerDay = static_cast(seconds(hours(24)).count()); + //Need to subtract 1 from daysInYear since it is not a zero-based count + const double nSecondsSince2000 = (daysSince2000 + daysInYear - 1) * SecondsPerDay; + + // 4 + // We need to remove additional leap seconds past 2000 and add them prior to + // 2000 to sync up the time zones + const double nLeapSecondsOffset = -countLeapSeconds( + year, + static_cast(std::floor(daysInYear)) + ); + + // 5 + const double nSecondsEpochOffset = static_cast( + seconds(hours(12)).count() + ); + + // Combine all of the values + const double epoch = nSecondsSince2000 + nLeapSecondsOffset - nSecondsEpochOffset; + return epoch; +} + documentation::Documentation RenderableSmallBody::Documentation() { using namespace documentation; return { @@ -531,9 +531,7 @@ void RenderableSmallBody::updateBuffers() { glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4*sizeof(GL_FLOAT)) ); - glBindVertexArray(0); - } } From e3a842b53f2f7e0d710de840b783476938ee1679 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 21 Oct 2019 15:38:45 -0600 Subject: [PATCH 027/214] Moving path to lua converter script --- apps/OpenSpace/main.cpp | 3 +++ src/engine/configuration.cpp | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 9d9fa49ba8..6396c8fe61 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -84,6 +84,9 @@ constexpr const char* _loggerCat = "main"; constexpr const char* SpoutTag = "Spout"; constexpr const char* OpenVRTag = "OpenVR"; +constexpr const char* ProfileToSceneConverter + = "${BASE}/scripts/convertProfileToScene.lua"; + sgct::Engine* SgctEngine; sgct::SharedVector _synchronizationBuffer; diff --git a/src/engine/configuration.cpp b/src/engine/configuration.cpp index dbb1e2e438..cbb6080af3 100644 --- a/src/engine/configuration.cpp +++ b/src/engine/configuration.cpp @@ -36,8 +36,6 @@ namespace { // We can't use ${SCRIPTS} here as that hasn't been defined by this point constexpr const char* InitialConfigHelper = "${BASE}/scripts/configuration_helper.lua"; - constexpr const char* ProfileToSceneConverter = - "${BASE}/scripts/convertProfileToScene.lua"; // Variable names for the openspace.cfg file // These are also used in the _doc include file From 204966b0e03bde23945f460670e185c04e040c80 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 22 Oct 2019 16:22:44 -0600 Subject: [PATCH 028/214] Got OpenSpace parse and conversion working for profile-to-scene file, then successful run with this resulting scene. --- apps/OpenSpace/main.cpp | 37 ++- scripts/_makeAsset.lua | 176 ----------- scripts/_parser.lua | 299 ------------------ scripts/convertProfileToScene.lua | 482 +++++++++++++++++++++++++++++- 4 files changed, 504 insertions(+), 490 deletions(-) delete mode 100644 scripts/_makeAsset.lua delete mode 100644 scripts/_parser.lua diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 6396c8fe61..b18ba85ab0 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -1191,16 +1191,33 @@ int main(int argc, char** argv) { if (!global::configuration.profile.empty()) { LINFO(fmt::format("Run Lua script to convert {}.profile to scene", global::configuration.profile)); - std::string setProfileFilenameInLuaState = "local ProfileFilename = \"" - + global::configuration.profile + ".profile\""; - ghoul::lua::runScript( - global::configuration.state, - setProfileFilenameInLuaState - ); - ghoul::lua::runScript( - global::configuration.state, - absPath(ProfileToSceneConverter) - ); + ghoul::lua::LuaState lState; + + // Get path where .scene files reside. Need to add extra escape slashes to + // accomodate lua parser. + std::string outputScenePath = absPath("${BASE}/data/assets"); + std::string search = "\\"; + std::string replace = "\\\\"; + for (std::string::size_type i = outputScenePath.find(search); + i != std::string::npos; + i = outputScenePath.find(search, i)) + { + outputScenePath.replace(i, search.length(), replace); + i += replace.length(); + } + + std::string setProfileFilenameInLuaState = "\ + openspace = {}\n\ + openspace.profile = {}\n\ + function openspace.profile.getFilename()\n\ + return \"" + global::configuration.profile + ".profile\"\ + end\n\ + function openspace.profile.getPath()\n\ + return \"" + outputScenePath + "\"\ + end\ + "; + ghoul::lua::runScript(lState, setProfileFilenameInLuaState); + ghoul::lua::runScriptFile(lState, absPath(ProfileToSceneConverter)); } // Determining SGCT configuration file diff --git a/scripts/_makeAsset.lua b/scripts/_makeAsset.lua deleted file mode 100644 index 1f3948f896..0000000000 --- a/scripts/_makeAsset.lua +++ /dev/null @@ -1,176 +0,0 @@ -local M = {} - -ModuleStr = "" -AssetStr = "" -KeyStr = "" -TimeStr = "" -MarkNodesStr = "" -PropertyStr = "" -CameraStr = "" - -function tableSize(T) - local size = 0 - for _ in pairs(T) do - size = size + 1 - end - return size -end - -function generateAsset(T, fileOut) - file = io.open(fileOut, "w") - io.output(file) - - --Module section - for i,j in pairs(T["Module"]) do - if not isBlank(j[2]) and not isBlank(j[3]) then - ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[2].."\nelse\n".." "..j[3].."\nend\n" - elseif not isBlank(j[3]) then - ModuleStr = ModuleStr.."if not openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[3].."\nend\n" - elseif not isBlank(j[2]) then - ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[2].."\nend\n" - end - end - - --Asset section - AssetStr = AssetStr.."asset.require('./base');\n" - AssetStr = AssetStr.."local assetHelper = asset.require('util/asset_helper')\n" - AssetStr = AssetStr.."local propertyHelper = asset.require('util/property_helper')\n" - AssetStr = AssetStr.."local sceneHelper = asset.require('util/scene_helper')\n" - AssetStr = AssetStr.."local renderableHelper = asset.require('util/renderable_helper')\n" - local assetType = "" - for i,j in pairs(T["Asset"]) do - if isBlank(j[2]) then - assetType = "required" - else - if not (j[2] == "required") and not (j[2] == "requested") then - printError("Asset arg 2/2 must be either 'required' or 'requested'.") - os.exit() - else - assetType = j[2] - end - end - AssetStr = AssetStr.."asset."..assetType.."('"..j[1].."')\n" - end - - --Keybindings section - if not (tableSize(T["Keybinding"]) == 0) then - KeyStr = KeyStr.."local Keybindings = {\n" - for i,j in pairs(T["Keybinding"]) do - KeyStr = KeyStr.." {\n" - KeyStr = KeyStr.." Key = \""..j[1].."\",\n" - KeyStr = KeyStr.." Documentation = \""..j[2].."\",\n" - KeyStr = KeyStr.." Name = \""..j[3].."\",\n" - KeyStr = KeyStr.." GuiPath = \""..j[4].."\",\n" - KeyStr = KeyStr.." Local = "..j[5]..",\n" - KeyStr = KeyStr.." Command = \""..j[6].."\"\n" - KeyStr = KeyStr.." },\n" - end - KeyStr = KeyStr.."}\n" - end - - --Time section - for i,j in pairs(T["Time"]) do - if not (j[1] == "absolute") and not (j[1] == "relative") then - printError("Time arg 1/1 must be either 'absolute' or 'relative'.") - os.exit() - elseif (j[1] == "absolute") then - TimeStr = TimeStr.." openspace.time.setTime(\""..j[2].."\")\n" - elseif (j[1] == "relative") then - TimeStr = TimeStr.." openspace.time.setTime(" - TimeStr = TimeStr.."openspace.time.advancedTime(now, \"" - TimeStr = TimeStr..j[2].."\"))\n" - end - end - - --MarkNodes section - mkNodLen = tableSize(T["MarkNodes"]) - if not (mkNodLen == 0) then - MarkNodesStr = MarkNodesStr.." openspace.markInterestingNodes({" - for i,j in pairs(T["MarkNodes"]) do - MarkNodesStr = MarkNodesStr.."\""..j.."\"" - if (i < mkNodLen) then - MarkNodesStr = MarkNodesStr..", " - end - end - MarkNodesStr = MarkNodesStr.."})\n" - end - - --Property section - for i,j in pairs(T["Property"]) do - if not (j[1] == "setPropertyValue") and not (j[1] == "setPropertyValueSingle") then - printError("Property arg 1/1 must be 'setPropertyValue[Single]'.") - os.exit() - else - PropertyStr = PropertyStr.." openspace."..j[1].."('"..j[2].."', "..j[3]..")\n" - end - end - - --Camera section - for i,j in pairs(T["Camera"]) do - if (j[1] == "setNavigationState") then - CameraStr = CameraStr.." openspace.navigation.setNavigationState({" - CameraStr = CameraStr.."Anchor = "..j[2]..", " - if not isBlank(j[3]) then - CameraStr = CameraStr.."Aim = "..j[3]..", " - end - if not isBlank(j[4]) then - CameraStr = CameraStr.."ReferenceFrame = "..j[4]..", " - end - CameraStr = CameraStr.."Position = {"..j[5].."}, " - if not isBlank(j[6]) then - CameraStr = CameraStr.."Up = {"..j[6].."}, " - end - if not isBlank(j[7]) then - CameraStr = CameraStr.."Yaw = "..j[7]..", " - end - if not isBlank(j[8]) then - CameraStr = CameraStr.."Pitch = "..j[8] - end - CameraStr = CameraStr.."})\n" - elseif (j[1] == "goToGeo") then - CameraStr = CameraStr.." openspace.navigation.goToGeo(" - if not isBlank(j[2]) then - CameraStr = CameraStr..j[2]..", " - end - CameraStr = CameraStr..j[3]..", "..j[4] - if not isBlank(j[5]) then - CameraStr = CameraStr..", "..j[5] - end - CameraStr = CameraStr..")\n" - else - printError("Camera arg 1/1 must be 'setNavigationState' or 'goToGeo'.") - os.exit() - end - end - - - --Write the file - io.write(ModuleStr) - io.write("\n") - io.write(AssetStr) - io.write("\n") - io.write(KeyStr) - io.write("\n") - io.write("asset.onInitialize(function ()\n") - io.write(TimeStr) - io.write("\n") - if not (tableSize(T["Keybinding"]) == 0) then - io.write(" sceneHelper.bindKeys(Keybindings)") - io.write("\n") - end - io.write(MarkNodesStr) - io.write("\n") - io.write(PropertyStr) - io.write("\n") - io.write(CameraStr) - io.write("\n") - io.write("end)\n") - - io.close(file) -end -M.generateAsset = generateAsset - -return M diff --git a/scripts/_parser.lua b/scripts/_parser.lua deleted file mode 100644 index 76103abc17..0000000000 --- a/scripts/_parser.lua +++ /dev/null @@ -1,299 +0,0 @@ -local M = {} - - -local version -local modulesTable = {} -local assetsTable = {} -local propertiesTable = {} -local timeTable = {} -local cameraTable = {} -local markNodesTable = {} -local keybindingsTable = {} -local resultTable = {} -local insideSection = false -local currFunction = "None" -local currSection = "None" -local numLinesVersion = 0 -local lineIndex = 1 - -function printError(message) - print("Error @ line "..lineIndex..": "..message) -end - -function splitByTab (inputstr) - sep = "\t" - t = {} - for match in (inputstr..sep):gmatch("(.-)"..sep) do - table.insert(t, match) - end - return t; -end - -function parseVersion(line) - numLinesVersion = numLinesVersion + 1 - if numLinesVersion > 1 then - printError("Too many lines in Version section.") - os.exit() - else - lineS = splitByTab(line) - if tableLen(lineS) > 1 then - printError("No tabs allowed in version entry.") - os.exit() - else - version = line - end - end -end - -function parseMarkNodes(line) - lineS = splitByTab(line) - if tableLen(lineS) > 1 then - printError("No tabs allowed in MarkNodes entry.") - os.exit() - else - table.insert(markNodesTable, line) - end -end - -function parseModule(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 3 then - printError("3 fields requried in a Module entry.") - os.exit() - else - table.insert(modulesTable, t) - end -end - -function parseAsset(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 2 then - printError("2 fields required in a Asset entry.") - os.exit() - else - local req = "required" - if t[2] == "requested" then - req = "requested" - end - table.insert(assetsTable, {t[1], req}) - end -end - -function parseProperty(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 3 then - printError("3 fields required in a Property entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Property set command (arg 1/3) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Property name (arg 2/3) is required.") - os.exit() - elseif isBlank(t[3]) then - printError("Property value to set (arg 3/3) is required.") - os.exit() - end - - if t[1] ~= "setPropertyValue" and t[1] ~= "setPropertyValueSingle" then - printError("Property set command '"..t[1].."' is not supported.") - os.exit() - end - - table.insert(propertiesTable, t) -end - -function parseKeybinding(line) - local numReqFields = 6 - t = {} - t = splitByTab(line) - if tableLen(t) < numReqFields then - printError(numReqFields.." fields required in a Keybinding entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Keybinding key (arg 1/6) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Keybinding documentation (arg 2/6) is required.") - os.exit() - elseif isBlank(t[3]) then - printError("Keybinding name (arg 3/6) is required.") - os.exit() - elseif isBlank(t[4]) then - printError("Keybinding GuiPath (arg 4/6) is required.") - os.exit() - elseif isBlank(t[5]) then - printError("Keybinding local(T/F) (arg 5/6) is required.") - os.exit() - elseif isBlank(t[6]) then - printError("Keybinding script to execute (arg 6/6) is required.") - os.exit() - end - - --If there are more than 6 fields then combine the final fields together - --assuming that this is a lua script that contains tabs - if tableLen(t) > numReqFields then - for i=(numReqFields + 1),tableLen(t) do - t[numReqFields] = t[numReqFields]..t[i] - end - end - - if t[5] ~= "true" and t[5] ~= "false" then - printError("Keybinding local arg must be true or false.") - os.exit() - end - - table.insert(keybindingsTable, {t[1], t[2], t[3], t[4], t[5], t[6]}) -end - -function parseTime(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 2 then - printError("2 fields required in a Time entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Time set type (arg 1/2) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Time value to set (arg 2/2) is required.") - os.exit() - end - - if t[1] ~= "absolute" and t[1] ~= "relative" then - printError("Time set type '"..t[1].."' is not supported.") - os.exit() - end - - table.insert(timeTable, t) -end - -function parseCamera(line) - t = {} - t = splitByTab(line) - - local cmd = t[1] - if cmd == "setNavigationState" then - if tableLen(t) ~= 8 then - printError("8 fields required in camera 'setNavigationState' line.") - os.exit() - elseif isBlank(t[2]) then - printError("Camera setNavigationState Anchor (arg 1/7) is required.") - os.exit() - elseif isBlank(t[5]) then - printError("Camera setNavigationState position vector (arg 4/7) is required.") - os.exit() - end - elseif cmd == "goToGeo" then - if tableLen(t) ~= 5 then - printError("5 fields required in camera 'goToGeo' line.") - os.exit() - elseif isBlank(t[3]) then - printError("Camera goToGeo Latitude (arg 2/4) is required.") - os.exit() - elseif isBlank(t[4]) then - printError("Camera goToGeo Longitude (arg 3/4) is required.") - os.exit() - end - else - printError("Camera position command '"..cmd.."' is not supported.") - os.exit() - end - - table.insert(cameraTable, t) -end - - -local parsingSections = { - {section = "Version", func = parseVersion}, - {section = "Module", func = parseModule}, - {section = "Asset", func = parseAsset}, - {section = "Property", func = parseProperty}, - {section = "Keybinding", func = parseKeybinding}, - {section = "Time", func = parseTime}, - {section = "Camera", func = parseCamera}, - {section = "MarkNodes", func = parseMarkNodes} -} - -function file_exists(file) - local f = io.open(file, "rb") - if f then - f:close() - end - return f ~= nil -end - -function lines_from(file) - if not file_exists(file) then - return {} - end - lines = {} - for line in io.lines(file) do - lines[#lines + 1] = line - end - return lines -end - -function determineSection(header) - header = header:sub(2) - for _,i in pairs(parsingSections) do - if i.section == header then - currSection = i.section - currFunction = i.func - return true - end - end - return false -end - -function isBlank(line) - return line:match("%S") == nil -end - -function parseCurrentSection(line) - currFunction(line) -end - -function tableLen(T) - local size = 0 - for _ in pairs(T) do - size = size + 1 - end - return size -end - -function parseProfile(fileIn) - local lines = lines_from(fileIn) - - for k,v in pairs(lines) do - if insideSection then - if isBlank(v) then - insideSection = false - else - parseCurrentSection(v) - end - elseif v:sub(1, 1) == "#" then - if determineSection(v) then - insideSection = true - end - end - lineIndex = lineIndex + 1 - end - - resultTable["Version"] = version - resultTable["Module"] = modulesTable - resultTable["Asset"] = assetsTable - resultTable["Property"] = propertiesTable - resultTable["Time"] = timeTable - resultTable["Camera"] = cameraTable - resultTable["MarkNodes"] = markNodesTable - resultTable["Keybinding"] = keybindingsTable - - return resultTable -end - -M.parseProfile = parseProfile -return M diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index a2e94d37b4..d1bb1b4275 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -1,7 +1,479 @@ -local parser = require("_parser") -local makeAsset = require("_makeAsset") +local version +local modulesTable = {} +local assetsTable = {} +local propertiesTable = {} +local timeTable = {} +local cameraTable = {} +local markNodesTable = {} +local keybindingsTable = {} +local resultTable = {} +local insideSection = false +local currFunction = "None" +local currSection = "None" +local numLinesVersion = 0 +local lineIndex = 1 -profileOut = ProfileFilename:match("^.+%.").."asset" +function printError(message) + print("Error @ line "..lineIndex..": "..message) +end -local resultTable = parser.parseProfile(ProfileFilename) -makeAsset.generateAsset(resultTable, profileOut) +function splitByTab (inputstr) + sep = "\t" + t = {} + for match in (inputstr..sep):gmatch("(.-)"..sep) do + table.insert(t, match) + end + return t; +end + +function parseVersion(line) + numLinesVersion = numLinesVersion + 1 + if numLinesVersion > 1 then + printError("Too many lines in Version section.") + os.exit() + else + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError("No tabs allowed in version entry.") + os.exit() + else + version = line + end + end +end + +function parseMarkNodes(line) + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError("No tabs allowed in MarkNodes entry.") + os.exit() + else + table.insert(markNodesTable, line) + end +end + +function parseModule(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError("3 fields requried in a Module entry.") + os.exit() + else + table.insert(modulesTable, t) + end +end + +function parseAsset(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError("2 fields required in a Asset entry.") + os.exit() + else + local req = "required" + if t[2] == "requested" then + req = "requested" + end + table.insert(assetsTable, {t[1], req}) + end +end + +function parseProperty(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError("3 fields required in a Property entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Property set command (arg 1/3) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Property name (arg 2/3) is required.") + os.exit() + elseif isBlank(t[3]) then + printError("Property value to set (arg 3/3) is required.") + os.exit() + end + + if t[1] ~= "setPropertyValue" and t[1] ~= "setPropertyValueSingle" then + printError("Property set command '"..t[1].."' is not supported.") + os.exit() + end + + table.insert(propertiesTable, t) +end + +function parseKeybinding(line) + local numReqFields = 6 + t = {} + t = splitByTab(line) + if tableLen(t) < numReqFields then + printError(numReqFields.." fields required in a Keybinding entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Keybinding key (arg 1/6) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Keybinding documentation (arg 2/6) is required.") + os.exit() + elseif isBlank(t[3]) then + printError("Keybinding name (arg 3/6) is required.") + os.exit() + elseif isBlank(t[4]) then + printError("Keybinding GuiPath (arg 4/6) is required.") + os.exit() + elseif isBlank(t[5]) then + printError("Keybinding local(T/F) (arg 5/6) is required.") + os.exit() + elseif isBlank(t[6]) then + printError("Keybinding script to execute (arg 6/6) is required.") + os.exit() + end + + --If there are more than 6 fields then combine the final fields together + --assuming that this is a lua script that contains tabs + if tableLen(t) > numReqFields then + for i=(numReqFields + 1),tableLen(t) do + t[numReqFields] = t[numReqFields]..t[i] + end + end + + if t[5] ~= "true" and t[5] ~= "false" then + printError("Keybinding local arg must be true or false.") + os.exit() + end + + table.insert(keybindingsTable, {t[1], t[2], t[3], t[4], t[5], t[6]}) +end + +function parseTime(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError("2 fields required in a Time entry.") + os.exit() + elseif isBlank(t[1]) then + printError("Time set type (arg 1/2) is required.") + os.exit() + elseif isBlank(t[2]) then + printError("Time value to set (arg 2/2) is required.") + os.exit() + end + + if t[1] ~= "absolute" and t[1] ~= "relative" then + printError("Time set type '"..t[1].."' is not supported.") + os.exit() + end + + table.insert(timeTable, t) +end + +function parseCamera(line) + t = {} + t = splitByTab(line) + + local cmd = t[1] + if cmd == "setNavigationState" then + if tableLen(t) ~= 8 then + printError("8 fields required in camera 'setNavigationState' line.") + os.exit() + elseif isBlank(t[2]) then + printError("Camera setNavigationState Anchor (arg 1/7) is required.") + os.exit() + elseif isBlank(t[5]) then + printError("Camera setNavigationState position vector (arg 4/7) is required.") + os.exit() + end + elseif cmd == "goToGeo" then + if tableLen(t) ~= 5 then + printError("5 fields required in camera 'goToGeo' line.") + os.exit() + elseif isBlank(t[3]) then + printError("Camera goToGeo Latitude (arg 2/4) is required.") + os.exit() + elseif isBlank(t[4]) then + printError("Camera goToGeo Longitude (arg 3/4) is required.") + os.exit() + end + else + printError("Camera position command '"..cmd.."' is not supported.") + os.exit() + end + + table.insert(cameraTable, t) +end + + +local parsingSections = { + {section = "Version", func = parseVersion}, + {section = "Module", func = parseModule}, + {section = "Asset", func = parseAsset}, + {section = "Property", func = parseProperty}, + {section = "Keybinding", func = parseKeybinding}, + {section = "Time", func = parseTime}, + {section = "Camera", func = parseCamera}, + {section = "MarkNodes", func = parseMarkNodes} +} + +function file_exists(file) + local f = io.open(file, "rb") + if f then + f:close() + end + return f ~= nil +end + +function lines_from(file) + if not file_exists(file) then + return {} + end + lines = {} + for line in io.lines(file) do + lines[#lines + 1] = line + end + return lines +end + +function determineSection(header) + header = header:sub(2) + for _,i in pairs(parsingSections) do + if i.section == header then + currSection = i.section + currFunction = i.func + return true + end + end + return false +end + +function isBlank(line) + return line:match("%S") == nil +end + +function parseCurrentSection(line) + currFunction(line) +end + +function tableLen(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function parseProfile(fileIn) + local lines = lines_from(fileIn) + + for k,v in pairs(lines) do + if insideSection then + if isBlank(v) then + insideSection = false + else + parseCurrentSection(v) + end + elseif v:sub(1, 1) == "#" then + if determineSection(v) then + insideSection = true + end + end + lineIndex = lineIndex + 1 + end + + resultTable["Version"] = version + resultTable["Module"] = modulesTable + resultTable["Asset"] = assetsTable + resultTable["Property"] = propertiesTable + resultTable["Time"] = timeTable + resultTable["Camera"] = cameraTable + resultTable["MarkNodes"] = markNodesTable + resultTable["Keybinding"] = keybindingsTable + + return resultTable +end + + + + +ModuleStr = "" +AssetStr = "" +KeyStr = "" +TimeStr = "" +MarkNodesStr = "" +PropertyStr = "" +CameraStr = "" + +function tableSize(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function generateAsset(T, fileOut) + file = io.open(fileOut, "w") + io.output(file) + + --Module section + for i,j in pairs(T["Module"]) do + if not isBlank(j[2]) and not isBlank(j[3]) then + ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[2].."\nelse\n".." "..j[3].."\nend\n" + elseif not isBlank(j[3]) then + ModuleStr = ModuleStr.."if not openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[3].."\nend\n" + elseif not isBlank(j[2]) then + ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" + ModuleStr = ModuleStr.." "..j[2].."\nend\n" + end + end + + --Asset section + AssetStr = AssetStr.."asset.require('./base');\n" + AssetStr = AssetStr.."local assetHelper = asset.require('util/asset_helper')\n" + AssetStr = AssetStr.."local propertyHelper = asset.require('util/property_helper')\n" + AssetStr = AssetStr.."local sceneHelper = asset.require('util/scene_helper')\n" + AssetStr = AssetStr.."local renderableHelper = asset.require('util/renderable_helper')\n" + local assetType = "" + for i,j in pairs(T["Asset"]) do + if isBlank(j[2]) then + assetType = "require" + else + if (j[2] == "required") then + assetType = "require" + elseif (j[2] == "requested") then + assetType = "request" + else + printError("Asset arg 2/2 must be either 'required' or 'requested'.") + os.exit() + end + end + AssetStr = AssetStr.."asset."..assetType.."('"..j[1].."')\n" + end + + --Keybindings section + if not (tableSize(T["Keybinding"]) == 0) then + KeyStr = KeyStr.."local Keybindings = {\n" + for i,j in pairs(T["Keybinding"]) do + KeyStr = KeyStr.." {\n" + KeyStr = KeyStr.." Key = \""..j[1].."\",\n" + KeyStr = KeyStr.." Documentation = \""..j[2].."\",\n" + KeyStr = KeyStr.." Name = \""..j[3].."\",\n" + KeyStr = KeyStr.." GuiPath = \""..j[4].."\",\n" + KeyStr = KeyStr.." Local = "..j[5]..",\n" + KeyStr = KeyStr.." Command = \""..j[6].."\"\n" + KeyStr = KeyStr.." },\n" + end + KeyStr = KeyStr.."}\n" + end + + --Time section + for i,j in pairs(T["Time"]) do + if not (j[1] == "absolute") and not (j[1] == "relative") then + printError("Time arg 1/1 must be either 'absolute' or 'relative'.") + os.exit() + elseif (j[1] == "absolute") then + TimeStr = TimeStr.." openspace.time.setTime(\""..j[2].."\")\n" + elseif (j[1] == "relative") then + TimeStr = TimeStr.." openspace.time.setTime(" + TimeStr = TimeStr.."openspace.time.advancedTime(now, \"" + TimeStr = TimeStr..j[2].."\"))\n" + end + end + + --MarkNodes section + mkNodLen = tableSize(T["MarkNodes"]) + if not (mkNodLen == 0) then + MarkNodesStr = MarkNodesStr.." openspace.markInterestingNodes({" + for i,j in pairs(T["MarkNodes"]) do + MarkNodesStr = MarkNodesStr.."\""..j.."\"" + if (i < mkNodLen) then + MarkNodesStr = MarkNodesStr..", " + end + end + MarkNodesStr = MarkNodesStr.."})\n" + end + + --Property section + for i,j in pairs(T["Property"]) do + if not (j[1] == "setPropertyValue") and not (j[1] == "setPropertyValueSingle") then + printError("Property arg 1/1 must be 'setPropertyValue[Single]'.") + os.exit() + else + PropertyStr = PropertyStr.." openspace."..j[1].."('"..j[2].."', "..j[3]..")\n" + end + end + + --Camera section + for i,j in pairs(T["Camera"]) do + if (j[1] == "setNavigationState") then + CameraStr = CameraStr.." openspace.navigation.setNavigationState({" + CameraStr = CameraStr.."Anchor = "..j[2]..", " + if not isBlank(j[3]) then + CameraStr = CameraStr.."Aim = "..j[3]..", " + end + if not isBlank(j[4]) then + CameraStr = CameraStr.."ReferenceFrame = "..j[4]..", " + end + CameraStr = CameraStr.."Position = {"..j[5].."}, " + if not isBlank(j[6]) then + CameraStr = CameraStr.."Up = {"..j[6].."}, " + end + if not isBlank(j[7]) then + CameraStr = CameraStr.."Yaw = "..j[7]..", " + end + if not isBlank(j[8]) then + CameraStr = CameraStr.."Pitch = "..j[8] + end + CameraStr = CameraStr.."})\n" + elseif (j[1] == "goToGeo") then + CameraStr = CameraStr.." openspace.navigation.goToGeo(" + if not isBlank(j[2]) then + CameraStr = CameraStr..j[2]..", " + end + CameraStr = CameraStr..j[3]..", "..j[4] + if not isBlank(j[5]) then + CameraStr = CameraStr..", "..j[5] + end + CameraStr = CameraStr..")\n" + else + printError("Camera arg 1/1 must be 'setNavigationState' or 'goToGeo'.") + os.exit() + end + end + + + --Write the file + io.write(ModuleStr) + io.write("\n") + io.write(AssetStr) + io.write("\n") + io.write(KeyStr) + io.write("\n") + io.write("asset.onInitialize(function ()\n") + io.write(TimeStr) + io.write("\n") + if not (tableSize(T["Keybinding"]) == 0) then + io.write(" sceneHelper.bindKeys(Keybindings)") + io.write("\n") + end + io.write(MarkNodesStr) + io.write("\n") + io.write(PropertyStr) + io.write("\n") + io.write(CameraStr) + io.write("\n") + io.write("end)\n") + + io.close(file) +end + +profileFilename = openspace.profile.getFilename() +profileOutFile = profileFilename:match("^.+%.").."scene" +profileOutPath = openspace.profile.getPath() +print("Using profile input "..profileFilename.."!") +print("Using output scene filepath "..profileOutFile.."!") +print("Using output path "..profileOutPath) +local resultTable = parseProfile(profileOutPath.."\\"..profileFilename) +generateAsset(resultTable, profileOutPath.."\\"..profileOutFile) From fbaeda103172760d1f4163c87a065be3418e0820 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 22 Oct 2019 16:27:21 -0600 Subject: [PATCH 029/214] Added test profile based on NewHorizons scene --- data/assets/newhorizons.profile | 60 +++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 data/assets/newhorizons.profile diff --git a/data/assets/newhorizons.profile b/data/assets/newhorizons.profile new file mode 100644 index 0000000000..1819abd3f5 --- /dev/null +++ b/data/assets/newhorizons.profile @@ -0,0 +1,60 @@ +#Version +1.0 + +#Asset +scene/solarsystem/missions/newhorizons/newhorizons required +scene/solarsystem/missions/newhorizons/model required + +#Property +setPropertyValueSingle NavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance 20.000000 +setPropertyValueSingle Scene.Pluto.Renderable.Enabled false +setPropertyValueSingle Scene.Charon.Renderable.Enabled false +setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false + +#Keybinding +a Sets the focus of the camera on 'NewHorizons'. Focus on New Horizons /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) +SHIFT+a Sets the focus of the camera on 'NewHorizons'. Anchor at New Horizons, Aim at Pluto /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) +s Sets the focus of the camera on 'Pluto' Focus on Pluto /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) +d Sets the focus of the camera on 'Charon'. Focus on New Charon /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Charon');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) +F7 Toggles New Horizons image projection. Toggle NH Image Projection /New Horizons false [[local enabled = openspace.getPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection'); openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection', not enabled); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.PerformProjection', not enabled)]] +F8 Removes all image projections from Pluto and Charon. Clear image projections /New Horizons false openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true) +F9 Jumps to the 14th of July 2015 at 0900 UTC and clears all projections. Reset time and projections /New Horizons false openspace.time.setTime('2015-07-14T09:00:00.00');openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true) +KP_8 Increases the height map exaggeration on Pluto. Pluto HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) +CTRL+I Increases the height map exaggeration on Pluto. Pluto HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) +KP_2 Decreases the height map exaggeration on Pluto. Pluto HeightExaggeration - /New Horizons false propertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) +CTRL+K Decreases the height map exaggeration on Pluto. Pluto HeightExaggeration - /New Horizons false propertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) +KP_9 Increases the height map exaggeration on Charon. Charon HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000) +CTRL+O Increases the height map exaggeration on Charon. Charon HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.CharonProjection.Renderable.HeightExaggeration', 5000) +KP_3 Decreases the height map exaggeration on Charon. Charon HeightExaggeration - /New Horizons false propertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000) +CTRL+L Decreases the height map exaggeration on Charon. Charon HeightExaggeration - /New Horizons false propertyHelper.decrement('Scene.CharonProjection.Renderable.HeightExaggeration', 5000) +o Toggles the visibility of the trail behind Pluto. Toggle Pluto Trail /New Horizons false propertyHelper.invert('Scene.PlutoBarycentricTrail.Renderable.Enabled') +j Toggles the visibility of the text labels of Pluto, Charon, Hydra, Nix, Kerberos, and Styx. Toggle Pluto Labels /New Horizons false renderableHelper.toggle('Scene.PlutoText') .. renderableHelper.toggle('Scene.CharonText') .. renderableHelper.toggle('Scene.HydraText') .. renderableHelper.toggle('Scene.NixText') .. renderableHelper.toggle('Scene.KerberosText') .. renderableHelper.toggle('Scene.StyxText') +l Toggles the visibility of the labels for the New Horizons instruments. Toggle New Horizons Labels /New Horizons false propertyHelper.fadeInOut('Scene.Labels.Renderable.Opacity', 2.0) +m Draws the instrument field of views in a solid color or as lines. Toggle instrument FOVs /New Horizons false propertyHelper.invert('Scene.NH_LORRI.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_LEISA.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN1.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN2.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_RED.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_BLUE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_FT.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_METHANE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_NIR.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_AIRGLOW.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_SOC.Renderable.SolidDraw') +Shift+t Toggles the visibility of the shadow visualization of Pluto and Charon. Toggle Shadows /New Horizons false renderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow') +t Toggles the trail of New Horizons. Toggle NH Trail /New Horizons false renderableHelper.toggle('Scene.NewHorizonsTrailPluto') +h Disables visibility of the trails Hide Trails /Rendering false local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false openspace.time.interpolateDeltaTime(1) +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false openspace.time.interpolateDeltaTime(5) +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false openspace.time.interpolateDeltaTime(10) +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false openspace.time.interpolateDeltaTime(20) +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false openspace.time.interpolateDeltaTime(40) +6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false openspace.time.interpolateDeltaTime(60) +7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false openspace.time.interpolateDeltaTime(120) +8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false openspace.time.interpolateDeltaTime(360) +9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false openspace.time.interpolateDeltaTime(540) +Shift+1 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false openspace.time.interpolateDeltaTime(1080) +Shift+2 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false openspace.time.interpolateDeltaTime(2160) +Shift+3 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false openspace.time.interpolateDeltaTime(4320) +Shift+4 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false openspace.time.interpolateDeltaTime(8640) + +#Time +absolute 2015-07-14T08:00:00.00 + +#Camera +setNavigationState "NewHorizons" "Root" -6.572656E1, -7.239404E1, -2.111890E1 0.102164, -0.362945, 0.926193 + +#MarkNodes +Pluto +NewHorizons +Charon From f20645d24a87f3f99b6e08c3d04a68efbb702184 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Tue, 22 Oct 2019 16:29:00 -0600 Subject: [PATCH 030/214] Modified config file to use test profile instead of scene --- openspace.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..aefdff3b92 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -42,8 +42,8 @@ SGCTConfig = sgct.config.single{} -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace - -Asset = "default" +Profile = "newhorizons" +-- Asset = "default" -- Asset = "default_full" -- Asset = "newhorizons" -- Asset = "rosetta" From 8fe544597a994cc854b0094f36c15391bd9877a5 Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 23 Oct 2019 19:05:01 -0600 Subject: [PATCH 031/214] Clean-up of convert profile-to-scene lua script. --- scripts/convertProfileToScene.lua | 116 ++++++++++++++---------------- 1 file changed, 55 insertions(+), 61 deletions(-) diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index d1bb1b4275..9c8e359f72 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -1,17 +1,18 @@ -local version -local modulesTable = {} -local assetsTable = {} -local propertiesTable = {} -local timeTable = {} -local cameraTable = {} -local markNodesTable = {} -local keybindingsTable = {} -local resultTable = {} -local insideSection = false -local currFunction = "None" -local currSection = "None" -local numLinesVersion = 0 -local lineIndex = 1 +version = "" +modulesTable = {} +assetsTable = {} +propertiesTable = {} +timeTable = {} +cameraTable = {} +markNodesTable = {} +keybindingsTable = {} +resultTable = {} +insideSection = false +currFunction = "None" +currSection = "None" +numLinesVersion = 0 +lineIndex = 1 + function printError(message) print("Error @ line "..lineIndex..": "..message) @@ -203,18 +204,6 @@ function parseCamera(line) table.insert(cameraTable, t) end - -local parsingSections = { - {section = "Version", func = parseVersion}, - {section = "Module", func = parseModule}, - {section = "Asset", func = parseAsset}, - {section = "Property", func = parseProperty}, - {section = "Keybinding", func = parseKeybinding}, - {section = "Time", func = parseTime}, - {section = "Camera", func = parseCamera}, - {section = "MarkNodes", func = parseMarkNodes} -} - function file_exists(file) local f = io.open(file, "rb") if f then @@ -292,17 +281,6 @@ function parseProfile(fileIn) return resultTable end - - - -ModuleStr = "" -AssetStr = "" -KeyStr = "" -TimeStr = "" -MarkNodesStr = "" -PropertyStr = "" -CameraStr = "" - function tableSize(T) local size = 0 for _ in pairs(T) do @@ -443,37 +421,53 @@ function generateAsset(T, fileOut) end end - --Write the file - io.write(ModuleStr) - io.write("\n") - io.write(AssetStr) - io.write("\n") - io.write(KeyStr) - io.write("\n") + io.write(ModuleStr.."\n") + io.write(AssetStr.."\n") + io.write(KeyStr.."\n") io.write("asset.onInitialize(function ()\n") - io.write(TimeStr) - io.write("\n") + io.write(TimeStr.."\n") if not (tableSize(T["Keybinding"]) == 0) then - io.write(" sceneHelper.bindKeys(Keybindings)") - io.write("\n") + io.write(" sceneHelper.bindKeys(Keybindings)\n") end - io.write(MarkNodesStr) - io.write("\n") - io.write(PropertyStr) - io.write("\n") - io.write(CameraStr) - io.write("\n") + io.write(MarkNodesStr.."\n") + io.write(PropertyStr.."\n") + io.write(CameraStr.."\n") io.write("end)\n") io.close(file) end +--[[ +########################################################################################## + M a i n +########################################################################################## +]]-- + +ModuleStr = "" +AssetStr = "" +KeyStr = "" +TimeStr = "" +MarkNodesStr = "" +PropertyStr = "" +CameraStr = "" + +parsingSections = { + {section = "Version", func = parseVersion}, + {section = "Module", func = parseModule}, + {section = "Asset", func = parseAsset}, + {section = "Property", func = parseProperty}, + {section = "Keybinding", func = parseKeybinding}, + {section = "Time", func = parseTime}, + {section = "Camera", func = parseCamera}, + {section = "MarkNodes", func = parseMarkNodes} +} + profileFilename = openspace.profile.getFilename() -profileOutFile = profileFilename:match("^.+%.").."scene" -profileOutPath = openspace.profile.getPath() -print("Using profile input "..profileFilename.."!") -print("Using output scene filepath "..profileOutFile.."!") -print("Using output path "..profileOutPath) -local resultTable = parseProfile(profileOutPath.."\\"..profileFilename) -generateAsset(resultTable, profileOutPath.."\\"..profileOutFile) +profilePath = openspace.profile.getPath() + +profileIn = profilePath.."\\"..profileFilename +assetOut = profilePath.."\\"..profileFilename:match("^.+%.").."scene" + +local resultTable = parseProfile(profileIn) +generateAsset(resultTable, assetOut) From bd27ac1ee15437d1555768336de505fb6c862f90 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 30 Oct 2019 05:47:22 -0400 Subject: [PATCH 032/214] Issue/988 (#989) * Added new FXAA implementation for test. * Fixed ghosting MW. --- src/rendering/framebufferrenderer.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 2007f13a53..284d2920c3 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -406,10 +406,16 @@ void FramebufferRenderer::applyTMO(float blackoutFactor) { _hdrFilteringProgram->setUniform(_hdrUniformCache.Saturation, _saturation); _hdrFilteringProgram->setUniform(_hdrUniformCache.Value, _value); + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + _hdrFilteringProgram->deactivate(); } @@ -440,10 +446,16 @@ void FramebufferRenderer::applyFXAA() { glm::vec2 inverseScreenSize(1.f/_resolution.x, 1.f/_resolution.y); _fxaaProgram->setUniform(_fxaaUniformCache.inverseScreenSize, inverseScreenSize); + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); + glDepthMask(true); + glEnable(GL_DEPTH_TEST); + _fxaaProgram->deactivate(); } @@ -633,7 +645,7 @@ void FramebufferRenderer::updateResolution() { _resolution.y, 0, GL_RGBA, - GL_BYTE, + GL_UNSIGNED_BYTE, nullptr ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -894,7 +906,7 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac if (doPerformanceMeasurements) { perfInternal = std::make_unique( "FramebufferRenderer::render::deferredTasks" - ); + ); } performDeferredTasks(tasks.deferredcasterTasks); } @@ -912,6 +924,8 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac if (_enableFXAA) { glBindFramebuffer(GL_FRAMEBUFFER, _fxaaBuffers.fxaaFramebuffer); + glDrawBuffers(1, ColorAttachment0Array); + glDisable(GL_BLEND); } else { // When applying the TMO, the result is saved to the default FBO to be displayed From da8beff8e99cd47836c0d428b0344755f1778fe7 Mon Sep 17 00:00:00 2001 From: liuloppan Date: Wed, 30 Oct 2019 13:18:46 +0100 Subject: [PATCH 033/214] Feature/interaction monitor (#999) * interaction monitor first commit * Renaming some member variables with underscore * Interaction monitor registering mouse events and touch events * Added setIdleTime * Adding to CMakeLists * Moved interactionmoitor.cpp to correct locatioN * Cleanup after review. Removed interaction type string and fixed indentation * Changed documentation description * Renamed hasNewWebInput to processNewWebInput * Some cleanup * Rename registerInteraction to markInteraction Add markInteraction calls to mouse and keyboard event sin OpenSpaceEngine --- include/openspace/engine/globals.h | 3 + .../interaction/interactionmonitor.h | 70 +++++++++++++ modules/touch/touchmodule.cpp | 97 ++++++++++--------- modules/touch/touchmodule.h | 16 +-- modules/webbrowser/src/eventhandler.cpp | 4 + src/CMakeLists.txt | 2 + src/engine/globals.cpp | 7 ++ src/engine/openspaceengine.cpp | 7 ++ src/interaction/interactionmonitor.cpp | 81 ++++++++++++++++ src/interaction/navigationhandler.cpp | 2 +- 10 files changed, 234 insertions(+), 55 deletions(-) create mode 100644 include/openspace/interaction/interactionmonitor.h create mode 100644 src/interaction/interactionmonitor.cpp diff --git a/include/openspace/engine/globals.h b/include/openspace/engine/globals.h index 994ba901fa..2e1ed8dd77 100644 --- a/include/openspace/engine/globals.h +++ b/include/openspace/engine/globals.h @@ -53,6 +53,7 @@ namespace configuration { struct Configuration; } namespace interaction { struct JoystickInputStates; struct WebsocketInputStates; + class InteractionMonitor; class KeybindingManager; class NavigationHandler; class SessionRecording; @@ -87,6 +88,7 @@ VersionChecker& gVersionChecker(); VirtualPropertyManager& gVirtualPropertyManager(); WindowDelegate& gWindowDelegate(); configuration::Configuration& gConfiguration(); +interaction::InteractionMonitor& gInteractionMonitor(); interaction::JoystickInputStates& gJoystickInputStates(); interaction::WebsocketInputStates& gWebsocketInputStates(); interaction::KeybindingManager& gKeybindingManager(); @@ -120,6 +122,7 @@ static VersionChecker& versionChecker = detail::gVersionChecker(); static VirtualPropertyManager& virtualPropertyManager = detail::gVirtualPropertyManager(); static WindowDelegate& windowDelegate = detail::gWindowDelegate(); static configuration::Configuration& configuration = detail::gConfiguration(); +static interaction::InteractionMonitor& interactionMonitor = detail::gInteractionMonitor(); static interaction::JoystickInputStates& joystickInputStates = detail::gJoystickInputStates(); static interaction::WebsocketInputStates& websocketInputStates = diff --git a/include/openspace/interaction/interactionmonitor.h b/include/openspace/interaction/interactionmonitor.h new file mode 100644 index 0000000000..59748a00c8 --- /dev/null +++ b/include/openspace/interaction/interactionmonitor.h @@ -0,0 +1,70 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___INTERACTIONMONITOR___H__ +#define __OPENSPACE_CORE___INTERACTIONMONITOR___H__ + +#include + +#include +#include + +namespace openspace::interaction { + +/** + * The class InteractionMonitor keeps track of user interactions during an OpenSpace + * session. It keeps track of when the latest interaction was made and of when the state + * changes to idle. + */ +class InteractionMonitor : public properties::PropertyOwner { +public: + InteractionMonitor(); + + void setActivityState(bool isActive); + void setIdleTime(float time); + + /* + * Called every frame from OpenSpaceEngine and calculates the activity state depending + * on the last registered interaction. + */ + void updateActivityState(); + + /* + * Called from all places we want to mark activity from. Updates the last registered + * interaction time + */ + void markInteraction(); + +private: + double _lastInteractionTime = 0; + properties::BoolProperty _isInActiveState; + properties::FloatProperty _idleTime; // in seconds + + // @TODO (lovisa) make a list of interactions to listen for + // and only allow registering updates from those interactions +}; + +} // namespace openspace::interaction + +#endif // __OPENSPACE_CORE___INTERACTIONMONITOR___H__ diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index 4c59fffdfb..49a866a620 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -46,54 +47,59 @@ using namespace TUIO; namespace openspace { -bool TouchModule::hasNewInput() { +bool TouchModule::processNewInput() { // Get new input from listener - listOfContactPoints = ear.getInput(); - ear.clearInput(); + + _listOfContactPoints = _ear.getInput(); + _ear.clearInput(); // Set touch property to active (to void mouse input, mainly for mtdev bridges) - touch.touchActive(!listOfContactPoints.empty()); + _touch.touchActive(!_listOfContactPoints.empty()); + + if (!_listOfContactPoints.empty()) { + global::interactionMonitor.registerInteraction(); + } // Erase old input id's that no longer exists - lastProcessed.erase( + _lastProcessed.erase( std::remove_if( - lastProcessed.begin(), - lastProcessed.end(), + _lastProcessed.begin(), + _lastProcessed.end(), [this](const Point& point) { return std::find_if( - listOfContactPoints.begin(), - listOfContactPoints.end(), + _listOfContactPoints.begin(), + _listOfContactPoints.end(), [&point](const TuioCursor& c) { return point.first == c.getSessionID(); } - ) == listOfContactPoints.end(); }), - lastProcessed.end()); + ) == _listOfContactPoints.end(); }), + _lastProcessed.end()); // if tap occured, we have new input - if (listOfContactPoints.empty() && lastProcessed.empty() && ear.tap()) { - TuioCursor c = ear.getTap(); - listOfContactPoints.push_back(c); - lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); - touch.tap(); + if (_listOfContactPoints.empty() && _lastProcessed.empty() && _ear.tap()) { + TuioCursor c = _ear.getTap(); + _listOfContactPoints.push_back(c); + _lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); + _touch.tap(); return true; } // Check if we need to parse touchevent to the webgui - hasNewWebInput(listOfContactPoints); + processNewWebInput(_listOfContactPoints); // Return true if we got new input - if (listOfContactPoints.size() == lastProcessed.size() && - !listOfContactPoints.empty()) + if (_listOfContactPoints.size() == _lastProcessed.size() && + !_listOfContactPoints.empty()) { bool newInput = true; // go through list and check if the last registrered time is newer than the one in // lastProcessed (last frame) std::for_each( - lastProcessed.begin(), - lastProcessed.end(), + _lastProcessed.begin(), + _lastProcessed.end(), [this, &newInput](Point& p) { std::vector::iterator cursor = std::find_if( - listOfContactPoints.begin(), - listOfContactPoints.end(), + _listOfContactPoints.begin(), + _listOfContactPoints.end(), [&p](const TuioCursor& c) { return c.getSessionID() == p.first; } ); double now = cursor->getPath().back().getTuioTime().getTotalMilliseconds(); @@ -113,10 +119,9 @@ bool TouchModule::hasNewInput() { } } -void TouchModule::hasNewWebInput(const std::vector& listOfContactPoints) { - // If one point input and no data in webPosition callback send mouse click to webgui +void TouchModule::processNewWebInput(const std::vector& listOfContactPoints) { bool isWebPositionCallbackZero = - (webPositionCallback.x == 0 && webPositionCallback.y == 0); + (_webPositionCallback.x == 0 && _webPositionCallback.y == 0); bool isSingleContactPoint = (listOfContactPoints.size() == 1); if (isSingleContactPoint && isWebPositionCallbackZero) { glm::ivec2 res = global::windowDelegate.currentWindowSize(); @@ -128,16 +133,16 @@ void TouchModule::hasNewWebInput(const std::vector& listOfContactPoi #ifdef OPENSPACE_MODULE_WEBBROWSER_ENABLED WebBrowserModule& module = *(global::moduleEngine.module()); if (module.eventHandler().hasContentCallback(pos.x, pos.y)) { - webPositionCallback = glm::vec2(pos.x, pos.y); + _webPositionCallback = glm::vec2(pos.x, pos.y); module.eventHandler().touchPressCallback(pos.x, pos.y); } } // Send mouse release if not same point input else if (!isSingleContactPoint && !isWebPositionCallbackZero) { WebBrowserModule& module = *(global::moduleEngine.module()); - module.eventHandler().touchReleaseCallback(webPositionCallback.x, - webPositionCallback.y); - webPositionCallback = glm::vec2(0, 0); + module.eventHandler().touchReleaseCallback(_webPositionCallback.x, + _webPositionCallback.y); + _webPositionCallback = glm::vec2(0, 0); #endif } } @@ -145,43 +150,43 @@ void TouchModule::hasNewWebInput(const std::vector& listOfContactPoi TouchModule::TouchModule() : OpenSpaceModule("Touch") { - addPropertySubOwner(touch); - addPropertySubOwner(markers); + addPropertySubOwner(_touch); + addPropertySubOwner(_markers); global::callback::initializeGL.push_back([&]() { LDEBUGC("TouchModule", "Initializing TouchMarker OpenGL"); - markers.initialize(); + _markers.initialize(); }); global::callback::deinitializeGL.push_back([&]() { LDEBUGC("TouchMarker", "Deinitialize TouchMarker OpenGL"); - markers.deinitialize(); + _markers.deinitialize(); }); global::callback::preSync.push_back([&]() { - touch.setCamera(global::navigationHandler.camera()); - touch.setFocusNode(global::navigationHandler.orbitalNavigator().anchorNode()); + _touch.setCamera(global::navigationHandler.camera()); + _touch.setFocusNode(global::navigationHandler.orbitalNavigator().anchorNode()); - if (hasNewInput() && global::windowDelegate.isMaster()) { - touch.updateStateFromInput(listOfContactPoints, lastProcessed); + if (processNewInput() && global::windowDelegate.isMaster()) { + _touch.updateStateFromInput(_listOfContactPoints, _lastProcessed); } - else if (listOfContactPoints.empty()) { - touch.resetAfterInput(); + else if (_listOfContactPoints.empty()) { + _touch.resetAfterInput(); } // update lastProcessed - lastProcessed.clear(); - for (const TuioCursor& c : listOfContactPoints) { - lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); + _lastProcessed.clear(); + for (const TuioCursor& c : _listOfContactPoints) { + _lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); } // used to save data from solver, only calculated for one frame when user chooses // in GUI - touch.unitTest(); + _touch.unitTest(); // calculate the new camera state for this frame - touch.step(global::windowDelegate.deltaTime()); + _touch.step(global::windowDelegate.deltaTime()); }); - global::callback::render.push_back([&]() { markers.render(listOfContactPoints); }); + global::callback::render.push_back([&]() { _markers.render(_listOfContactPoints); }); } diff --git a/modules/touch/touchmodule.h b/modules/touch/touchmodule.h index b916c00318..a596944ab2 100644 --- a/modules/touch/touchmodule.h +++ b/modules/touch/touchmodule.h @@ -41,19 +41,19 @@ namespace openspace { /** * Returns true if new touch input occured since the last frame */ - bool hasNewInput(); + bool processNewInput(); /** * Checks if touchevent should be parsed to the webgui */ - void hasNewWebInput(const std::vector& listOfContactPoints); + void processNewWebInput(const std::vector& listOfContactPoints); - TuioEar ear; - TouchInteraction touch; - TouchMarker markers; - std::vector listOfContactPoints; + TuioEar _ear; + TouchInteraction _touch; + TouchMarker _markers; + std::vector _listOfContactPoints; // contains an id and the TuioPoint that was processed last frame - std::vector lastProcessed; - glm::ivec2 webPositionCallback = glm::ivec2(0,0); + std::vector _lastProcessed; + glm::ivec2 _webPositionCallback = glm::ivec2(0,0); }; } // namespace openspace diff --git a/modules/webbrowser/src/eventhandler.cpp b/modules/webbrowser/src/eventhandler.cpp index 1231178231..9cffd5a35b 100644 --- a/modules/webbrowser/src/eventhandler.cpp +++ b/modules/webbrowser/src/eventhandler.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -225,6 +226,7 @@ bool EventHandler::mouseButtonCallback(MouseButton button, return false; } + global::interactionMonitor.registerInteraction(); MouseButtonState& state = (button == MouseButton::Left) ? _leftButton : _rightButton; int clickCount = BrowserInstance::SingleClick; @@ -274,7 +276,9 @@ bool EventHandler::mousePositionCallback(double x, double y) { _mousePosition.x = floor(static_cast(x) * dpiScaling.x); _mousePosition.y = floor(static_cast(y) * dpiScaling.y); _browserInstance->sendMouseMoveEvent(mouseEvent()); + global::interactionMonitor.registerInteraction(); // Let the mouse event trickle on + return false; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ddb716d4a6..d6bae69e26 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/engine/syncengine.cpp ${OPENSPACE_BASE_DIR}/src/engine/virtualpropertymanager.cpp ${OPENSPACE_BASE_DIR}/src/interaction/camerainteractionstates.cpp + ${OPENSPACE_BASE_DIR}/src/interaction/interactionmonitor.cpp ${OPENSPACE_BASE_DIR}/src/interaction/inputstate.cpp ${OPENSPACE_BASE_DIR}/src/interaction/joystickinputstate.cpp ${OPENSPACE_BASE_DIR}/src/interaction/joystickcamerastates.cpp @@ -228,6 +229,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/interaction/delayedvariable.inl ${OPENSPACE_BASE_DIR}/include/openspace/interaction/camerainteractionstates.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/inputstate.h + ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interactionmonitor.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.h ${OPENSPACE_BASE_DIR}/include/openspace/interaction/interpolator.inl ${OPENSPACE_BASE_DIR}/include/openspace/interaction/joystickinputstate.h diff --git a/src/engine/globals.cpp b/src/engine/globals.cpp index eda76862d9..6e0bb08628 100644 --- a/src/engine/globals.cpp +++ b/src/engine/globals.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -150,6 +151,11 @@ configuration::Configuration& gConfiguration() { return g; } +interaction::InteractionMonitor& gInteractionMonitor() { + static interaction::InteractionMonitor g; + return g; +} + interaction::JoystickInputStates& gJoystickInputStates() { static interaction::JoystickInputStates g; return g; @@ -214,6 +220,7 @@ void initialize() { global::navigationHandler.setPropertyOwner(&global::rootPropertyOwner); // New property subowners also have to be added to the ImGuiModule callback! global::rootPropertyOwner.addPropertySubOwner(global::navigationHandler); + global::rootPropertyOwner.addPropertySubOwner(global::interactionMonitor); global::rootPropertyOwner.addPropertySubOwner(global::sessionRecording); global::rootPropertyOwner.addPropertySubOwner(global::timeManager); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index d62d07937d..5ca2fdfec6 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1030,6 +1031,7 @@ void OpenSpaceEngine::preSynchronization() { } global::sessionRecording.preSynchronization(); global::parallelPeer.preSynchronization(); + global::interactionMonitor.updateActivityState(); } for (const std::function& func : global::callback::preSync) { @@ -1218,6 +1220,7 @@ void OpenSpaceEngine::keyboardCallback(Key key, KeyModifier mod, KeyAction actio global::navigationHandler.keyboardCallback(key, mod, action); global::keybindingManager.keyboardCallback(key, mod, action); + global::interactionMonitor.markInteraction(); } void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) { @@ -1230,6 +1233,7 @@ void OpenSpaceEngine::charCallback(unsigned int codepoint, KeyModifier modifier) } global::luaConsole.charCallback(codepoint, modifier); + global::interactionMonitor.markInteraction(); } void OpenSpaceEngine::mouseButtonCallback(MouseButton button, @@ -1265,6 +1269,7 @@ void OpenSpaceEngine::mouseButtonCallback(MouseButton button, } global::navigationHandler.mouseButtonCallback(button, action); + global::interactionMonitor.markInteraction(); } void OpenSpaceEngine::mousePositionCallback(double x, double y) { @@ -1274,6 +1279,7 @@ void OpenSpaceEngine::mousePositionCallback(double x, double y) { } global::navigationHandler.mousePositionCallback(x, y); + global::interactionMonitor.markInteraction(); } void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) { @@ -1286,6 +1292,7 @@ void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) { } global::navigationHandler.mouseScrollWheelCallback(posY); + global::interactionMonitor.markInteraction(); } std::vector OpenSpaceEngine::encode() { diff --git a/src/interaction/interactionmonitor.cpp b/src/interaction/interactionmonitor.cpp new file mode 100644 index 0000000000..8c6afe7617 --- /dev/null +++ b/src/interaction/interactionmonitor.cpp @@ -0,0 +1,81 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "InteractionMonitor"; + + constexpr openspace::properties::Property::PropertyInfo IdleTimeInfo = { + "IdleTime", + "Idle Time", + "Time in seconds that has passed from latest registered interaction until the " + "application goes idle." + }; + constexpr openspace::properties::Property::PropertyInfo IsInActiveStateInfo = { + "IsInActiveState", + "Is State Active", + "Keeps track whether the interaction session is in active state or not. False if " + "application is in idle state, true if it is in active state." + }; +} // namespace + +namespace openspace::interaction { + +InteractionMonitor::InteractionMonitor() + : properties::PropertyOwner({ "InteractionMonitor" }) + , _isInActiveState(IsInActiveStateInfo, false) + , _idleTime(IdleTimeInfo, 120.f) +{ + addProperty(_isInActiveState); + addProperty(_idleTime); +} + +void InteractionMonitor::setActivityState(bool isActive) { + _isInActiveState = isActive; +} + +void InteractionMonitor::setIdleTime(float time) { + _idleTime = time; +} + +void InteractionMonitor::updateActivityState() { + const double currentApplicationTime = global::windowDelegate.applicationTime(); + const double timeDiff = currentApplicationTime - _lastInteractionTime; + + if (timeDiff >= _idleTime && _isInActiveState) { + _isInActiveState = false; + } +} + +void InteractionMonitor::markInteraction() { + _lastInteractionTime = global::windowDelegate.applicationTime(); + _isInActiveState = true; +} + +} // namespace openspace::interaction diff --git a/src/interaction/navigationhandler.cpp b/src/interaction/navigationhandler.cpp index 3cb6361ddf..e8f8545335 100644 --- a/src/interaction/navigationhandler.cpp +++ b/src/interaction/navigationhandler.cpp @@ -642,7 +642,7 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() { "locally or remotely. The latter being the default." }, { - "clearJoystickButotn", + "clearJoystickButton", &luascriptfunctions::clearJoystickButton, {}, "int", From 98079cea3c242f187999389e4b324c9f31a5a602 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 30 Oct 2019 14:26:53 +0100 Subject: [PATCH 034/214] Feature/get navigation state (#1001) Implement lua function getNavigationState --- .../openspace/interaction/navigationhandler.h | 1 + src/interaction/navigationhandler.cpp | 41 ++++++++--- src/interaction/navigationhandler_lua.inl | 71 +++++++++++++++++++ 3 files changed, 103 insertions(+), 10 deletions(-) diff --git a/include/openspace/interaction/navigationhandler.h b/include/openspace/interaction/navigationhandler.h index 89fc965785..dcdd4df76b 100644 --- a/include/openspace/interaction/navigationhandler.h +++ b/include/openspace/interaction/navigationhandler.h @@ -136,6 +136,7 @@ public: WebsocketCameraStates::AxisNormalize shouldNormalize = WebsocketCameraStates::AxisNormalize::No); + NavigationState navigationState() const; NavigationState navigationState(const SceneGraphNode& referenceFrame) const; void saveNavigationState(const std::string& filepath, diff --git a/src/interaction/navigationhandler.cpp b/src/interaction/navigationhandler.cpp index e8f8545335..9c85dbbd3a 100644 --- a/src/interaction/navigationhandler.cpp +++ b/src/interaction/navigationhandler.cpp @@ -337,6 +337,18 @@ void NavigationHandler::keyboardCallback(Key key, KeyModifier modifier, KeyActio _inputState.keyboardCallback(key, modifier, action); } +NavigationHandler::NavigationState NavigationHandler::navigationState() const { + const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ? + _orbitalNavigator.anchorNode() : + sceneGraph()->root(); + ghoul_assert( + referenceFrame, + "The root will always exist and the anchor node ought to be reset when removed" + ); + + return navigationState(*referenceFrame); +} + NavigationHandler::NavigationState NavigationHandler::navigationState( const SceneGraphNode& referenceFrame) const { @@ -383,12 +395,9 @@ NavigationHandler::NavigationState NavigationHandler::navigationState( void NavigationHandler::saveNavigationState(const std::string& filepath, const std::string& referenceFrameIdentifier) { - const SceneGraphNode* referenceFrame = _orbitalNavigator.followingAnchorRotation() ? - _orbitalNavigator.anchorNode() : - sceneGraph()->root(); - + NavigationHandler::NavigationState state; if (!referenceFrameIdentifier.empty()) { - referenceFrame = sceneGraphNode(referenceFrameIdentifier); + const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier); if (!referenceFrame) { LERROR(fmt::format( "Could not find node '{}' to use as reference frame", @@ -396,17 +405,18 @@ void NavigationHandler::saveNavigationState(const std::string& filepath, )); return; } + state = navigationState(*referenceFrame).dictionary(); + } else { + state = navigationState().dictionary(); } if (!filepath.empty()) { std::string absolutePath = absPath(filepath); LINFO(fmt::format("Saving camera position: {}", absolutePath)); - ghoul::Dictionary cameraDict = navigationState(*referenceFrame).dictionary(); ghoul::DictionaryLuaFormatter formatter; - std::ofstream ofs(absolutePath.c_str()); - ofs << "return " << formatter.format(cameraDict); + ofs << "return " << formatter.format(state.dictionary()); ofs.close(); } } @@ -558,13 +568,24 @@ scripting::LuaLibrary NavigationHandler::luaLibrary() { return { "navigation", { + { + "getNavigationState", + &luascriptfunctions::getNavigationState, + {}, + "[string]", + "Return the current navigation state as a lua table. The optional " + "argument is the scene graph node to use as reference frame. By default, " + "the reference frame will picked based on whether the orbital navigator " + "is currently following the anchor node rotation. If it is, the anchor " + "will be chosen as reference frame. If not, the reference frame will be " + "set to the scene graph root." + }, { "setNavigationState", &luascriptfunctions::setNavigationState, {}, "table", - "Set the navigation state. " - "The argument must be a valid Navigation State." + "Set the navigation state. The argument must be a valid Navigation State." }, { "saveNavigationState", diff --git a/src/interaction/navigationhandler_lua.inl b/src/interaction/navigationhandler_lua.inl index 6ca1baec8a..c7fe94143d 100644 --- a/src/interaction/navigationhandler_lua.inl +++ b/src/interaction/navigationhandler_lua.inl @@ -46,6 +46,77 @@ int loadNavigationState(lua_State* L) { return 0; } +int getNavigationState(lua_State* L) { + const int n = ghoul::lua::checkArgumentsAndThrow( + L, + { 0, 1 }, + "lua::getNavigationState" + ); + + interaction::NavigationHandler::NavigationState state; + if (n == 1) { + const std::string referenceFrameIdentifier = ghoul::lua::value(L, 1); + const SceneGraphNode* referenceFrame = sceneGraphNode(referenceFrameIdentifier); + if (!referenceFrame) { + LERROR(fmt::format( + "Could not find node '{}' to use as reference frame", + referenceFrameIdentifier + )); + lua_settop(L, 0); + return 0; + } + state = global::navigationHandler.navigationState(*referenceFrame); + } + else { + state = global::navigationHandler.navigationState(); + } + + lua_settop(L, 0); + + const auto pushVector = [](lua_State* L, const glm::dvec3& v) { + lua_newtable(L); + ghoul::lua::push(L, 1, v.x); + lua_rawset(L, -3); + ghoul::lua::push(L, 2, v.y); + lua_rawset(L, -3); + ghoul::lua::push(L, 3, v.z); + lua_rawset(L, -3); + }; + + lua_newtable(L); + ghoul::lua::push(L, "Anchor", state.anchor); + lua_rawset(L, -3); + + if (!state.aim.empty()) { + ghoul::lua::push(L, "Aim", state.aim); + lua_rawset(L, -3); + } + if (!state.referenceFrame.empty()) { + ghoul::lua::push(L, "ReferenceFrame", state.referenceFrame); + lua_rawset(L, -3); + } + ghoul::lua::push(L, "Position"); + pushVector(L, state.position); + lua_rawset(L, -3); + + if (state.up.has_value()) { + ghoul::lua::push(L, "Up"); + pushVector(L, state.up.value()); + lua_rawset(L, -3); + } + if (state.yaw != 0) { + ghoul::lua::push(L, "Yaw", state.yaw); + lua_rawset(L, -3); + } + if (state.pitch != 0) { + ghoul::lua::push(L, "Pitch", state.pitch); + lua_rawset(L, -3); + } + + ghoul_assert(lua_gettop(L) == 1, "Incorrect number of items left on stack"); + return 1; +} + int setNavigationState(lua_State* L) { ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setNavigationState"); From c96794bf275080baee704b421f6f4003bf9cb060 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 30 Oct 2019 16:20:26 +0100 Subject: [PATCH 035/214] Update modules to call InteractionMonitor.markInteraction --- modules/touch/touchmodule.cpp | 2 +- modules/webbrowser/src/eventhandler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index 49a866a620..f0e38dd2c6 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -56,7 +56,7 @@ bool TouchModule::processNewInput() { _touch.touchActive(!_listOfContactPoints.empty()); if (!_listOfContactPoints.empty()) { - global::interactionMonitor.registerInteraction(); + global::interactionMonitor.markInteraction(); } // Erase old input id's that no longer exists diff --git a/modules/webbrowser/src/eventhandler.cpp b/modules/webbrowser/src/eventhandler.cpp index 9cffd5a35b..c805e22722 100644 --- a/modules/webbrowser/src/eventhandler.cpp +++ b/modules/webbrowser/src/eventhandler.cpp @@ -226,7 +226,7 @@ bool EventHandler::mouseButtonCallback(MouseButton button, return false; } - global::interactionMonitor.registerInteraction(); + global::interactionMonitor.markInteraction(); MouseButtonState& state = (button == MouseButton::Left) ? _leftButton : _rightButton; int clickCount = BrowserInstance::SingleClick; @@ -276,9 +276,9 @@ bool EventHandler::mousePositionCallback(double x, double y) { _mousePosition.x = floor(static_cast(x) * dpiScaling.x); _mousePosition.y = floor(static_cast(y) * dpiScaling.y); _browserInstance->sendMouseMoveEvent(mouseEvent()); - global::interactionMonitor.registerInteraction(); - // Let the mouse event trickle on + global::interactionMonitor.markInteraction(); + // Let the mouse event trickle on return false; } From e471d73e2c94140045b13ccf790b8a6c62b3715e Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 31 Oct 2019 10:54:54 -0600 Subject: [PATCH 036/214] Convert units for semimajor axis, period, and epoch --- .../space/rendering/renderablesmallbody.cpp | 37 +++++++++++-------- modules/space/rendering/renderablesmallbody.h | 3 ++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index eaef22af7e..4b996eef54 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -189,18 +189,18 @@ int countLeapSeconds(int year, int dayOfYear) { double epochFromSubstring(const std::string& epochString) { // The epochString is in the form: - // YYDDD.DDDDDDDD - // With YY being the last two years of the launch epoch, the first DDD the day - // of the year and the remaning a fractional part of the day + // YYYYMMDD.ddddddd + // With YYYY as the year, MM the month (1 - 12), DD the day of month (1-31), + // and dddd the fraction of that day. // The main overview of this function: - // 1. Reconstruct the full year from the YY part + // 1. Read the year value // 2. Calculate the number of seconds since the beginning of the year // 2.a Get the number of full days since the beginning of the year // 2.b If the year is a leap year, modify the number of days // 3. Convert the number of days to a number of seconds // 4. Get the number of leap seconds since January 1st, 2000 and remove them - // 5. Adjust for the fact the epoch starts on 1st Januaray at 12:00:00, not + // 5. Adjust for the fact the epoch starts on 1st January at 12:00:00, not // midnight // According to https://celestrak.com/columns/v04n03/ @@ -209,12 +209,8 @@ double epochFromSubstring(const std::string& epochString) { // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! - // 1. Get the full year - std::string yearPrefix = [y = epochString.substr(0, 2)](){ - int year = std::atoi(y.c_str()); - return year >= 57 ? "19" : "20"; - }(); - const int year = std::atoi((yearPrefix + epochString.substr(0, 2)).c_str()); + // 1. Get the year + int year = std::atoi(epochString.substr(0, 4).c_str()); const int daysSince2000 = countDays(year); // 2. @@ -348,34 +344,45 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { KeplerParameters keplerElements; // Object designator string std::getline(file, name, ','); + // (Ignore object status for NEO, PHA, diameter) std::getline(file, ignore, ','); std::getline(file, ignore, ','); std::getline(file, ignore, ','); + // Eccentricity (unit-less) std::getline(file, ignore, ','); keplerElements.eccentricity = std::stod(ignore); + // Semi-major axis (astronomical units - au) std::getline(file, ignore, ','); keplerElements.semiMajorAxis = std::stod(ignore); + keplerElements.semiMajorAxis *= convertAuToKm; + // Inclination (degrees) std::getline(file, ignore, ','); keplerElements.inclination = std::stod(ignore); + // Longitude of ascending node (degrees) std::getline(file, ignore, ','); keplerElements.ascendingNode = std::stod(ignore); + // Argument of Periapsis (degrees) std::getline(file, ignore, ','); - keplerElements.argumentOfPeriapsis = std::std(ignore); + keplerElements.argumentOfPeriapsis = std::stod(ignore); + // Mean Anomaly (degrees) std::getline(file, ignore, ','); - keplerElements.meanAnomaly = std::std(ignore); + keplerElements.meanAnomaly = std::stod(ignore); + // Epoch (MJD) std::getline(file, ignore, ','); - keplerElements.epoch = std::std(ignore); + keplerElements.epoch = epochFromSubstring(ignore); + // Period (days) std::getline(file, ignore, ','); - keplerElements.period = std::std(ignore); + keplerElements.period = std::stod(ignore); + keplerElements.period *= convertDaysToSecs; _sbData.push_back(keplerElements); _sbNames.push_back(name); diff --git a/modules/space/rendering/renderablesmallbody.h b/modules/space/rendering/renderablesmallbody.h index 17b1b9df3d..1cd569b7da 100644 --- a/modules/space/rendering/renderablesmallbody.h +++ b/modules/space/rendering/renderablesmallbody.h @@ -123,6 +123,9 @@ private: UniformCache(modelView, projection, lineFade, inGameTime, color, opacity, numberOfSegments) _uniformCache; + + const double convertAuToKm = 1.496e8; + const double convertDaysToSecs = 86400.; }; } // namespace openspace From afb889ff82c0c2cf73c99f0cf0e205cea1179944 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 1 Nov 2019 10:41:59 +0100 Subject: [PATCH 037/214] Feature/serve screenshots (#1003) * Take screnshots using lua function, returning screenshot number. Add screenshot endpoint. * Change capitalization from screenShot to screenshot * Fix screenshot filename collision bug when using multiple windows. --- apps/OpenSpace/main.cpp | 6 +- data/assets/util/default_keybindings.asset | 8 +-- data/assets/util/screenshots_endpoint.asset | 21 +++++++ data/assets/util/testing_keybindings.asset | 4 +- include/openspace/engine/windowdelegate.h | 2 +- include/openspace/rendering/renderengine.h | 12 ++-- modules/webgui/webguimodule.cpp | 15 +++-- src/interaction/sessionrecording.cpp | 2 +- src/rendering/renderengine.cpp | 63 ++++++++++----------- src/rendering/renderengine_lua.inl | 10 ++++ 10 files changed, 89 insertions(+), 54 deletions(-) create mode 100644 data/assets/util/screenshots_endpoint.asset diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 1be2584abe..51fa7aa05e 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -383,7 +383,10 @@ void mainInitFunc() { for (size_t i = 0; i < nWindows; ++i) { sgct::SGCTWindow* w = SgctEngine->getWindowPtr(i); - constexpr const char* screenshotNames = "OpenSpace"; + const std::string screenshotNames = nWindows > 1 ? + fmt::format("OpenSpace_{}", i) : + "OpenSpace"; + sgct_core::ScreenCapture* cpt0 = w->getScreenCapturePointer(0); sgct_core::ScreenCapture* cpt1 = w->getScreenCapturePointer(1); @@ -1014,6 +1017,7 @@ void setSgctDelegateFunctions() { sgctDelegate.takeScreenshot = [](bool applyWarping) { sgct::SGCTSettings::instance()->setCaptureFromBackBuffer(applyWarping); sgct::Engine::instance()->takeScreenshot(); + return sgct::Engine::instance()->getScreenShotNumber(); }; sgctDelegate.swapBuffer = []() { GLFWwindow* w = glfwGetCurrentContext(); diff --git a/data/assets/util/default_keybindings.asset b/data/assets/util/default_keybindings.asset index 1022144d37..cd8559d306 100644 --- a/data/assets/util/default_keybindings.asset +++ b/data/assets/util/default_keybindings.asset @@ -20,16 +20,16 @@ local Keybindings = { { Key = "PRINT_SCREEN", Name = "Take Screenshot", - Command = "openspace.setPropertyValueSingle('RenderEngine.TakeScreenshot', nil)", - Documentation = "Saves the contents of the screen to a file in the working directory.", + Command = "openspace.takeScreenshot()", + Documentation = "Saves the contents of the screen to a file in the ${SCREENSHOTS} directory.", GuiPath = "/Rendering", Local = true }, { Key = "F12", Name = "Take Screenshot", - Command = "openspace.setPropertyValueSingle('RenderEngine.TakeScreenshot', nil)", - Documentation = "Saves the contents of the screen to a file in the working directory.", + Command = "openspace.takeScreenshot()", + Documentation = "Saves the contents of the screen to a file in the ${SCREENSHOTS} directory.", GuiPath = "/Rendering", Local = true }, diff --git a/data/assets/util/screenshots_endpoint.asset b/data/assets/util/screenshots_endpoint.asset new file mode 100644 index 0000000000..712b0a5a8b --- /dev/null +++ b/data/assets/util/screenshots_endpoint.asset @@ -0,0 +1,21 @@ +asset.onInitialize(function () + -- Disable the server, add production gui endpoint, and restart server. + -- The temporary disabling avoids restarting the server on each property change. + -- TODO: Add a trigger property to the module to restart the server "manually" + -- and remove automatic restart on each property change, + -- since frequent restarting seems to be unstable on mac. + + local enabled = openspace.getPropertyValue("Modules.WebGui.ServerProcessEnabled") + openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", false) + + local directories = openspace.getPropertyValue("Modules.WebGui.Directories") + directories[#directories + 1] = "screenshots" + directories[#directories + 1] = "${SCREENSHOTS}" + openspace.setPropertyValueSingle("Modules.WebGui.Directories", directories) + openspace.setPropertyValueSingle("Modules.WebGui.ServerProcessEnabled", enabled) +end) + +asset.onDeinitialize(function () + -- TODO: Remove endpoints. As of 2019-10-29, OpenSpace sometimes + -- crashes when endpoints are removed while the application is closing. +end) \ No newline at end of file diff --git a/data/assets/util/testing_keybindings.asset b/data/assets/util/testing_keybindings.asset index 8565b3c1cf..e902f34c37 100644 --- a/data/assets/util/testing_keybindings.asset +++ b/data/assets/util/testing_keybindings.asset @@ -7,8 +7,8 @@ local Keybindings = { { Key = "F7", Name = "Take Screenshot", - Command = "openspace.setPropertyValueSingle('RenderEngine.TakeScreenshot', nil)", - Documentation = "Saves the contents of the screen to a file in the working directory.", + Command = "openspace.takeScreenshot()", + Documentation = "Saves the contents of the screen to a file in the ${SCREENSHOTS} directory.", GuiPath = "/Rendering", Local = true } diff --git a/include/openspace/engine/windowdelegate.h b/include/openspace/engine/windowdelegate.h index b3c44e181d..324c838b86 100644 --- a/include/openspace/engine/windowdelegate.h +++ b/include/openspace/engine/windowdelegate.h @@ -107,7 +107,7 @@ struct WindowDelegate { bool (*isFisheyeRendering)() = []() { return false; }; - void (*takeScreenshot)(bool applyWarping) = [](bool) { }; + unsigned int(*takeScreenshot)(bool applyWarping) = [](bool) { return 0u; }; void (*swapBuffer)() = []() {}; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 8093c16c4d..943c8a0ae0 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -142,9 +142,14 @@ public: void setResolveData(ghoul::Dictionary resolveData); /** - * Mark that one screenshot should be taken + * Take a screenshot and store in the ${SCREENSHOTS} directory */ - void takeScreenShot(); + void takeScreenshot(); + + /** + * Get the filename of the latest screenshot + */ + unsigned int latestScreenshotNumber() const; /** * Returns the Lua library that contains all Lua functions available to affect the @@ -187,8 +192,6 @@ private: properties::BoolProperty _showVersionInfo; properties::BoolProperty _showCameraInfo; - properties::TriggerProperty _takeScreenshot; - bool _shouldTakeScreenshot = false; properties::BoolProperty _applyWarping; properties::BoolProperty _showFrameInformation; #ifdef OPENSPACE_WITH_INSTRUMENTATION @@ -226,6 +229,7 @@ private: properties::Vec3Property _masterRotation; uint64_t _frameNumber = 0; + unsigned int _latestScreenshotNumber = 0; std::vector _programs; diff --git a/modules/webgui/webguimodule.cpp b/modules/webgui/webguimodule.cpp index 41a7f4c49f..86d86666d3 100644 --- a/modules/webgui/webguimodule.cpp +++ b/modules/webgui/webguimodule.cpp @@ -246,16 +246,15 @@ void WebGuiModule::startProcess() { std::string formattedDirectories = "["; std::vector directories = _directories.value(); - bool first = true; - - for (const std::string& str : directories) { - if (!first) { + for (size_t i = 0; i < directories.size(); ++i) { + std::string arg = directories[i]; + if (i & 1) { + arg = absPath(arg); + } + formattedDirectories += "\\\"" + escapedJson(escapedJson(arg)) + "\\\""; + if (i != directories.size() - 1) { formattedDirectories += ","; } - first = false; - - // Escape twice: First json, and then bash (which needs same escape sequences) - formattedDirectories += "\\\"" + escapedJson(escapedJson(str)) + "\\\""; } formattedDirectories += "]"; diff --git a/src/interaction/sessionrecording.cpp b/src/interaction/sessionrecording.cpp index b46206e6d7..c0c7a22674 100644 --- a/src/interaction/sessionrecording.cpp +++ b/src/interaction/sessionrecording.cpp @@ -1033,7 +1033,7 @@ void SessionRecording::moveAheadInTime() { const Renderable* focusRenderable = focusNode->renderable(); if (!focusRenderable || focusRenderable->renderedWithDesiredData()) { _saveRenderingCurrentRecordedTime += _saveRenderingDeltaTime; - global::renderEngine.takeScreenShot(); + global::renderEngine.takeScreenshot(); } } } diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 212e30ea12..918f5638f2 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -124,16 +124,6 @@ namespace { "shown on the screen" }; - constexpr openspace::properties::Property::PropertyInfo TakeScreenshotInfo = { - "TakeScreenshot", - "Take Screenshot", - "If this property is triggered, a screenshot is taken and stored in the current " - "working directory (which is the same directory where the OpenSpace.exe) is " - "located in most cases. The images are prefixed with 'SGCT' and postfixed with " - "the number of frames. This function will silently overwrite images that are " - "already present in the folder." - }; - constexpr openspace::properties::Property::PropertyInfo ApplyWarpingInfo = { "ApplyWarpingScreenshot", "Apply Warping to Screenshots", @@ -264,7 +254,6 @@ RenderEngine::RenderEngine() , _showLog(ShowLogInfo, true) , _showVersionInfo(ShowVersionInfo, true) , _showCameraInfo(ShowCameraInfo, true) - , _takeScreenshot(TakeScreenshotInfo) , _applyWarping(ApplyWarpingInfo, false) , _showFrameInformation(ShowFrameNumberInfo, false) #ifdef OPENSPACE_WITH_INSTRUMENTATION @@ -379,9 +368,6 @@ RenderEngine::RenderEngine() }); addProperty(_horizFieldOfView); - _takeScreenshot.onChange([this](){ _shouldTakeScreenshot = true; }); - addProperty(_takeScreenshot); - addProperty(_showFrameInformation); #ifdef OPENSPACE_WITH_INSTRUMENTATION _saveFrameInformation.onChange([&]() { @@ -864,21 +850,6 @@ void RenderEngine::renderDashboard() { void RenderEngine::postDraw() { ++_frameNumber; - if (_shouldTakeScreenshot) { - // We only create the directory here, as we don't want to spam the users - // screenshot folder everytime we start OpenSpace even when we are not taking any - // screenshots. So the first time we actually take one, we create the folder: - if (!FileSys.directoryExists(absPath("${SCREENSHOTS}"))) { - FileSys.createDirectory( - absPath("${SCREENSHOTS}"), - ghoul::filesystem::FileSystem::Recursive::Yes - ); - } - - global::windowDelegate.takeScreenshot(_applyWarping); - _shouldTakeScreenshot = false; - } - if (global::performanceManager.isEnabled()) { global::performanceManager.storeScenePerformanceMeasurements( scene()->allSceneGraphNodes() @@ -1061,10 +1032,28 @@ void RenderEngine::setResolveData(ghoul::Dictionary resolveData) { } /** - * Mark that one screenshot should be taken -*/ -void RenderEngine::takeScreenShot() { - _shouldTakeScreenshot = true; + * Take a screenshot and store it in the ${SCREENSHOTS} directory + */ +void RenderEngine::takeScreenshot() { + // We only create the directory here, as we don't want to spam the users + // screenshot folder everytime we start OpenSpace even when we are not taking any + // screenshots. So the first time we actually take one, we create the folder: + + if (!FileSys.directoryExists(absPath("${SCREENSHOTS}"))) { + FileSys.createDirectory( + absPath("${SCREENSHOTS}"), + ghoul::filesystem::FileSystem::Recursive::Yes + ); + } + + _latestScreenshotNumber = global::windowDelegate.takeScreenshot(_applyWarping); +} + +/** + * Get the latest screenshot filename + */ +unsigned int RenderEngine::latestScreenshotNumber() const { + return _latestScreenshotNumber; } /** @@ -1123,6 +1112,14 @@ scripting::LuaLibrary RenderEngine::luaLibrary() { "Given a ScreenSpaceRenderable name this script will remove it from the " "renderengine" }, + { + "takeScreenshot", + &luascriptfunctions::takeScreenshot, + {}, + "", + "Take a screenshot and return the screenshot number. The screenshot will " + "be stored in the ${SCREENSHOTS} folder. " + } }, }; } diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 3222c6b6e3..932e861a50 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -89,4 +89,14 @@ int removeScreenSpaceRenderable(lua_State* L) { return 0; } +int takeScreenshot(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::takeScreenshot"); + + global::renderEngine.takeScreenshot(); + const unsigned int screenshotNumber = global::renderEngine.latestScreenshotNumber(); + + lua_pushinteger(L, screenshotNumber); + return 1; +} + }// namespace openspace::luascriptfunctions From c3510948fd16fff3e6e26119d0b71fab4446c1ec Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sun, 10 Nov 2019 13:52:45 +0100 Subject: [PATCH 038/214] Add script function to easily add GIBS image layers to Earth --- ext/ghoul | 2 +- .../globebrowsing/scripts/layer_support.lua | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ext/ghoul b/ext/ghoul index 38272a9b7d..e6ef5101e7 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 38272a9b7d30bc07656336d35cbaae3a24ffd4bb +Subproject commit e6ef5101e7dd5e5ba19329ed9f5e5806e257b5ed diff --git a/modules/globebrowsing/scripts/layer_support.lua b/modules/globebrowsing/scripts/layer_support.lua index d76864112f..4ac0cf6971 100644 --- a/modules/globebrowsing/scripts/layer_support.lua +++ b/modules/globebrowsing/scripts/layer_support.lua @@ -48,6 +48,16 @@ openspace.globebrowsing.documentation = { "}" .. ")" }, + { + Name = "addGibsLayer", + Arguments = "string, string, string, string, string", + Documentation = "Adds a new layer from NASA GIBS to the Earth globe. Arguments " .. + "are: imagery layer name, imagery resolution, start date, end date, format. " .. + "For all specifications, see " .. + "https://wiki.earthdata.nasa.gov/display/GIBS/GIBS+Available+Imagery+Products" .. + "Usage:" .. + "openspace.globebrowsing.addGibsLayer('AIRS_Temperature_850hPa_Night', '2km', '2013-07-15', 'Present', 'png')" + }, { Name = "parseInfoFile", Arguments = "string", @@ -97,6 +107,14 @@ openspace.globebrowsing.documentation = { } } +openspace.globebrowsing.addGibsLayer = function(layer, resolution, format, startDate, endDate) + if endDate == 'Present' then + endDate = '' + end + local xml = openspace.globebrowsing.createTemporalGibsGdalXml(layer, startDate, endDate, '1d', resolution, format) + openspace.globebrowsing.addLayer('Earth', 'ColorLayers', { Identifier = layer, Type = "TemporalTileLayer", FilePath = xml }) +end + openspace.globebrowsing.createTemporalGibsGdalXml = function (layerName, startDate, endDate, timeResolution, resolution, format) temporalTemplate = "" .. @@ -332,5 +350,4 @@ openspace.globebrowsing.loadWMSServersFromFile = function (file_path) ) end end - end From 0fce6a8d268949b6855d5e67391b52e70d29ae52 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sun, 10 Nov 2019 14:17:23 -0500 Subject: [PATCH 039/214] Super-fast volume (aka Downscaled Volume Rendering). --- .../scene/milkyway/milkyway/volume.asset | 4 +- .../openspace/rendering/framebufferrenderer.h | 11 + include/openspace/rendering/volumeraycaster.h | 19 ++ modules/galaxy/rendering/renderablegalaxy.cpp | 14 ++ modules/galaxy/rendering/renderablegalaxy.h | 2 + shaders/framebuffer/hdrAndFiltering.frag | 1 - .../framebuffer/mergeDownscaledVolume.frag | 35 ++++ .../framebuffer/mergeDownscaledVolume.vert | 33 +++ shaders/framebuffer/raycastframebuffer.frag | 5 +- src/rendering/framebufferrenderer.cpp | 193 +++++++++++++++++- 10 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 shaders/framebuffer/mergeDownscaledVolume.frag create mode 100644 shaders/framebuffer/mergeDownscaledVolume.vert diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 0d1537d45e..78195a1b5c 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -24,7 +24,9 @@ local MilkyWayVolumeGalaxy = { Type = "Volume", Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", Dimensions = {1024, 1024, 128}, - Size = {1.2E21, 1.2E21, 0.15E21} + Size = {1.2E21, 1.2E21, 0.15E21}, + Steps = 480, + Downscale = 0.5, }, Points = { Type = "Points", diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index a49568fe17..4529fd60a4 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -70,6 +70,7 @@ public: void updateDeferredcastData(); void updateHDRAndFiltering(); void updateFXAA(); + void updateDownscaledVolume(); void setResolution(glm::ivec2 res) override; void setHDRExposure(float hdrExposure) override; @@ -110,6 +111,8 @@ private: void resolveMSAA(float blackoutFactor); void applyTMO(float blackoutFactor); void applyFXAA(); + void updateDownscaleColorTexture(); + void writeDownscaledVolume(); std::map _raycastData; RaycasterProgObjMap _exitPrograms; @@ -122,10 +125,12 @@ private: std::unique_ptr _hdrFilteringProgram; std::unique_ptr _tmoProgram; std::unique_ptr _fxaaProgram; + std::unique_ptr _downscaledVolumeProgram; UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma, Hue, Saturation, Value) _hdrUniformCache; UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache; + UniformCache(downscaledRenderedVolume) _writeDownscaledVolumeUniformCache; GLint _defaultFBO; GLuint _screenQuad; @@ -157,6 +162,12 @@ private: GLuint fxaaTexture; } _fxaaBuffers; + struct { + GLuint framebuffer; + GLuint colorTexture; + float currentDownscaleFactor = 1.f; + } _downscaleVolumeRendering; + unsigned int _pingPongIndex = 0u; bool _dirtyDeferredcastData; diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index f8ed000553..687a5f335a 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -128,6 +128,25 @@ public: * helper file) which should be a prefix to all symbols defined by the helper */ virtual std::string helperPath() const = 0; + + virtual void setMaxSteps(int nsteps) { _rayCastMaxSteps = nsteps; }; + + virtual const int maxSteps() const { return _rayCastMaxSteps; }; + + virtual void setDownscaleRender(float value) { _downscaleRenderConst = value; }; + + virtual const float downscaleRender() const { return _downscaleRenderConst; }; + +private: + /** + * Maximum number of integration steps to be executed by the volume integrator. + */ + int _rayCastMaxSteps = 1000; + + /** + * Enable and set the downscale rendering of the volume. Used to improve performance. + */ + float _downscaleRenderConst = 1.0f; }; } // namespace openspace diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 1d88c2da23..758ab082a1 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -224,6 +224,18 @@ namespace openspace { LERROR("No volume dimensions specified."); } + if (volumeDictionary.hasKey("Steps")) { + _rayCastSteps = static_cast(volumeDictionary.value("Steps")); + } + else { + LINFO("Number of raycasting steps not specified for Milkway Galaxy." + " Using default value."); + } + + if (volumeDictionary.hasKey("Downscale")) { + _downScaleVolumeRendering = volumeDictionary.value("Downscale"); + } + if (!dictionary.hasKeyAndValue("Points")) { LERROR("No points dictionary specified."); } @@ -470,6 +482,8 @@ void RenderableGalaxy::update(const UpdateData& data) { volumeTransform[3] += translation; _pointTransform[3] += translation; + _raycaster->setDownscaleRender(_downScaleVolumeRendering); + _raycaster->setMaxSteps(_rayCastSteps); _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); _raycaster->setModelTransform(volumeTransform); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 0b49d848c4..8346820b99 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -79,6 +79,8 @@ private: glm::ivec3 _volumeDimensions; std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; + int _rayCastSteps = 1000; + float _downScaleVolumeRendering = 1.f; std::unique_ptr _raycaster; std::unique_ptr>> _volume; diff --git a/shaders/framebuffer/hdrAndFiltering.frag b/shaders/framebuffer/hdrAndFiltering.frag index b22ebd9bc4..0e2b3b2090 100644 --- a/shaders/framebuffer/hdrAndFiltering.frag +++ b/shaders/framebuffer/hdrAndFiltering.frag @@ -38,7 +38,6 @@ uniform float Hue; uniform float Saturation; uniform float Value; uniform float Lightness; -uniform int nAaSamples; uniform sampler2D hdrFeedingTexture; diff --git a/shaders/framebuffer/mergeDownscaledVolume.frag b/shaders/framebuffer/mergeDownscaledVolume.frag new file mode 100644 index 0000000000..f34a300742 --- /dev/null +++ b/shaders/framebuffer/mergeDownscaledVolume.frag @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout (location = 0) out vec4 finalColor; + +uniform sampler2D downscaledRenderedVolume; + +in vec2 texCoord; + +void main() { + finalColor = texture(downscaledRenderedVolume, texCoord); +} diff --git a/shaders/framebuffer/mergeDownscaledVolume.vert b/shaders/framebuffer/mergeDownscaledVolume.vert new file mode 100644 index 0000000000..f737e51882 --- /dev/null +++ b/shaders/framebuffer/mergeDownscaledVolume.vert @@ -0,0 +1,33 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout(location = 0) in vec4 position; +out vec2 texCoord; + +void main() { + texCoord = 0.5 + position.xy * 0.5; + gl_Position = position; +} diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index b5a972cff8..120bcdd2b8 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -32,6 +32,8 @@ uniform bool insideRaycaster; uniform vec3 cameraPosInRaycaster; uniform vec2 windowSize; +uniform int rayCastSteps; + #include "blending.glsl" #include "rand.glsl" #include "floatoperations.glsl" @@ -45,7 +47,6 @@ uniform vec2 windowSize; out vec4 finalColor; #define ALPHA_LIMIT 0.99 -#define RAYCAST_MAX_STEPS 480 #include <#{getEntryPath}> @@ -99,7 +100,7 @@ void main() { for (nSteps = 0; (accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT || - accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < RAYCAST_MAX_STEPS; + accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < rayCastSteps; ++nSteps) { if (nextStepSize < raycastDepth / 10000000000.f) { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 2007f13a53..b6ce5df96e 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -59,6 +59,10 @@ namespace { "renderedTexture", "inverseScreenSize" }; + constexpr const std::array DownscaledVolumeUniformNames = { + "downscaledRenderedVolume" + }; + constexpr const char* ExitFragmentShaderPath = "${SHADERS}/framebuffer/exitframebuffer.frag"; constexpr const char* RaycastFragmentShaderPath = @@ -184,6 +188,10 @@ void FramebufferRenderer::initialize() { glGenFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glGenTextures(1, &_fxaaBuffers.fxaaTexture); + // DownscaleVolumeRendering + glGenFramebuffers(1, &_downscaleVolumeRendering.framebuffer); + glGenTextures(1, &_downscaleVolumeRendering.colorTexture); + // Allocate Textures/Buffers Memory updateResolution(); @@ -307,11 +315,29 @@ void FramebufferRenderer::initialize() { LERROR("FXAA framebuffer is not complete"); } + //================================================// + //===== Downscale Volume Rendering Buffers =====// + //================================================// + glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + _downscaleVolumeRendering.colorTexture, + 0 + ); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Downscale Volume Rendering framebuffer is not complete"); + } + + // JCC: Moved to here to avoid NVidia: "Program/shader state performance warning" // Building programs updateHDRAndFiltering(); updateFXAA(); updateDeferredcastData(); + updateDownscaledVolume(); // Sets back to default FBO glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); @@ -326,6 +352,11 @@ void FramebufferRenderer::initialize() { _fxaaUniformCache, FXAAUniformNames ); + ghoul::opengl::updateUniformLocations( + *_downscaledVolumeProgram, + _writeDownscaledVolumeUniformCache, + DownscaledVolumeUniformNames + ); global::raycasterManager.addListener(*this); global::deferredcasterManager.addListener(*this); @@ -342,6 +373,7 @@ void FramebufferRenderer::deinitialize() { glDeleteFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer); glDeleteFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glDeleteFramebuffers(1, &_pingPongBuffers.framebuffer); + glDeleteFramebuffers(1, &_downscaleVolumeRendering.framebuffer); glDeleteTextures(1, &_gBuffers.colorTexture); glDeleteTextures(1, &_gBuffers.depthTexture); @@ -350,7 +382,8 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_fxaaBuffers.fxaaTexture); glDeleteTextures(1, &_gBuffers.positionTexture); glDeleteTextures(1, &_gBuffers.normalTexture); - + glDeleteTextures(1, &_downscaleVolumeRendering.colorTexture); + glDeleteTextures(1, &_pingPongBuffers.colorTexture[1]); glDeleteTextures(1, &_exitColorTexture); @@ -447,6 +480,90 @@ void FramebufferRenderer::applyFXAA() { _fxaaProgram->deactivate(); } +void FramebufferRenderer::updateDownscaleColorTexture() { + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void FramebufferRenderer::writeDownscaledVolume() { + const bool doPerformanceMeasurements = global::performanceManager.isEnabled(); + std::unique_ptr perfInternal; + + if (doPerformanceMeasurements) { + perfInternal = std::make_unique( + "FramebufferRenderer::render::writeDownscaledVolume" + ); + } + + // Saving current OpenGL state + GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0); + + GLenum blendEquationRGB; + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); + + GLenum blendEquationAlpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + + GLenum blendDestAlpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + + GLenum blendDestRGB; + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); + + GLenum blendSrcAlpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + + GLenum blendSrcRGB; + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); + + glEnablei(GL_BLEND, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + _downscaledVolumeProgram->activate(); + + ghoul::opengl::TextureUnit downscaledTextureUnit; + downscaledTextureUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + _downscaleVolumeRendering.colorTexture + ); + + _downscaledVolumeProgram->setUniform( + _writeDownscaledVolumeUniformCache.downscaledRenderedVolume, + downscaledTextureUnit + ); + + glEnablei(GL_BLEND, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + _downscaledVolumeProgram->deactivate(); + + // Restores blending state + glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); + + if (!blendEnabled) { + glDisablei(GL_BLEND, 0); + } + +} + void FramebufferRenderer::update() { if (_dirtyResolution) { updateResolution(); @@ -480,6 +597,16 @@ void FramebufferRenderer::update() { ); } + if (_downscaledVolumeProgram->isDirty()) { + _downscaledVolumeProgram->rebuildFromFile(); + + ghoul::opengl::updateUniformLocations( + *_downscaledVolumeProgram, + _writeDownscaledVolumeUniformCache, + DownscaledVolumeUniformNames + ); + } + using K = VolumeRaycaster*; using V = std::unique_ptr; for (const std::pair& program : _exitPrograms) { @@ -639,6 +766,23 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // Downscale Volume Rendering + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Volume Rendering Textures glBindTexture(GL_TEXTURE_2D, _exitColorTexture); glTexImage2D( @@ -822,6 +966,17 @@ void FramebufferRenderer::updateFXAA() { //_fxaaProgram->setIgnoreUniformLocationError(IgnoreError::Yes); } +void FramebufferRenderer::updateDownscaledVolume() { + _downscaledVolumeProgram = ghoul::opengl::ProgramObject::Build( + "Write Downscaled Volume Program", + absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.vert"), + absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.frag") + ); + using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; + //_downscaledVolumeProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + //_downscaledVolumeProgram->setIgnoreUniformLocationError(IgnoreError::Yes); +} + void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) { // Set OpenGL default rendering state glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); @@ -945,7 +1100,20 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector exitProgram->deactivate(); } - glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); + glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); + if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { + _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; + updateDownscaleColorTexture(); + } + glClear(GL_COLOR_BUFFER_BIT); + } + else { + glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); + } + glm::vec3 cameraPosition; bool isCameraInside = raycaster->isCameraInside( raycasterTask.renderData, @@ -977,6 +1145,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycastProgram) { + raycastProgram->setUniform("rayCastSteps", raycaster->maxSteps()); + raycaster->preRaycast(_raycastData[raycaster], *raycastProgram); ghoul::opengl::TextureUnit exitColorTextureUnit; @@ -994,7 +1164,16 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture); raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); - raycastProgram->setUniform("windowSize", static_cast(_resolution)); + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + raycastProgram->setUniform( + "windowSize", + glm::vec2(_resolution.x * scaleDown, _resolution.y * scaleDown) + ); + } + else { + raycastProgram->setUniform("windowSize", static_cast(_resolution)); + } glDisable(GL_DEPTH_TEST); glDepthMask(false); @@ -1015,6 +1194,14 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector else { LWARNING("Raycaster is not attached when trying to perform raycaster task"); } + + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + glViewport(0, 0, _resolution.x, _resolution.y); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); + writeDownscaledVolume(); + + } } } From c469dd78a087edd94194f9fcc399ed905179eb3c Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Mon, 11 Nov 2019 11:20:17 +0100 Subject: [PATCH 040/214] Update sgct --- apps/OpenSpace/ext/sgct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSpace/ext/sgct b/apps/OpenSpace/ext/sgct index 25c8d30bde..9f62068efb 160000 --- a/apps/OpenSpace/ext/sgct +++ b/apps/OpenSpace/ext/sgct @@ -1 +1 @@ -Subproject commit 25c8d30bde216066840d197e4443def196c70e17 +Subproject commit 9f62068efb344d37f1c1e2bf0303f838ef7da9f3 From 2537b9e16b7c95f2d637e6f6c0346e17f627e227 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 09:57:46 -0500 Subject: [PATCH 041/214] Fixed shadow's dependency. --- .../solarsystem/planets/earth/earth.asset | 4 ++ .../solarsystem/planets/saturn/saturn.asset | 10 ++-- .../globebrowsing/shaders/renderer_fs.glsl | 2 + modules/globebrowsing/shaders/rings_fs.glsl | 2 + modules/globebrowsing/src/renderableglobe.cpp | 54 ++++++++++--------- modules/globebrowsing/src/renderableglobe.h | 1 + modules/globebrowsing/src/shadowcomponent.cpp | 11 ++-- 7 files changed, 47 insertions(+), 37 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index 3c90956e24..c1482969d0 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -263,6 +263,10 @@ local Earth = { } --Caster2 = { Name = "Independency Day Ship", Radius = 0.0, } }, + Shadows = { + Enabled = true, + DistanceFraction = 40.0 + }, Labels = { Enable = false, FileName = labelsPath .. "/Earth.labels", diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 49748b1bf7..91bd69519c 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -39,11 +39,11 @@ local Saturn = { Texture = textures .. "/saturn_rings.png", Size = 140445000, Offset = { 74500 / 140445.100671159, 1.0 }, -- min / max extend - Shadows = { - Enabled = true, - DistanceFraction = 50.0 - } - } + }, + Shadows = { + Enabled = true, + DistanceFraction = 40.0 + } }, Tag = { "planet_solarSystem", "planet_giants" }, GUI = { diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index 77926c9ce8..d418937e77 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -270,7 +270,9 @@ Fragment getFragment() { normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; + //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + float sum = 0; int fStep = 5; for (int i = 0; i < fStep; ++i) { diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 551f1ebb01..1dfd5df308 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -76,7 +76,9 @@ Fragment getFragment() { normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; + //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + float sum = 0; int fStep = 2; sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, -fStep)); diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 9b226dd9ca..8027d54a55 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -675,10 +675,12 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) ghoul::Dictionary ringsDic; dictionary.getValue("Rings", ringsDic); - if (ringsDic.hasKey("Shadows")) { - _shadowComponent.initialize(); - addPropertySubOwner(_shadowComponent); - } + } + + if (dictionary.hasKey("Shadows")) { + _shadowComponent.initialize(); + addPropertySubOwner(_shadowComponent); + _hasShadows = true; } #ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION @@ -698,6 +700,9 @@ void RenderableGlobe::initializeGL() { if (_hasRings) { _ringsComponent.initializeGL(); + } + + if (_hasShadows) { _shadowComponent.initializeGL(); } @@ -725,6 +730,9 @@ void RenderableGlobe::deinitializeGL() { if (_hasRings) { _ringsComponent.deinitializeGL(); + } + + if (_hasShadows) { _shadowComponent.deinitializeGL(); } } @@ -753,40 +761,38 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask //renderChunks(data, rendererTask); //_globeLabelsComponent.draw(data); + if (_hasShadows && _shadowComponent.isEnabled()) { + // Set matrices and other GL states + RenderData lightRenderData(_shadowComponent.begin(data)); - if (_hasRings && _ringsComponent.isEnabled()) { - if (_shadowComponent.isEnabled()) { - // Set matrices and other GL states - RenderData lightRenderData(_shadowComponent.begin(data)); - - glDisable(GL_BLEND); - - // Render from light source point of view - renderChunks(lightRenderData, rendererTask, {}, true); + glDisable(GL_BLEND); + + // Render from light source point of view + renderChunks(lightRenderData, rendererTask, {}, true); + if (_hasRings && _ringsComponent.isEnabled()) { _ringsComponent.draw(lightRenderData, RingsComponent::GeometryOnly); + } - glEnable(GL_BLEND); - - _shadowComponent.end(); + glEnable(GL_BLEND); - // Render again from original point of view - renderChunks(data, rendererTask, _shadowComponent.shadowMapData()); + _shadowComponent.end(); + + // Render again from original point of view + renderChunks(data, rendererTask, _shadowComponent.shadowMapData()); + if (_hasRings && _ringsComponent.isEnabled()) { _ringsComponent.draw( data, RingsComponent::GeometryAndShading, _shadowComponent.shadowMapData() ); } - else { - renderChunks(data, rendererTask); - _ringsComponent.draw(data, RingsComponent::GeometryAndShading); - } } else { renderChunks(data, rendererTask); + if (_hasRings && _ringsComponent.isEnabled()) { + _ringsComponent.draw(data, RingsComponent::GeometryAndShading); + } } - - } catch (const ghoul::opengl::TextureUnit::TextureUnitError&) { std::string layer = _lastChangedLayer ? _lastChangedLayer->guiName() : ""; diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 240f281736..60ee41413a 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -291,6 +291,7 @@ private: RingsComponent _ringsComponent; ShadowComponent _shadowComponent; bool _hasRings = false; + bool _hasShadows = false; // Labels GlobeLabelsComponent _globeLabelsComponent; diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 1a64a0836f..ec03a3e706 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -165,7 +165,7 @@ namespace openspace { ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) : properties::PropertyOwner({ "Shadows" }) , _saveDepthTexture(SaveDepthTextureInfo) - , _distanceFraction(DistanceFractionInfo, 3, 1, 10000) + , _distanceFraction(DistanceFractionInfo, 20, 1, 10000) , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) , _shadowMapDictionary(dictionary) , _shadowDepthTextureHeight(4096) @@ -182,12 +182,8 @@ namespace openspace { { using ghoul::filesystem::File; - if (dictionary.hasKey("Rings")) { - ghoul::Dictionary ringsDic; - dictionary.getValue("Rings", ringsDic); - if (ringsDic.hasKey("Shadows")) { - ringsDic.getValue("Shadows", _shadowMapDictionary); - } + if (dictionary.hasKey("Shadows")) { + dictionary.getValue("Shadows", _shadowMapDictionary); } documentation::testSpecificationAndThrow( @@ -201,7 +197,6 @@ namespace openspace { _shadowMapDictionary.value(DistanceFractionInfo.identifier) ); } - _saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; }); From 86bd05276ff78a78340efacb3809820750880fa4 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 13:29:32 -0500 Subject: [PATCH 042/214] Added slide control for downscaling factor. --- modules/galaxy/rendering/renderablegalaxy.cpp | 12 ++++++++++++ modules/galaxy/rendering/renderablegalaxy.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 758ab082a1..8597c7a5e0 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -117,6 +117,13 @@ namespace { "Enabled points", "" // @TODO Missing documentation }; + + constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = { + "Downscale", + "Downscale Factor Volume Rendering", + "This value set the downscaling factor" + " when rendering the current volume." + }; } // namespace namespace openspace { @@ -135,6 +142,7 @@ namespace openspace { , _enabledPointsRatio(EnabledPointsRatioInfo, 0.5f, 0.01f, 1.0f) , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) , _rotation(RotationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(6.28f)) + , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) { dictionary.getValue("VolumeRenderingEnabled", _volumeRenderingEnabled); dictionary.getValue("StarRenderingEnabled", _starRenderingEnabled); @@ -232,6 +240,9 @@ namespace openspace { " Using default value."); } + _downScaleVolumeRendering.setVisibility( + openspace::properties::Property::Visibility::Developer + ); if (volumeDictionary.hasKey("Downscale")) { _downScaleVolumeRendering = volumeDictionary.value("Downscale"); } @@ -319,6 +330,7 @@ void RenderableGalaxy::initializeGL() { addProperty(_enabledPointsRatio); addProperty(_translation); addProperty(_rotation); + addProperty(_downScaleVolumeRendering); // initialize points. if (!_pointsFilename.empty()) { diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 8346820b99..ea7ddcb824 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -71,6 +71,7 @@ private: properties::FloatProperty _enabledPointsRatio; properties::Vec3Property _translation; properties::Vec3Property _rotation; + properties::FloatProperty _downScaleVolumeRendering; std::unique_ptr _pointSpreadFunctionTexture; std::unique_ptr _pointSpreadFunctionFile; @@ -80,7 +81,6 @@ private: std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; int _rayCastSteps = 1000; - float _downScaleVolumeRendering = 1.f; std::unique_ptr _raycaster; std::unique_ptr>> _volume; From 6ca304724759d8d9e3f267d7571f68a29f98e922 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 14:39:28 -0500 Subject: [PATCH 043/214] Updated ToyVolume. Add downscaling controls. --- .../rendering/renderabletoyvolume.cpp | 29 +++++++++++++++++++ .../toyvolume/rendering/renderabletoyvolume.h | 3 ++ openspace.cfg | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/toyvolume/rendering/renderabletoyvolume.cpp b/modules/toyvolume/rendering/renderabletoyvolume.cpp index ccb5018780..a5c37bf4e2 100644 --- a/modules/toyvolume/rendering/renderabletoyvolume.cpp +++ b/modules/toyvolume/rendering/renderabletoyvolume.cpp @@ -29,8 +29,10 @@ #include #include #include +#include namespace { + constexpr const char* _loggerCat = "Renderable ToyVolume"; constexpr openspace::properties::Property::PropertyInfo SizeInfo = { "Size", "Size", @@ -66,6 +68,13 @@ namespace { "Color", "" // @TODO Missing documentation }; + + constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = { + "Downscale", + "Downscale Factor Volume Rendering", + "This value set the downscaling factor" + " when rendering the current volume." + }; } // namespace namespace openspace { @@ -78,6 +87,7 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary) , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(10.f)) , _rotation(RotationInfo, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f)) , _color(ColorInfo, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f)) + , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) { if (dictionary.hasKeyAndValue(ScalingExponentInfo.identifier)) { _scalingExponent = static_cast( @@ -104,6 +114,22 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary) if (dictionary.hasKeyAndValue(StepSizeInfo.identifier)) { _stepSize = static_cast(dictionary.value(StepSizeInfo.identifier)); } + + _downScaleVolumeRendering.setVisibility( + openspace::properties::Property::Visibility::Developer + ); + if (dictionary.hasKey("Downscale")) { + _downScaleVolumeRendering = dictionary.value("Downscale"); + } + + if (dictionary.hasKey("Steps")) { + _rayCastSteps = static_cast(dictionary.value("Steps")); + } + else { + LINFO("Number of raycasting steps not specified for ToyVolume." + " Using default value."); + } + } RenderableToyVolume::~RenderableToyVolume() {} @@ -131,6 +157,7 @@ void RenderableToyVolume::initializeGL() { addProperty(_translation); addProperty(_rotation); addProperty(_color); + addProperty(_downScaleVolumeRendering); } void RenderableToyVolume::deinitializeGL() { @@ -167,6 +194,8 @@ void RenderableToyVolume::update(const UpdateData& data) { _raycaster->setStepSize(_stepSize); _raycaster->setModelTransform(transform); _raycaster->setTime(data.time.j2000Seconds()); + _raycaster->setDownscaleRender(_downScaleVolumeRendering); + _raycaster->setMaxSteps(_rayCastSteps); } } diff --git a/modules/toyvolume/rendering/renderabletoyvolume.h b/modules/toyvolume/rendering/renderabletoyvolume.h index 8c1b0a36e0..d946bd21f9 100644 --- a/modules/toyvolume/rendering/renderabletoyvolume.h +++ b/modules/toyvolume/rendering/renderabletoyvolume.h @@ -55,8 +55,11 @@ private: properties::Vec3Property _translation; properties::Vec3Property _rotation; properties::Vec4Property _color; + properties::FloatProperty _downScaleVolumeRendering; std::unique_ptr _raycaster; + + int _rayCastSteps = 1000; }; } // namespace openspace diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..996fa99556 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,7 +27,7 @@ SGCTConfig = sgct.config.single{} -- SGCTConfig = sgct.config.fisheye{1024, 1024} -- A 4k fisheye rendering in a 1024x1024 window --- SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} +SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} From 7e8cae4a515e1c524632611f25e794ce9e8b0895 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 14:48:35 -0500 Subject: [PATCH 044/214] Improved volume border color. --- src/rendering/framebufferrenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 39a85fe1fd..f45c618b76 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -793,6 +793,8 @@ void FramebufferRenderer::updateResolution() { ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); // Volume Rendering Textures From 966a9f757e02f857700e5f7f3f4ac3e42e73a272 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 11 Nov 2019 17:00:32 -0700 Subject: [PATCH 045/214] Finished code to compute fraction of days in year from DB file Still needs work to get time in MJD however --- .../space/rendering/renderablesmallbody.cpp | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 4b996eef54..4b6bbf4664 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -93,6 +93,25 @@ const std::vector LeapYears = { 2044, 2048, 2052, 2056 }; +const std::vector DaysOfMonths = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +enum class Months { + January = 0, + February, + March, + April, + May, + June, + July, + August, + September, + October, + November, + December +}; + // Count the number of full days since the beginning of 2000 to the beginning of // the parameter 'year' int countDays(int year) { @@ -187,6 +206,25 @@ int countLeapSeconds(int year, int dayOfYear) { return nLeapSeconds; } +int daysIntoGivenYear(int year, int month, int dayOfMonth) { + //month and dayCount are zero-based + month -= 1; + int dayCount = dayOfMonth - 1; + + for (int m = Months::January; m < month; ++m) { + dayCount += DaysOfMonths[m]; + if (m == Months::March) { + const auto leapTest = std::find(LeapYears.begin(), LeapYears.end(), year); + if (leapTest != LeapYears.end()) { + // We are in a leap year, so we have an effective day more if we are + // beyond the end of february + dayCount--; + } + } + } + return dayCount; +} + double epochFromSubstring(const std::string& epochString) { // The epochString is in the form: // YYYYMMDD.ddddddd @@ -195,9 +233,7 @@ double epochFromSubstring(const std::string& epochString) { // The main overview of this function: // 1. Read the year value - // 2. Calculate the number of seconds since the beginning of the year - // 2.a Get the number of full days since the beginning of the year - // 2.b If the year is a leap year, modify the number of days + // 2. Get the number of full days since the beginning of the year // 3. Convert the number of days to a number of seconds // 4. Get the number of leap seconds since January 1st, 2000 and remove them // 5. Adjust for the fact the epoch starts on 1st January at 12:00:00, not @@ -209,31 +245,23 @@ double epochFromSubstring(const std::string& epochString) { // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! - // 1. Get the year + // 1 int year = std::atoi(epochString.substr(0, 4).c_str()); const int daysSince2000 = countDays(year); - // 2. - // 2.a - double daysInYear = std::atof(epochString.substr(2).c_str()); - - // 2.b - const bool isInLeapYear = std::find( - LeapYears.begin(), - LeapYears.end(), - year - ) != LeapYears.end(); - if (isInLeapYear && daysInYear >= 60) { - // We are in a leap year, so we have an effective day more if we are - // beyond the end of february (= 31+29 days) - --daysInYear; - } + // 2 + int monthNum = std::atoi(epochString.substr(4, 2).c_str()); + int dayOfMonthNum = std::atoi(epochString.substr(6, 2).c_str()); + double fractionOfDay = std::atof(epochString.substr(9, 7).c_str()); + double daysInYear = static_cast(daysIntoGivenYear(year, monthNum, + dayOfMonthNum)); + daysInYear += fractionOfDay; // 3 using namespace std::chrono; const int SecondsPerDay = static_cast(seconds(hours(24)).count()); //Need to subtract 1 from daysInYear since it is not a zero-based count - const double nSecondsSince2000 = (daysSince2000 + daysInYear - 1) * SecondsPerDay; + const double nSecondsInCurrYear = daysInYear * SecondsPerDay; // 4 // We need to remove additional leap seconds past 2000 and add them prior to From 0defd03684259be78e4ffec13e871789b52c1672 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 12 Nov 2019 11:46:47 -0700 Subject: [PATCH 046/214] Corrected epoch date calculations --- .../space/rendering/renderablesmallbody.cpp | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 4b6bbf4664..bceb72da06 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -86,7 +86,7 @@ namespace { namespace openspace { // The list of leap years only goes until 2056 as we need to touch this file then -// again anyway ;) +// again anyway, due to TLE format only supporting 2-digit years starting in 1957. const std::vector LeapYears = { 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, @@ -213,14 +213,6 @@ int daysIntoGivenYear(int year, int month, int dayOfMonth) { for (int m = Months::January; m < month; ++m) { dayCount += DaysOfMonths[m]; - if (m == Months::March) { - const auto leapTest = std::find(LeapYears.begin(), LeapYears.end(), year); - if (leapTest != LeapYears.end()) { - // We are in a leap year, so we have an effective day more if we are - // beyond the end of february - dayCount--; - } - } } return dayCount; } @@ -233,35 +225,43 @@ double epochFromSubstring(const std::string& epochString) { // The main overview of this function: // 1. Read the year value - // 2. Get the number of full days since the beginning of the year + // 2. Calculate the number of seconds since the beginning of the year + // 2.a Get the number of full days since the beginning of the year + // 2.b If the year is a leap year, modify the number of days // 3. Convert the number of days to a number of seconds // 4. Get the number of leap seconds since January 1st, 2000 and remove them // 5. Adjust for the fact the epoch starts on 1st January at 12:00:00, not // midnight - // According to https://celestrak.com/columns/v04n03/ - // Apparently, US Space Command sees no need to change the two-line element - // set format yet since no artificial earth satellites existed prior to 1957. - // By their reasoning, two-digit years from 57-99 correspond to 1957-1999 and - // those from 00-56 correspond to 2000-2056. We'll see each other again in 2057! - // 1 int year = std::atoi(epochString.substr(0, 4).c_str()); const int daysSince2000 = countDays(year); - // 2 + // 2. + // 2.a int monthNum = std::atoi(epochString.substr(4, 2).c_str()); int dayOfMonthNum = std::atoi(epochString.substr(6, 2).c_str()); + int wholeDaysInto = daysIntoGivenYear(year, monthNum, dayOfMonthNum); double fractionOfDay = std::atof(epochString.substr(9, 7).c_str()); - double daysInYear = static_cast(daysIntoGivenYear(year, monthNum, - dayOfMonthNum)); - daysInYear += fractionOfDay; + double daysInYear = static_cast(wholeDaysInto) + fractionOfDay; + + // 2.b + const bool isInLeapYear = std::find( + LeapYears.begin(), + LeapYears.end(), + year + ) != LeapYears.end(); + if (isInLeapYear && daysInYear >= 60) { + // We are in a leap year, so we have an effective day more if we are + // beyond the end of february (= 31+29 days) + --daysInYear; + } // 3 using namespace std::chrono; const int SecondsPerDay = static_cast(seconds(hours(24)).count()); //Need to subtract 1 from daysInYear since it is not a zero-based count - const double nSecondsInCurrYear = daysInYear * SecondsPerDay; + const double nSecondsSince2000 = (daysSince2000 + daysInYear - 1) * SecondsPerDay; // 4 // We need to remove additional leap seconds past 2000 and add them prior to From caa02ca20ac68c5564a21ecb7e985d602807b78c Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 12 Nov 2019 17:19:23 -0500 Subject: [PATCH 047/214] Clean up. Added the raycasting number of steps as a slider for user's control. --- modules/galaxy/rendering/renderablegalaxy.cpp | 21 ++++++++++++++----- modules/galaxy/rendering/renderablegalaxy.h | 2 +- openspace.cfg | 2 +- shaders/framebuffer/raycastframebuffer.frag | 4 ++-- src/rendering/framebufferrenderer.cpp | 6 +++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 8597c7a5e0..9dfe003559 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -124,6 +124,12 @@ namespace { "This value set the downscaling factor" " when rendering the current volume." }; + + constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo = { + "Steps", + "Number of RayCasting Steps", + "This value set the number of integration steps during the raycasting procedure." + }; } // namespace namespace openspace { @@ -143,6 +149,7 @@ namespace openspace { , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) , _rotation(RotationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(6.28f)) , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) + , _numberOfRayCastingSteps(NumberOfRayCastingStepsInfo, 1000.f, 1.f, 1000.f) { dictionary.getValue("VolumeRenderingEnabled", _volumeRenderingEnabled); dictionary.getValue("StarRenderingEnabled", _starRenderingEnabled); @@ -232,8 +239,10 @@ namespace openspace { LERROR("No volume dimensions specified."); } - if (volumeDictionary.hasKey("Steps")) { - _rayCastSteps = static_cast(volumeDictionary.value("Steps")); + if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) { + _numberOfRayCastingSteps = static_cast( + volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier) + ); } else { LINFO("Number of raycasting steps not specified for Milkway Galaxy." @@ -243,8 +252,9 @@ namespace openspace { _downScaleVolumeRendering.setVisibility( openspace::properties::Property::Visibility::Developer ); - if (volumeDictionary.hasKey("Downscale")) { - _downScaleVolumeRendering = volumeDictionary.value("Downscale"); + if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { + _downScaleVolumeRendering = + volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); } if (!dictionary.hasKeyAndValue("Points")) { @@ -331,6 +341,7 @@ void RenderableGalaxy::initializeGL() { addProperty(_translation); addProperty(_rotation); addProperty(_downScaleVolumeRendering); + addProperty(_numberOfRayCastingSteps); // initialize points. if (!_pointsFilename.empty()) { @@ -495,7 +506,7 @@ void RenderableGalaxy::update(const UpdateData& data) { _pointTransform[3] += translation; _raycaster->setDownscaleRender(_downScaleVolumeRendering); - _raycaster->setMaxSteps(_rayCastSteps); + _raycaster->setMaxSteps(_numberOfRayCastingSteps); _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); _raycaster->setModelTransform(volumeTransform); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index ea7ddcb824..d074bd848b 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -72,6 +72,7 @@ private: properties::Vec3Property _translation; properties::Vec3Property _rotation; properties::FloatProperty _downScaleVolumeRendering; + properties::FloatProperty _numberOfRayCastingSteps; std::unique_ptr _pointSpreadFunctionTexture; std::unique_ptr _pointSpreadFunctionFile; @@ -80,7 +81,6 @@ private: glm::ivec3 _volumeDimensions; std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; - int _rayCastSteps = 1000; std::unique_ptr _raycaster; std::unique_ptr>> _volume; diff --git a/openspace.cfg b/openspace.cfg index 996fa99556..b47a47aa89 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,7 +27,7 @@ SGCTConfig = sgct.config.single{} -- SGCTConfig = sgct.config.fisheye{1024, 1024} -- A 4k fisheye rendering in a 1024x1024 window -SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} +-- SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 120bcdd2b8..4cb79d25a0 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -28,7 +28,6 @@ uniform sampler2D exitColorTexture; uniform sampler2D exitDepthTexture; uniform sampler2D mainDepthTexture; -uniform bool insideRaycaster; uniform vec3 cameraPosInRaycaster; uniform vec2 windowSize; @@ -53,6 +52,7 @@ out vec4 finalColor; void main() { vec2 texCoord = vec2(gl_FragCoord.xy / windowSize); + // Boundary position in view space vec4 exitColorTexture = texture(exitColorTexture, texCoord); // If we don't have an exit, discard the ray @@ -80,7 +80,7 @@ void main() { vec3 direction = normalize(diff); float raycastDepth = length(diff); - float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); + float geoDepth = denormalizeFloat((texture(mainDepthTexture, texCoord).x)); float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.f, 1.f); raycastDepth = geoRatio * raycastDepth; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index f45c618b76..76f571cf01 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1116,7 +1116,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector exitProgram->deactivate(); } - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); @@ -1180,7 +1180,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture); raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); raycastProgram->setUniform( "windowSize", @@ -1211,7 +1211,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector LWARNING("Raycaster is not attached when trying to perform raycaster task"); } - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); From aaa73415e9a62b1dc169c090cf4882ea19285d83 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 13 Nov 2019 15:36:13 -0500 Subject: [PATCH 048/214] Final touches in MW volume. --- data/assets/scene/milkyway/milkyway/volume.asset | 3 +-- include/openspace/rendering/framebufferrenderer.h | 1 + src/rendering/framebufferrenderer.cpp | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 78195a1b5c..5e88cb9052 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -25,8 +25,7 @@ local MilkyWayVolumeGalaxy = { Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", Dimensions = {1024, 1024, 128}, Size = {1.2E21, 1.2E21, 0.15E21}, - Steps = 480, - Downscale = 0.5, + Downscale = 0.4, }, Points = { Type = "Points", diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 4529fd60a4..952bf13d68 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -112,6 +112,7 @@ private: void applyTMO(float blackoutFactor); void applyFXAA(); void updateDownscaleColorTexture(); + void updateExitVolumeTextures(); void writeDownscaledVolume(); std::map _raycastData; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 76f571cf01..7d43b4d981 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -560,10 +560,14 @@ void FramebufferRenderer::writeDownscaledVolume() { glEnablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDisable(GL_DEPTH_TEST); + glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + _downscaledVolumeProgram->deactivate(); // Restores blending state @@ -1212,7 +1216,6 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycaster->downscaleRender() < 1.f) { - float scaleDown = raycaster->downscaleRender(); glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); From 0c82d0bbdd7b8bbdd760d541d9f96dc03218faa4 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 14 Nov 2019 14:40:04 -0700 Subject: [PATCH 049/214] Adding asset files for SSSB data --- .../scene/solarsystem/sssb/neo_pha.asset | 11 ++++ .../scene/solarsystem/sssb/sssb_shared.asset | 58 +++++++++++++++++++ modules/space/spacemodule.cpp | 1 + 3 files changed, 70 insertions(+) create mode 100644 data/assets/scene/solarsystem/sssb/neo_pha.asset create mode 100644 data/assets/scene/solarsystem/sssb/sssb_shared.asset diff --git a/data/assets/scene/solarsystem/sssb/neo_pha.asset b/data/assets/scene/solarsystem/sssb/neo_pha.asset new file mode 100644 index 0000000000..a0eafd20d5 --- /dev/null +++ b/data/assets/scene/solarsystem/sssb/neo_pha.asset @@ -0,0 +1,11 @@ +local assetHelper = asset.require('util/asset_helper') +local shared = asset.require('../sssb_shared') + +local group = { + Title = "PHA", + Url = "http://www.celestrak.com/NORAD/elements/education.txt", + TrailColor = { 0.75, 0.75, 0.35 } +} + +local tle = shared.downloadSssbDatabaseFile(asset, group.Url, group.Title) +shared.registerSatelliteGroupObjects(asset, group, tle, true) diff --git a/data/assets/scene/solarsystem/sssb/sssb_shared.asset b/data/assets/scene/solarsystem/sssb/sssb_shared.asset new file mode 100644 index 0000000000..c01988f074 --- /dev/null +++ b/data/assets/scene/solarsystem/sssb/sssb_shared.asset @@ -0,0 +1,58 @@ +local transforms = asset.require('scene/solarsystem/sun/transforms') +local assetHelper = asset.require('util/asset_helper') + +local satImageFolder = asset.syncedResource({ + Name = "Satellite Image Files", + Type = "HttpSynchronization", + Identifier = "tle_satellites_images", + Version = 1 +}) + +function downloadSssbDatabaseFile(sceneAsset, url, name) + local identifier = name + identifier = identifier:gsub(" ", "") + identifier = identifier:gsub("&", "") + identifier = identifier:gsub("-", "") + return sceneAsset.syncedResource({ + Name = "Small SolarSystem Body Data (" .. name .. ")", + Type = "UrlSynchronization", + Identifier = "sssb_data_" .. identifier, + Url = url + }) +end + +local registerSssbGroupObjects = function(containingAsset, group, sssbFolder, shouldAddDuplicates) + local filename = group.Url:match("([^/]+)$") + local filenameSansExt = filename:gsub(filename:match("(%.%w+)$"), "") + + local path = sssbFolder .. "/" .. filename + + function numLinesInFile(filename) + local ctr = 0 + for _ in io.lines(filename) do ctr = ctr + 1 end + return ctr + end + + function sssBodies(title, file, color) + return { + Identifier = title, + Parent = transforms.SolarSystemBarycenter.Identifier, + Renderable = { + Type = "RenderableSmallBody", + Path = file, + Segments = 160, + Color = color, + Fade = 0.5 + }, + GUI = { + Path = "/Solar System/sssb" + } + } + end + + local SssbBatch = sssBodies(filenameSansExt, path, group.TrailColor) + assetHelper.registerSceneGraphNodesAndExport(containingAsset, { SssbBatch }) +end + +asset.export("downloadSssbDatabaseFile", downloadSssbDatabaseFile) +asset.export("registerSssbGroupObjects", registerSssbGroupObjects) diff --git a/modules/space/spacemodule.cpp b/modules/space/spacemodule.cpp index e52e2fc8ca..6521a82cd4 100644 --- a/modules/space/spacemodule.cpp +++ b/modules/space/spacemodule.cpp @@ -82,6 +82,7 @@ void SpaceModule::internalInitialize(const ghoul::Dictionary&) { fRenderable->registerClass("RenderableRings"); fRenderable->registerClass("RenderableSatellites"); + fRenderable->registerClass("RenderableSmallBody"); fRenderable->registerClass("RenderableStars"); auto fTranslation = FactoryManager::ref().factory(); From 74c754d92390d6fbb7fe030a24968c065eac2d71 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 15 Nov 2019 17:32:43 -0500 Subject: [PATCH 050/214] Viewing Map. --- .../globebrowsing/shaders/smviewer_fs.glsl | 38 ++++++++++++++ .../globebrowsing/shaders/smviewer_vs.glsl | 51 +++++++++++++++++++ modules/globebrowsing/src/renderableglobe.cpp | 2 + modules/globebrowsing/src/shadowcomponent.cpp | 31 +++++++++++ modules/globebrowsing/src/shadowcomponent.h | 9 +++- 5 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 modules/globebrowsing/shaders/smviewer_fs.glsl create mode 100644 modules/globebrowsing/shaders/smviewer_vs.glsl diff --git a/modules/globebrowsing/shaders/smviewer_fs.glsl b/modules/globebrowsing/shaders/smviewer_fs.glsl new file mode 100644 index 0000000000..be189229f1 --- /dev/null +++ b/modules/globebrowsing/shaders/smviewer_fs.glsl @@ -0,0 +1,38 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "PowerScaling/powerScaling_fs.hglsl" +#include "fragment.glsl" + +in vec2 texCoord; + +uniform sampler2D shadowMapTexture; + +Fragment getFragment() { + Fragment frag; + frag.color = vec4(vec3(1.f) - texture(shadowMapTexture, texCoord).rrr, 1.f); + frag.depth = 0.f; + + return frag; +} diff --git a/modules/globebrowsing/shaders/smviewer_vs.glsl b/modules/globebrowsing/shaders/smviewer_vs.glsl new file mode 100644 index 0000000000..a69397368e --- /dev/null +++ b/modules/globebrowsing/shaders/smviewer_vs.glsl @@ -0,0 +1,51 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +out vec2 texCoord; + +const vec3 posData[6] = vec3[] ( + vec3(1.0, -0.5, 0.0), + vec3(0.5, -0.5, 0.0), + vec3(0.5, -1.0, 0.0), + vec3(1.0, -1.0, 0.0), + vec3(1.0, -0.5, 0.0), + vec3(0.5, -1.0, 0.0) +); + +const vec2 texData[6] = vec2[] ( + vec2(1.0, 1.0), + vec2(0.0, 1.0), + vec2(0.0, 0.0), + vec2(1.0, 0.0), + vec2(1.0, 1.0), + vec2(0.0, 0.0) + +); + +void main() { + texCoord = texData[ gl_VertexID ]; + gl_Position = vec4(posData[ gl_VertexID ], 1.0); +} \ No newline at end of file diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 8027d54a55..792bfa3257 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -775,6 +775,8 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask glEnable(GL_BLEND); + _shadowComponent.setViewDepthMap(true); + _shadowComponent.end(); // Render again from original point of view diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index ec03a3e706..f0fcb217b8 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -406,6 +406,33 @@ namespace openspace { if (_blendIsEnabled) { glEnable(GL_BLEND); } + + if (_viewDepthMap) { + if (!_renderDMProgram) { + _renderDMProgram = global::renderEngine.buildRenderProgram( + "ShadowMappingDebuggingProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_fs.glsl") + ); + } + + if (!_quadVAO) { + glGenVertexArrays(1, &_quadVAO); + } + + ghoul::opengl::TextureUnit shadowMapUnit; + shadowMapUnit.activate(); + glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); + + _renderDMProgram->activate(); + + _renderDMProgram->setUniform("shadowMapTexture", shadowMapUnit); + + glBindVertexArray(_quadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + + _renderDMProgram->deactivate(); + } } void ShadowComponent::update(const UpdateData& /*data*/) { @@ -655,4 +682,8 @@ namespace openspace { ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const { return _shadowData; } + + void ShadowComponent::setViewDepthMap(bool enable) { + _viewDepthMap = enable; + } } // namespace openspace diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index bfdbb7c0b5..5391e7714a 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -81,13 +81,15 @@ namespace openspace { RenderData begin(const RenderData& data); void end(); void update(const UpdateData& data); - + static documentation::Documentation Documentation(); bool isEnabled() const; ShadowComponent::ShadowMapData shadowMapData() const; + void setViewDepthMap(bool enable); + private: void createDepthTexture(); void createShadowFBO(); @@ -152,7 +154,10 @@ namespace openspace { std::unique_ptr _lightCamera; // DEBUG - bool _executeDepthTextureSave; + bool _executeDepthTextureSave = false; + bool _viewDepthMap = false; + std::unique_ptr _renderDMProgram; + GLuint _quadVAO = 0u; }; From ad96ecb1ca4cd36f48cbe6f225cef35eb6316f92 Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 18 Nov 2019 14:42:10 -0700 Subject: [PATCH 051/214] Fix for goToGeo camera init type --- scripts/convertProfileToScene.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index 9c8e359f72..81b122e74c 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -406,7 +406,7 @@ function generateAsset(T, fileOut) end CameraStr = CameraStr.."})\n" elseif (j[1] == "goToGeo") then - CameraStr = CameraStr.." openspace.navigation.goToGeo(" + CameraStr = CameraStr.." openspace.globebrowsing.goToGeo(" if not isBlank(j[2]) then CameraStr = CameraStr..j[2]..", " end From c6b460ab74ef9843357651bda0f7eee772483efd Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 22 Nov 2019 18:11:49 -0500 Subject: [PATCH 052/214] Added planet label rendering. Added Earth's label. --- .../solarsystem/planets/earth/earth.asset | 38 +- modules/base/CMakeLists.txt | 2 + modules/base/basemodule.cpp | 3 + modules/base/rendering/renderablelabels.cpp | 449 ++++++++++++++++++ modules/base/rendering/renderablelabels.h | 108 +++++ .../rendering/renderablebillboardscloud.cpp | 1 - 6 files changed, 599 insertions(+), 2 deletions(-) create mode 100644 modules/base/rendering/renderablelabels.cpp create mode 100644 modules/base/rendering/renderablelabels.h diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index 3c90956e24..22f7b7c225 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -287,6 +287,42 @@ local Earth = { } } +local EarthLabel = { + Identifier = "EarthLabel", + Parent = Earth.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Earth", + FontSize = 100.0, + LabelSize = 6.5, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, -8.0E6, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 1.0E7, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Earth Label", + Path = "/Solar System/Planets/Earth" + } +} -assetHelper.registerSceneGraphNodesAndExport(asset, { Earth }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Earth, EarthLabel }) diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 2ce1e6846c..8ba250eac0 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -41,6 +41,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablelabels.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimagelocal.h @@ -88,6 +89,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/multimodelgeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablelabels.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimagelocal.cpp diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index ba70bd6c2e..ca0c8d4975 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -122,6 +123,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { fRenderable->registerClass("RenderableBoxGrid"); fRenderable->registerClass("RenderableCartesianAxes"); + fRenderable->registerClass("RenderableLabels"); fRenderable->registerClass("RenderableModel"); fRenderable->registerClass("RenderablePlaneImageLocal"); fRenderable->registerClass("RenderablePlaneImageOnline"); @@ -189,6 +191,7 @@ std::vector BaseModule::documentations() const { DashboardItemVelocity::Documentation(), RenderableBoxGrid::Documentation(), + RenderableLabels::Documentation(), RenderableModel::Documentation(), RenderablePlane::Documentation(), RenderableSphere::Documentation(), diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp new file mode 100644 index 0000000000..9c9a3cb213 --- /dev/null +++ b/modules/base/rendering/renderablelabels.cpp @@ -0,0 +1,449 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "base::RenderableLabels"; + + enum BlendMode { + BlendModeNormal = 0, + BlendModeAdditive + }; + + constexpr const int ViewDirection = 0; + constexpr const int NormalDirection = 1; + + constexpr openspace::properties::Property::PropertyInfo BlendModeInfo = { + "BlendMode", + "Blending Mode", + "This determines the blending mode that is applied to this plane." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelColorInfo = { + "LabelColor", + "Label Color", + "The label color for the astronomical object." + }; + + constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { + "FontSize", + "Font Size", + "The font size for the astronomical object labels." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelSizeInfo = { + "LabelSize", + "Label Size", + "The label size for the astronomical object labels." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelTextInfo = { + "LabelText", + "Label Text", + "The text that will be displayed on screen." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelMinSizeInfo = { + "LabelMinSize", + "Label Min Size", + "The minimal size (in pixels) of the labels for the astronomical " + "objects being rendered." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelMaxSizeInfo = { + "LabelMaxSize", + "Label Max Size", + "The maximum size (in pixels) of the labels for the astronomical " + "objects being rendered." + }; + + constexpr openspace::properties::Property::PropertyInfo TransformationMatrixInfo = { + "TransformationMatrix", + "Transformation Matrix", + "Transformation matrix to be applied to each astronomical object." + }; + + constexpr openspace::properties::Property::PropertyInfo LabelOrientationOptionInfo = { + "LabelOrientationOption", + "Label Orientation Option", + "Label orientation rendering mode." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeInDistancesInfo = { + "FadeInDistances", + "Fade-In Start and End Distances", + "These values determine the initial and final distances from the center of " + "our galaxy from which the astronomical object will start and end " + "fading-in." + }; + + constexpr openspace::properties::Property::PropertyInfo DisableFadeInInfo = { + "DisableFadeIn", + "Disable Fade-in effect", + "Enables/Disables the Fade-in effect." + }; + + constexpr openspace::properties::Property::PropertyInfo + CorrectionSizeEndDistanceInfo = { + "CorrectionSizeEndDistance", + "Distance in 10^X meters where correction size stops acting.", + "Distance in 10^X meters where correction size stops acting." + }; + + constexpr openspace::properties::Property::PropertyInfo CorrectionSizeFactorInfo = { + "CorrectionSizeFactor", + "Control variable for distance size.", + "" + }; + + constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { + "EnablePixelSizeControl", + "Enable pixel size control.", + "Enable pixel size control for rectangular projections." + }; +} // namespace + +namespace openspace { + +documentation::Documentation RenderableLabels::Documentation() { + using namespace documentation; + return { + "Renderable Labels", + "base_renderable_labels", + { + { + BlendModeInfo.identifier, + new StringInListVerifier({ "Normal", "Additive" }), + Optional::Yes, + BlendModeInfo.description, // + " The default value is 'Normal'.", + } + } + }; +} + +RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _blendMode(BlendModeInfo, properties::OptionProperty::DisplayType::Dropdown) + , _labelColor( + LabelColorInfo, + glm::vec4(1.f, 1.f, 1.f, 1.f), + glm::vec4(0.f), + glm::vec4(1.f) + ) + , _labelSize(LabelSizeInfo, 8.f, 0.5f, 30.f) + , _fontSize(FontSizeInfo, 50.f, 1.f, 100.f) + , _labelMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) + , _labelMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f) + , _pixelSizeControl(PixelSizeControlInfo, false) + , _fadeInDistance( + FadeInDistancesInfo, + glm::vec2(0.f), + glm::vec2(0.f), + glm::vec2(100.f) + ) + , _disableFadeInDistance(DisableFadeInInfo, true) + , _correctionSizeEndDistance(CorrectionSizeEndDistanceInfo, 17.f, 12.f, 25.f) + , _correctionSizeFactor(CorrectionSizeFactorInfo, 8.f, 0.f, 20.f) + , _labelOrientationOption(LabelOrientationOptionInfo, properties::OptionProperty::DisplayType::Dropdown) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableLabels" + ); + + registerUpdateRenderBinFromOpacity(); + + _blendMode.addOptions({ + { BlendModeNormal, "Normal" }, + { BlendModeAdditive, "Additive"} + }); + _blendMode.onChange([&]() { + switch (_blendMode) { + case BlendModeNormal: + setRenderBinFromOpacity(); + break; + case BlendModeAdditive: + setRenderBin(Renderable::RenderBin::Transparent); + break; + default: + throw ghoul::MissingCaseException(); + } + }); + + if (dictionary.hasKey(BlendModeInfo.identifier)) { + const std::string v = dictionary.value(BlendModeInfo.identifier); + if (v == "Normal") { + _blendMode = BlendModeNormal; + } + else if (v == "Additive") { + _blendMode = BlendModeAdditive; + } + } + + addProperty(_blendMode); + + _labelOrientationOption.addOption(ViewDirection, "Camera View Direction"); + _labelOrientationOption.addOption(NormalDirection, "Camera Position Normal"); + + _labelOrientationOption = NormalDirection; + if (dictionary.hasKeyAndValue(LabelOrientationOptionInfo.identifier)) { + const std::string o = dictionary.value(LabelOrientationOptionInfo.identifier); + + if (o == "Camera View Direction") { + _labelOrientationOption = ViewDirection; + } + else if (o == "Camera Position Normal") { + _labelOrientationOption = NormalDirection; + } + } + + if (dictionary.hasKey(LabelTextInfo.identifier)) { + _labelText = dictionary.value(LabelTextInfo.identifier); + } + + addProperty(_labelOrientationOption); + + _labelColor.setViewOption(properties::Property::ViewOptions::Color); + if (dictionary.hasKey(LabelColorInfo.identifier)) { + _labelColor = dictionary.value(LabelColorInfo.identifier); + } + addProperty(_labelColor); + + if (dictionary.hasKey(FontSizeInfo.identifier)) { + _fontSize = dictionary.value(FontSizeInfo.identifier); + } + _fontSize.onChange([&]() { + _font = global::fontManager.font( + "Mono", + _fontSize, + ghoul::fontrendering::FontManager::Outline::Yes, + ghoul::fontrendering::FontManager::LoadGlyphs::No + ); + }); + addProperty(_fontSize); + + if (dictionary.hasKey(LabelSizeInfo.identifier)) { + _labelSize = dictionary.value(LabelSizeInfo.identifier); + } + addProperty(_labelSize); + + if (dictionary.hasKey(LabelMinSizeInfo.identifier)) { + _labelMinSize = dictionary.value(LabelMinSizeInfo.identifier); + } + addProperty(_labelMinSize); + + if (dictionary.hasKey(LabelMaxSizeInfo.identifier)) { + _labelMaxSize = dictionary.value(LabelMaxSizeInfo.identifier); + } + addProperty(_labelMaxSize); + + if (dictionary.hasKey(TransformationMatrixInfo.identifier)) { + _transformationMatrix = dictionary.value( + TransformationMatrixInfo.identifier + ); + } + + if (dictionary.hasKey(FadeInDistancesInfo.identifier)) { + glm::vec2 v = dictionary.value(FadeInDistancesInfo.identifier); + _fadeInDistance = v; + _disableFadeInDistance = false; + addProperty(_fadeInDistance); + addProperty(_disableFadeInDistance); + } + + if (dictionary.hasKey(CorrectionSizeEndDistanceInfo.identifier)) { + _correctionSizeEndDistance = static_cast( + dictionary.value(CorrectionSizeEndDistanceInfo.identifier) + ); + } + addProperty(_correctionSizeEndDistance); + + if (dictionary.hasKey(CorrectionSizeFactorInfo.identifier)) { + _correctionSizeFactor = static_cast( + dictionary.value(CorrectionSizeFactorInfo.identifier) + ); + + addProperty(_correctionSizeFactor); + } + + + if (dictionary.hasKey(PixelSizeControlInfo.identifier)) { + _pixelSizeControl = dictionary.value(PixelSizeControlInfo.identifier); + addProperty(_pixelSizeControl); + } + + //setBoundingSphere(_size); +} + +bool RenderableLabels::isReady() const { + return true; +} + +void RenderableLabels::initialize() { + bool success = true;// loadData(); + if (!success) { + throw ghoul::RuntimeError("Error loading objects labels data."); + } + + setRenderBin(Renderable::RenderBin::Transparent); +} + +void RenderableLabels::initializeGL() { + if (_font == nullptr) { + //size_t _fontSize = 50; + _font = global::fontManager.font( + "Mono", + _fontSize, + ghoul::fontrendering::FontManager::Outline::Yes, + ghoul::fontrendering::FontManager::LoadGlyphs::No + ); + } +} + +void RenderableLabels::deinitializeGL() { +} + +void RenderableLabels::render(const RenderData& data, RendererTasks&) { + + //bool additiveBlending = (_blendMode == BlendModeAdditive); + //if (additiveBlending) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + //} + + float fadeInVariable = 1.f; + if (!_disableFadeInDistance) { + float distCamera = static_cast(glm::length(data.camera.positionVec3())); + const glm::vec2 fadeRange = _fadeInDistance; + const float a = 1.f / ((fadeRange.y - fadeRange.x)); + const float b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); + const float funcValue = a * distCamera + b; + fadeInVariable *= funcValue > 1.f ? 1.f : funcValue; + + if (funcValue < 0.01f) { + return; + } + } + + //glm::dmat4 modelMatrix = + // glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation + // glm::dmat4(data.modelTransform.rotation) * // Spice rotation + // glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + glm::dmat4 modelMatrix(1.0); + glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix; + glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); + + glm::dmat4 modelViewProjectionMatrix = projectionMatrix * modelViewMatrix; + + glm::dvec3 cameraViewDirectionWorld = -data.camera.viewDirectionWorldSpace(); + glm::dvec3 cameraUpDirectionWorld = data.camera.lookUpVectorWorldSpace(); + glm::dvec3 orthoRight = glm::normalize( + glm::cross(cameraUpDirectionWorld, cameraViewDirectionWorld) + ); + if (orthoRight == glm::dvec3(0.0)) { + glm::dvec3 otherVector( + cameraUpDirectionWorld.y, + cameraUpDirectionWorld.x, + cameraUpDirectionWorld.z + ); + orthoRight = glm::normalize(glm::cross(otherVector, cameraViewDirectionWorld)); + } + glm::dvec3 orthoUp = glm::normalize(glm::cross(cameraViewDirectionWorld, orthoRight)); + + renderLabels(data, modelViewProjectionMatrix, orthoRight, orthoUp, fadeInVariable); + + //if (additiveBlending) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + //} +} + +void RenderableLabels::update(const UpdateData&) { + // JCC: Change font size? +} + +void RenderableLabels::renderLabels(const RenderData& data, + const glm::dmat4& modelViewProjectionMatrix, + const glm::dvec3& orthoRight, + const glm::dvec3& orthoUp, + float fadeInVariable) +{ + glm::vec4 textColor = _labelColor; + + textColor.a *= fadeInVariable; + textColor.a *= _opacity; + + ghoul::fontrendering::FontRenderer::ProjectedLabelsInformation labelInfo; + + labelInfo.orthoRight = orthoRight; + labelInfo.orthoUp = orthoUp; + labelInfo.minSize = static_cast(_labelMinSize); + labelInfo.maxSize = static_cast(_labelMaxSize); + labelInfo.cameraPos = data.camera.positionVec3(); + labelInfo.cameraLookUp = data.camera.lookUpVectorWorldSpace(); + labelInfo.renderType = _labelOrientationOption; + labelInfo.mvpMatrix = modelViewProjectionMatrix; + labelInfo.scale = powf(10.f, _labelSize); + labelInfo.enableDepth = true; + labelInfo.enableFalseDepth = false; + + // We don't use spice rotation and scale + glm::vec3 transformedPos( + _transformationMatrix * glm::dvec4(data.modelTransform.translation, 1.0) + ); + + ghoul::fontrendering::FontRenderer::defaultProjectionRenderer().render( + *_font, + transformedPos, + _labelText, + textColor, + labelInfo + ); +} +} // namespace openspace diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h new file mode 100644 index 0000000000..f0ee7392eb --- /dev/null +++ b/modules/base/rendering/renderablelabels.h @@ -0,0 +1,108 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___RENDERABLELABELS___H__ +#define __OPENSPACE_MODULE_BASE___RENDERABLELABELS___H__ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace ghoul::filesystem { class File; } +namespace ghoul::fontrendering { class Font; } +namespace ghoul::opengl { + class ProgramObject; + class Texture; +} // namespace ghoul::opengl + +namespace openspace { + +struct RenderData; +struct UpdateData; + +namespace documentation { struct Documentation; } + +struct LinePoint; + +class RenderableLabels : public Renderable { +public: + RenderableLabels(const ghoul::Dictionary& dictionary); + + void initialize() override; + void initializeGL() override; + void deinitializeGL() override; + + bool isReady() const override; + + void render(const RenderData& data, RendererTasks& rendererTask) override; + void update(const UpdateData& data) override; + + static documentation::Documentation Documentation(); + +protected: + properties::OptionProperty _blendMode; + +private: + void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, + const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); + + properties::Vec4Property _labelColor; + properties::FloatProperty _labelSize; + properties::FloatProperty _fontSize; + properties::FloatProperty _labelMinSize; + properties::FloatProperty _labelMaxSize; + properties::BoolProperty _pixelSizeControl; + properties::Vec2Property _fadeInDistance; + properties::BoolProperty _disableFadeInDistance; + properties::FloatProperty _correctionSizeEndDistance; + properties::FloatProperty _correctionSizeFactor; + + properties::OptionProperty _labelOrientationOption; + + std::shared_ptr _font; + + std::string _speckFile; + std::string _colorMapFile; + std::string _labelFile; + std::string _colorOptionString; + std::string _datavarSizeOptionString; + + std::string _labelText; + + // Data may require some type of transformation prior the spice transformation being + // applied. + glm::dmat4 _transformationMatrix = glm::dmat4(1.0); +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___RENDERABLELABELS___H__ diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index da42b36210..40d332b2d6 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include From 747e699d5f8b6b766cf1af3cf38df6e465ac476e Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 25 Nov 2019 13:10:11 -0500 Subject: [PATCH 053/214] Added other planets. --- .../dwarf_planets/pluto/pluto.asset | 39 ++++++++++++++++++- .../solarsystem/planets/earth/earth.asset | 2 +- .../solarsystem/planets/jupiter/jupiter.asset | 39 ++++++++++++++++++- .../scene/solarsystem/planets/mars/mars.asset | 39 ++++++++++++++++++- .../solarsystem/planets/mercury/mercury.asset | 38 +++++++++++++++++- .../solarsystem/planets/neptune/neptune.asset | 39 ++++++++++++++++++- .../solarsystem/planets/saturn/saturn.asset | 38 +++++++++++++++++- .../solarsystem/planets/uranus/uranus.asset | 39 ++++++++++++++++++- .../solarsystem/planets/venus/venus.asset | 38 +++++++++++++++++- 9 files changed, 299 insertions(+), 12 deletions(-) diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index 8d2b891b4b..b4de13d9d1 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -59,6 +59,41 @@ local Pluto = { } } +local PlutoLabel = { + Identifier = "PlutoLabel", + Parent = Pluto.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Pluto", + FontSize = 100.0, + LabelSize = 8.9, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Pluto Label", + Path = "/Solar System/Planets/Pluto" + } +} - -assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Pluto, PlutoLabel }) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index 22f7b7c225..d6d6c43ddc 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -307,7 +307,7 @@ local EarthLabel = { Type = "RenderableLabels", LabelText = "Earth", FontSize = 100.0, - LabelSize = 6.5, + LabelSize = 8.6, LabelMaxSize = 100.0, LabelMinSize = 1.0, BlendMode = "Additive", diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index 9333c339c1..6cc5961b41 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -42,6 +42,41 @@ local Jupiter = { } } +local JupiterLabel = { + Identifier = "JupiterLabel", + Parent = Jupiter.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Jupiter", + FontSize = 100.0, + LabelSize = 8.6, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Jupiter Label", + Path = "/Solar System/Planets/Jupiter" + } +} - -assetHelper.registerSceneGraphNodesAndExport(asset, { Jupiter }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Jupiter, JupiterLabel }) diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index 57ee23d861..5912db1141 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -187,4 +187,41 @@ local Mars = { } } -assetHelper.registerSceneGraphNodesAndExport(asset, { Mars }) +local MarsLabel = { + Identifier = "MarsLabel", + Parent = Mars.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Mars", + FontSize = 100.0, + LabelSize = 8.5, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, -8.0E6, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 1.0E7, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Mars Label", + Path = "/Solar System/Planets/Mars" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { Mars, MarsLabel }) diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index d2bcf7c591..868d83520d 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -223,5 +223,41 @@ local Mercury = { } } +local MercuryLabel = { + Identifier = "MercuryLabel", + Parent = Mercury.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Mercury", + FontSize = 100.0, + LabelSize = 8.3, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Mercury Label", + Path = "/Solar System/Planets/Mercury" + } +} -assetHelper.registerSceneGraphNodesAndExport(asset, { Mercury }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Mercury, MercuryLabel }) diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset index 677395e8e5..03016589de 100644 --- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset +++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset @@ -40,4 +40,41 @@ local Neptune = { } } -assetHelper.registerSceneGraphNodesAndExport(asset, { Neptune }) +local NeptuneLabel = { + Identifier = "NeptuneLabel", + Parent = Neptune.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Neptune", + FontSize = 100.0, + LabelSize = 8.8, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Neptune Label", + Path = "/Solar System/Planets/Neptune" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { Neptune, NeptuneLabel }) diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 77b45972f2..aabb1d9fb2 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -57,6 +57,42 @@ local SaturnRings = { } } +local SaturnLabel = { + Identifier = "SaturnLabel", + Parent = Saturn.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Saturn", + FontSize = 100.0, + LabelSize = 8.7, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Saturn Label", + Path = "/Solar System/Planets/Saturn" + } +} -assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Saturn, SaturnRings, SaturnLabel }) diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index 1bb29fa184..d4ec613b8c 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -42,6 +42,41 @@ local Uranus = { } } +local UranusLabel = { + Identifier = "UranusLabel", + Parent = Uranus.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Uranus", + FontSize = 100.0, + LabelSize = 8.7, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Neptune Label", + Path = "/Solar System/Planets/Uranus" + } +} - -assetHelper.registerSceneGraphNodesAndExport(asset, { Uranus }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Uranus, UranusLabel }) diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 0b7617dad2..051ba208d1 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -64,6 +64,42 @@ local Venus = { } } +local VenusLabel = { + Identifier = "VenusLabel", + Parent = Venus.Identifier, + -- Transform = { + -- Translation = { + -- Type = "SpiceTranslation", + -- Target = "EARTH", + -- Observer = "EARTH BARYCENTER" + -- }, + -- -- Rotation = { + -- -- Type = "SpiceRotation", + -- -- SourceFrame = "IAU_MOON", + -- -- DestinationFrame = "GALACTIC" + -- -- } + -- }, + Renderable = { + Enabled = true, + Type = "RenderableLabels", + LabelText = "Venus", + FontSize = 100.0, + LabelSize = 8.4, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + BlendMode = "Additive", + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Venus Label", + Path = "/Solar System/Planets/Venus" + } +} -assetHelper.registerSceneGraphNodesAndExport(asset, { Venus }) +assetHelper.registerSceneGraphNodesAndExport(asset, { Venus, VenusLabel }) From dfb08b98e5aec3db4cc0c382a270a2557a97b614 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 25 Nov 2019 13:15:31 -0500 Subject: [PATCH 054/214] Removed unused code. --- modules/base/rendering/renderablelabels.cpp | 31 --------------------- modules/base/rendering/renderablelabels.h | 4 +-- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 9c9a3cb213..1e71a91ed4 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -127,19 +127,6 @@ namespace { "Enables/Disables the Fade-in effect." }; - constexpr openspace::properties::Property::PropertyInfo - CorrectionSizeEndDistanceInfo = { - "CorrectionSizeEndDistance", - "Distance in 10^X meters where correction size stops acting.", - "Distance in 10^X meters where correction size stops acting." - }; - - constexpr openspace::properties::Property::PropertyInfo CorrectionSizeFactorInfo = { - "CorrectionSizeFactor", - "Control variable for distance size.", - "" - }; - constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { "EnablePixelSizeControl", "Enable pixel size control.", @@ -186,8 +173,6 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) glm::vec2(100.f) ) , _disableFadeInDistance(DisableFadeInInfo, true) - , _correctionSizeEndDistance(CorrectionSizeEndDistanceInfo, 17.f, 12.f, 25.f) - , _correctionSizeFactor(CorrectionSizeFactorInfo, 8.f, 0.f, 20.f) , _labelOrientationOption(LabelOrientationOptionInfo, properties::OptionProperty::DisplayType::Dropdown) { documentation::testSpecificationAndThrow( @@ -296,22 +281,6 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) addProperty(_disableFadeInDistance); } - if (dictionary.hasKey(CorrectionSizeEndDistanceInfo.identifier)) { - _correctionSizeEndDistance = static_cast( - dictionary.value(CorrectionSizeEndDistanceInfo.identifier) - ); - } - addProperty(_correctionSizeEndDistance); - - if (dictionary.hasKey(CorrectionSizeFactorInfo.identifier)) { - _correctionSizeFactor = static_cast( - dictionary.value(CorrectionSizeFactorInfo.identifier) - ); - - addProperty(_correctionSizeFactor); - } - - if (dictionary.hasKey(PixelSizeControlInfo.identifier)) { _pixelSizeControl = dictionary.value(PixelSizeControlInfo.identifier); addProperty(_pixelSizeControl); diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index f0ee7392eb..9c424964c7 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -83,9 +83,7 @@ private: properties::BoolProperty _pixelSizeControl; properties::Vec2Property _fadeInDistance; properties::BoolProperty _disableFadeInDistance; - properties::FloatProperty _correctionSizeEndDistance; - properties::FloatProperty _correctionSizeFactor; - + properties::OptionProperty _labelOrientationOption; std::shared_ptr _font; From ef2d14d7fa872c5aac35fcc896b7b7c273daf381 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 25 Nov 2019 13:30:39 -0500 Subject: [PATCH 055/214] Changed default label's orientation. --- .../assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset | 3 ++- data/assets/scene/solarsystem/planets/earth/earth.asset | 5 +++-- data/assets/scene/solarsystem/planets/jupiter/jupiter.asset | 1 + data/assets/scene/solarsystem/planets/mars/mars.asset | 1 + data/assets/scene/solarsystem/planets/mercury/mercury.asset | 1 + data/assets/scene/solarsystem/planets/neptune/neptune.asset | 1 + data/assets/scene/solarsystem/planets/saturn/saturn.asset | 1 + data/assets/scene/solarsystem/planets/uranus/uranus.asset | 1 + data/assets/scene/solarsystem/planets/venus/venus.asset | 1 + 9 files changed, 12 insertions(+), 3 deletions(-) diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index b4de13d9d1..8f2d2f3036 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -83,6 +83,7 @@ local PlutoLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, BlendMode = "Additive", + LabelOrientationOption = "Camera View Direction", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, @@ -92,7 +93,7 @@ local PlutoLabel = { }, GUI = { Name = "Pluto Label", - Path = "/Solar System/Planets/Pluto" + Path = "/Solar System/Dwarf Planets/Pluto" } } diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index d6d6c43ddc..cb14706431 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -310,11 +310,12 @@ local EarthLabel = { LabelSize = 8.6, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { - 1.0, 0.0, 0.0, -8.0E6, + 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 1.0E7, + 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, }, diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index 6cc5961b41..1996531c87 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -65,6 +65,7 @@ local JupiterLabel = { LabelSize = 8.6, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index 5912db1141..0575f88e03 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -210,6 +210,7 @@ local MarsLabel = { LabelSize = 8.5, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, -8.0E6, diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index 868d83520d..1d24fa241d 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -246,6 +246,7 @@ local MercuryLabel = { LabelSize = 8.3, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset index 03016589de..5e617b7286 100644 --- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset +++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset @@ -63,6 +63,7 @@ local NeptuneLabel = { LabelSize = 8.8, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index aabb1d9fb2..22a223eb3a 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -81,6 +81,7 @@ local SaturnLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, BlendMode = "Additive", + LabelOrientationOption = "Camera View Direction", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index d4ec613b8c..f522c2fa89 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -65,6 +65,7 @@ local UranusLabel = { LabelSize = 8.7, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 051ba208d1..3572c07083 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -87,6 +87,7 @@ local VenusLabel = { LabelSize = 8.4, LabelMaxSize = 100.0, LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, From 60813e3209d20674f7902ff3d0964ec6fc3b5aa9 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 26 Nov 2019 11:06:39 -0500 Subject: [PATCH 056/214] Final version with volume depth interpolation. --- .../openspace/rendering/framebufferrenderer.h | 6 +- .../framebuffer/mergeDownscaledVolume.frag | 4 +- shaders/framebuffer/raycastframebuffer.frag | 1 + src/rendering/framebufferrenderer.cpp | 60 +++++++++++++++++-- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 952bf13d68..7dd048052f 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -111,7 +111,7 @@ private: void resolveMSAA(float blackoutFactor); void applyTMO(float blackoutFactor); void applyFXAA(); - void updateDownscaleColorTexture(); + void updateDownscaleTextures(); void updateExitVolumeTextures(); void writeDownscaledVolume(); @@ -131,7 +131,8 @@ private: UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma, Hue, Saturation, Value) _hdrUniformCache; UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache; - UniformCache(downscaledRenderedVolume) _writeDownscaledVolumeUniformCache; + UniformCache(downscaledRenderedVolume, downscaledRenderedVolumeDepth) + _writeDownscaledVolumeUniformCache; GLint _defaultFBO; GLuint _screenQuad; @@ -166,6 +167,7 @@ private: struct { GLuint framebuffer; GLuint colorTexture; + GLuint depthbuffer; float currentDownscaleFactor = 1.f; } _downscaleVolumeRendering; diff --git a/shaders/framebuffer/mergeDownscaledVolume.frag b/shaders/framebuffer/mergeDownscaledVolume.frag index f34a300742..14a6405735 100644 --- a/shaders/framebuffer/mergeDownscaledVolume.frag +++ b/shaders/framebuffer/mergeDownscaledVolume.frag @@ -27,9 +27,11 @@ layout (location = 0) out vec4 finalColor; uniform sampler2D downscaledRenderedVolume; +uniform sampler2D downscaledRenderedVolumeDepth; in vec2 texCoord; void main() { - finalColor = texture(downscaledRenderedVolume, texCoord); + finalColor = texture(downscaledRenderedVolume, texCoord); + gl_FragDepth = texture(downscaledRenderedVolumeDepth, texCoord).r; } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 4cb79d25a0..bff04b1dbe 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -126,5 +126,6 @@ void main() { finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3.f); finalColor.rgb /= finalColor.a ; + gl_FragDepth = normalizeFloat(entryDepth); } diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 7d43b4d981..6f9d372218 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -59,8 +59,8 @@ namespace { "renderedTexture", "inverseScreenSize" }; - constexpr const std::array DownscaledVolumeUniformNames = { - "downscaledRenderedVolume" + constexpr const std::array DownscaledVolumeUniformNames = { + "downscaledRenderedVolume", "downscaledRenderedVolumeDepth" }; constexpr const char* ExitFragmentShaderPath = @@ -191,6 +191,7 @@ void FramebufferRenderer::initialize() { // DownscaleVolumeRendering glGenFramebuffers(1, &_downscaleVolumeRendering.framebuffer); glGenTextures(1, &_downscaleVolumeRendering.colorTexture); + glGenTextures(1, &_downscaleVolumeRendering.depthbuffer); // Allocate Textures/Buffers Memory updateResolution(); @@ -325,6 +326,12 @@ void FramebufferRenderer::initialize() { _downscaleVolumeRendering.colorTexture, 0 ); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + _downscaleVolumeRendering.depthbuffer, + 0 + ); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { @@ -383,6 +390,7 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_gBuffers.positionTexture); glDeleteTextures(1, &_gBuffers.normalTexture); glDeleteTextures(1, &_downscaleVolumeRendering.colorTexture); + glDeleteTextures(1, &_downscaleVolumeRendering.depthbuffer); glDeleteTextures(1, &_pingPongBuffers.colorTexture[1]); @@ -492,7 +500,7 @@ void FramebufferRenderer::applyFXAA() { _fxaaProgram->deactivate(); } -void FramebufferRenderer::updateDownscaleColorTexture() { +void FramebufferRenderer::updateDownscaleTextures() { glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); glTexImage2D( GL_TEXTURE_2D, @@ -507,6 +515,23 @@ void FramebufferRenderer::updateDownscaleColorTexture() { ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); + + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } void FramebufferRenderer::writeDownscaledVolume() { @@ -557,6 +582,19 @@ void FramebufferRenderer::writeDownscaledVolume() { downscaledTextureUnit ); + ghoul::opengl::TextureUnit downscaledDepthUnit; + downscaledDepthUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + _downscaleVolumeRendering.depthbuffer + ); + + _downscaledVolumeProgram->setUniform( + _writeDownscaledVolumeUniformCache.downscaledRenderedVolumeDepth, + downscaledDepthUnit + ); + + glEnablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -800,6 +838,20 @@ void FramebufferRenderer::updateResolution() { float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Volume Rendering Textures glBindTexture(GL_TEXTURE_2D, _exitColorTexture); @@ -1126,7 +1178,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; - updateDownscaleColorTexture(); + updateDownscaleTextures(); } glClear(GL_COLOR_BUFFER_BIT); } From 099488106ad44c7fcf574f0eb6119a4985671b9b Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 26 Nov 2019 16:13:46 -0500 Subject: [PATCH 057/214] Fixed issues in Shadows and improved quality. --- .../solarsystem/planets/earth/earth.asset | 9 +- .../globebrowsing/shaders/renderer_fs.glsl | 2 +- modules/globebrowsing/shaders/rings_fs.glsl | 2 +- .../globebrowsing/shaders/smviewer_fs.glsl | 4 +- modules/globebrowsing/src/renderableglobe.cpp | 5 +- modules/globebrowsing/src/shadowcomponent.cpp | 141 +++++++++++------- modules/globebrowsing/src/shadowcomponent.h | 2 + 7 files changed, 103 insertions(+), 62 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index c1482969d0..44150fd439 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -263,10 +263,11 @@ local Earth = { } --Caster2 = { Name = "Independency Day Ship", Radius = 0.0, } }, - Shadows = { - Enabled = true, - DistanceFraction = 40.0 - }, + -- Shadows = { + -- Enabled = true, + -- DistanceFraction = 70.0, + -- DepthMapSize = {7680.0, 4320.0} + -- }, Labels = { Enable = false, FileName = labelsPath .. "/Earth.labels", diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index d418937e77..e3281fcedd 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -267,7 +267,7 @@ Fragment getFragment() { float shadow = 1.0; if ( shadowCoords.w > 1 ) { vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); + normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 1dfd5df308..d1be63cef7 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -73,7 +73,7 @@ Fragment getFragment() { float shadow = 1.0; if ( shadowCoords.z >= 0 ) { vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.3); + normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; diff --git a/modules/globebrowsing/shaders/smviewer_fs.glsl b/modules/globebrowsing/shaders/smviewer_fs.glsl index be189229f1..0d58b4e8aa 100644 --- a/modules/globebrowsing/shaders/smviewer_fs.glsl +++ b/modules/globebrowsing/shaders/smviewer_fs.glsl @@ -25,9 +25,11 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" +precision highp float; + in vec2 texCoord; -uniform sampler2D shadowMapTexture; +uniform highp sampler2D shadowMapTexture; Fragment getFragment() { Fragment frag; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 792bfa3257..191b351738 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -574,7 +574,6 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _generalProperties.eclipseShadowsEnabled.onChange(notifyShaderRecompilation); _generalProperties.eclipseHardShadows.onChange(notifyShaderRecompilation); _generalProperties.performShading.onChange(notifyShaderRecompilation); - _generalProperties.shadowMapping.onChange(notifyShaderRecompilation); _debugProperties.showChunkEdges.onChange(notifyShaderRecompilation); _debugProperties.showHeightResolution.onChange(notifyShaderRecompilation); _debugProperties.showHeightIntensities.onChange(notifyShaderRecompilation); @@ -681,7 +680,9 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _shadowComponent.initialize(); addPropertySubOwner(_shadowComponent); _hasShadows = true; + _generalProperties.shadowMapping = true; } + _generalProperties.shadowMapping.onChange(notifyShaderRecompilation); #ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION _module = global::moduleEngine.module(); @@ -775,7 +776,7 @@ void RenderableGlobe::render(const RenderData& data, RendererTasks& rendererTask glEnable(GL_BLEND); - _shadowComponent.setViewDepthMap(true); + _shadowComponent.setViewDepthMap(false); _shadowComponent.end(); diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index f0fcb217b8..f857588011 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -79,6 +79,12 @@ namespace { "considered as the new light source distance." }; + constexpr openspace::properties::Property::PropertyInfo DepthMapSizeInfo = { + "DepthMapSize", + "Depth Map Size", + "The depth map size in pixels. You must entry the width and height values." + }; + void checkFrameBufferState(const std::string& codePosition) { if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { @@ -201,6 +207,23 @@ namespace openspace { _executeDepthTextureSave = true; }); + + if (_shadowMapDictionary.hasKey(DepthMapSizeInfo.identifier)) { + glm::vec2 depthMapSize = + _shadowMapDictionary.value(DepthMapSizeInfo.identifier); + _shadowDepthTextureWidth = depthMapSize.x; + _shadowDepthTextureHeight = depthMapSize.y; + _dynamicDepthTextureRes = false; + } + else { + glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); + _shadowDepthTextureWidth = renderingResolution.x * 2; + _shadowDepthTextureHeight = renderingResolution.y * 2; + _dynamicDepthTextureRes = true; + } + + _viewDepthMap = false; + addProperty(_enabled); addProperty(_saveDepthTexture); addProperty(_distanceFraction); @@ -420,12 +443,12 @@ namespace openspace { glGenVertexArrays(1, &_quadVAO); } + _renderDMProgram->activate(); + ghoul::opengl::TextureUnit shadowMapUnit; shadowMapUnit.activate(); glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - _renderDMProgram->activate(); - _renderDMProgram->setUniform("shadowMapTexture", shadowMapUnit); glBindVertexArray(_quadVAO); @@ -437,61 +460,22 @@ namespace openspace { void ShadowComponent::update(const UpdateData& /*data*/) { _sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition(); + + glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); + if (_dynamicDepthTextureRes && ((_shadowDepthTextureWidth != renderingResolution.x) || + (_shadowDepthTextureHeight != renderingResolution.y))) { + _shadowDepthTextureWidth = renderingResolution.x * 2; + _shadowDepthTextureHeight = renderingResolution.y * 2; + updateDepthTexture(); + } } void ShadowComponent::createDepthTexture() { glGenTextures(1, &_shadowDepthTexture); - glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - glTexStorage2D( - GL_TEXTURE_2D, - 1, - GL_DEPTH_COMPONENT32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight - ); - - /*glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_DEPTH_COMPONENT32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - 0, - GL_DEPTH_COMPONENT, - GL_FLOAT, - 0 - );*/ + updateDepthTexture(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, ShadowBorder); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + checkGLError("createDepthTexture() -- Depth texture created"); - checkGLError("createDepthTexture() -- Depth testure created"); - - /*glGenTextures(1, &_positionInLightSpaceTexture); - glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGB32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - 0, - GL_RGBA, - GL_FLOAT, - nullptr - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ - - glBindTexture(GL_TEXTURE_2D, 0); - _shadowData.shadowDepthTexture = _shadowDepthTexture; //_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; } @@ -499,8 +483,7 @@ namespace openspace { void ShadowComponent::createShadowFBO() { // Saves current FBO first glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); - - + glGenFramebuffers(1, &_shadowFBO); glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); glFramebufferTexture( @@ -528,6 +511,58 @@ namespace openspace { glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); } + void ShadowComponent::updateDepthTexture() { + glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); + /* + glTexStorage2D( + GL_TEXTURE_2D, + 1, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight + ); + */ + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + 0 + ); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, ShadowBorder); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + /*glGenTextures(1, &_positionInLightSpaceTexture); + glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ + + glBindTexture(GL_TEXTURE_2D, 0); + } + void ShadowComponent::saveDepthBuffer() { int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight; GLubyte * buffer = new GLubyte[size]; diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 5391e7714a..602a480f00 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -93,6 +93,7 @@ namespace openspace { private: void createDepthTexture(); void createShadowFBO(); + void updateDepthTexture(); // Debug void saveDepthBuffer(); @@ -119,6 +120,7 @@ namespace openspace { int _shadowDepthTextureHeight; int _shadowDepthTextureWidth; + bool _dynamicDepthTextureRes = true; GLuint _shadowDepthTexture; GLuint _positionInLightSpaceTexture; From e2e86c12abe09ff27eafc326a8aeb9077ac80e34 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 26 Nov 2019 17:07:27 -0500 Subject: [PATCH 058/214] Ops. Cleaning depth buffer now. --- src/rendering/framebufferrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 6f9d372218..3e145ecf5a 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1180,7 +1180,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; updateDownscaleTextures(); } - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } else { glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); From 278bd3edaf8024926159992d746c83e1f4fbd0d1 Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 27 Nov 2019 11:31:06 -0700 Subject: [PATCH 059/214] Adding a profile equivalent for all existing scenes --- data/assets/apollo8.profile | 35 ++++++++++++++++++++ data/assets/apollo_sites.profile | 36 +++++++++++++++++++++ data/assets/dawn.profile | 18 +++++++++++ data/assets/default.profile | 17 ++++++++++ data/assets/default_full.profile | 23 +++++++++++++ data/assets/gaia.profile | 22 +++++++++++++ data/assets/insight.profile | 29 +++++++++++++++++ data/assets/juno.profile | 37 +++++++++++++++++++++ data/assets/messenger.profile | 41 +++++++++++++++++++++++ data/assets/newhorizons.profile | 40 +++++++++++------------ data/assets/osirisrex.profile | 45 ++++++++++++++++++++++++++ data/assets/rosetta.profile | 35 ++++++++++++++++++++ data/assets/touch.profile | 25 ++++++++++++++ data/assets/voyager.profile | 54 +++++++++++++++++++++++++++++++ scripts/convertProfileToScene.lua | 5 +-- 15 files changed, 440 insertions(+), 22 deletions(-) create mode 100644 data/assets/apollo8.profile create mode 100644 data/assets/apollo_sites.profile create mode 100644 data/assets/dawn.profile create mode 100644 data/assets/default.profile create mode 100644 data/assets/default_full.profile create mode 100644 data/assets/gaia.profile create mode 100644 data/assets/insight.profile create mode 100644 data/assets/juno.profile create mode 100644 data/assets/messenger.profile create mode 100644 data/assets/osirisrex.profile create mode 100644 data/assets/rosetta.profile create mode 100644 data/assets/touch.profile create mode 100644 data/assets/voyager.profile diff --git a/data/assets/apollo8.profile b/data/assets/apollo8.profile new file mode 100644 index 0000000000..f9a9c003fc --- /dev/null +++ b/data/assets/apollo8.profile @@ -0,0 +1,35 @@ +#Version +1.0 + +#Asset +scene/solarsystem/planets/earth/moon/moon required +scene/solarsystem/missions/apollo/apollo8 required +scene/solarsystem/planets/earth/earth required + +#Property +setPropertyValueSingle NavigationHandler.OrbitalNavigator.MinimumAllowedDistance 0.000000 +setPropertyValueSingle Scene.Moon.Renderable.LodScaleFactor 24.0 + +#Keybinding +E Jump to right before the earthrise photo Set Earthrise time /Missions/Apollo/8 false "openspace.time.setPause(true); openspace.time.setDeltaTime(1); openspace.time.setTime('1968 DEC 24 16:37:31'); openspace.navigation.setNavigationState({Anchor = 'Apollo8', Position = { 1.494592E1, 3.236777E1, -4.171296E1 }, ReferenceFrame = 'Root', Up = { 0.960608E0, -0.212013E0, 0.179675E0 }}); openspace.setPropertyValue('*Trail.Renderable.Enabled', false)" +U Jump to time right before Apollo 8 liftoff, with its trail enabled Set Apollo 8 launch time /Missions/Apollo/8 false "openspace.time.setTime('1968-12-21T12:51:37.00'); openspace.setPropertyValueSingle('Scene.Apollo8LaunchTrail.Renderable.Enabled', true)" +K Toggles Moon Kaguya color layer Toggle Kaguya layer on the Moon /Missions/Apollo false propertyHelper.invert('Scene.Moon.Renderable.Layers.ColorLayers.Kaguya_Utah.Enabled') +T Toggles the trails of the Apollo 8 orbits, focused around the Moon Toggle Apollo 8 orbits /Missions/Apollo/8 false propertyHelper.invert('Scene.Apollo8MoonTrail.Renderable.Enabled') +SHIFT+T Toggles the trails of the Apollo 8 Launch, focused around the Earth Toggle Apollo 8 launch trail /Missions/Apollo/8 false propertyHelper.invert('Scene.Apollo8LaunchTrail.Renderable.Enabled') +CTRL+T Toggles the trails of the full Apollo 8, with Earth's frame of reference Toggles Apollo 8 full trail /Missions/Apollo/8 false propertyHelper.invert('Scene.Apollo8EarthBarycenterTrail.Renderable.Enabled') +S Toggles shading for the Moon Toggle Moon shading /Missions/Apollo false propertyHelper.invert('Scene.Moon.Renderable.PerformShading') +PAGE_UP Set camera focus to Apollo 8 Focus on Apollo 8 /Missions/Apollo/8 false "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo8'); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +PAGE_DOWN Set camera focus to the Moon Focus on Moon /Missions/Apollo false "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Moon'); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +HOME Set camera focus to the Earth Focus on Earth /Missions/Apollo false "openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth'); openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" + +#Time +absolute 1968-12-21T12:51:51.0 + +#Camera +goToGeo "Earth" 20 -60 15000000 + +#MarkNodes +Earth +Moon +Apollo8 +Apollo8Launch diff --git a/data/assets/apollo_sites.profile b/data/assets/apollo_sites.profile new file mode 100644 index 0000000000..f014e5b36d --- /dev/null +++ b/data/assets/apollo_sites.profile @@ -0,0 +1,36 @@ +#Version +1.0 + +#Asset +scene/solarsystem/planets/earth/moon/moon required +scene/solarsystem/missions/apollo/apollo8 required +scene/solarsystem/missions/apollo/apollo11 required +scene/solarsystem/missions/apollo/a17_lem required +scene/solarsystem/missions/apollo/apollo_globebrowsing required +scene/solarsystem/missions/apollo/apollo_11_lem_flipbook required +scene/solarsystem/missions/apollo/insignias_map required + +#Property +setPropertyValueSingle Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.BlendMode 0 +setPropertyValueSingle Scene.Apollo11LemDescentModel.Renderable.RotationVector { 273.750,28.0,309.85 } +setPropertyValueSingle Scene.Apollo11LemLandedModel.Renderable.RotationVector { 273.750,28.0,309.85 } +setPropertyValueSingle Scene.Moon.Renderable.PerformShading false + +#Keybinding +m Focus on Moon Focus on Moon /Missions/Apollo false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Moon'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);" +F9 Disable apollo site on moon when switching Disable Apollo site /Missions/Apollo false "openspace.setPropertyValue('Scene.Moon.Renderable.Layers.ColorLayers.A17_*.Enabled', false); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', false); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', false); openspace.setPropertyValueSingle('Scene.Apollo11MoonTrail.Renderable.Enabled', false); openspace.setPropertyValueSingle('Scene.Apollo11LemTrail.Renderable.Enabled', false); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_17.Enabled', false);" +F11 Setup for A11 site Setup A11 site /Missions/Apollo/11 false "openspace.time.setTime('1969 JUL 20 20:17:40'); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_11.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A11_M177481212_p_longlat.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.LodScaleFactor', 20.11); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo11LemPosition'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil); openspace.setPropertyValueSingle('Scene.Apollo11MoonTrail.Renderable.Enabled', true); openspace.setPropertyValueSingle('Scene.Apollo11LemTrail.Renderable.Enabled', true);" +F7 Setup for A17 site Setup A17 site /Missions/Apollo/17 false "openspace.time.setTime('1972 DEC 12 19:47:11'); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.BlendMode', 0.000000); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_travmap.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.HeightLayers.LRO_NAC_Apollo_17.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_LEM.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_LEM.BlendMode', 0.000000); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_NAC_Alt_p.Enabled', true); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_NAC_Alt_p.BlendMode', 0.000000); openspace.setPropertyValueSingle('Scene.Moon.Renderable.LodScaleFactor', 20.17); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Apollo17LemModel'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil); openspace.setPropertyValueSingle('Scene.Moon.Renderable.Layers.ColorLayers.A17_station7.BlendMode', 0.000000);" + +#Time +absolute 1972 DEC 12 19:47:11 + +#Camera +goToGeo "Moon" 20 -60 15000000 + +#MarkNodes +Moon +Apollo11LemModel +Apollo17LemModel +Apollo11 +Apollo11LunarLander diff --git a/data/assets/dawn.profile b/data/assets/dawn.profile new file mode 100644 index 0000000000..533e43d6dc --- /dev/null +++ b/data/assets/dawn.profile @@ -0,0 +1,18 @@ +#Version +1.0 + +#Asset +scene/solarsystem/missions/dawn/ceres required +scene/solarsystem/missions/dawn/dawn required +scene/solarsystem/missions/dawn/vesta required + +#Time +absolute 2011 AUG 06 00:00:00 + +#Camera +setNavigationState "Dawn" 526781518487.171326, 257168309890.072144, -1381125204152.817383 + +#MarkNodes +Dawn +Ceres +Vesta diff --git a/data/assets/default.profile b/data/assets/default.profile new file mode 100644 index 0000000000..b708a2d253 --- /dev/null +++ b/data/assets/default.profile @@ -0,0 +1,17 @@ +#Version +1.0 + +#Asset +scene/solarsystem/planets/earth/earth required + +#Time +relative -1d + +#Camera +goToGeo "Earth" 58.5877 16.1924 20000000 + +#MarkNodes +Earth +Mars +Moon +Sun diff --git a/data/assets/default_full.profile b/data/assets/default_full.profile new file mode 100644 index 0000000000..e6c2522523 --- /dev/null +++ b/data/assets/default_full.profile @@ -0,0 +1,23 @@ +#Version +1.0 + +#Asset +scene/solarsystem/planets/earth/earth required +scene/solarsystem/planets/jupiter/minor_moons required +scene/solarsystem/planets/saturn/minor_moons required +scene/solarsystem/planets/uranus/minor_moons required +scene/solarsystem/planets/neptune/inner_moons required +scene/solarsystem/planets/neptune/irregular_prograde_moons required +scene/solarsystem/planets/neptune/irregular_retrograde_moons required + +#Time +relative -1d + +#Camera +goToGeo "Earth" 58.5877 16.1924 20000000 + +#MarkNodes +Earth +Mars +Moon +Sun diff --git a/data/assets/gaia.profile b/data/assets/gaia.profile new file mode 100644 index 0000000000..82d54557b1 --- /dev/null +++ b/data/assets/gaia.profile @@ -0,0 +1,22 @@ +#Version +1.0 + +#Module +Gaia openspace.printFatal('Could not load scene due to missing module "gaia"') + +#Asset +scene/solarsystem/planets/earth/earth required +scene/milkyway/gaia/gaiastars required +scene/milkyway/gaia/apogee required +scene/milkyway/gaia/galah required +scene/solarsystem/missions/gaia/gaia required +scene/solarsystem/missions/gaia/trail required + +#Property +setPropertyValueSingle Scene.Stars.Renderable.Enabled false + +#Camera +setNavigationState "Earth" 1000000000000.0, 1000000000000.0, 1000000000000.0 + +#MarkNodes +Gaia diff --git a/data/assets/insight.profile b/data/assets/insight.profile new file mode 100644 index 0000000000..0491c3e059 --- /dev/null +++ b/data/assets/insight.profile @@ -0,0 +1,29 @@ +#Version +1.0 + +#Asset +scene/solarsystem/missions/insight/edl required + +#Property +setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false +setPropertyValueSingle Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset -469.300000 +setPropertyValueSingle Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Settings.Offset -470.800006 +setPropertyValueSingle Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Enabled true +setPropertyValueSingle Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Multiplier 2.81690 +setPropertyValueSingle Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Settings.Gamma 0.938970 +setPropertyValueSingle Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Gamma 2.394370 +setPropertyValueSingle Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Enabled true + + +#Keybinding +i Setup Insight landing layers Setup Insight layers /Missions/Insight false "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', -469.300000); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Settings.Offset', -470.800006); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.insight_ctx.Enabled', true); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Enabled', true); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Multiplier', 2.816900); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Settings.Gamma', 0.938970); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Gamma', 2.394370); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Enabled', true);" +SHIFT+i Undo Insight landing layers setup Unset Insight layers /Missions/Insight false "openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.Mola_Utah.Settings.Offset', 0); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Settings.Offset', 0); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.insight_ctx.Enabled', false); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.HeightLayers.OnMarsHiRISELS.Enabled', false); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Enabled', false); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Multiplier', 1.0); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.OnMarsHiRISELS.Settings.Gamma', 1.0); openspace.setPropertyValueSingle('Scene.Mars.Renderable.Layers.ColorLayers.MOC_WA_Color_Utah.Settings.Gamma', 1.0);" + +#Time +absolute 2018 NOV 26 19:39:03.68 + +#Camera +setNavigationState "Insight" "Root" 8.430115E0, -1.791710E1, 2.813660E0 0.494659E0,0.357162E0,0.792306E0 + +#MarkNodes +Insight diff --git a/data/assets/juno.profile b/data/assets/juno.profile new file mode 100644 index 0000000000..d2bb28a316 --- /dev/null +++ b/data/assets/juno.profile @@ -0,0 +1,37 @@ +#Version +1.0 + +#Asset +scene/solarsystem/missions/juno/juno required + +#Keybinding +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" +6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" +7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" +8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" +9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" +0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" +Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" +Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" +Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" +Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" +Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" +Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" +Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" +Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" +Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" +Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" + +#Time +absolute 2016-07-01T10:05:00.00 + +#Camera +setNavigationState "Juno" "Root" 1.243398E8, 7.176068E7, -1.519733E7 -0.377400E0, 0.764573E0, 0.522492E0 + +#MarkNodes +Jupiter +Juno diff --git a/data/assets/messenger.profile b/data/assets/messenger.profile new file mode 100644 index 0000000000..8a508388d9 --- /dev/null +++ b/data/assets/messenger.profile @@ -0,0 +1,41 @@ +#Version +1.0 + +#Module +Volume asset.require('scene/solarsystem/missions/messenger/mercurymagnetosphere') openspace.printWarning("Volume module is not loaded, skipping asset: mercurymagnetosphere") + +#Asset +scene/solarsystem/missions/messenger/messengerSC required + +#Keybinding +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" +6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" +7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" +8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" +9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" +0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" +Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" +Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" +Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" +Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" +Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" +Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" +Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" +Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" +Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" +Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" + +#Time +absolute 2011 MAY 13 00:05:18 + +#Camera +setNavigationState "Mercury" "Root" 2.423690E11, 1.979038E11, -2.241483E10 -0.492046E0, 0.666088E0, 0.560551E0 + +#MarkNodes +Mercury +Messenger +Sun diff --git a/data/assets/newhorizons.profile b/data/assets/newhorizons.profile index 1819abd3f5..ff3a46a096 100644 --- a/data/assets/newhorizons.profile +++ b/data/assets/newhorizons.profile @@ -12,13 +12,13 @@ setPropertyValueSingle Scene.Charon.Renderable.Enabled false setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false #Keybinding -a Sets the focus of the camera on 'NewHorizons'. Focus on New Horizons /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) -SHIFT+a Sets the focus of the camera on 'NewHorizons'. Anchor at New Horizons, Aim at Pluto /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) -s Sets the focus of the camera on 'Pluto' Focus on Pluto /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) -d Sets the focus of the camera on 'Charon'. Focus on New Charon /New Horizons false openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Charon');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil) +a Sets the focus of the camera on 'NewHorizons'. Focus on New Horizons /New Horizons false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +SHIFT+a Sets the focus of the camera on 'NewHorizons'. Anchor at New Horizons, Aim at Pluto /New Horizons false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'NewHorizons');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', 'Pluto');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +s Sets the focus of the camera on 'Pluto' Focus on Pluto /New Horizons false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Pluto') ;openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +d Sets the focus of the camera on 'Charon'. Focus on New Charon /New Horizons false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Charon');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', '');openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" F7 Toggles New Horizons image projection. Toggle NH Image Projection /New Horizons false [[local enabled = openspace.getPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection'); openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.PerformProjection', not enabled); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.PerformProjection', not enabled)]] -F8 Removes all image projections from Pluto and Charon. Clear image projections /New Horizons false openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true) -F9 Jumps to the 14th of July 2015 at 0900 UTC and clears all projections. Reset time and projections /New Horizons false openspace.time.setTime('2015-07-14T09:00:00.00');openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true) +F8 Removes all image projections from Pluto and Charon. Clear image projections /New Horizons false "openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true); openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)" +F9 Jumps to the 14th of July 2015 at 0900 UTC and clears all projections. Reset time and projections /New Horizons false "openspace.time.setTime('2015-07-14T09:00:00.00');openspace.setPropertyValue('Scene.PlutoProjection.Renderable.ProjectionComponent.ClearAllProjections', true);openspace.setPropertyValue('Scene.CharonProjection.Renderable.ProjectionComponent.ClearAllProjections', true)" KP_8 Increases the height map exaggeration on Pluto. Pluto HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) CTRL+I Increases the height map exaggeration on Pluto. Pluto HeightExaggeration + /New Horizons false propertyHelper.increment('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) KP_2 Decreases the height map exaggeration on Pluto. Pluto HeightExaggeration - /New Horizons false propertyHelper.decrement('Scene.PlutoProjection.Renderable.HeightExaggeration', 5000) @@ -33,20 +33,20 @@ l Toggles the visibility of the labels for the New Horizons instruments. Toggle m Draws the instrument field of views in a solid color or as lines. Toggle instrument FOVs /New Horizons false propertyHelper.invert('Scene.NH_LORRI.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_LEISA.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN1.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_PAN2.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_RED.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_BLUE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_FT.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_METHANE.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_RALPH_MVIC_NIR.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_AIRGLOW.Renderable.SolidDraw') .. propertyHelper.invert('Scene.NH_ALICE_SOC.Renderable.SolidDraw') Shift+t Toggles the visibility of the shadow visualization of Pluto and Charon. Toggle Shadows /New Horizons false renderableHelper.toggle('Scene.PlutoShadow') .. renderableHelper.toggle('Scene.CharonShadow') t Toggles the trail of New Horizons. Toggle NH Trail /New Horizons false renderableHelper.toggle('Scene.NewHorizonsTrailPluto') -h Disables visibility of the trails Hide Trails /Rendering false local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end -1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false openspace.time.interpolateDeltaTime(1) -2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false openspace.time.interpolateDeltaTime(5) -3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false openspace.time.interpolateDeltaTime(10) -4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false openspace.time.interpolateDeltaTime(20) -5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false openspace.time.interpolateDeltaTime(40) -6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false openspace.time.interpolateDeltaTime(60) -7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false openspace.time.interpolateDeltaTime(120) -8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false openspace.time.interpolateDeltaTime(360) -9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false openspace.time.interpolateDeltaTime(540) -Shift+1 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false openspace.time.interpolateDeltaTime(1080) -Shift+2 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false openspace.time.interpolateDeltaTime(2160) -Shift+3 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false openspace.time.interpolateDeltaTime(4320) -Shift+4 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false openspace.time.interpolateDeltaTime(8640) +h Disables visibility of the trails Hide Trails /Rendering false "local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end" +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" +6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false "openspace.time.interpolateDeltaTime(60)" +7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false "openspace.time.interpolateDeltaTime(120)" +8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" +9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false "openspace.time.interpolateDeltaTime(540)" +0 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false "openspace.time.interpolateDeltaTime(1080)" +Shift+1 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false "openspace.time.interpolateDeltaTime(2160)" +Shift+2 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false "openspace.time.interpolateDeltaTime(4320)" +Shift+3 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false "openspace.time.interpolateDeltaTime(8640)" #Time absolute 2015-07-14T08:00:00.00 diff --git a/data/assets/osirisrex.profile b/data/assets/osirisrex.profile new file mode 100644 index 0000000000..eec35f2466 --- /dev/null +++ b/data/assets/osirisrex.profile @@ -0,0 +1,45 @@ +#Version +1.0 + +#Asset +scene/solarsystem/missions/osirisrex/model required +scene/solarsystem/missions/osirisrex/osirisrex required + +#Property +setPropertyValueSingle NavigationHandler.OrbitalNavigator.FollowAnchorNodeRotationDistance 20.000000 +setPropertyValueSingle Scene.Pluto.Renderable.Enabled false +setPropertyValueSingle Scene.Charon.Renderable.Enabled false +setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false + +#Keybinding +a Sets the focus of the camera on 'OsirisRex'. Focus on OsirisRex /Missions/Osiris Rex false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'OsirisRex'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +s Sets the focus of the camera on 'Bennu' Focus on Bennu /Missions/Osiris Rex false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'BennuBarycenter'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +F8 Sets the time to the approach at Bennu. Set Bennu approach time /Missions/Osiris Rex false "openspace.printInfo('Set time: Approach'); openspace.time.setTime('2018-SEP-11 21:31:01.183')" +F9 Sets the time to the preliminary survey of Bennu. Set Bennu survey time /Missions/Osiris Rex false "openspace.printInfo('Set time: Preliminary Survey'); openspace.time.setTime('2018-NOV-20 01:13:12.183')" +F10 Sets the time to the orbital B event. Set orbital B event time /Missions/Osiris Rex false "openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186')" +F11 Sets the time to the recon event. Set recon event time /Missions/Osiris Rex false "openspace.printInfo('Set time: Recon'); openspace.time.setTime('2019-MAY-25 03:50:31.195')" +q Toggles the visibility of the text marking the location of the Sun. Toggle Sun marker /Missions/Osiris Rex false propertyHelper.invert('Scene.SunMarker.Renderable.Enabled') +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" +6 Setting the simulation speed to 60 seconds per realtime second Set sim speed 60 /Simulation Speed false "openspace.time.interpolateDeltaTime(60)" +7 Setting the simulation speed to 120 seconds per realtime second Set sim speed 120 /Simulation Speed false "openspace.time.interpolateDeltaTime(120)" +8 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" +9 Setting the simulation speed to 540 seconds per realtime second Set sim speed 540 /Simulation Speed false "openspace.time.interpolateDeltaTime(540)" +0 Setting the simulation speed to 1080 seconds per realtime second Set sim speed 1080 /Simulation Speed false "openspace.time.interpolateDeltaTime(1080)" +Shift+1 Setting the simulation speed to 2160 seconds per realtime second Set sim speed 2160 /Simulation Speed false "openspace.time.interpolateDeltaTime(2160)" +Shift+2 Setting the simulation speed to 4320 seconds per realtime second Set sim speed 4320 /Simulation Speed false "openspace.time.interpolateDeltaTime(4320)" +Shift+3 Setting the simulation speed to 8640 seconds per realtime second Set sim speed 8640 /Simulation Speed false "openspace.time.interpolateDeltaTime(8640)" + +#Time +absolute 2018 10 30 23:00:00.500 + +#Camera +setNavigationState "OsirisRex" 26974590199.661884, 76314608558.908020, -127086452897.101791 + +#MarkNodes +OsirisRex +BennuBarycenter +Earth diff --git a/data/assets/rosetta.profile b/data/assets/rosetta.profile new file mode 100644 index 0000000000..0b0bd37881 --- /dev/null +++ b/data/assets/rosetta.profile @@ -0,0 +1,35 @@ +#Version +1.0 + +#Module +Volume asset.require('scene/solarsystem/missions/messenger/mercurymagnetosphere') openspace.printWarning("Volume module is not loaded, skipping asset: mercurymagnetosphere") + +#Asset +scene/solarsystem/missions/rosetta/67p required +scene/solarsystem/missions/rosetta/rosetta required + +#Property +setPropertyValue Scene.67P.Renderable.PerformShading false +setPropertyValue Scene.ImagePlaneRosetta.Renderable.Enabled false + +#Keybinding +a Sets the focus of the camera on '67P'. Focus on 67P /Missions/Rosetta false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', '67P'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +s Sets the focus of the camera on 'Rosetta' Focus on Rosetta /Missions/Rosetta false "openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Anchor', 'Rosetta'); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.Aim', ''); openspace.setPropertyValue('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil)" +F5 Jumps to the time of initial approach of Rosetta to 67P. Set initial approach time /Missions/Rosetta false "openspace.time.setTime('2014-08-01T03:05:18.101')" +F6 Jumps to the time when the Philae lander is released. Set lander release time /Missions/Rosetta false "openspace.time.setTime('2014-11-12T08:20:00.00')" +F8 Removes all image projections from 67P. Clear 67P projections /Missions/Rosetta false "openspace.setPropertyValue('Scene.67P.Renderable.ProjectionComponent.ClearAllProjections', true)" +e Toggles the visibility of all trails further from the Sun than 67P. Toggle outer planetary trails /Missions/Rosetta false renderableHelper.toggle('Scene.JupiterTrail')..renderableHelper.toggle('Scene.SaturnTrail')..renderableHelper.toggle('Scene.UranusTrail')..renderableHelper.toggle('Scene.NeptuneTrail') +i Toggles the visibility of the free floating image plane. Toggle image plane /Missions/Rosetta false renderableHelper.toggle('Scene.ImagePlaneRosetta') +g Toggles the visibility of Philae's trail. Toggle Philae trail /Missions/Rosetta false renderableHelper.toggle('Scene.PhilaeTrail') +p Enables or disables the image projection on 67P. Toggle 67P projection /Missions/Rosetta false propertyHelper.invert('Scene.67P.Renderable.ProjectionComponent.PerformProjection') + +#Time +absolute 2014-08-01T03:05:00.000 + +#Camera +setNavigationState "67P" "Root" -7.294781E5 , -6.657894E5, 2.509047E6 0.146529E0, 0.944727E0, 0.293290E0 + +#MarkNodes +67P +Rosetta +Philae diff --git a/data/assets/touch.profile b/data/assets/touch.profile new file mode 100644 index 0000000000..237a1c79b5 --- /dev/null +++ b/data/assets/touch.profile @@ -0,0 +1,25 @@ +#Version +1.0 + +#Module +Touch local webGui = asset.require('util/webgui'); webGui.setCefRoute("ontouch") openspace.printFatal('Could not load scene due to missing module "touch"') + +#Asset +scene/solarsystem/planets/earth/earth required +util/webgui required + +#Property +setPropertyValueSingle Scene.Pluto.Renderable.Enabled false +setPropertyValueSingle Scene.Charon.Renderable.Enabled false +setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false + +#Time +relative -1d + +#Camera +setNavigationState "Earth" 58.5877,16.1924,20000000 + +#MarkNodes +Earth +Mars +Moon diff --git a/data/assets/voyager.profile b/data/assets/voyager.profile new file mode 100644 index 0000000000..150344f1e1 --- /dev/null +++ b/data/assets/voyager.profile @@ -0,0 +1,54 @@ +#Version +1.0 + +#Asset +scene/solarsystem/planets/jupiter/minor_moons required +scene/solarsystem/planets/saturn/minor_moons required +scene/solarsystem/planets/uranus/minor_moons required +scene/solarsystem/planets/neptune/inner_moons required +scene/solarsystem/planets/neptune/irregular_prograde_moons required +scene/solarsystem/planets/neptune/irregular_retrograde_moons required +scene/solarsystem/missions/voyager/voyager1 required +scene/solarsystem/missions/voyager/voyager2 required + +#Keybinding +1 Setting the simulation speed to 1 seconds per realtime second Set sim speed 1 /Simulation Speed false "openspace.time.interpolateDeltaTime(1)" +2 Setting the simulation speed to 5 seconds per realtime second Set sim speed 5 /Simulation Speed false "openspace.time.interpolateDeltaTime(5)" +3 Setting the simulation speed to 10 seconds per realtime second Set sim speed 10 /Simulation Speed false "openspace.time.interpolateDeltaTime(10)" +4 Setting the simulation speed to 20 seconds per realtime second Set sim speed 20 /Simulation Speed false "openspace.time.interpolateDeltaTime(20)" +5 Setting the simulation speed to 40 seconds per realtime second Set sim speed 40 /Simulation Speed false "openspace.time.interpolateDeltaTime(40)" +6 Setting the simulation speed to 90 seconds per realtime second Set sim speed 90 /Simulation Speed false "openspace.time.interpolateDeltaTime(90)" +7 Setting the simulation speed to 360 seconds per realtime second Set sim speed 360 /Simulation Speed false "openspace.time.interpolateDeltaTime(360)" +8 Setting the simulation speed to 720 seconds per realtime second Set sim speed 720 /Simulation Speed false "openspace.time.interpolateDeltaTime(720)" +9 Setting the simulation speed to 2880 seconds per realtime second Set sim speed 2880 /Simulation Speed false "openspace.time.interpolateDeltaTime(2880)" +0 Setting the simulation speed to 14400 seconds per realtime second Set sim speed 14400 /Simulation Speed false "openspace.time.interpolateDeltaTime(14400)" +Shift+1 Setting the simulation speed to 28800 seconds per realtime second Set sim speed 28800 /Simulation Speed false "openspace.time.interpolateDeltaTime(28800)" +Shift+2 Setting the simulation speed to 57600 seconds per realtime second Set sim speed 57600 /Simulation Speed false "openspace.time.interpolateDeltaTime(57600)" +Shift+3 Setting the simulation speed to 115200 seconds per realtime second Set sim speed 115200 /Simulation Speed false "openspace.time.interpolateDeltaTime(115200)" +Shift+4 Setting the simulation speed to 230400 seconds per realtime second Set sim speed 230400 /Simulation Speed false "openspace.time.interpolateDeltaTime(230400)" +Shift+5 Setting the simulation speed to 460800 seconds per realtime second Set sim speed 460800 /Simulation Speed false "openspace.time.interpolateDeltaTime(460800)" +Shift+6 Setting the simulation speed to 921600 seconds per realtime second Set sim speed 921600 /Simulation Speed false "openspace.time.interpolateDeltaTime(921600)" +Shift+7 Setting the simulation speed to 1843200 seconds per realtime second Set sim speed 1843200 /Simulation Speed false "openspace.time.interpolateDeltaTime(1843200)" +Shift+8 Setting the simulation speed to 3686400 seconds per realtime second Set sim speed 3686400 /Simulation Speed false "openspace.time.interpolateDeltaTime(3686400)" +Shift+9 Setting the simulation speed to 7372800 seconds per realtime second Set sim speed 7372800 /Simulation Speed false "openspace.time.interpolateDeltaTime(7372800)" +Shift+0 Setting the simulation speed to 14745600 seconds per realtime second Set sim speed 14745600 /Simulation Speed false "openspace.time.interpolateDeltaTime(14745600)" + +#Property +setPropertyValueSingle Scene.Pluto.Renderable.Enabled false +setPropertyValueSingle Scene.Charon.Renderable.Enabled false +setPropertyValueSingle Scene.PlutoBarycenterTrail.Renderable.Enabled false + +#Time +absolute 1977 SEP 10 12:00:00 + +#Camera +setNavigationState "Voyager_1" "Root" 526781518487.171326, 257168309890.072144, -1381125204152.817383 + +#MarkNodes +Earth +Voyager 1 +Voyager 2 +Jupiter +Saturn +Uranus +Neptune diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index 81b122e74c..1b6b90f008 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -340,7 +340,7 @@ function generateAsset(T, fileOut) KeyStr = KeyStr.." Name = \""..j[3].."\",\n" KeyStr = KeyStr.." GuiPath = \""..j[4].."\",\n" KeyStr = KeyStr.." Local = "..j[5]..",\n" - KeyStr = KeyStr.." Command = \""..j[6].."\"\n" + KeyStr = KeyStr.." Command = "..j[6].."\n" KeyStr = KeyStr.." },\n" end KeyStr = KeyStr.."}\n" @@ -354,7 +354,8 @@ function generateAsset(T, fileOut) elseif (j[1] == "absolute") then TimeStr = TimeStr.." openspace.time.setTime(\""..j[2].."\")\n" elseif (j[1] == "relative") then - TimeStr = TimeStr.." openspace.time.setTime(" + TimeStr = TimeStr.." local now = openspace.time.currentWallTime();" + TimeStr = TimeStr.." openspace.time.setTime(" TimeStr = TimeStr.."openspace.time.advancedTime(now, \"" TimeStr = TimeStr..j[2].."\"))\n" end From a33057d8302ce40cb59a9a4aa8881850eaeaeaeb Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Mon, 2 Dec 2019 14:09:15 +0100 Subject: [PATCH 060/214] Feature/integrated touchserver (#1015) * WINDOWS: Touch server integrated into module The touch server functionality has been integrated into the touch module which is enabled by-default when the touch module is used on a windows build. The touch-hook checks for a connected digitizer (pen or touchscreen, but I haven't tested pen) This commit should also fix two potential low-risk race conditions in the tuioear.cpp file. * Added comment regarding which window we use * Added copyright notice on the win32_touch files Also changed from #pragma to #ifndef * Fixes based on review - Added anonymous namespace - Put win32hook in openspace namespace - Fixed indentations and linebreaks - Fixed an issue regarding global state deinitialization --- apps/OpenSpace/main.cpp | 10 ++ include/openspace/engine/windowdelegate.h | 4 + modules/touch/CMakeLists.txt | 2 + modules/touch/include/tuioear.h | 7 +- modules/touch/include/win32_touch.h | 41 ++++++ modules/touch/src/tuioear.cpp | 14 +- modules/touch/src/win32_touch.cpp | 166 ++++++++++++++++++++++ modules/touch/touchmodule.cpp | 13 ++ modules/touch/touchmodule.h | 7 + 9 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 modules/touch/include/win32_touch.h create mode 100644 modules/touch/src/win32_touch.cpp diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 51fa7aa05e..8f119dd707 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -1042,6 +1042,16 @@ void setSgctDelegateFunctions() { sgct::SGCTWindow* w = sgct::Engine::instance()->getWindowPtr(0); w->setHorizFieldOfView(hFovDeg); }; + #ifdef WIN32 + sgctDelegate.getNativeWindowHandle = [](size_t windowIndex) -> void* { + sgct::SGCTWindow* w = sgct::Engine::instance()->getWindowPtr(windowIndex); + if(w) { + HWND hWnd = glfwGetWin32Window(w->getWindowHandle()); + return reinterpret_cast(hWnd); + } + return nullptr; + }; + #endif // WIN32 sgctDelegate.frustumMode = []() { using FM = sgct_core::Frustum::FrustumMode; switch (sgct::Engine::instance()->getCurrentFrustumMode()) { diff --git a/include/openspace/engine/windowdelegate.h b/include/openspace/engine/windowdelegate.h index 324c838b86..70f6f21d3d 100644 --- a/include/openspace/engine/windowdelegate.h +++ b/include/openspace/engine/windowdelegate.h @@ -118,6 +118,10 @@ struct WindowDelegate { double (*getHorizFieldOfView)() = []() { return 0.0; }; void (*setHorizFieldOfView)(float hFovDeg) = [](float) { }; + + void* (*getNativeWindowHandle)(size_t windowIndex) = [](size_t) -> void* { + return nullptr; + }; using GLProcAddress = void(*)(void); diff --git a/modules/touch/CMakeLists.txt b/modules/touch/CMakeLists.txt index 35929a64b4..07190880d5 100644 --- a/modules/touch/CMakeLists.txt +++ b/modules/touch/CMakeLists.txt @@ -29,6 +29,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/tuioear.h ${CMAKE_CURRENT_SOURCE_DIR}/include/touchinteraction.h ${CMAKE_CURRENT_SOURCE_DIR}/include/touchmarker.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/win32_touch.h ) source_group("Header Files" FILES ${HEADER_FILES}) @@ -37,6 +38,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/tuioear.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/touchinteraction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/touchmarker.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/win32_touch.cpp ) source_group("Source Files" FILES ${SOURCE_FILES}) diff --git a/modules/touch/include/tuioear.h b/modules/touch/include/tuioear.h index 3e8625c82e..a05296ba89 100644 --- a/modules/touch/include/tuioear.h +++ b/modules/touch/include/tuioear.h @@ -61,9 +61,7 @@ class TuioEar : public TUIO::TuioListener { public: TuioEar(); ~TuioEar() { - _tuioClient->disconnect(); - delete _tuioClient; - delete _oscReceiver; + _tuioClient.disconnect(); } /** @@ -108,8 +106,7 @@ class TuioEar : public TUIO::TuioListener { TUIO::TuioCursor _tapCo = TUIO::TuioCursor(-1, -1, -1.0f, -1.0f); std::mutex _mx; - TUIO::TuioClient *_tuioClient; - TUIO::OscReceiver *_oscReceiver; + TUIO::TuioClient _tuioClient; std::vector _list; diff --git a/modules/touch/include/win32_touch.h b/modules/touch/include/win32_touch.h new file mode 100644 index 0000000000..21a39fbc03 --- /dev/null +++ b/modules/touch/include/win32_touch.h @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_TOUCH___WIN32_TOUCH___H__ +#define __OPENSPACE_MODULE_TOUCH___WIN32_TOUCH___H__ + +#ifdef WIN32 + +namespace openspace { + +class Win32TouchHook { +public: + Win32TouchHook(void* nativeWindow); + ~Win32TouchHook(); +}; + +} // namespace openspace + +#endif // WIN32 +#endif // __OPENSPACE_MODULE_TOUCH___WIN32_TOUCH___H__ diff --git a/modules/touch/src/tuioear.cpp b/modules/touch/src/tuioear.cpp index 4ba8c7e24b..4a9969f241 100644 --- a/modules/touch/src/tuioear.cpp +++ b/modules/touch/src/tuioear.cpp @@ -115,10 +115,12 @@ void TuioEar::removeTuioBlob(TuioBlob*) { } void TuioEar::refresh(TuioTime) { } // about every 15ms std::vector TuioEar::getInput() { + std::lock_guard lock(_mx); return _list; } bool TuioEar::tap() { + std::lock_guard lock(_mx); if (_tap) { _tap = false; return !_tap; @@ -129,7 +131,7 @@ bool TuioEar::tap() { } TuioCursor TuioEar::getTap() { - std::lock_guard lock(_mx); + std::lock_guard lock(_mx); return _tapCo; } @@ -157,9 +159,9 @@ void TuioEar::clearInput() { } // Standard UDP IP connection to port 3333 -TuioEar::TuioEar() { - _oscReceiver = new UdpReceiver(3333); - _tuioClient = new TuioClient(_oscReceiver); - _tuioClient->addTuioListener(this); - _tuioClient->connect(); +TuioEar::TuioEar() + : _tuioClient(3333) +{ + _tuioClient.addTuioListener(this); + _tuioClient.connect(); } diff --git a/modules/touch/src/win32_touch.cpp b/modules/touch/src/win32_touch.cpp new file mode 100644 index 0000000000..8d248d3a63 --- /dev/null +++ b/modules/touch/src/win32_touch.cpp @@ -0,0 +1,166 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifdef WIN32 + +#include + +#include +#include + +#include + +#include + +#include +#include + +namespace { + constexpr const char* _loggerCat = "win32_touch"; + HHOOK gTouchHook{ nullptr }; + bool gStarted{ false }; + TUIO::TuioServer* gTuioServer{ nullptr }; + std::unordered_map gCursorMap; +} + +namespace openspace { + +// This hook will only work for Win7+ Digitizers. +// - Once GLFW has native touch support, we can remove this windows-specific code +LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) { + if (nCode < 0) { + return CallNextHookEx(0, nCode, wParam, lParam); + } + if (nCode == HC_ACTION) { + LPMSG pStruct = reinterpret_cast(lParam); + const UINT message = pStruct->message; + switch (message) { + case WM_POINTERDOWN: + case WM_POINTERUPDATE: + case WM_POINTERUP: + { + POINTER_INFO pointerInfo = {}; + if (GetPointerInfo(GET_POINTERID_WPARAM(pStruct->wParam), &pointerInfo)) { + RECT rect; + GetClientRect(pStruct->hwnd, reinterpret_cast(&rect)); + + POINT p = pointerInfo.ptPixelLocation; + // native touch to screen conversion + ScreenToClient(pStruct->hwnd, reinterpret_cast(&p)); + + float xPos = (float)p.x / (float)(rect.right - rect.left); + float yPos = (float)p.y / (float)(rect.bottom - rect.top); + if (pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { + // Handle new touchpoint + gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); + gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor(xPos, yPos); + gTuioServer->commitFrame(); + } + else if (pointerInfo.pointerFlags & POINTER_FLAG_UPDATE) { + // Handle update of touchpoint + TUIO::TuioTime frameTime = TUIO::TuioTime::getSessionTime(); + if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime) { + break; + } + gTuioServer->initFrame(frameTime); + gTuioServer->updateTuioCursor(gCursorMap[pointerInfo.pointerId], xPos, yPos); + gTuioServer->commitFrame(); + } + else if (pointerInfo.pointerFlags & POINTER_FLAG_UP) { + // Handle removed touchpoint + gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); + gTuioServer->removeTuioCursor(gCursorMap[pointerInfo.pointerId]); + gTuioServer->commitFrame(); + gCursorMap.erase(pointerInfo.pointerId); + } + } + break; + } + } + } + + // Pass the hook along! + return CallNextHookEx(0, nCode, wParam, lParam); +} + +Win32TouchHook::Win32TouchHook(void* nativeWindow) +{ + HWND hWnd = reinterpret_cast(nativeWindow); + if (hWnd == nullptr) { + LINFO("No windowhandle available for touch input."); + return; + } + + // Test for touch: + int value = GetSystemMetrics(SM_DIGITIZER); + if ((value & NID_READY) == 0) { + // Don't bother setting up touch hooks? + return; + } + // stack ready, drivers installed and digitizer is ready for input + if (value & NID_MULTI_INPUT) { + // Digitizer is multitouch + LINFO("Found Multitouch input digitizer!"); + } + if (value & NID_INTEGRATED_TOUCH) { + // Integrated touch + } + + // This should be needed, but we seem to receive messages even without it, + // probably a Win7+ behaviour + // Also - RegisterTouchWindow enables Windows gestures, which we don't want + // since they produce visual feedback for "press-and-tap" etc. + // RegisterTouchWindow(hWnd, TWF_FINETOUCH | TWF_WANTPALM); + + // TODO: Would be nice to find out if the gesture "press-and-tap" can be disabled + // basically we don't really care for windows gestures for now... + // this disables press and hold (right-click) gesture + const DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD; + + ATOM atom = ::GlobalAddAtom(MICROSOFT_TABLETPENSERVICE_PROPERTY); + ::SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast(dwHwndTabletProperty)); + ::GlobalDeleteAtom(atom); + + if (!gStarted) { + gStarted = true; + gTuioServer = new TUIO::TuioServer("localhost", 3333); + TUIO::TuioTime::initSession(); + gTouchHook = SetWindowsHookExW(WH_GETMESSAGE, HookCallback, GetModuleHandleW(NULL), GetCurrentThreadId()); + if (!gTouchHook) { + LINFO(fmt::format("Failed to setup WindowsHook for touch input redirection")); + delete gTuioServer; + gStarted = false; + } + } +} + +Win32TouchHook::~Win32TouchHook() { + if (gStarted) { + UnhookWindowsHookEx(gTouchHook); + delete gTuioServer; + } +} + +} // namespace openspace +#endif // WIN32 diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index f0e38dd2c6..a47e2fe4d2 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -23,6 +23,7 @@ ****************************************************************************************/ #include +#include #include #include @@ -156,6 +157,14 @@ TouchModule::TouchModule() global::callback::initializeGL.push_back([&]() { LDEBUGC("TouchModule", "Initializing TouchMarker OpenGL"); _markers.initialize(); +#ifdef WIN32 + // We currently only support one window of touch input internally + // so here we grab the first window-handle and use it. + void* nativeWindowHandle = global::windowDelegate.getNativeWindowHandle(0); + if (nativeWindowHandle) { + _win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle)); + } +#endif //WIN32 }); global::callback::deinitializeGL.push_back([&]() { @@ -190,4 +199,8 @@ TouchModule::TouchModule() } +TouchModule::~TouchModule() { + //intentionally left empty +} + } // namespace openspace diff --git a/modules/touch/touchmodule.h b/modules/touch/touchmodule.h index a596944ab2..5300967a36 100644 --- a/modules/touch/touchmodule.h +++ b/modules/touch/touchmodule.h @@ -31,11 +31,15 @@ namespace openspace { + #ifdef WIN32 + class Win32TouchHook; + #endif //WIN32 class TouchModule : public OpenSpaceModule { using Point = std::pair; public: TouchModule(); + ~TouchModule(); private: /** @@ -54,6 +58,9 @@ namespace openspace { // contains an id and the TuioPoint that was processed last frame std::vector _lastProcessed; glm::ivec2 _webPositionCallback = glm::ivec2(0,0); +#ifdef WIN32 + std::unique_ptr _win32TouchHook; +#endif //WIN32 }; } // namespace openspace From 386ce8bec691daf9187706f31d1332de80c1c5fa Mon Sep 17 00:00:00 2001 From: liuloppan Date: Mon, 2 Dec 2019 15:10:11 +0100 Subject: [PATCH 061/214] Feature/nodelines (#1013) * Setup line render between Mars and Earth * Updating property handling * Precision fix * Cleanup and making functions and variables private * Adding linewidth property * Using opacity property for line color * Cleanup from review --- modules/base/CMakeLists.txt | 4 + modules/base/basemodule.cpp | 3 + modules/base/rendering/renderablenodeline.cpp | 305 ++++++++++++++++++ modules/base/rendering/renderablenodeline.h | 86 +++++ modules/base/shaders/line_fs.glsl | 42 +++ modules/base/shaders/line_vs.glsl | 43 +++ 6 files changed, 483 insertions(+) create mode 100644 modules/base/rendering/renderablenodeline.cpp create mode 100644 modules/base/rendering/renderablenodeline.h create mode 100644 modules/base/shaders/line_fs.glsl create mode 100644 modules/base/shaders/line_vs.glsl diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index 2ce1e6846c..29379351a0 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -42,6 +42,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablenodeline.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimagelocal.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimageonline.h @@ -89,6 +90,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableboxgrid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablecartesianaxes.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablemodel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablenodeline.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplane.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimagelocal.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableplaneimageonline.cpp @@ -124,6 +126,8 @@ set(SHADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/shaders/grid_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/imageplane_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/imageplane_vs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/line_fs.glsl + ${CMAKE_CURRENT_SOURCE_DIR}/shaders/line_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/model_fs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/model_vs.glsl ${CMAKE_CURRENT_SOURCE_DIR}/shaders/plane_fs.glsl diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index ba70bd6c2e..3535e48522 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { fRenderable->registerClass("RenderableBoxGrid"); fRenderable->registerClass("RenderableCartesianAxes"); fRenderable->registerClass("RenderableModel"); + fRenderable->registerClass("RenderableNodeLine"); fRenderable->registerClass("RenderablePlaneImageLocal"); fRenderable->registerClass("RenderablePlaneImageOnline"); fRenderable->registerClass("RenderableSphere"); @@ -190,6 +192,7 @@ std::vector BaseModule::documentations() const { RenderableBoxGrid::Documentation(), RenderableModel::Documentation(), + RenderableNodeLine::Documentation(), RenderablePlane::Documentation(), RenderableSphere::Documentation(), RenderableTrailOrbit::Documentation(), diff --git a/modules/base/rendering/renderablenodeline.cpp b/modules/base/rendering/renderablenodeline.cpp new file mode 100644 index 0000000000..56bbdd53a0 --- /dev/null +++ b/modules/base/rendering/renderablenodeline.cpp @@ -0,0 +1,305 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char* ProgramName = "NodeLineProgram"; + constexpr const char* Root = "Root"; + + constexpr openspace::properties::Property::PropertyInfo StartNodeInfo = { + "StartNode", + "Start Node", + "The identifier of the node the line starts from. " + }; + + constexpr openspace::properties::Property::PropertyInfo EndNodeInfo = { + "EndNode", + "End Node", + "The identifier of the node the line ends at. " + }; + + constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { + "Color", + "Color", + "This value determines the RGB color for the line." + }; + + constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = { + "LineWidth", + "Line Width", + "This value specifies the line width." + }; +} // namespace + +namespace openspace { + +documentation::Documentation RenderableNodeLine::Documentation() { + using namespace documentation; + return { + "Renderable Node Line", + "base_renderable_renderablenodeline", + { + { + StartNodeInfo.identifier, + new StringVerifier, + Optional::No, + StartNodeInfo.description + }, + { + EndNodeInfo.identifier, + new StringVerifier, + Optional::No, + EndNodeInfo.description + }, + { + LineColorInfo.identifier, + new DoubleVector3Verifier, + Optional::Yes, + LineColorInfo.description + }, + { + LineWidthInfo.identifier, + new DoubleVerifier, + Optional::Yes, + LineWidthInfo.description + } + } + }; +} + +RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) + : Renderable(dictionary) + , _lineColor(LineColorInfo, glm::vec3(1.f, 1.f, 1.f), glm::vec3(0.f), glm::vec3(1.f)) + , _lineWidth(LineWidthInfo, 2.f, 1.f, 20.f) + , _start(StartNodeInfo, Root) + , _end(EndNodeInfo, Root) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableNodeLine" + ); + + _start = dictionary.value(StartNodeInfo.identifier); + _end = dictionary.value(EndNodeInfo.identifier); + + if (dictionary.hasKey(LineColorInfo.identifier)) { + _lineColor = dictionary.value(LineColorInfo.identifier); + } + if (dictionary.hasKey(LineWidthInfo.identifier)) { + _lineWidth = static_cast(dictionary.value(LineWidthInfo.identifier)); + } + + addProperty(_start); + addProperty(_end); + addProperty(_lineColor); + addProperty(_lineWidth); + addProperty(_opacity); +} + +void RenderableNodeLine::initializeGL() { + _program = BaseModule::ProgramObjectManager.request( + ProgramName, + []() -> std::unique_ptr { + return global::renderEngine.buildRenderProgram( + ProgramName, + absPath("${MODULE_BASE}/shaders/line_vs.glsl"), + absPath("${MODULE_BASE}/shaders/line_fs.glsl") + ); + } + ); + + // Generate + glGenVertexArrays(1, &_vaoId); + glGenBuffers(1, &_vBufferId); + + bindGL(); + + glVertexAttribPointer(_locVertex, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr); + glEnableVertexAttribArray(_locVertex); + + unbindGL(); +} + +void RenderableNodeLine::deinitializeGL() { + + glDeleteVertexArrays(1, &_vaoId); + _vaoId = 0; + + glDeleteBuffers(1, &_vBufferId); + _vBufferId = 0; + + BaseModule::ProgramObjectManager.release( + ProgramName, + [](ghoul::opengl::ProgramObject* p) { + global::renderEngine.removeRenderProgram(p); + } + ); + _program = nullptr; +} + +bool RenderableNodeLine::isReady() const { + bool ready = true; + ready &= (_program != nullptr); + return ready; +} + +void RenderableNodeLine::unbindGL() { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +void RenderableNodeLine::bindGL() +{ + glBindVertexArray(_vaoId); + glBindBuffer(GL_ARRAY_BUFFER, _vBufferId); +} + +void RenderableNodeLine::updateVertexData() +{ + _vertexArray.clear(); + + // Update the positions of the nodes + _startPos = getCoordinatePosFromAnchorNode(global::renderEngine.scene()->sceneGraphNode(_start)->worldPosition()); + _endPos = getCoordinatePosFromAnchorNode(global::renderEngine.scene()->sceneGraphNode(_end)->worldPosition()); + + _vertexArray.push_back(_startPos.x); + _vertexArray.push_back(_startPos.y); + _vertexArray.push_back(_startPos.z); + + _vertexArray.push_back(_endPos.x); + _vertexArray.push_back(_endPos.y); + _vertexArray.push_back(_endPos.z); + + _vertexArray; + + bindGL(); + glBufferData( + GL_ARRAY_BUFFER, + _vertexArray.size() * sizeof(float), + _vertexArray.data(), + GL_DYNAMIC_DRAW + ); + + //update vertex attributes + glVertexAttribPointer(_locVertex, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr); + + unbindGL(); +} + +void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { + + updateVertexData(); + + _program->activate(); + + glm::dmat4 anchorTranslation(1.0); + // Update anchor node information, used to counter precision problems + if (global::navigationHandler.orbitalNavigator().anchorNode()) { + anchorTranslation = glm::translate(glm::dmat4(1.0), global::navigationHandler.orbitalNavigator().anchorNode()->worldPosition()); + } + + const glm::dmat4 modelTransform = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * + modelTransform * anchorTranslation; + + _program->setUniform("modelViewTransform", glm::mat4(modelViewTransform)); + _program->setUniform("projectionTransform", data.camera.projectionMatrix()); + _program->setUniform("color", glm::vec4(_lineColor.value(), _opacity)); + + // Save current state: + GLboolean isBlendEnabled = glIsEnabledi(GL_BLEND, 0); + GLboolean isLineSmoothEnabled = glIsEnabled(GL_LINE_SMOOTH); + GLfloat currentLineWidth; + glGetFloatv(GL_LINE_WIDTH, ¤tLineWidth); + + GLenum blendEquationRGB, blendEquationAlpha, blendDestAlpha, + blendDestRGB, blendSrcAlpha, blendSrcRGB; + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); + + // Change GL state: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnablei(GL_BLEND, 0); + glEnable(GL_LINE_SMOOTH); + glLineWidth(_lineWidth); + + // Bind and draw + bindGL(); + glDrawArrays(GL_LINES, 0, 2); + + // Restore GL State + unbindGL(); + _program->deactivate(); + glLineWidth(currentLineWidth); + glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); + if (!isBlendEnabled) { + glDisablei(GL_BLEND, 0); + } + if (!isLineSmoothEnabled) { + glDisable(GL_LINE_SMOOTH); + } +} + + +/* Returns a position that is relative to the current + anchor node. This is a method to handle precision + problems that occur when approaching a line end point */ +glm::dvec3 RenderableNodeLine::getCoordinatePosFromAnchorNode(glm::dvec3 worldPos) { + + glm::dvec3 anchorNodePos(0); + + if (global::navigationHandler.orbitalNavigator().anchorNode()) { + anchorNodePos = global::navigationHandler.orbitalNavigator().anchorNode()->worldPosition(); + } + glm::dvec3 diffPos = glm::dvec3(worldPos.x - anchorNodePos.x, worldPos.y - anchorNodePos.y, + worldPos.z - anchorNodePos.z); + + return diffPos; +} + + +} // namespace openspace diff --git a/modules/base/rendering/renderablenodeline.h b/modules/base/rendering/renderablenodeline.h new file mode 100644 index 0000000000..d8866def1b --- /dev/null +++ b/modules/base/rendering/renderablenodeline.h @@ -0,0 +1,86 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___RENDERABLENODELINE___H__ +#define __OPENSPACE_MODULE_BASE___RENDERABLENODELINE___H__ + +#include + +#include +#include +#include +#include +#include + +namespace ghoul::opengl { class ProgramObject; } + +namespace openspace { + +namespace documentation { struct Documentation; } + +class Translation; + +/** + * This is a class for a line that is drawn between two nodes in OpenSpace. + */ +class RenderableNodeLine : public Renderable { +public: + RenderableNodeLine(const ghoul::Dictionary& dictionary); + ~RenderableNodeLine() = default; + + static documentation::Documentation Documentation(); + +private: + void initializeGL() override; + void deinitializeGL() override; + + bool isReady() const override; + void updateVertexData(); + void render(const RenderData& data, RendererTasks& rendererTask) override; + + void unbindGL(); + void bindGL(); + + glm::dvec3 getCoordinatePosFromAnchorNode(glm::dvec3 worldPos); + + ghoul::opengl::ProgramObject* _program; + /// The vertex attribute location for position + /// must correlate to layout location in vertex shader + const GLuint _locVertex = 0; + GLuint _vaoId = 0; + GLuint _vBufferId = 0; + std::vector _vertexArray; + + glm::dvec3 _startPos; + glm::dvec3 _endPos; + + properties::StringProperty _start; + properties::StringProperty _end; + properties::Vec3Property _lineColor; + properties::FloatProperty _lineWidth; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___RENDERABLENODELINE___H__ diff --git a/modules/base/shaders/line_fs.glsl b/modules/base/shaders/line_fs.glsl new file mode 100644 index 0000000000..9479a98897 --- /dev/null +++ b/modules/base/shaders/line_fs.glsl @@ -0,0 +1,42 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include "fragment.glsl" +#include "floatoperations.glsl" + +in float vs_depth; +in vec4 vs_positionViewSpace; + +uniform vec4 color; + +Fragment getFragment() { + Fragment frag; + + frag.color = color; + + frag.depth = vs_depth; + frag.gPosition = vs_positionViewSpace; + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + return frag; +} diff --git a/modules/base/shaders/line_vs.glsl b/modules/base/shaders/line_vs.glsl new file mode 100644 index 0000000000..2e68d502c6 --- /dev/null +++ b/modules/base/shaders/line_vs.glsl @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout(location = 0) in vec3 in_position; + +out float vs_depth; +out vec4 vs_positionViewSpace; + +uniform mat4 modelViewTransform; +uniform mat4 projectionTransform; + +void main() { + vs_positionViewSpace = vec4(modelViewTransform * dvec4(in_position, 1)); + vec4 positionScreenSpace = projectionTransform * vs_positionViewSpace; + vs_depth = positionScreenSpace.w; + gl_Position = positionScreenSpace; + + // Set z to 0 to disable near and far plane, unique handling for perspective in space + gl_Position.z = 0.f; +} From ede1a9dd42522070abe2bf9f0dd355e158898974 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 4 Dec 2019 09:48:35 +0100 Subject: [PATCH 062/214] Use a StaticTranslation to position the Milky Way (#1007) --- .../scene/milkyway/milkyway/volume.asset | 19 +++++++++++++++---- modules/galaxy/shaders/points_vs.glsl | 2 -- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 0d1537d45e..f4ad4a9385 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -10,15 +10,25 @@ local data = asset.syncedResource({ Version = 1 }) +local kiloparsec = 3.086E19 + local MilkyWayVolumeGalaxy = { - Identifier = "Milky Way Volume", + Identifier = "MilkyWayVolume", Parent = transforms.SolarSystemBarycenter.Identifier, + Transform = { + Translation = { + Type = "StaticTranslation", + -- The center of the Milky Way is approximately 8 kiloparsec from the Sun. + -- The x-axis of galactic coordinates points from the sun towards the center + -- of the galaxy. + Position = {8 * kiloparsec, 0, 0} + } + }, Renderable = { Type = "RenderableGalaxy", StepSize = 0.01, AbsorptionMultiply = 200, EmissionMultiply = 250, - Translation = {0.2, 0, 0}, Rotation = {3.1415926, 3.1248, 4.45741}, Volume = { Type = "Volume", @@ -34,9 +44,10 @@ local MilkyWayVolumeGalaxy = { } }, GUI = { - Path = "/Milky Way" + Path = "/Milky Way", + Name = "Milky Way Volume" } } local objects = { MilkyWayVolumeGalaxy } -assetHelper.registerSceneGraphNodesAndExport(asset, objects) \ No newline at end of file +assetHelper.registerSceneGraphNodesAndExport(asset, objects) diff --git a/modules/galaxy/shaders/points_vs.glsl b/modules/galaxy/shaders/points_vs.glsl index ecfd7b3d15..456d12923b 100644 --- a/modules/galaxy/shaders/points_vs.glsl +++ b/modules/galaxy/shaders/points_vs.glsl @@ -50,8 +50,6 @@ void main() { dpos.xyz *= 8.0; dpos = modelMatrix * dpos; dpos /= PARSEC; - //It lies about 8 kpc from the center on what is known as the Orion Arm of the Milky Way - dpos.x += 8000; vec4 positionScreenSpace = z_normalization(vec4(cameraViewProjectionMatrix * dpos)); vs_color = in_color; From a66e872e4e774be3f1e4593ad8c928a149a48dba Mon Sep 17 00:00:00 2001 From: Stefan Seibert Date: Wed, 4 Dec 2019 10:01:35 +0100 Subject: [PATCH 063/214] Improvements in Performance due to adopted usage of CEF Message Loop (#1017) * Changing the way how we pump the CEF update loop to improve performance * Updated Intervall description --- modules/webbrowser/src/webbrowserapp.cpp | 5 +++-- modules/webbrowser/webbrowsermodule.cpp | 20 +++++++------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/modules/webbrowser/src/webbrowserapp.cpp b/modules/webbrowser/src/webbrowserapp.cpp index dc49bd8fa9..f5f1aa05ac 100644 --- a/modules/webbrowser/src/webbrowserapp.cpp +++ b/modules/webbrowser/src/webbrowserapp.cpp @@ -43,8 +43,9 @@ void WebBrowserApp::OnContextCreated(CefRefPtr, CefRefPtr, void WebBrowserApp::OnBeforeCommandLineProcessing(const CefString&, CefRefPtr commandLine) { -// command_line->AppendSwitch("disable-gpu"); -// command_line->AppendSwitch("disable-gpu-compositing"); + commandLine->AppendSwitch("disable-gpu"); + commandLine->AppendSwitch("disable-gpu-compositing"); + commandLine->AppendSwitch("enable-begin-frame-scheduling"); commandLine->AppendSwitchWithValue("autoplay-policy", "no-user-gesture-required"); } diff --git a/modules/webbrowser/webbrowsermodule.cpp b/modules/webbrowser/webbrowsermodule.cpp index bf11e5eb34..eb86fe070b 100644 --- a/modules/webbrowser/webbrowsermodule.cpp +++ b/modules/webbrowser/webbrowsermodule.cpp @@ -142,16 +142,6 @@ void WebBrowserModule::internalInitialize(const ghoul::Dictionary& dictionary) { _cefHost = std::make_unique(_webHelperLocation); LDEBUG("Starting CEF... done!"); - global::callback::preSync.emplace_back([this]() { - if (_cefHost && !_browsers.empty()) { - _cefHost->doMessageLoopWork(); - - const std::chrono::time_point timeAfter = - std::chrono::high_resolution_clock::now(); - webbrowser::latestCall = timeAfter; - } - }); - if (dictionary.hasValue(UpdateBrowserBetweenRenderablesInfo.identifier)) { _updateBrowserBetweenRenderables = dictionary.value(UpdateBrowserBetweenRenderablesInfo.identifier); @@ -218,14 +208,18 @@ bool WebBrowserModule::isEnabled() const { return _enabled; } -namespace webbrowser { - /** * Logic for the webbrowser performance hotfix, * described in more detail in globalscallbacks.h. */ +namespace webbrowser { -std::chrono::microseconds interval = std::chrono::microseconds(1); + /** +* The time interval to describe how often the CEF message loop needs to +* be pumped to work properly. A value of 10000 us updates CEF a 100 times +* per second which is enough for fluid interaction without wasting resources +*/ +std::chrono::microseconds interval = std::chrono::microseconds(10000); std::chrono::time_point latestCall; CefHost* cefHost = nullptr; From b41edb9c02c799025693b30bc7ff8ec38d789b43 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sun, 8 Dec 2019 14:50:19 -0500 Subject: [PATCH 064/214] Added more control over shadow generation. Added documentation. Merged Master. --- .../globebrowsing/shaders/renderer_fs.glsl | 35 +++++++------ modules/globebrowsing/shaders/rings_fs.glsl | 33 ++++++------ modules/globebrowsing/src/renderableglobe.cpp | 28 +++++++++- modules/globebrowsing/src/renderableglobe.h | 20 +++++--- modules/globebrowsing/src/ringscomponent.cpp | 51 ++++++++++++++++++- modules/globebrowsing/src/ringscomponent.h | 5 +- modules/globebrowsing/src/shadowcomponent.cpp | 12 ++++- 7 files changed, 137 insertions(+), 47 deletions(-) diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index e3281fcedd..082f8630aa 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -62,6 +62,8 @@ uniform float orenNayarRoughness; #if SHADOW_MAPPING_ENABLED in vec4 shadowCoords; uniform sampler2DShadow shadowMapTexture; +uniform int nShadowSamples; +uniform float zFightingPercentage; #endif #if USE_ECLIPSE_SHADOWS @@ -267,26 +269,23 @@ Fragment getFragment() { float shadow = 1.0; if ( shadowCoords.w > 1 ) { vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w); - normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; - normalizedShadowCoords.w = 1.0; + normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; - //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); - - float sum = 0; - int fStep = 5; - for (int i = 0; i < fStep; ++i) { - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, -fStep + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep + i, fStep - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, -fStep + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep - i, fStep - i)); + float sum = 0; + for (int i = 0; i < nShadowSamples; ++i) { + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); } - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0)); - shadow = sum / (8.f * fStep + 1.f); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + shadow = sum / (8.f * nShadowSamples + 1.f); } frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow; #endif diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index d1be63cef7..c31eef3ff4 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -37,6 +37,8 @@ uniform float transparency; uniform bool hasSunPosition; uniform vec3 sunPosition; uniform float _nightFactor; +uniform int nShadowSamples; +uniform float zFightingPercentage; // temp in vec4 fragPosInLightSpace; @@ -73,24 +75,23 @@ Fragment getFragment() { float shadow = 1.0; if ( shadowCoords.z >= 0 ) { vec4 normalizedShadowCoords = shadowCoords; - normalizedShadowCoords.z = normalizeFloat(normalizedShadowCoords.w - 0.005 * normalizedShadowCoords.w); - normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; - normalizedShadowCoords.w = 1.0; - - //shadow = textureProj(shadowMapTexture, normalizedShadowCoords); + normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); + normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; + normalizedShadowCoords.w = 1.0; float sum = 0; - int fStep = 2; - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, -fStep)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-fStep, fStep)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, -fStep)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0, fStep)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, -fStep)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( fStep, fStep)); - shadow = sum / 9.f; + for (int i = 0; i < nShadowSamples; ++i) { + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); + } + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + shadow = sum / (8.f * nShadowSamples + 1.f); } // The normal for the one plane depends on whether we are dealing diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 191b351738..56477c915e 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -190,6 +190,20 @@ namespace { "Enables shadow mapping algorithm. Used by renderable rings too." }; + constexpr openspace::properties::Property::PropertyInfo ZFightingPercentageInfo = { + "ZFightingPercentage", + "Z-Fighting Percentage", + "The percentage of the correct distance to the surface being shadowed. " + "Possible values: [0.0, 1.0]" + }; + + constexpr openspace::properties::Property::PropertyInfo NumberShadowSamplesInfo = { + "NumberShadowSamples", + "Number of Shadow Samples", + "The number of samples used during shadow mapping calculation " + "(Percentage Closer Filtering)." + }; + constexpr openspace::properties::Property::PropertyInfo TargetLodScaleFactorInfo = { "TargetLodScaleFactor", "Target Level of Detail Scale Factor", @@ -502,12 +516,15 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) BoolProperty(EclipseInfo, false), BoolProperty(EclipseHardShadowsInfo, false), BoolProperty(ShadowMappingInfo, false), + FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f), + IntProperty(NumberShadowSamplesInfo, 5, 1, 20), FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f), FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f), IntProperty(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3) }) + , _shadowMappingPropertyOwner({ "Shadow Mapping" }) , _debugPropertyOwner({ "Debug" }) , _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments) , _leftRoot(Chunk(LeftHemisphereIndex)) @@ -544,7 +561,12 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) addProperty(_generalProperties.useAccurateNormals); addProperty(_generalProperties.eclipseShadowsEnabled); addProperty(_generalProperties.eclipseHardShadows); - addProperty(_generalProperties.shadowMapping); + + _shadowMappingPropertyOwner.addProperty(_generalProperties.shadowMapping); + _shadowMappingPropertyOwner.addProperty(_generalProperties.zFightingPercentage); + _shadowMappingPropertyOwner.addProperty(_generalProperties.nShadowSamples); + addPropertySubOwner(_shadowMappingPropertyOwner); + _generalProperties.targetLodScaleFactor.onChange([this]() { float sf = _generalProperties.targetLodScaleFactor; _generalProperties.currentLodScaleFactor = sf; @@ -1296,6 +1318,8 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); program.setUniform("shadowMapTexture", shadowMapUnit); + program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); + program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage); } glEnable(GL_DEPTH_TEST); @@ -1420,6 +1444,8 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); program.setUniform("shadowMapTexture", shadowMapUnit); + program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); + program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage); } glEnable(GL_DEPTH_TEST); diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index 60ee41413a..d21445e1f9 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -129,25 +129,29 @@ private: properties::BoolProperty showHeightIntensities; properties::BoolProperty levelByProjectedAreaElseDistance; properties::BoolProperty resetTileProviders; - properties::IntProperty modelSpaceRenderingCutoffLevel; - properties::IntProperty dynamicLodIterationCount; + properties::IntProperty modelSpaceRenderingCutoffLevel; + properties::IntProperty dynamicLodIterationCount; } _debugProperties; struct { - properties::BoolProperty performShading; - properties::BoolProperty useAccurateNormals; - properties::BoolProperty eclipseShadowsEnabled; - properties::BoolProperty eclipseHardShadows; - properties::BoolProperty shadowMapping; + properties::BoolProperty performShading; + properties::BoolProperty useAccurateNormals; + properties::BoolProperty eclipseShadowsEnabled; + properties::BoolProperty eclipseHardShadows; + properties::BoolProperty shadowMapping; + properties::FloatProperty zFightingPercentage; + properties::IntProperty nShadowSamples; properties::FloatProperty targetLodScaleFactor; properties::FloatProperty currentLodScaleFactor; properties::FloatProperty cameraMinHeight; properties::FloatProperty orenNayarRoughness; - properties::IntProperty nActiveLayers; + properties::IntProperty nActiveLayers; } _generalProperties; properties::PropertyOwner _debugPropertyOwner; + properties::PropertyOwner _shadowMappingPropertyOwner; + /** * Test if a specific chunk can safely be culled without affecting the rendered * image. diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 699201e654..c9f20cdb41 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -56,9 +56,10 @@ #include namespace { - constexpr const std::array UniformNames = { + constexpr const std::array UniformNames = { "modelViewProjectionMatrix", "textureOffset", "transparency", "_nightFactor", - "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture" + "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture", + "nShadowSamples", "zFightingPercentage" }; constexpr const std::array GeomUniformNames = { @@ -101,6 +102,20 @@ namespace { "This value determines the transparency of part of the rings depending on the " "color values. For this value v, the transparency is equal to length(color) / v." }; + + constexpr openspace::properties::Property::PropertyInfo ZFightingPercentageInfo = { + "ZFightingPercentage", + "Z-Fighting Percentage", + "The percentage of the correct distance to the surface being shadowed. " + "Possible values: [0.0, 1.0]" + }; + + constexpr openspace::properties::Property::PropertyInfo NumberShadowSamplesInfo = { + "NumberShadowSamples", + "Number of Shadow Samples", + "The number of samples used during shadow mapping calculation " + "(Percentage Closer Filtering)." + }; } // namespace namespace openspace { @@ -140,6 +155,18 @@ namespace openspace { new DoubleVerifier, Optional::Yes, TransparencyInfo.description + }, + { + ZFightingPercentageInfo.identifier, + new DoubleVerifier, + Optional::Yes, + ZFightingPercentageInfo.description + }, + { + NumberShadowSamplesInfo.identifier, + new IntVerifier, + Optional::Yes, + NumberShadowSamplesInfo.description } } }; @@ -153,6 +180,8 @@ namespace openspace { , _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f) , _transparency(TransparencyInfo, 0.15f, 0.f, 1.f) , _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true) + , _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f) + , _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 20) , _ringsDictionary(dictionary) { using ghoul::filesystem::File; @@ -204,6 +233,22 @@ namespace openspace { _ringsDictionary.value(TransparencyInfo.identifier) ); } + + // Shadow Mapping Quality Controls + if (_ringsDictionary.hasKey(ZFightingPercentageInfo.identifier)) { + _zFightingPercentage = _ringsDictionary.value( + ZFightingPercentageInfo.identifier + ); + } + addProperty(_zFightingPercentage); + + if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) { + _nShadowSamples = _ringsDictionary.value( + NumberShadowSamplesInfo.identifier + ); + } + addProperty(_nShadowSamples); + addProperty(_transparency); } @@ -287,6 +332,8 @@ namespace openspace { _shader->setUniform(_uniformCache.transparency, _transparency); _shader->setUniform(_uniformCache.nightFactor, _nightFactor); _shader->setUniform(_uniformCache.sunPosition, _sunPosition); + _shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); + _shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage); ringTextureUnit.activate(); _texture->bind(); diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index 0b4d796bf9..4804af9ae3 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -92,11 +92,14 @@ namespace openspace { properties::FloatProperty _nightFactor; properties::FloatProperty _transparency; properties::BoolProperty _enabled; + properties::FloatProperty _zFightingPercentage; + properties::IntProperty _nShadowSamples; std::unique_ptr _shader; std::unique_ptr _geometryOnlyShader; UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, - sunPosition, ringTexture, shadowMatrix, shadowMapTexture + sunPosition, ringTexture, shadowMatrix, shadowMapTexture, + nShadowSamples, zFightingPercentage ) _uniformCache; UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture) _geomUniformCache; diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index f857588011..da2d166bd6 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -163,13 +163,19 @@ namespace openspace { new DoubleVerifier, Optional::Yes, DistanceFractionInfo.description + }, + { + DepthMapSizeInfo.identifier, + new Vector2ListVerifier, + Optional::Yes, + DepthMapSizeInfo.description } } }; } ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) - : properties::PropertyOwner({ "Shadows" }) + : properties::PropertyOwner({ "Shadows Component" }) , _saveDepthTexture(SaveDepthTextureInfo) , _distanceFraction(DistanceFractionInfo, 20, 1, 10000) , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) @@ -222,6 +228,10 @@ namespace openspace { _dynamicDepthTextureRes = true; } + _saveDepthTexture.onChange([&]() { + _executeDepthTextureSave = true; + }); + _viewDepthMap = false; addProperty(_enabled); From 6432f484c4d8ca0fe3eb641fa76f3b2260d969ce Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sun, 8 Dec 2019 18:44:08 -0500 Subject: [PATCH 065/214] Changed to accpet text label updating. Added super-fine controls for fading effects. --- .../solarsystem/planets/earth/earth.asset | 7 + modules/base/rendering/renderablelabels.cpp | 321 +++++++++++++++--- modules/base/rendering/renderablelabels.h | 54 ++- 3 files changed, 328 insertions(+), 54 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index cb14706431..1b735b3e66 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -312,6 +312,13 @@ local EarthLabel = { LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", + EnableFading = true, + FadeStartUnit = "au", + FadeStartDistance = 1.5, + FadeStartSpeed = 1.0, + FadeEndUnit = "au", + FadeEndDistance = 15.0, + FadeEndSpeed = 25.0, TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 1e71a91ed4..38a3449127 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -49,6 +49,15 @@ namespace { constexpr const char* _loggerCat = "base::RenderableLabels"; + constexpr const char* MeterUnit = "m"; + constexpr const char* KilometerUnit = "Km"; + constexpr const char* AstronomicalUnit = "au"; + constexpr const char* ParsecUnit = "pc"; + constexpr const char* KiloparsecUnit = "Kpc"; + constexpr const char* MegaparsecUnit = "Mpc"; + constexpr const char* GigaparsecUnit = "Gpc"; + constexpr const char* GigalightyearUnit = "Gly"; + enum BlendMode { BlendModeNormal = 0, BlendModeAdditive @@ -57,6 +66,8 @@ namespace { constexpr const int ViewDirection = 0; constexpr const int NormalDirection = 1; + constexpr double PARSEC = 0.308567756E17; + constexpr openspace::properties::Property::PropertyInfo BlendModeInfo = { "BlendMode", "Blending Mode", @@ -113,18 +124,10 @@ namespace { "Label orientation rendering mode." }; - constexpr openspace::properties::Property::PropertyInfo FadeInDistancesInfo = { - "FadeInDistances", - "Fade-In Start and End Distances", - "These values determine the initial and final distances from the center of " - "our galaxy from which the astronomical object will start and end " - "fading-in." - }; - - constexpr openspace::properties::Property::PropertyInfo DisableFadeInInfo = { - "DisableFadeIn", - "Disable Fade-in effect", - "Enables/Disables the Fade-in effect." + constexpr openspace::properties::Property::PropertyInfo EnableFadingEffectInfo = { + "EnableFading", + "Enable/Disable Fade-in effect", + "Enable/Disable the Fade-in effect." }; constexpr openspace::properties::Property::PropertyInfo PixelSizeControlInfo = { @@ -132,6 +135,42 @@ namespace { "Enable pixel size control.", "Enable pixel size control for rectangular projections." }; + + constexpr openspace::properties::Property::PropertyInfo FadeStartUnitOptionInfo = { + "FadeStartUnit", + "Fade-In/-Out Start Unit.", + "Unit for fade-in/-out starting position calculation." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeEndUnitOptionInfo = { + "FadeEndUnit", + "Fade-In/-Out End Unit.", + "Unit for fade-in/-out ending position calculation." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeStartDistInfo = { + "FadeStartDistance", + "Fade-In/-Out starting distance.", + "Fade-In/-Out starting distance." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeEndDistInfo = { + "FadeEndDistance", + "Fade-In/-Out ending distance.", + "Fade-In/-Out ending distance." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeStartSpeedInfo = { + "FadeStartSpeed", + "Fade-In/-Out starting speed.", + "Fade-In/-Out starting speed." + }; + + constexpr openspace::properties::Property::PropertyInfo FadeEndSpeedInfo = { + "FadeEndSpeed", + "Fade-In/-Out ending speed.", + "Fade-In/-Out ending speed." + }; } // namespace namespace openspace { @@ -166,14 +205,15 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) , _labelMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) , _labelMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f) , _pixelSizeControl(PixelSizeControlInfo, false) - , _fadeInDistance( - FadeInDistancesInfo, - glm::vec2(0.f), - glm::vec2(0.f), - glm::vec2(100.f) - ) - , _disableFadeInDistance(DisableFadeInInfo, true) + , _enableFadingEffect(EnableFadingEffectInfo, false) + , _labelText(LabelTextInfo) + , _fadeStartDistance(FadeStartDistInfo, 1.f, 0.f, 100.f) + , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f) + , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f) + , _fadeEndSpeed(FadeEndSpeedInfo, 1.f, 1.f, 100.f) , _labelOrientationOption(LabelOrientationOptionInfo, properties::OptionProperty::DisplayType::Dropdown) + , _fadeStartUnitOption(FadeStartUnitOptionInfo, properties::OptionProperty::DisplayType::Dropdown) + , _fadeEndUnitOption(FadeEndUnitOptionInfo, properties::OptionProperty::DisplayType::Dropdown) { documentation::testSpecificationAndThrow( Documentation(), @@ -230,6 +270,7 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) if (dictionary.hasKey(LabelTextInfo.identifier)) { _labelText = dictionary.value(LabelTextInfo.identifier); } + addProperty(_labelText); addProperty(_labelOrientationOption); @@ -273,19 +314,135 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) ); } - if (dictionary.hasKey(FadeInDistancesInfo.identifier)) { - glm::vec2 v = dictionary.value(FadeInDistancesInfo.identifier); - _fadeInDistance = v; - _disableFadeInDistance = false; - addProperty(_fadeInDistance); - addProperty(_disableFadeInDistance); - } - if (dictionary.hasKey(PixelSizeControlInfo.identifier)) { _pixelSizeControl = dictionary.value(PixelSizeControlInfo.identifier); addProperty(_pixelSizeControl); } + if (dictionary.hasKey(EnableFadingEffectInfo.identifier)) { + _enableFadingEffect = dictionary.value(EnableFadingEffectInfo.identifier); + } + addProperty(_enableFadingEffect); + + if (dictionary.hasKey(FadeStartDistInfo.identifier)) { + _fadeStartDistance = dictionary.value(FadeStartDistInfo.identifier); + } + + addProperty(_fadeStartDistance); + + _fadeStartUnitOption.addOption(Meter, MeterUnit); + _fadeStartUnitOption.addOption(Kilometer, KilometerUnit); + _fadeStartUnitOption.addOption(AU, AstronomicalUnit); + _fadeStartUnitOption.addOption(Parsec, ParsecUnit); + _fadeStartUnitOption.addOption(Kiloparsec, KiloparsecUnit); + _fadeStartUnitOption.addOption(Megaparsec, MegaparsecUnit); + _fadeStartUnitOption.addOption(Gigaparsec, GigaparsecUnit); + _fadeStartUnitOption.addOption(GigalightYears, GigalightyearUnit); + + _fadeStartUnitOption = AU; + + if (dictionary.hasKey(FadeStartUnitOptionInfo.identifier)) { + std::string unit = dictionary.value(FadeStartUnitOptionInfo.identifier); + if (unit == MeterUnit) { + _fadeStartUnitOption = Meter; + } + else if (unit == KilometerUnit) { + _fadeStartUnitOption = Kilometer; + } + else if (unit == AstronomicalUnit) { + _fadeStartUnitOption = AU; + } + else if (unit == ParsecUnit) { + _fadeStartUnitOption = Parsec; + } + else if (unit == KiloparsecUnit) { + _fadeStartUnitOption = Kiloparsec; + } + else if (unit == MegaparsecUnit) { + _fadeStartUnitOption = Megaparsec; + } + else if (unit == GigaparsecUnit) { + _fadeStartUnitOption = Gigaparsec; + } + else if (unit == GigalightyearUnit) { + _fadeStartUnitOption = GigalightYears; + } + else { + LWARNING( + "No unit given for RenderableLabels. Using kilometer as units." + ); + _fadeStartUnitOption = Kilometer; + } + } + + addProperty(_fadeStartUnitOption); + + if (dictionary.hasKey(FadeStartSpeedInfo.identifier)) { + _fadeStartSpeed = dictionary.value(FadeStartSpeedInfo.identifier); + } + + addProperty(_fadeStartSpeed); + + if (dictionary.hasKey(FadeEndDistInfo.identifier)) { + _fadeEndDistance = dictionary.value(FadeEndDistInfo.identifier); + } + + addProperty(_fadeEndDistance); + + _fadeEndUnitOption.addOption(Meter, MeterUnit); + _fadeEndUnitOption.addOption(Kilometer, KilometerUnit); + _fadeEndUnitOption.addOption(AU, AstronomicalUnit); + _fadeEndUnitOption.addOption(Parsec, ParsecUnit); + _fadeEndUnitOption.addOption(Kiloparsec, KiloparsecUnit); + _fadeEndUnitOption.addOption(Megaparsec, MegaparsecUnit); + _fadeEndUnitOption.addOption(Gigaparsec, GigaparsecUnit); + _fadeEndUnitOption.addOption(GigalightYears, GigalightyearUnit); + + _fadeEndUnitOption = AU; + + if (dictionary.hasKey(FadeEndUnitOptionInfo.identifier)) { + std::string unit = dictionary.value(FadeEndUnitOptionInfo.identifier); + if (unit == MeterUnit) { + _fadeEndUnitOption = Meter; + } + else if (unit == KilometerUnit) { + _fadeEndUnitOption = Kilometer; + } + else if (unit == AstronomicalUnit) { + _fadeEndUnitOption = AU; + } + else if (unit == ParsecUnit) { + _fadeEndUnitOption = Parsec; + } + else if (unit == KiloparsecUnit) { + _fadeEndUnitOption = Kiloparsec; + } + else if (unit == MegaparsecUnit) { + _fadeEndUnitOption = Megaparsec; + } + else if (unit == GigaparsecUnit) { + _fadeEndUnitOption = Gigaparsec; + } + else if (unit == GigalightyearUnit) { + _fadeEndUnitOption = GigalightYears; + } + else { + LWARNING( + "No unit given for RenderableLabels. Using kilometer as units." + ); + _fadeEndUnitOption = Kilometer; + } + } + + addProperty(_fadeEndUnitOption); + + if (dictionary.hasKey(FadeEndSpeedInfo.identifier)) { + _fadeEndSpeed = dictionary.value(FadeEndSpeedInfo.identifier); + } + + addProperty(_fadeEndSpeed); + + //setBoundingSphere(_size); } @@ -326,24 +483,20 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { //} float fadeInVariable = 1.f; - if (!_disableFadeInDistance) { - float distCamera = static_cast(glm::length(data.camera.positionVec3())); - const glm::vec2 fadeRange = _fadeInDistance; - const float a = 1.f / ((fadeRange.y - fadeRange.x)); - const float b = -(fadeRange.x / (fadeRange.y - fadeRange.x)); - const float funcValue = a * distCamera + b; - fadeInVariable *= funcValue > 1.f ? 1.f : funcValue; - - if (funcValue < 0.01f) { - return; - } + + if (_enableFadingEffect) { + float distanceNodeToCamera = glm::distance( + data.camera.positionVec3(), + data.modelTransform.translation + ); + float sUnit = getUnit(_fadeStartUnitOption); + float eUnit = getUnit(_fadeEndUnitOption); + float startX = _fadeStartDistance * sUnit; + float endX = _fadeEndDistance * eUnit; + //fadeInVariable = changedPerlinSmoothStepFunc(distanceNodeToCamera, startX, endX); + fadeInVariable = linearSmoothStepFunc(distanceNodeToCamera, startX, endX, sUnit, eUnit); } - //glm::dmat4 modelMatrix = - // glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation - // glm::dmat4(data.modelTransform.rotation) * // Spice rotation - // glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); - glm::dmat4 modelMatrix(1.0); glm::dmat4 modelViewMatrix = data.camera.combinedViewMatrix() * modelMatrix; glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); @@ -374,7 +527,10 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { } void RenderableLabels::update(const UpdateData&) { - // JCC: Change font size? +} + +void RenderableLabels::setLabelText(const std::string & newText) { + _labelText = newText; } void RenderableLabels::renderLabels(const RenderData& data, @@ -415,4 +571,81 @@ void RenderableLabels::renderLabels(const RenderData& data, labelInfo ); } + +float RenderableLabels::changedPerlinSmoothStepFunc(const float x, + const float startX, + const float endX) const +{ + float f1 = 6.f * powf((x - startX), 5.f) - 15.f * powf((x - startX), 4.f) + + 10.f * powf((x - startX), 3.f); + float f2 = -6.f * powf((x - endX), 5.f) + 15.f * powf((x - endX), 4.f) - + 10.f * powf((x - endX), 3.f) + 1.f; + float f3 = 1.f; + + if (x <= startX) { + return std::clamp(f1, 0.f, 1.f); + } + else if (x > startX && x < endX) { + return f3; + } + else if (x >= endX) { + return std::clamp(f2, 0.f, 1.f); + } +} + +float RenderableLabels::linearSmoothStepFunc(const float x, + const float startX, + const float endX, + const float sUnit, + const float eUnit) const +{ + float sdiv = 1.f / (sUnit * _fadeStartSpeed); + float ediv = -1.f / (eUnit * _fadeEndSpeed); + float f1 = sdiv * (x - startX) + 1.f; + float f2 = ediv * (x - endX) + 1.f; + float f3 = 1.f; + + if (x <= startX) { + return std::clamp(f1, 0.f, 1.f); + } + else if (x > startX && x < endX) { + return f3; + } + else if (x >= endX) { + return std::clamp(f2, 0.f, 1.f); + } +} + +float RenderableLabels::getUnit(int unit) const { + + float scale = 0.f; + switch (static_cast(unit)) { + case Meter: + scale = 1.f; + break; + case Kilometer: + scale = 1e3f; + break; + case AU: + scale = 149597870700.f; + break; + case Parsec: + scale = static_cast(PARSEC); + break; + case Kiloparsec: + scale = static_cast(1e3 * PARSEC); + break; + case Megaparsec: + scale = static_cast(1e6 * PARSEC); + break; + case Gigaparsec: + scale = static_cast(1e9 * PARSEC); + break; + case GigalightYears: + scale = static_cast(306391534.73091 * PARSEC); + break; + } + + return scale; +} } // namespace openspace diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 9c424964c7..491755f825 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -54,6 +54,18 @@ namespace documentation { struct Documentation; } struct LinePoint; class RenderableLabels : public Renderable { +private: + enum Unit { + Meter = 0, + Kilometer = 1, + AU = 2, + Parsec = 3, + Kiloparsec = 4, + Megaparsec = 5, + Gigaparsec = 6, + GigalightYears = 7 + }; + public: RenderableLabels(const ghoul::Dictionary& dictionary); @@ -68,6 +80,8 @@ public: static documentation::Documentation Documentation(); + void setLabelText(const std::string & newText); + protected: properties::OptionProperty _blendMode; @@ -75,16 +89,38 @@ private: void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); - properties::Vec4Property _labelColor; - properties::FloatProperty _labelSize; - properties::FloatProperty _fontSize; - properties::FloatProperty _labelMinSize; - properties::FloatProperty _labelMaxSize; - properties::BoolProperty _pixelSizeControl; - properties::Vec2Property _fadeInDistance; - properties::BoolProperty _disableFadeInDistance; + float changedPerlinSmoothStepFunc( + const float x, + const float startX, + const float endX + ) const; + float linearSmoothStepFunc( + const float x, + const float startX, + const float endX, + const float sUnit, + const float eUnit + ) const; + + float getUnit(int unit) const; + + properties::Vec4Property _labelColor; + properties::FloatProperty _labelSize; + properties::FloatProperty _fontSize; + properties::FloatProperty _labelMinSize; + properties::FloatProperty _labelMaxSize; + properties::BoolProperty _pixelSizeControl; + properties::BoolProperty _enableFadingEffect; + properties::StringProperty _labelText; + properties::FloatProperty _fadeStartDistance; + properties::FloatProperty _fadeEndDistance; + properties::FloatProperty _fadeStartSpeed; + properties::FloatProperty _fadeEndSpeed; + properties::OptionProperty _labelOrientationOption; + properties::OptionProperty _fadeStartUnitOption; + properties::OptionProperty _fadeEndUnitOption; std::shared_ptr _font; @@ -94,8 +130,6 @@ private: std::string _colorOptionString; std::string _datavarSizeOptionString; - std::string _labelText; - // Data may require some type of transformation prior the spice transformation being // applied. glm::dmat4 _transformationMatrix = glm::dmat4(1.0); From 9a50b27b27e12c24171d80ce10fb3f706c8f679e Mon Sep 17 00:00:00 2001 From: liuloppan Date: Mon, 9 Dec 2019 18:01:59 +0100 Subject: [PATCH 066/214] Update frontend hash Updated to latest frontend hash --- data/assets/util/webgui.asset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/assets/util/webgui.asset b/data/assets/util/webgui.asset index aa33c1e6ed..94f3998ed4 100644 --- a/data/assets/util/webgui.asset +++ b/data/assets/util/webgui.asset @@ -3,7 +3,7 @@ asset.require('./static_server') local guiCustomization = asset.require('customization/gui') -- Select which commit hashes to use for the frontend and backend -local frontendHash = "7f464f7ede73b0e9edd1869eeb90465a5194dd29" +local frontendHash = "be37b84637a88a6961504a8648a4f509bfb07475" local dataProvider = "data.openspaceproject.com/files/webgui" local frontend = asset.syncedResource({ From dc29676b8a614f513931b24c0658674767dcd9cd Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 9 Dec 2019 15:33:04 -0700 Subject: [PATCH 067/214] Debugging SSSB asset and renderable structure --- data/assets/default.scene | 2 ++ data/assets/scene/solarsystem/sssb/neo_pha.asset | 12 ++++-------- data/assets/scene/solarsystem/sssb/sssb_shared.asset | 12 ++++++------ modules/space/rendering/renderablesmallbody.cpp | 2 +- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/data/assets/default.scene b/data/assets/default.scene index c6d3e2523c..3436ab5034 100644 --- a/data/assets/default.scene +++ b/data/assets/default.scene @@ -2,6 +2,8 @@ asset.require('./base') local earthAsset = asset.require('scene/solarsystem/planets/earth/earth') +asset.require('scene/solarsystem/sssb/neo_pha') + asset.onInitialize(function () local now = openspace.time.currentWallTime() -- Jump back one day to be able to show complete weather data on Earth. diff --git a/data/assets/scene/solarsystem/sssb/neo_pha.asset b/data/assets/scene/solarsystem/sssb/neo_pha.asset index a0eafd20d5..1651a9930b 100644 --- a/data/assets/scene/solarsystem/sssb/neo_pha.asset +++ b/data/assets/scene/solarsystem/sssb/neo_pha.asset @@ -1,11 +1,7 @@ local assetHelper = asset.require('util/asset_helper') -local shared = asset.require('../sssb_shared') +local sharedSssb = asset.require('./sssb_shared') -local group = { - Title = "PHA", - Url = "http://www.celestrak.com/NORAD/elements/education.txt", - TrailColor = { 0.75, 0.75, 0.35 } -} +local filename = 'sample.csv' -local tle = shared.downloadSssbDatabaseFile(asset, group.Url, group.Title) -shared.registerSatelliteGroupObjects(asset, group, tle, true) +local telem = asset.localResource(filename) +sharedSssb.registerSssbGroupObjects(asset, filename, telem, true) diff --git a/data/assets/scene/solarsystem/sssb/sssb_shared.asset b/data/assets/scene/solarsystem/sssb/sssb_shared.asset index c01988f074..0153cc2b44 100644 --- a/data/assets/scene/solarsystem/sssb/sssb_shared.asset +++ b/data/assets/scene/solarsystem/sssb/sssb_shared.asset @@ -21,11 +21,11 @@ function downloadSssbDatabaseFile(sceneAsset, url, name) }) end -local registerSssbGroupObjects = function(containingAsset, group, sssbFolder, shouldAddDuplicates) - local filename = group.Url:match("([^/]+)$") - local filenameSansExt = filename:gsub(filename:match("(%.%w+)$"), "") - - local path = sssbFolder .. "/" .. filename +local registerSssbGroupObjects = function(containingAsset, filename, sssbFolder, shouldAddDuplicates) + --local filename = group.Url:match("([^/]+)$") + local filenameSansExt = filename:gsub(filename:match("(%.%w+)$"), "") + --local path = sssbFolder .. "/" .. filename + local trailColor = { 0.75, 0.75, 0.35 } function numLinesInFile(filename) local ctr = 0 @@ -50,7 +50,7 @@ local registerSssbGroupObjects = function(containingAsset, group, sssbFolder, sh } end - local SssbBatch = sssBodies(filenameSansExt, path, group.TrailColor) + local SssbBatch = sssBodies('sssb_'..filenameSansExt, sssbFolder, trailColor) assetHelper.registerSceneGraphNodesAndExport(containingAsset, { SssbBatch }) end diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index bceb72da06..403f0ecbf2 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -46,7 +46,7 @@ namespace { constexpr const char* ProgramName = "RenderableSmallBody"; - constexpr const char* _loggerCat = "Satellites"; + constexpr const char* _loggerCat = "SmallSolarSystemBody"; static const openspace::properties::Property::PropertyInfo PathInfo = { "Path", From 43296979d8b5e4dca88d1301df083ce5e822d82d Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 10 Dec 2019 15:15:52 +0100 Subject: [PATCH 068/214] Fixed rotation matrices in touch Fixed rotation matrices in the touchmodule, while at it I also moved out the lev-marq solver from the touchinteraction.cpp to its own file, in an effort to make the code lighter to read. Also changed some logic in how touch intersection is made with the scenenodes. --- modules/touch/CMakeLists.txt | 2 + modules/touch/include/directinputsolver.h | 71 +++++ modules/touch/include/touchinteraction.h | 28 +- modules/touch/src/directinputsolver.cpp | 271 ++++++++++++++++++ modules/touch/src/touchinteraction.cpp | 333 ++++------------------ modules/touch/src/win32_touch.cpp | 4 +- modules/touch/touchmodule.cpp | 2 +- 7 files changed, 402 insertions(+), 309 deletions(-) create mode 100644 modules/touch/include/directinputsolver.h create mode 100644 modules/touch/src/directinputsolver.cpp diff --git a/modules/touch/CMakeLists.txt b/modules/touch/CMakeLists.txt index 07190880d5..d0b7ec5289 100644 --- a/modules/touch/CMakeLists.txt +++ b/modules/touch/CMakeLists.txt @@ -26,6 +26,7 @@ include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ext/levmarq.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/directinputsolver.h ${CMAKE_CURRENT_SOURCE_DIR}/include/tuioear.h ${CMAKE_CURRENT_SOURCE_DIR}/include/touchinteraction.h ${CMAKE_CURRENT_SOURCE_DIR}/include/touchmarker.h @@ -35,6 +36,7 @@ source_group("Header Files" FILES ${HEADER_FILES}) set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/ext/levmarq.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/directinputsolver.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/tuioear.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/touchinteraction.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/touchmarker.cpp diff --git a/modules/touch/include/directinputsolver.h b/modules/touch/include/directinputsolver.h new file mode 100644 index 0000000000..418f01a535 --- /dev/null +++ b/modules/touch/include/directinputsolver.h @@ -0,0 +1,71 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ +#define __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ + + +#include + +#include + +#include + + +namespace openspace { + +class Camera; +class SceneGraphNode; + +// Stores the selected node, the cursor ID as well as the surface coordinates the +// cursor touched +struct SelectedBody { + long id; + SceneGraphNode* node; + glm::dvec3 coordinates; +}; + +class DirectInputSolver { +public: + DirectInputSolver(); + bool solve(const std::vector& list, + const std::vector& selectedBodies, + std::vector* calculatedValues, + const Camera& camera); + int getNDof() { return _nDof; } + + const LMstat& getLevMarqStat() { return _lmstat; } + void setLevMarqVerbosity(bool verbose) { _lmstat.verbose = verbose; } + +private: + int _nDof; + LMstat _lmstat; +}; + + + +} // openspace namespace + +#endif // __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ + diff --git a/modules/touch/include/touchinteraction.h b/modules/touch/include/touchinteraction.h index f8de436b4b..5cfddec46e 100644 --- a/modules/touch/include/touchinteraction.h +++ b/modules/touch/include/touchinteraction.h @@ -27,7 +27,7 @@ #include -#include +#include #include #include @@ -38,6 +38,8 @@ #include #include +#include + //#define TOUCH_DEBUG_PROPERTIES //#define TOUCH_DEBUG_NODE_PICK_MESSAGES @@ -79,27 +81,6 @@ public: glm::dvec2 pan; }; - // Stores the selected node, the cursor ID as well as the surface coordinates the - // cursor touched - struct SelectedBody { - long id; - SceneGraphNode* node; - glm::dvec3 coordinates; - }; - - // Used in the LM algorithm - struct FunctionData { - std::vector selectedPoints; - std::vector screenPoints; - int nDOF; - glm::dvec2(*castToNDC)(const glm::dvec3&, Camera&, SceneGraphNode*); - double(*distToMinimize)(double* par, int x, void* fdata, LMstat* lmstat); - Camera* camera; - SceneGraphNode* node; - LMstat stats; - double objectScreenRadius; - }; - /* Main function call * 1 Checks if doubleTap occured * 2 Goes through the guiMode() function @@ -258,7 +239,8 @@ private: bool _guiON; std::vector _selected; SceneGraphNode* _pickingSelected = nullptr; - LMstat _lmstat; + std::unique_ptr _solver; + glm::dquat _toSlerp; glm::dvec3 _centroid; diff --git a/modules/touch/src/directinputsolver.cpp b/modules/touch/src/directinputsolver.cpp new file mode 100644 index 0000000000..43624e6af6 --- /dev/null +++ b/modules/touch/src/directinputsolver.cpp @@ -0,0 +1,271 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + + +#include +#include + + +namespace openspace { + +// Used in the LM algorithm +struct FunctionData { + std::vector selectedPoints; + std::vector screenPoints; + int nDOF; + const Camera* camera; + SceneGraphNode* node; + LMstat stats; +}; + + +DirectInputSolver::DirectInputSolver() + : _nDof(0) +{ + levmarq_init(&_lmstat); +} + +// project back a 3D point in model view to clip space [-1,1] coordinates on the view plane +glm::dvec2 castToNDC(const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) { + glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) * + (node->worldRotationMatrix() * vec + + (node->worldPosition() - camera.positionVec3())); + + glm::dvec4 clipspace = camera.projectionMatrix() * glm::dvec4(posInCamSpace, 1.0); + return (glm::dvec2(clipspace) / clipspace.w); +} + +// Returns the screen point s(xi,par) dependent the transform M(par) and object point xi +double distToMinimize(double* par, int x, void* fdata, LMstat* lmstat) { + FunctionData* ptr = reinterpret_cast(fdata); + + // Apply transform to camera and find the new screen point of the updated camera state + + // { vec2 globalRot, zoom, roll, vec2 localRot } + double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; + for (int i = 0; i < ptr->nDOF; ++i) { + q[i] = par[i]; + } + + using namespace glm; + // Create variables from current state + dvec3 camPos = ptr->camera->positionVec3(); + dvec3 centerPos = ptr->node->worldPosition(); + + dvec3 directionToCenter = normalize(centerPos - camPos); + dvec3 lookUp = ptr->camera->lookUpVectorWorldSpace(); + dvec3 camDirection = ptr->camera->viewDirectionWorldSpace(); + + // Make a representation of the rotation quaternion with local and global + // rotations + dmat4 lookAtMat = lookAt( + dvec3(0, 0, 0), + directionToCenter, + // To avoid problem with lookup in up direction + normalize(camDirection + lookUp)); + dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); + dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion(); + + { // Roll + dquat rollRot = angleAxis(q[3], dvec3(0.0, 0.0, 1.0)); + localCamRot = localCamRot * rollRot; + } + { // Panning (local rotation) + dvec3 eulerAngles(q[5], q[4], 0); + dquat panRot = dquat(eulerAngles); + localCamRot = localCamRot * panRot; + } + { // Orbit (global rotation) + dvec3 eulerAngles(q[1], q[0], 0); + dquat rotationDiffCamSpace = dquat(eulerAngles); + + dvec3 centerToCamera = camPos - centerPos; + + dquat rotationDiffWorldSpace = + globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); + dvec3 rotationDiffVec3 = + centerToCamera * rotationDiffWorldSpace - centerToCamera; + camPos += rotationDiffVec3; + + centerToCamera = camPos - centerPos; + directionToCenter = normalize(-centerToCamera); + dvec3 lookUpWhenFacingCenter = + globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace()); + lookAtMat = lookAt( + dvec3(0, 0, 0), + directionToCenter, + lookUpWhenFacingCenter); + globalCamRot = normalize(quat_cast(inverse(lookAtMat))); + } + { // Zooming + camPos += directionToCenter * q[2]; + } + // Update the camera state + Camera cam = *(ptr->camera); + cam.setPositionVec3(camPos); + cam.setRotation(globalCamRot * localCamRot); + + // we now have a new position and orientation of camera, project surfacePoint to + // the new screen to get distance to minimize + glm::dvec2 newScreenPoint = castToNDC( + ptr->selectedPoints.at(x), + cam, + ptr->node + ); + lmstat->pos.push_back(newScreenPoint); + return glm::length(ptr->screenPoints.at(x) - newScreenPoint); +} + +// Gradient of distToMinimize w.r.t par (using forward difference) +void gradient(double* g, double* par, int x, void* fdata, LMstat* lmstat) { + FunctionData* ptr = reinterpret_cast(fdata); + double f0 = distToMinimize(par, x, fdata, lmstat); + // scale value to find minimum step size h, dependant on planet size + double scale = log10(ptr->node->boundingSphere()); + std::vector dPar(ptr->nDOF, 0.0); + dPar.assign(par, par + ptr->nDOF); + + for (int i = 0; i < ptr->nDOF; ++i) { + // Initial values + double h = 1e-8; + double lastG = 1; + dPar.at(i) += h; + double f1 = distToMinimize(dPar.data(), x, fdata, lmstat); + dPar.at(i) = par[i]; + // Iterative process to find the minimum step h that gives a good gradient + for (int j = 0; j < 100; ++j) { + if ((f1 - f0) != 0 && lastG == 0) { // found minimum step size h + // scale up to get a good initial guess value + h *= scale * scale * scale; + + // clamp min step size to a fraction of the incoming parameter + if (i == 2) { + double epsilon = 1e-3; + // make sure incoming parameter is larger than 0 + h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h); + } + else if (ptr->nDOF == 2) { + h = std::max(std::abs(dPar.at(i)) * 0.001, h); + } + + // calculate f1 with good h for finite difference + dPar.at(i) += h; + f1 = distToMinimize(dPar.data(), x, fdata, lmstat); + dPar.at(i) = par[i]; + break; + } + else if ((f1 - f0) != 0 && lastG != 0) { // h too big + h /= scale; + } + else if ((f1 - f0) == 0) { // h too small + h *= scale; + } + lastG = f1 - f0; + dPar.at(i) += h; + f1 = distToMinimize(dPar.data(), x, fdata, lmstat); + dPar.at(i) = par[i]; + } + g[i] = (f1 - f0) / h; + } + if (ptr->nDOF == 2) { + // normalize on 1 finger case to allow for horizontal/vertical movement + for (int i = 0; i < 2; ++i) { + g[i] = g[i] / std::abs(g[i]); + } + } + else if (ptr->nDOF == 6) { + for (int i = 0; i < ptr->nDOF; ++i) { + // lock to only pan and zoom on 3 finger case, no roll/orbit + g[i] = (i == 2) ? g[i] : g[i] / std::abs(g[i]); + } + } +} + +bool DirectInputSolver::solve(const std::vector& list, + const std::vector& selectedBodies, + std::vector *parameters, + const Camera &camera) +{ + + int nFingers = std::min(static_cast(list.size()), 3); + _nDof = std::min(nFingers * 2, 6); + + // Parse input data to be used in the LM algorithm + std::vector selectedPoints; + std::vector screenPoints; + + for (int i = 0; i < nFingers; ++i) { + const SelectedBody& sb = selectedBodies.at(i); + selectedPoints.push_back(sb.coordinates); + screenPoints.emplace_back(2 * (list[i].getX() - 0.5), -2 * (list[i].getY() - 0.5)); + + // This might be needed when we're directing the touchtable from another screen? + // std::vector::const_iterator c = std::find_if( + // list.begin(), + // list.end(), + // [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; } + // ); + // if (c != list.end()) { + // // normalized -1 to 1 coordinates on screen + // screenPoints.emplace_back(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5)); + // } + // else { + // global::moduleEngine.module()->touchInput = { + // true, + // glm::dvec2(0.0, 0.0), + // 1 + // }; + // resetAfterInput(); + // return; + // } + } + + FunctionData fData = { + selectedPoints, + screenPoints, + _nDof, + &camera, + selectedBodies.at(0).node, + _lmstat + }; + void* dataPtr = reinterpret_cast(&fData); + + bool result = levmarq( + _nDof, + parameters->data(), + static_cast(screenPoints.size()), + nullptr, + distToMinimize, + gradient, + dataPtr, + &_lmstat + ); + + return result; +} + +} // openspace namespace + diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index 1653b13248..f9600b9e6f 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -23,7 +23,9 @@ ****************************************************************************************/ #include + #include +#include #include #include @@ -320,6 +322,7 @@ TouchInteraction::TouchInteraction() , _zoomOutTap(false) , _lmSuccess(true) , _guiON(false) + , _solver(new DirectInputSolver()) #ifdef TOUCH_DEBUG_PROPERTIES , _debugProperties() #endif @@ -369,11 +372,8 @@ TouchInteraction::TouchInteraction() } }); - levmarq_init(&_lmstat); - _time.initSession(); } - // Called each frame if there is any input void TouchInteraction::updateStateFromInput(const std::vector& list, std::vector& lastProcessed) @@ -513,231 +513,21 @@ void TouchInteraction::directControl(const std::vector& list) { #ifdef TOUCH_DEBUG_PROPERTIES LINFO("DirectControl"); #endif - // Returns the screen point s(xi,par) dependent the transform M(par) and object - // point xi - auto distToMinimize = [](double* par, int x, void* fdata, LMstat* lmstat) { - FunctionData* ptr = reinterpret_cast(fdata); - - // Apply transform to camera and find the new screen point of the updated camera - // state - - // { vec2 globalRot, zoom, roll, vec2 localRot } - double q[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; - for (int i = 0; i < ptr->nDOF; ++i) { - q[i] = par[i]; - } - - using namespace glm; - // Create variables from current state - dvec3 camPos = ptr->camera->positionVec3(); - dvec3 centerPos = ptr->node->worldPosition(); - - dvec3 directionToCenter = normalize(centerPos - camPos); - dvec3 lookUp = ptr->camera->lookUpVectorWorldSpace(); - dvec3 camDirection = ptr->camera->viewDirectionWorldSpace(); - - // Make a representation of the rotation quaternion with local and global - // rotations - dmat4 lookAtMat = lookAt( - dvec3(0, 0, 0), - directionToCenter, - // To avoid problem with lookup in up direction - normalize(camDirection + lookUp)); - dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); - dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion(); - - { // Roll - dquat rollRot = angleAxis(q[3], dvec3(0.0, 0.0, 1.0)); - localCamRot = localCamRot * rollRot; - } - { // Panning (local rotation) - dvec3 eulerAngles(q[5], q[4], 0); - dquat panRot = dquat(eulerAngles); - localCamRot = localCamRot * panRot; - } - { // Orbit (global rotation) - dvec3 eulerAngles(q[1], q[0], 0); - dquat rotationDiffCamSpace = dquat(eulerAngles); - - dvec3 centerToCamera = camPos - centerPos; - - dquat rotationDiffWorldSpace = - globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); - dvec3 rotationDiffVec3 = - centerToCamera * rotationDiffWorldSpace - centerToCamera; - camPos += rotationDiffVec3; - - centerToCamera = camPos - centerPos; - directionToCenter = normalize(-centerToCamera); - dvec3 lookUpWhenFacingCenter = - globalCamRot * dvec3(ptr->camera->lookUpVectorCameraSpace()); - lookAtMat = lookAt( - dvec3(0, 0, 0), - directionToCenter, - lookUpWhenFacingCenter); - globalCamRot = normalize(quat_cast(inverse(lookAtMat))); - } - { // Zooming - camPos += directionToCenter * q[2]; - } - // Update the camera state - Camera cam = *(ptr->camera); - cam.setPositionVec3(camPos); - cam.setRotation(globalCamRot * localCamRot); - - // we now have a new position and orientation of camera, project surfacePoint to - // the new screen to get distance to minimize - glm::dvec2 newScreenPoint = ptr->castToNDC( - ptr->selectedPoints.at(x), - cam, - ptr->node - ); - lmstat->pos.push_back(newScreenPoint); - return glm::length(ptr->screenPoints.at(x) - newScreenPoint); - }; - // Gradient of distToMinimize w.r.t par (using forward difference) - auto gradient = [](double* g, double* par, int x, void* fdata, LMstat* lmstat) { - FunctionData* ptr = reinterpret_cast(fdata); - double h, lastG, f1, f0 = ptr->distToMinimize(par, x, fdata, lmstat); - // scale value to find minimum step size h, dependant on planet size - double scale = log10(ptr->node->boundingSphere()); - std::vector dPar(ptr->nDOF, 0.0); - dPar.assign(par, par + ptr->nDOF); - - for (int i = 0; i < ptr->nDOF; ++i) { - // Initial values - h = 1e-8; - lastG = 1; - dPar.at(i) += h; - f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat); - dPar.at(i) = par[i]; - // Iterative process to find the minimum step h that gives a good gradient - for (int j = 0; j < 100; ++j) { - if ((f1 - f0) != 0 && lastG == 0) { // found minimum step size h - // scale up to get a good initial guess value - h *= scale * scale * scale; - - // clamp min step size to a fraction of the incoming parameter - if (i == 2) { - double epsilon = 1e-3; - // make sure incoming parameter is larger than 0 - h = std::max(std::max(std::abs(dPar.at(i)), epsilon) * 0.001, h); - } - else if (ptr->nDOF == 2) { - h = std::max(std::abs(dPar.at(i)) * 0.001, h); - } - - // calculate f1 with good h for finite difference - dPar.at(i) += h; - f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat); - dPar.at(i) = par[i]; - break; - } - else if ((f1 - f0) != 0 && lastG != 0) { // h too big - h /= scale; - } - else if ((f1 - f0) == 0) { // h too small - h *= scale; - } - lastG = f1 - f0; - dPar.at(i) += h; - f1 = ptr->distToMinimize(dPar.data(), x, fdata, lmstat); - dPar.at(i) = par[i]; - } - g[i] = (f1 - f0) / h; - } - if (ptr->nDOF == 2) { - // normalize on 1 finger case to allow for horizontal/vertical movement - for (int i = 0; i < 2; ++i) { - g[i] = g[i]/std::abs(g[i]); - } - } - else if (ptr->nDOF == 6) { - for (int i = 0; i < ptr->nDOF; ++i) { - // lock to only pan and zoom on 3 finger case, no roll/orbit - g[i] = (i == 2) ? g[i] : g[i] / std::abs(g[i]); - } - } - }; - - // project back a 3D point in model view to clip space [-1,1] coordinates on the view - // plane - auto castToNDC = [](const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) { - glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) * - (node->rotationMatrix() * vec + - (node->worldPosition() - camera.positionVec3())); - - glm::dvec4 clipspace = camera.projectionMatrix() * glm::dvec4(posInCamSpace, 1.0); - return (glm::dvec2(clipspace) / clipspace.w); - }; - - // only send in first three fingers (to make it easier for LMA to converge on 3+ - // finger case with only zoom/pan) - int nFingers = std::min(static_cast(list.size()), 3); - int nDOF = std::min(nFingers * 2, 6); - std::vector par(nDOF, 0.0); - par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit - par.at(1) = _lastVel.orbit.y; - - // Parse input data to be used in the LM algorithm - std::vector selectedPoints; - std::vector screenPoints; - for (int i = 0; i < nFingers; ++i) { - const SelectedBody& sb = _selected.at(i); - selectedPoints.push_back(sb.coordinates); - - std::vector::const_iterator c = std::find_if( - list.begin(), - list.end(), - [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; } - ); - if (c != list.end()) { - // normalized -1 to 1 coordinates on screen - screenPoints.emplace_back(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5)); - } - else { - global::moduleEngine.module()->touchInput = { - true, - glm::dvec2(0.0, 0.0), - 1 - }; - resetAfterInput(); - return; - } - } - - FunctionData fData = { - selectedPoints, - screenPoints, - nDOF, - castToNDC, - distToMinimize, - _camera, - _selected.at(0).node, - _lmstat, - _currentRadius - }; - void* dataPtr = reinterpret_cast(&fData); // finds best transform values for the new camera state and stores them in par - _lmSuccess = levmarq( - nDOF, - par.data(), - static_cast(screenPoints.size()), - nullptr, - distToMinimize, - gradient, - dataPtr, - &_lmstat - ); + std::vector par(6, 0.0); + par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit + par.at(1) = _lastVel.orbit.y; + _lmSuccess = _solver->solve(list, _selected, &par, *_camera); + int nDof = _solver->getNDof(); if (_lmSuccess && !_unitTest) { // if good values were found set new camera state _vel.orbit = glm::dvec2(par.at(0), par.at(1)); - if (nDOF > 2) { + if (nDof > 2) { _vel.zoom = par.at(2); _vel.roll = par.at(3); - if (_panEnabled && nDOF > 4) { + if (_panEnabled && nDof > 4) { _vel.roll = 0.0; _vel.pan = glm::dvec2(par.at(4), par.at(5)); } @@ -785,19 +575,17 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { glm::dquat camToWorldSpace = _camera->rotationQuaternion(); glm::dvec3 camPos = _camera->positionVec3(); std::vector newSelected; - - struct PickingInfo { - SceneGraphNode* node; - double pickingDistanceNDC; - double pickingDistanceWorld; + + //node & distance + std::tuple currentlyPicked = { + nullptr, + std::numeric_limits::max() }; - std::vector pickingInfo; - + for (const TuioCursor& c : list) { double xCo = 2 * (c.getX() - 0.5); double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen - // vec3(projectionmatrix * clipspace), divide with w? glm::dvec3 cursorInWorldSpace = camToWorldSpace * glm::dvec3(glm::inverse(_camera->projectionMatrix()) * glm::dvec4(xCo, yCo, -1.0, 1.0)); @@ -808,20 +596,12 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { for (SceneGraphNode* node : selectableNodes) { double boundingSphere = node->boundingSphere(); glm::dvec3 camToSelectable = node->worldPosition() - camPos; - double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) / - glm::length(cursorInWorldSpace) - boundingSphere; - if (dist <= 0.0) { - // finds intersection closest point between boundingsphere and line in - // world coordinates, assumes line direction is normalized - double d = glm::dot(raytrace, camToSelectable); - double root = boundingSphere * boundingSphere - - glm::dot(camToSelectable, camToSelectable) + d * d; - if (root > 0) { // two intersection points (take the closest one) - d -= sqrt(root); - } - glm::dvec3 intersectionPoint = camPos + d * raytrace; - glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) * - (intersectionPoint - node->worldPosition()); + glm::dvec3 intersectionPos = {}; + glm::dvec3 intersectionNormal = {}; + bool intersected = glm::intersectRaySphere(camPos, raytrace, node->worldPosition(), boundingSphere, intersectionPos, intersectionNormal); + if (intersected) { + glm::dvec3 pointInModelView = glm::inverse(node->worldRotationMatrix()) * + (intersectionPos - node->worldPosition()); // Add id, node and surface coordinates to the selected list std::vector::iterator oldNode = std::find_if( @@ -830,9 +610,7 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { [id](SelectedBody s) { return s.id == id; } ); if (oldNode != newSelected.end()) { - double oldNodeDist = glm::length( - oldNode->node->worldPosition() - camPos - ); + double oldNodeDist = glm::length(oldNode->node->worldPosition() - camPos); if (glm::length(camToSelectable) < oldNodeDist) { // new node is closer, remove added node and add the new one // instead @@ -859,56 +637,44 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { // We either want to select the object if it's bounding sphere as been // touched (checked by the first part of this loop above) or if the touch // point is within a minimum distance of the center - if (dist <= 0.0 || (ndcDist <= _pickingRadiusMinimum)) { - // If the user touched the planet directly, this is definitely the one - // they are interested in => minimum distance - if (dist <= 0.0) { + // If the user touched the planet directly, this is definitely the one + // they are interested in => minimum distance + if (intersected) { #ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - LINFOC( - node->identifier(), - "Picking candidate based on direct touch" - ); + LINFOC( + node->identifier(), + "Picking candidate based on direct touch" + ); #endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - pickingInfo.push_back({ - node, - -std::numeric_limits::max(), - -std::numeric_limits::max() - }); - } - else { - // The node was considered due to minimum picking distance radius + currentlyPicked = { + node, + -std::numeric_limits::max() + }; + } + else if (ndcDist <= _pickingRadiusMinimum) { + // The node was considered due to minimum picking distance radius #ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - LINFOC( - node->identifier(), - "Picking candidate based on proximity" - ); + LINFOC( + node->identifier(), + "Picking candidate based on proximity" + ); #endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - pickingInfo.push_back({ + double dist = length(intersectionPos - camPos); + if (dist < std::get<1>(currentlyPicked)) { + currentlyPicked = { node, - ndcDist, dist - }); + }; } } } } } - - // After we are done with all of the nodes, we can sort the picking list and pick the - // one that fits best (= is closest or was touched directly) - std::sort( - pickingInfo.begin(), - pickingInfo.end(), - [](const PickingInfo& lhs, const PickingInfo& rhs) { - return lhs.pickingDistanceWorld < rhs.pickingDistanceWorld; - } - ); - // If an item has been picked, it's in the first position of the vector now - if (!pickingInfo.empty()) { - _pickingSelected = pickingInfo.begin()->node; + if (SceneGraphNode* node = std::get<0>(currentlyPicked)) { + _pickingSelected = node; #ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES LINFOC("Picking", "Picked node: " + _pickingSelected->identifier()); #endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES @@ -1447,7 +1213,7 @@ void TouchInteraction::step(double dt) { void TouchInteraction::unitTest() { if (_unitTest) { - _lmstat.verbose = true; + _solver->setLevMarqVerbosity(true); // set _selected pos and new pos (on screen) std::vector lastFrame = { @@ -1468,7 +1234,7 @@ void TouchInteraction::unitTest() { snprintf(buffer, sizeof(char) * 32, "lmdata%i.csv", _numOfTests); _numOfTests++; std::ofstream file(buffer); - file << _lmstat.data; + file << _solver->getLevMarqStat().data; // clear everything _selected.clear(); @@ -1480,6 +1246,7 @@ void TouchInteraction::unitTest() { _lastVel = _vel; _unitTest = false; + _solver->setLevMarqVerbosity(false); // could be the camera copy in func } } diff --git a/modules/touch/src/win32_touch.cpp b/modules/touch/src/win32_touch.cpp index 8d248d3a63..32331c8bb3 100644 --- a/modules/touch/src/win32_touch.cpp +++ b/modules/touch/src/win32_touch.cpp @@ -69,8 +69,8 @@ LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) { // native touch to screen conversion ScreenToClient(pStruct->hwnd, reinterpret_cast(&p)); - float xPos = (float)p.x / (float)(rect.right - rect.left); - float yPos = (float)p.y / (float)(rect.bottom - rect.top); + float xPos = static_cast(p.x) / static_cast(rect.right - rect.left); + float yPos = static_cast(p.y) / static_cast(rect.bottom - rect.top); if (pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { // Handle new touchpoint gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index a47e2fe4d2..f968095a44 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -164,7 +164,7 @@ TouchModule::TouchModule() if (nativeWindowHandle) { _win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle)); } -#endif //WIN32 +#endif }); global::callback::deinitializeGL.push_back([&]() { From 140de3d808b0f46bbe4cc217adbd8bfdcee7cdfc Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 10 Dec 2019 12:55:58 -0500 Subject: [PATCH 069/214] Added automatic documentation and Sun's label. --- data/assets/scene/solarsystem/sun/sun.asset | 35 +++++++- modules/base/rendering/renderablelabels.cpp | 98 ++++++++++++++++++++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index cc887dc4d2..81f72297f9 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -27,4 +27,37 @@ local Sun = { } } -assetHelper.registerSceneGraphNodesAndExport(asset, { Sun }) +local SunLabel = { + Identifier = "SunLabel", + Parent = Sun.Identifier, + Renderable = { + Enabled = false, + Type = "RenderableLabels", + LabelText = "Sun", + FontSize = 100.0, + LabelSize = 8.6, + LabelMaxSize = 100.0, + LabelMinSize = 1.0, + LabelOrientationOption = "Camera View Direction", + BlendMode = "Additive", + EnableFading = true, + FadeStartUnit = "pc", + FadeStartDistance = 0.1, + FadeStartSpeed = 1.0, + FadeEndUnit = "pc", + FadeEndDistance = 1.0, + FadeEndSpeed = 4.0, + TransformationMatrix = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + }, + }, + GUI = { + Name = "Sun Label", + Path = "/Solar System/Sun" + } +} + +assetHelper.registerSceneGraphNodesAndExport(asset, { Sun, SunLabel }) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 38a3449127..ff20e8cbad 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -186,7 +186,103 @@ documentation::Documentation RenderableLabels::Documentation() { new StringInListVerifier({ "Normal", "Additive" }), Optional::Yes, BlendModeInfo.description, // + " The default value is 'Normal'.", - } + }, + { + LabelOrientationOptionInfo.identifier, + new StringInListVerifier({ "Camera View Direction", "Camera Position Normal" }), + Optional::Yes, + LabelOrientationOptionInfo.description, + }, + { + LabelColorInfo.identifier, + new DoubleVector4Verifier, + Optional::Yes, + LabelColorInfo.description, + }, + { + LabelColorInfo.identifier, + new DoubleVector4Verifier, + Optional::Yes, + LabelColorInfo.description, + }, + { + LabelTextInfo.identifier, + new StringVerifier, + Optional::No, + LabelTextInfo.description + }, + { + FontSizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FontSizeInfo.description + }, + { + LabelSizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + LabelSizeInfo.description + }, + { + LabelMinSizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + LabelMinSizeInfo.description + }, + { + LabelMaxSizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + LabelMaxSizeInfo.description + }, + { + EnableFadingEffectInfo.identifier, + new BoolVerifier, + Optional::Yes, + EnableFadingEffectInfo.description + }, + { + PixelSizeControlInfo.identifier, + new BoolVerifier, + Optional::Yes, + PixelSizeControlInfo.description + }, + { + FadeStartUnitOptionInfo.identifier, + new StringInListVerifier({"m", "Km", "au", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + Optional::Yes, + FadeStartUnitOptionInfo.description, + }, + { + FadeEndUnitOptionInfo.identifier, + new StringInListVerifier({"m", "Km", "au", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + Optional::Yes, + FadeEndUnitOptionInfo.description, + }, + { + FadeStartDistInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FadeStartDistInfo.description + }, + { + FadeEndDistInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FadeEndDistInfo.description + }, + { + FadeStartSpeedInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FadeStartSpeedInfo.description + }, + { + FadeEndSpeedInfo.identifier, + new DoubleVerifier, + Optional::Yes, + FadeEndSpeedInfo.description + }, } }; } From 69fb1eec20b4adcca5b93aa30dfd9fac4ee06094 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 11 Dec 2019 09:56:45 +0100 Subject: [PATCH 070/214] Fixed edge case and cleanup Fixed picking edge case, where we now will sort our elements as before Also used another ray-sphere intersect fn as we did not use everything from the other one. --- modules/touch/src/touchinteraction.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index f9600b9e6f..fa0cb44c56 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -594,12 +594,13 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { long id = c.getSessionID(); for (SceneGraphNode* node : selectableNodes) { - double boundingSphere = node->boundingSphere(); + double boundingSphereSquared = double(node->boundingSphere()) * double(node->boundingSphere()); glm::dvec3 camToSelectable = node->worldPosition() - camPos; - glm::dvec3 intersectionPos = {}; - glm::dvec3 intersectionNormal = {}; - bool intersected = glm::intersectRaySphere(camPos, raytrace, node->worldPosition(), boundingSphere, intersectionPos, intersectionNormal); + double intersectionDist = 0.0; + bool intersected = glm::intersectRaySphere(camPos, raytrace, node->worldPosition(), + boundingSphereSquared, intersectionDist); if (intersected) { + glm::dvec3 intersectionPos = camPos + raytrace * intersectionDist; glm::dvec3 pointInModelView = glm::inverse(node->worldRotationMatrix()) * (intersectionPos - node->worldPosition()); @@ -660,7 +661,7 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { "Picking candidate based on proximity" ); #endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - double dist = length(intersectionPos - camPos); + double dist = length(camToSelectable); if (dist < std::get<1>(currentlyPicked)) { currentlyPicked = { node, From 3e23e4323c6a4a95908be4af689000331c158371 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Wed, 11 Dec 2019 13:30:52 -0700 Subject: [PATCH 071/214] Feature/venus magellan (#1020) * Updated Venus asset and added wms for Magellan mosaic imagery * Adding Magellan height layer --- .../map_service_configs/Utah/MagellanDEM.wms | 21 ++++++++++++ .../Utah/MagellanMosaic.wms | 21 ++++++++++++ .../solarsystem/planets/venus/venus.asset | 33 ++++++++++++++----- 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms create mode 100644 data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms diff --git a/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms new file mode 100644 index 0000000000..c8072a6e30 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanDEM.wms @@ -0,0 +1,21 @@ + + + http://openspace.sci.utah.edu/Venus/MagellanDEM/tile/${z}/${y}/${x} + + + -180.0 + 90.0 + 180.0 + -90.0 + 8192 + 4096 + 4 + top + + GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]] + 256 + 256 + 1 + 10 + 5 + diff --git a/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms new file mode 100644 index 0000000000..084e231ea4 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/venus/map_service_configs/Utah/MagellanMosaic.wms @@ -0,0 +1,21 @@ + + + http://openspace.sci.utah.edu/Venus/MagellanMosaic/tile/${z}/${y}/${x} + + + -180.0 + 84.0 + 180.0 + -80.0 + 506928 + 230948 + 9 + top + + GEOGCS["GCS_Venus",DATUM["D_Venus",SPHEROID["Venus_localRadius",6051000,0]],PRIMEM["Reference_Meridian",0],UNIT["Degree",0.0174532925199433]] + 512 + 512 + 1 + 10 + 5 + diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 0b7617dad2..d11b371752 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -4,7 +4,7 @@ asset.require("spice/base") asset.request('./trail') local labelsPath = asset.require('./venus_labels').LabelsPath - +local mapServiceConfigs = asset.localResource("map_service_configs") local textures = asset.syncedResource({ Name = "Venus Textures", @@ -13,6 +13,28 @@ local textures = asset.syncedResource({ Version = 1 }) +local color_layers = { + { + Identifier = "Texture", + FilePath = textures .. "/venus.jpg", + Enabled = true + }, + { + Identifier = "Magellan_Mosaic_Utah", + Name = "Magellan Mosaic [Utah]", + FilePath = mapServiceConfigs .. "/Utah/MagellanMosaic.wms" + } +} + +local height_layers = { + { + Identifier = "Magellan", + Name = "Magellan Elevation [Utah]", + FilePath = mapServiceConfigs .. "/Utah/MagellanDEM.wms", + TilePixelSize = 64 + } +} + local Venus = { Identifier = "Venus", Parent = transforms.VenusBarycenter.Identifier, @@ -33,13 +55,8 @@ local Venus = { Radii = { 6051900.0, 6051900.0, 6051800.0 }, SegmentsPerPatch = 64, Layers = { - ColorLayers = { - { - Identifier = "Texture", - FilePath = textures .. "/venus.jpg", - Enabled = true - } - } + ColorLayers = color_layers, + HeightLayers = height_layers }, Labels = { Enable = false, From 5509fb0a6bf6cf7d5d3af44c72b1b13e07b2af5f Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 11 Dec 2019 15:38:11 -0500 Subject: [PATCH 072/214] Added more units to refine fading controls. Updated Sun fading values. --- data/assets/scene/solarsystem/sun/sun.asset | 14 +++--- modules/base/rendering/renderablelabels.cpp | 54 +++++++++++++++++++-- modules/base/rendering/renderablelabels.h | 16 +++--- 3 files changed, 68 insertions(+), 16 deletions(-) diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index 81f72297f9..0ca4e4a8be 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -31,22 +31,22 @@ local SunLabel = { Identifier = "SunLabel", Parent = Sun.Identifier, Renderable = { - Enabled = false, + Enabled = true, Type = "RenderableLabels", LabelText = "Sun", FontSize = 100.0, - LabelSize = 8.6, + LabelSize = 13.127, LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", BlendMode = "Additive", EnableFading = true, - FadeStartUnit = "pc", - FadeStartDistance = 0.1, - FadeStartSpeed = 1.0, + FadeStartUnit = "Pm", + FadeStartDistance = 2.841, + FadeStartSpeed = 1.375, FadeEndUnit = "pc", - FadeEndDistance = 1.0, - FadeEndSpeed = 4.0, + FadeEndDistance = 1.326, + FadeEndSpeed = 1.0, TransformationMatrix = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index ff20e8cbad..a5b33f2624 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -51,7 +51,11 @@ namespace { constexpr const char* MeterUnit = "m"; constexpr const char* KilometerUnit = "Km"; + constexpr const char* MegameterUnit = "Mm"; + constexpr const char* GigameterUnit = "Gm"; constexpr const char* AstronomicalUnit = "au"; + constexpr const char* TerameterUnit = "Tm"; + constexpr const char* PetameterUnit = "Pm"; constexpr const char* ParsecUnit = "pc"; constexpr const char* KiloparsecUnit = "Kpc"; constexpr const char* MegaparsecUnit = "Mpc"; @@ -249,13 +253,13 @@ documentation::Documentation RenderableLabels::Documentation() { }, { FadeStartUnitOptionInfo.identifier, - new StringInListVerifier({"m", "Km", "au", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + new StringInListVerifier({"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), Optional::Yes, FadeStartUnitOptionInfo.description, }, { FadeEndUnitOptionInfo.identifier, - new StringInListVerifier({"m", "Km", "au", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + new StringInListVerifier({"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), Optional::Yes, FadeEndUnitOptionInfo.description, }, @@ -428,7 +432,11 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeStartUnitOption.addOption(Meter, MeterUnit); _fadeStartUnitOption.addOption(Kilometer, KilometerUnit); + _fadeStartUnitOption.addOption(Megameter, MegameterUnit); + _fadeStartUnitOption.addOption(Gigameter, GigameterUnit); _fadeStartUnitOption.addOption(AU, AstronomicalUnit); + _fadeStartUnitOption.addOption(Terameter, TerameterUnit); + _fadeStartUnitOption.addOption(Petameter, PetameterUnit); _fadeStartUnitOption.addOption(Parsec, ParsecUnit); _fadeStartUnitOption.addOption(Kiloparsec, KiloparsecUnit); _fadeStartUnitOption.addOption(Megaparsec, MegaparsecUnit); @@ -445,9 +453,21 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) else if (unit == KilometerUnit) { _fadeStartUnitOption = Kilometer; } + else if (unit == MegameterUnit) { + _fadeStartUnitOption = Megameter; + } + else if (unit == GigameterUnit) { + _fadeStartUnitOption = Gigameter; + } else if (unit == AstronomicalUnit) { _fadeStartUnitOption = AU; } + else if (unit == TerameterUnit) { + _fadeStartUnitOption = Terameter; + } + else if (unit == PetameterUnit) { + _fadeStartUnitOption = Petameter; + } else if (unit == ParsecUnit) { _fadeStartUnitOption = Parsec; } @@ -487,7 +507,11 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeEndUnitOption.addOption(Meter, MeterUnit); _fadeEndUnitOption.addOption(Kilometer, KilometerUnit); + _fadeEndUnitOption.addOption(Megameter, MegameterUnit); + _fadeEndUnitOption.addOption(Gigameter, GigameterUnit); _fadeEndUnitOption.addOption(AU, AstronomicalUnit); + _fadeEndUnitOption.addOption(Terameter, TerameterUnit); + _fadeEndUnitOption.addOption(Petameter, PetameterUnit); _fadeEndUnitOption.addOption(Parsec, ParsecUnit); _fadeEndUnitOption.addOption(Kiloparsec, KiloparsecUnit); _fadeEndUnitOption.addOption(Megaparsec, MegaparsecUnit); @@ -504,9 +528,21 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) else if (unit == KilometerUnit) { _fadeEndUnitOption = Kilometer; } + else if (unit == MegameterUnit) { + _fadeEndUnitOption = Megameter; + } + else if (unit == GigameterUnit) { + _fadeEndUnitOption = Gigameter; + } else if (unit == AstronomicalUnit) { _fadeEndUnitOption = AU; } + else if (unit == TerameterUnit) { + _fadeEndUnitOption = Terameter; + } + else if (unit == PetameterUnit) { + _fadeEndUnitOption = Petameter; + } else if (unit == ParsecUnit) { _fadeEndUnitOption = Parsec; } @@ -720,11 +756,23 @@ float RenderableLabels::getUnit(int unit) const { scale = 1.f; break; case Kilometer: - scale = 1e3f; + scale = 1e3; + break; + case Megameter: + scale = 1e6; + break; + case Gigameter: + scale = 1e9; break; case AU: scale = 149597870700.f; break; + case Terameter: + scale = 1e12; + break; + case Petameter: + scale = 1e15; + break; case Parsec: scale = static_cast(PARSEC); break; diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 491755f825..c0fa9848e9 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -58,12 +58,16 @@ private: enum Unit { Meter = 0, Kilometer = 1, - AU = 2, - Parsec = 3, - Kiloparsec = 4, - Megaparsec = 5, - Gigaparsec = 6, - GigalightYears = 7 + Megameter = 2, + Gigameter = 3, + AU = 4, + Terameter = 5, + Petameter = 6, + Parsec = 7, + Kiloparsec = 8, + Megaparsec = 9, + Gigaparsec = 10, + GigalightYears = 11 }; public: From fba204a51ff6865e4ce094806fcb03f35292ab20 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 11 Dec 2019 15:59:26 -0500 Subject: [PATCH 073/214] Added Venus atm. --- data/assets/scene/solarsystem/planets.asset | 1 + .../planets/venus/atmosphere.asset | 66 +++++++++++++++++++ .../solarsystem/planets/venus/venus.asset | 3 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 data/assets/scene/solarsystem/planets/venus/atmosphere.asset diff --git a/data/assets/scene/solarsystem/planets.asset b/data/assets/scene/solarsystem/planets.asset index 8603643031..a631b33339 100644 --- a/data/assets/scene/solarsystem/planets.asset +++ b/data/assets/scene/solarsystem/planets.asset @@ -1,6 +1,7 @@ asset.request('./planets/mercury/mercury') asset.request('./planets/venus/venus') +asset.request('./planets/venus/atmosphere') asset.request('./planets/earth/earth') asset.request('./planets/earth/atmosphere') diff --git a/data/assets/scene/solarsystem/planets/venus/atmosphere.asset b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset new file mode 100644 index 0000000000..40a95cdc54 --- /dev/null +++ b/data/assets/scene/solarsystem/planets/venus/atmosphere.asset @@ -0,0 +1,66 @@ +local transforms = asset.require('./venus') +local assetHelper = asset.require('util/asset_helper') + + + +local Atmosphere = { + Identifier = "VenusAtmosphere", + Parent = transforms.Venus.Identifier, + Renderable = { + Type = "RenderableAtmosphere", + Atmosphere = { + -- Atmosphere radius in Km + AtmosphereRadius = 6121.9, + PlanetRadius = 6051.9, + PlanetAverageGroundReflectance = 0.018, + GroundRadianceEmittion = 0.8, + SunIntensity = 11.47, + --MieScatteringExtinctionPropCoefficient = 0.23862, + Rayleigh = { + Coefficients = { + -- Wavelengths are given in 10^-9m + Wavelengths = { 680, 550, 440 }, + -- Reflection coefficients are given in km^-1 + Scattering = { 19.518E-3, 13.83E-3, 3.65E-3 } + -- In Rayleigh scattering, the coefficients of + -- absorption and scattering are the same. + }, + -- Thichkness of atmosphere if its density were uniform, in Km + H_R = 6.7 + }, + -- Default + Mie = { + Coefficients = { + -- Reflection coefficients are given in km^-1 + Scattering = { 53.61771e-3, 53.61771e-3, 53.61771e-3 }, + -- Extinction coefficients are a fraction of the Scattering coefficients + Extinction = { 53.61771e-3/0.98979, 53.61771e-3/0.98979, 53.61771e-3/0.98979 } + }, + -- Mie Height scale (atmosphere thickness for constant density) in Km + H_M = 9.8, + -- Mie Phase Function Value (G e [-1.0, 1.0]. + -- If G = 1.0, Mie phase function = Rayleigh Phase Function) + G = 0.85 + }, + Image = { + ToneMapping = jToneMapping, + Exposure = 0.4, + Background = 1.8, + Gamma = 1.85 + }, + Debug = { + -- PreCalculatedTextureScale is a float from 1.0 to N, with N > 0.0 and N in Naturals (i.e., 1, 2, 3, 4, 5....) + PreCalculatedTextureScale = 1.0, + SaveCalculatedTextures = false + } + } + }, + GUI = { + Name = "Venus Atmosphere", + Path = "/Solar System/Planets/Venus" + } +} + + + +assetHelper.registerSceneGraphNodesAndExport(asset, { Atmosphere }) diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 0b7617dad2..07e74fdf25 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -30,7 +30,8 @@ local Venus = { }, Renderable = { Type = "RenderableGlobe", - Radii = { 6051900.0, 6051900.0, 6051800.0 }, + --Radii = { 6051900.0, 6051900.0, 6051800.0 }, + Radii = { 6051900.0, 6051900.0, 6051900.0 }, SegmentsPerPatch = 64, Layers = { ColorLayers = { From bc7d973e904cd7f1312588cd3d447baa202562bb Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 11 Dec 2019 16:03:55 -0700 Subject: [PATCH 074/214] Fix for issue 1023: prevents crash when using satellites and changing segments property, and fixes rendering errors. --- .../earth/satellites/satellites_shared.asset | 2 +- .../space/rendering/renderablesatellites.cpp | 25 ++++++------------- .../space/rendering/renderablesatellites.h | 2 -- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset index 58b3e35ec4..e5fde6d30c 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset @@ -56,7 +56,7 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder Renderable = { Type = "RenderableSatellites", Path = file, - Segments = 160, + Segments = 120, Color = color, Fade = 0.5 }, diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp index 7453ff44f5..5476bf828f 100644 --- a/modules/space/rendering/renderablesatellites.cpp +++ b/modules/space/rendering/renderablesatellites.cpp @@ -66,13 +66,6 @@ namespace { "method includes lines. If the rendering mode is set to Points, this value is " "ignored." }; - constexpr openspace::properties::Property::PropertyInfo FadeInfo = { - "Fade", - "Line fade", - "The fading factor that is applied to the trail if the 'EnableFade' value is " - "'true'. If it is 'false', this setting has no effect. The higher the number, " - "the less fading is applied." - }; constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { "Color", "Color", @@ -301,12 +294,6 @@ documentation::Documentation RenderableSatellites::Documentation() { Optional::Yes, LineWidthInfo.description }, - { - FadeInfo.identifier, - new DoubleVerifier, - Optional::Yes, - FadeInfo.description - }, { LineColorInfo.identifier, new DoubleVector3Verifier, @@ -320,8 +307,7 @@ documentation::Documentation RenderableSatellites::Documentation() { RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _path(PathInfo) - , _nSegments(SegmentsInfo) - , _lineFade(FadeInfo) + , _nSegments(SegmentsInfo, 120, 4, 1024) { documentation::testSpecificationAndThrow( @@ -332,16 +318,21 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) _path = dictionary.value(PathInfo.identifier); _nSegments = static_cast(dictionary.value(SegmentsInfo.identifier)); - _lineFade = static_cast(dictionary.value(FadeInfo.identifier)); if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) { _appearance.lineColor = dictionary.value(LineColorInfo.identifier); } + auto reinitializeTrailBuffers = [this]() { + initializeGL(); + }; + + _path.onChange(reinitializeTrailBuffers); + _nSegments.onChange(reinitializeTrailBuffers); + addPropertySubOwner(_appearance); addProperty(_path); addProperty(_nSegments); - addProperty(_lineFade); } diff --git a/modules/space/rendering/renderablesatellites.h b/modules/space/rendering/renderablesatellites.h index e052683cfc..b2bf0864a0 100644 --- a/modules/space/rendering/renderablesatellites.h +++ b/modules/space/rendering/renderablesatellites.h @@ -113,8 +113,6 @@ private: properties::StringProperty _path; properties::UIntProperty _nSegments; - properties::DoubleProperty _lineFade; - RenderableTrail::Appearance _appearance; glm::vec3 _position; From 30ace4c002e76c223763260e37930c963a4941ce Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 11 Dec 2019 18:53:50 -0700 Subject: [PATCH 075/214] Fixed problem with references to RenderableSmallBody class --- data/assets/scene/solarsystem/sssb/sssb_shared.asset | 12 ++++++------ modules/space/rendering/renderablesmallbody.cpp | 4 ++-- modules/space/rendering/renderablesmallbody.h | 6 +++--- modules/space/spacemodule.cpp | 4 +++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/data/assets/scene/solarsystem/sssb/sssb_shared.asset b/data/assets/scene/solarsystem/sssb/sssb_shared.asset index 0153cc2b44..62c127a54b 100644 --- a/data/assets/scene/solarsystem/sssb/sssb_shared.asset +++ b/data/assets/scene/solarsystem/sssb/sssb_shared.asset @@ -1,12 +1,12 @@ local transforms = asset.require('scene/solarsystem/sun/transforms') local assetHelper = asset.require('util/asset_helper') -local satImageFolder = asset.syncedResource({ - Name = "Satellite Image Files", - Type = "HttpSynchronization", - Identifier = "tle_satellites_images", - Version = 1 -}) +--local satImageFolder = asset.syncedResource({ +-- Name = "Satellite Image Files", +-- Type = "HttpSynchronization", +-- Identifier = "tle_satellites_images", +-- Version = 1 +--}) function downloadSssbDatabaseFile(sceneAsset, url, name) local identifier = name diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 403f0ecbf2..6602658b11 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -97,7 +97,7 @@ const std::vector DaysOfMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; -enum class Months { +enum Months { January = 0, February, March, @@ -285,7 +285,7 @@ documentation::Documentation RenderableSmallBody::Documentation() { using namespace documentation; return { "RenderableSmallBody", - "space_renderable_satellites", + "small solar system bodies", { { SegmentsInfo.identifier, diff --git a/modules/space/rendering/renderablesmallbody.h b/modules/space/rendering/renderablesmallbody.h index 1cd569b7da..4f0ca15e81 100644 --- a/modules/space/rendering/renderablesmallbody.h +++ b/modules/space/rendering/renderablesmallbody.h @@ -22,8 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ -#define __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ +#ifndef __OPENSPACE_MODULE_SPACE___RENDERABLESMALLBODY___H__ +#define __OPENSPACE_MODULE_SPACE___RENDERABLESMALLBODY___H__ #include @@ -130,5 +130,5 @@ private: } // namespace openspace -#endif // __OPENSPACE_MODULE_SPACE___RENDERABLESATELLITES___H__ +#endif // __OPENSPACE_MODULE_SPACE___RENDERABLESMALLBODY___H__ diff --git a/modules/space/spacemodule.cpp b/modules/space/spacemodule.cpp index 6521a82cd4..2a2af2edee 100644 --- a/modules/space/spacemodule.cpp +++ b/modules/space/spacemodule.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include //#include @@ -82,7 +83,7 @@ void SpaceModule::internalInitialize(const ghoul::Dictionary&) { fRenderable->registerClass("RenderableRings"); fRenderable->registerClass("RenderableSatellites"); - fRenderable->registerClass("RenderableSmallBody"); + fRenderable->registerClass("RenderableSmallBody"); fRenderable->registerClass("RenderableStars"); auto fTranslation = FactoryManager::ref().factory(); @@ -116,6 +117,7 @@ std::vector SpaceModule::documentations() const { RenderableConstellationBounds::Documentation(), RenderableRings::Documentation(), RenderableSatellites::Documentation(), + RenderableSmallBody::Documentation(), RenderableStars::Documentation(), SpiceRotation::Documentation(), SpiceTranslation::Documentation(), From 72d2dfb7eda334712d3bd64ab10f72dd14047786 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 12 Dec 2019 16:03:03 -0700 Subject: [PATCH 076/214] Fixiing problems with reading csv file --- modules/space/CMakeLists.txt | 2 + .../space/rendering/renderablesatellites.cpp | 8 - .../space/rendering/renderablesatellites.h | 10 + .../space/rendering/renderablesmallbody.cpp | 199 ++++++------------ 4 files changed, 71 insertions(+), 148 deletions(-) diff --git a/modules/space/CMakeLists.txt b/modules/space/CMakeLists.txt index a2cf29a899..d6632f40d6 100644 --- a/modules/space/CMakeLists.txt +++ b/modules/space/CMakeLists.txt @@ -29,6 +29,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableconstellationbounds.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablerings.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesatellites.h + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesmallbody.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.h ${CMAKE_CURRENT_SOURCE_DIR}/translation/keplertranslation.h @@ -44,6 +45,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderableconstellationbounds.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablerings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesatellites.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablesmallbody.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderablestars.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/simplespheregeometry.cpp ${CMAKE_CURRENT_SOURCE_DIR}/translation/keplertranslation.cpp diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp index 7453ff44f5..585157e4c3 100644 --- a/modules/space/rendering/renderablesatellites.cpp +++ b/modules/space/rendering/renderablesatellites.cpp @@ -84,14 +84,6 @@ namespace { } namespace openspace { - - // The list of leap years only goes until 2056 as we need to touch this file then - // again anyway ;) - const std::vector LeapYears = { - 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, - 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, - 2044, 2048, 2052, 2056 - }; // Count the number of full days since the beginning of 2000 to the beginning of // the parameter 'year' diff --git a/modules/space/rendering/renderablesatellites.h b/modules/space/rendering/renderablesatellites.h index e052683cfc..0c230a6fe0 100644 --- a/modules/space/rendering/renderablesatellites.h +++ b/modules/space/rendering/renderablesatellites.h @@ -37,6 +37,16 @@ namespace openspace { +const std::vector LeapYears = { + 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, + 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, + 2044, 2048, 2052, 2056 +}; +int countDays(int year); +int countLeapSeconds(int year, int dayOfYear); +double calculateSemiMajorAxis(double meanMotion); +double epochFromSubstring(const std::string& epochString); + class RenderableSatellites : public Renderable { public: RenderableSatellites(const ghoul::Dictionary& dictionary); diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 6602658b11..82185536d5 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -84,14 +85,6 @@ namespace { } namespace openspace { - -// The list of leap years only goes until 2056 as we need to touch this file then -// again anyway, due to TLE format only supporting 2-digit years starting in 1957. -const std::vector LeapYears = { - 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, - 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, - 2044, 2048, 2052, 2056 -}; const std::vector DaysOfMonths = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 @@ -112,100 +105,6 @@ enum Months { December }; -// Count the number of full days since the beginning of 2000 to the beginning of -// the parameter 'year' -int countDays(int year) { - // Find the position of the current year in the vector, the difference - // between its position and the position of 2000 (for J2000) gives the - // number of leap years - constexpr const int Epoch = 2000; - constexpr const int DaysRegularYear = 365; - constexpr const int DaysLeapYear = 366; - - if (year == Epoch) { - return 0; - } - - // Get the position of the most recent leap year - const auto lb = std::lower_bound(LeapYears.begin(), LeapYears.end(), year); - - // Get the position of the epoch - const auto y2000 = std::find(LeapYears.begin(), LeapYears.end(), Epoch); - - // The distance between the two iterators gives us the number of leap years - const int nLeapYears = static_cast(std::abs(std::distance(y2000, lb))); - - const int nYears = std::abs(year - Epoch); - const int nRegularYears = nYears - nLeapYears; - - // Get the total number of days as the sum of leap years + non leap years - const int result = nRegularYears * DaysRegularYear + nLeapYears * DaysLeapYear; - return result; -} - -// Returns the number of leap seconds that lie between the {year, dayOfYear} -// time point and { 2000, 1 } -int countLeapSeconds(int year, int dayOfYear) { - // Find the position of the current year in the vector; its position in - // the vector gives the number of leap seconds - struct LeapSecond { - int year; - int dayOfYear; - bool operator<(const LeapSecond& rhs) const { - return std::tie(year, dayOfYear) < std::tie(rhs.year, rhs.dayOfYear); - } - }; - - const LeapSecond Epoch = { 2000, 1 }; - - // List taken from: https://www.ietf.org/timezones/data/leap-seconds.list - static const std::vector LeapSeconds = { - { 1972, 1 }, - { 1972, 183 }, - { 1973, 1 }, - { 1974, 1 }, - { 1975, 1 }, - { 1976, 1 }, - { 1977, 1 }, - { 1978, 1 }, - { 1979, 1 }, - { 1980, 1 }, - { 1981, 182 }, - { 1982, 182 }, - { 1983, 182 }, - { 1985, 182 }, - { 1988, 1 }, - { 1990, 1 }, - { 1991, 1 }, - { 1992, 183 }, - { 1993, 182 }, - { 1994, 182 }, - { 1996, 1 }, - { 1997, 182 }, - { 1999, 1 }, - { 2006, 1 }, - { 2009, 1 }, - { 2012, 183 }, - { 2015, 182 }, - { 2017, 1 } - }; - - // Get the position of the last leap second before the desired date - LeapSecond date { year, dayOfYear }; - const auto it = std::lower_bound(LeapSeconds.begin(), LeapSeconds.end(), date); - - // Get the position of the Epoch - const auto y2000 = std::lower_bound( - LeapSeconds.begin(), - LeapSeconds.end(), - Epoch - ); - - // The distance between the two iterators gives us the number of leap years - const int nLeapSeconds = static_cast(std::abs(std::distance(y2000, it))); - return nLeapSeconds; -} - int daysIntoGivenYear(int year, int month, int dayOfMonth) { //month and dayCount are zero-based month -= 1; @@ -217,7 +116,7 @@ int daysIntoGivenYear(int year, int month, int dayOfMonth) { return dayCount; } -double epochFromSubstring(const std::string& epochString) { +double epochFromYMDdSubstring(const std::string& epochString) { // The epochString is in the form: // YYYYMMDD.ddddddd // With YYYY as the year, MM the month (1 - 12), DD the day of month (1-31), @@ -367,54 +266,74 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { std::string line; std::string name; std::string ignore; - std::getline(file, line); // get rid of first line (header) - for (std::streamoff i = 0; i < numberOfLines; i++) { - KeplerParameters keplerElements; - // Object designator string - std::getline(file, name, ','); + std::streamoff csvLine; - // (Ignore object status for NEO, PHA, diameter) - std::getline(file, ignore, ','); - std::getline(file, ignore, ','); - std::getline(file, ignore, ','); + try { + std::getline(file, line); // get rid of first line (header) + for (csvLine = 0; csvLine < numberOfLines; csvLine++) { + KeplerParameters keplerElements; + // Object designator string + std::getline(file, name, ','); - // Eccentricity (unit-less) - std::getline(file, ignore, ','); - keplerElements.eccentricity = std::stod(ignore); + // (Ignore object status for NEO, PHA, diameter) + std::getline(file, ignore, ','); + std::getline(file, ignore, ','); + std::getline(file, ignore, ','); - // Semi-major axis (astronomical units - au) - std::getline(file, ignore, ','); - keplerElements.semiMajorAxis = std::stod(ignore); - keplerElements.semiMajorAxis *= convertAuToKm; + // Ignore date + std::getline(file, ignore, ','); - // Inclination (degrees) - std::getline(file, ignore, ','); - keplerElements.inclination = std::stod(ignore); + // Eccentricity (unit-less) + std::getline(file, ignore, ','); + keplerElements.eccentricity = std::stod(ignore); - // Longitude of ascending node (degrees) - std::getline(file, ignore, ','); - keplerElements.ascendingNode = std::stod(ignore); + // Semi-major axis (astronomical units - au) + std::getline(file, ignore, ','); + keplerElements.semiMajorAxis = std::stod(ignore); + keplerElements.semiMajorAxis *= convertAuToKm; - // Argument of Periapsis (degrees) - std::getline(file, ignore, ','); - keplerElements.argumentOfPeriapsis = std::stod(ignore); + // Inclination (degrees) + std::getline(file, ignore, ','); + keplerElements.inclination = std::stod(ignore); - // Mean Anomaly (degrees) - std::getline(file, ignore, ','); - keplerElements.meanAnomaly = std::stod(ignore); + // Longitude of ascending node (degrees) + std::getline(file, ignore, ','); + keplerElements.ascendingNode = std::stod(ignore); - // Epoch (MJD) - std::getline(file, ignore, ','); - keplerElements.epoch = epochFromSubstring(ignore); + // Argument of Periapsis (degrees) + std::getline(file, ignore, ','); + keplerElements.argumentOfPeriapsis = std::stod(ignore); - // Period (days) - std::getline(file, ignore, ','); - keplerElements.period = std::stod(ignore); - keplerElements.period *= convertDaysToSecs; + // Mean Anomaly (degrees) + std::getline(file, ignore, ','); + keplerElements.meanAnomaly = std::stod(ignore); - _sbData.push_back(keplerElements); - _sbNames.push_back(name); + // Epoch (MJD) + std::getline(file, ignore, ','); + keplerElements.epoch = epochFromYMDdSubstring(ignore); + + // Period (days) + std::getline(file, ignore); + keplerElements.period = std::stod(ignore); + keplerElements.period *= convertDaysToSecs; + + _sbData.push_back(keplerElements); + _sbNames.push_back(name); + } } + catch (std::invalid_argument&) { + LERROR(fmt::format( + "invalid_argument exception on line {} of {}", + csvLine - 1, filename + )); + } + catch (std::out_of_range&) { + LERROR(fmt::format( + "out_of_range exception on line {} of {}", + csvLine - 1, filename + )); + } + file.close(); } From 99c995565b13078e6727b092900a516179eec647 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Fri, 13 Dec 2019 07:47:05 -0700 Subject: [PATCH 077/214] Fix for issue 1023: prevents crash when using satellites and changing segments property, and fixes rendering errors. (#1028) --- .../earth/satellites/satellites_shared.asset | 2 +- .../space/rendering/renderablesatellites.cpp | 25 ++++++------------- .../space/rendering/renderablesatellites.h | 2 -- 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset index 58b3e35ec4..e5fde6d30c 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset @@ -56,7 +56,7 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder Renderable = { Type = "RenderableSatellites", Path = file, - Segments = 160, + Segments = 120, Color = color, Fade = 0.5 }, diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp index 7453ff44f5..5476bf828f 100644 --- a/modules/space/rendering/renderablesatellites.cpp +++ b/modules/space/rendering/renderablesatellites.cpp @@ -66,13 +66,6 @@ namespace { "method includes lines. If the rendering mode is set to Points, this value is " "ignored." }; - constexpr openspace::properties::Property::PropertyInfo FadeInfo = { - "Fade", - "Line fade", - "The fading factor that is applied to the trail if the 'EnableFade' value is " - "'true'. If it is 'false', this setting has no effect. The higher the number, " - "the less fading is applied." - }; constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { "Color", "Color", @@ -301,12 +294,6 @@ documentation::Documentation RenderableSatellites::Documentation() { Optional::Yes, LineWidthInfo.description }, - { - FadeInfo.identifier, - new DoubleVerifier, - Optional::Yes, - FadeInfo.description - }, { LineColorInfo.identifier, new DoubleVector3Verifier, @@ -320,8 +307,7 @@ documentation::Documentation RenderableSatellites::Documentation() { RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _path(PathInfo) - , _nSegments(SegmentsInfo) - , _lineFade(FadeInfo) + , _nSegments(SegmentsInfo, 120, 4, 1024) { documentation::testSpecificationAndThrow( @@ -332,16 +318,21 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) _path = dictionary.value(PathInfo.identifier); _nSegments = static_cast(dictionary.value(SegmentsInfo.identifier)); - _lineFade = static_cast(dictionary.value(FadeInfo.identifier)); if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) { _appearance.lineColor = dictionary.value(LineColorInfo.identifier); } + auto reinitializeTrailBuffers = [this]() { + initializeGL(); + }; + + _path.onChange(reinitializeTrailBuffers); + _nSegments.onChange(reinitializeTrailBuffers); + addPropertySubOwner(_appearance); addProperty(_path); addProperty(_nSegments); - addProperty(_lineFade); } diff --git a/modules/space/rendering/renderablesatellites.h b/modules/space/rendering/renderablesatellites.h index e052683cfc..b2bf0864a0 100644 --- a/modules/space/rendering/renderablesatellites.h +++ b/modules/space/rendering/renderablesatellites.h @@ -113,8 +113,6 @@ private: properties::StringProperty _path; properties::UIntProperty _nSegments; - properties::DoubleProperty _lineFade; - RenderableTrail::Appearance _appearance; glm::vec3 _position; From b2d2039dc27e9e489ea74ced58e0aff4430cacf2 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Fri, 13 Dec 2019 19:04:06 +0100 Subject: [PATCH 078/214] Trail fading for satellites and debris --- .../space/rendering/renderablesatellites.cpp | 22 ++++++++++++++----- .../space/rendering/renderablesatellites.h | 4 ---- modules/space/shaders/debrisViz_fs.glsl | 16 +++++++++++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/modules/space/rendering/renderablesatellites.cpp b/modules/space/rendering/renderablesatellites.cpp index 5476bf828f..9998db6b2c 100644 --- a/modules/space/rendering/renderablesatellites.cpp +++ b/modules/space/rendering/renderablesatellites.cpp @@ -308,7 +308,6 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _path(PathInfo) , _nSegments(SegmentsInfo, 120, 4, 1024) - { documentation::testSpecificationAndThrow( Documentation(), @@ -322,6 +321,14 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) { _appearance.lineColor = dictionary.value(LineColorInfo.identifier); } + if (dictionary.hasKeyAndValue("FadeInfo")) { + _appearance.lineFade = static_cast( + dictionary.value("FadeInfo") + ); + } + else { + _appearance.lineFade = 20; + } auto reinitializeTrailBuffers = [this]() { initializeGL(); @@ -333,6 +340,9 @@ RenderableSatellites::RenderableSatellites(const ghoul::Dictionary& dictionary) addPropertySubOwner(_appearance); addProperty(_path); addProperty(_nSegments); + addProperty(_opacity); + + setRenderBin(Renderable::RenderBin::Overlay); } @@ -475,7 +485,6 @@ void RenderableSatellites::initializeGL() { _uniformCache.opacity = _programObject->uniformLocation("opacity"); updateBuffers(); - setRenderBin(Renderable::RenderBin::Overlay); } void RenderableSatellites::deinitializeGL() { @@ -514,9 +523,12 @@ void RenderableSatellites::render(const RenderData& data, RendererTasks&) { data.camera.combinedViewMatrix() * modelTransform ); + // Because we want the property to work similar to the planet trails + float fade = static_cast(pow(_appearance.lineFade.maxValue() - _appearance.lineFade, 2.0)); + _programObject->setUniform(_uniformCache.projection, data.camera.projectionMatrix()); _programObject->setUniform(_uniformCache.color, _appearance.lineColor); - _programObject->setUniform(_uniformCache.lineFade, _appearance.lineFade); + _programObject->setUniform(_uniformCache.lineFade, fade); glLineWidth(_appearance.lineWidth); @@ -595,10 +607,10 @@ void RenderableSatellites::updateBuffers() { ); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)0); // stride : 4*sizeof(GL_FLOAT) + 2*sizeof(GL_DOUBLE) + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), nullptr); glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4*sizeof(GL_FLOAT)) ); + glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4 * sizeof(GL_FLOAT))); glBindVertexArray(0); diff --git a/modules/space/rendering/renderablesatellites.h b/modules/space/rendering/renderablesatellites.h index b2bf0864a0..8f58d936d8 100644 --- a/modules/space/rendering/renderablesatellites.h +++ b/modules/space/rendering/renderablesatellites.h @@ -94,10 +94,6 @@ private: /// trail. std::vector _vertexBufferData; - /// The index array that is potentially used in the draw call. If this is empty, no - /// element draw call is used. - std::vector _indexBufferData; - GLuint _vertexArray; GLuint _vertexBuffer; GLuint _indexBuffer; diff --git a/modules/space/shaders/debrisViz_fs.glsl b/modules/space/shaders/debrisViz_fs.glsl index ada17beb95..e54886d99a 100644 --- a/modules/space/shaders/debrisViz_fs.glsl +++ b/modules/space/shaders/debrisViz_fs.glsl @@ -63,15 +63,25 @@ Fragment getFragment() { vertexDistance_f += 1.0; } - float invert = 1.0 - vertexDistance_f; - float fade = clamp(invert * lineFade, 0.0, 1.0); + float invert = pow((1.0 - vertexDistance_f), lineFade); + float fade = clamp(invert, 0.0, 1.0); + // Currently even fully transparent lines can occlude other lines, thus we discard + // these fragments since debris and satellites are rendered so close to each other + if (fade < 0.05) { + discard; + } Fragment frag; + + // Use additive blending for some values to make the discarding less abrupt + if (fade < 0.15) { + frag.blend = BLEND_MODE_ADDITIVE; + } + frag.color = vec4(color, fade * opacity); frag.depth = vs_position_w; frag.gPosition = viewSpacePosition; frag.gNormal = vec4(1, 1, 1, 0); - // frag.blend = BLEND_MODE_ADDITIVE; // to debug using colors use this if-statment. From cf3a64110399caa37b3289d716a8b2c852b27cfa Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 09:50:34 +0100 Subject: [PATCH 079/214] Some small cleanup Remove virtual attribute from some of the raycaster functions --- data/assets/scene/milkyway/milkyway/volume.asset | 8 ++++---- include/openspace/rendering/volumeraycaster.h | 8 ++++---- modules/galaxy/rendering/renderablegalaxy.cpp | 5 ++--- src/rendering/framebufferrenderer.cpp | 4 +--- src/rendering/volumeraycaster.cpp | 16 ++++++++++++++++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index adbd05e08a..2ae420e931 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -21,7 +21,7 @@ local MilkyWayVolumeGalaxy = { -- The center of the Milky Way is approximately 8 kiloparsec from the Sun. -- The x-axis of galactic coordinates points from the sun towards the center -- of the galaxy. - Position = {8 * kiloparsec, 0, 0} + Position = { 8 * kiloparsec, 0, 0 } } }, Renderable = { @@ -29,12 +29,12 @@ local MilkyWayVolumeGalaxy = { StepSize = 0.01, AbsorptionMultiply = 200, EmissionMultiply = 250, - Rotation = {3.1415926, 3.1248, 4.45741}, + Rotation = { 3.1415926, 3.1248, 4.45741 }, Volume = { Type = "Volume", Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", - Dimensions = {1024, 1024, 128}, - Size = {1.2E21, 1.2E21, 0.15E21}, + Dimensions = { 1024, 1024, 128 }, + Size = { 1.2E21, 1.2E21, 0.15E21 }, Downscale = 0.4, }, Points = { diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index 687a5f335a..aa1133606e 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -129,13 +129,13 @@ public: */ virtual std::string helperPath() const = 0; - virtual void setMaxSteps(int nsteps) { _rayCastMaxSteps = nsteps; }; + void setMaxSteps(int nsteps); - virtual const int maxSteps() const { return _rayCastMaxSteps; }; + int maxSteps() const; - virtual void setDownscaleRender(float value) { _downscaleRenderConst = value; }; + void setDownscaleRender(float value); - virtual const float downscaleRender() const { return _downscaleRenderConst; }; + float downscaleRender() const; private: /** diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 9dfe003559..71edb8d372 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -245,8 +245,7 @@ namespace openspace { ); } else { - LINFO("Number of raycasting steps not specified for Milkway Galaxy." - " Using default value."); + LINFO("Number of raycasting steps not specified. Using default value."); } _downScaleVolumeRendering.setVisibility( @@ -254,7 +253,7 @@ namespace openspace { ); if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { _downScaleVolumeRendering = - volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); + volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); } if (!dictionary.hasKeyAndValue("Points")) { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 3e145ecf5a..a6b327149b 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1271,14 +1271,12 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); - } } } void FramebufferRenderer::performDeferredTasks( - const std::vector& tasks - ) + const std::vector& tasks) { for (const DeferredcasterTask& deferredcasterTask : tasks) { Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster; diff --git a/src/rendering/volumeraycaster.cpp b/src/rendering/volumeraycaster.cpp index 17d13627c0..954bda7ac7 100644 --- a/src/rendering/volumeraycaster.cpp +++ b/src/rendering/volumeraycaster.cpp @@ -33,4 +33,20 @@ bool VolumeRaycaster::isCameraInside(const RenderData&, glm::vec3&) { return false; } +void VolumeRaycaster::setMaxSteps(int nsteps) { + _rayCastMaxSteps = nsteps; +} + +int VolumeRaycaster::maxSteps() const { + return _rayCastMaxSteps; +} + +void VolumeRaycaster::setDownscaleRender(float value) { + _downscaleRenderConst = value; +} + +float VolumeRaycaster::downscaleRender() const { + return _downscaleRenderConst; +} + } // namespace openspace From 2f1805b6514f81322c0343a6dc4627ac0ea387f3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 10:09:41 +0100 Subject: [PATCH 080/214] Some general cleanup of the code --- modules/touch/include/directinputsolver.h | 34 ++++++-------- modules/touch/include/touchinteraction.h | 4 +- modules/touch/src/directinputsolver.cpp | 56 +++++++++++++---------- modules/touch/src/touchinteraction.cpp | 54 +++++++++++++--------- modules/touch/src/win32_touch.cpp | 38 ++++++++++----- 5 files changed, 109 insertions(+), 77 deletions(-) diff --git a/modules/touch/include/directinputsolver.h b/modules/touch/include/directinputsolver.h index 418f01a535..50f5cbeceb 100644 --- a/modules/touch/include/directinputsolver.h +++ b/modules/touch/include/directinputsolver.h @@ -25,11 +25,8 @@ #ifndef __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ #define __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ - #include - #include - #include @@ -38,33 +35,30 @@ namespace openspace { class Camera; class SceneGraphNode; -// Stores the selected node, the cursor ID as well as the surface coordinates the -// cursor touched -struct SelectedBody { - long id; - SceneGraphNode* node; - glm::dvec3 coordinates; -}; - class DirectInputSolver { public: + // Stores the selected node, the cursor ID as well as the surface coordinates the + // cursor touched + struct SelectedBody { + long id; + SceneGraphNode* node; + glm::dvec3 coordinates; + }; + DirectInputSolver(); bool solve(const std::vector& list, - const std::vector& selectedBodies, - std::vector* calculatedValues, - const Camera& camera); - int getNDof() { return _nDof; } + const std::vector& selectedBodies, + std::vector* calculatedValues, const Camera& camera); + int getNDof() const; - const LMstat& getLevMarqStat() { return _lmstat; } - void setLevMarqVerbosity(bool verbose) { _lmstat.verbose = verbose; } + const LMstat& getLevMarqStat(); + void setLevMarqVerbosity(bool verbose); private: - int _nDof; + int _nDof = 0; LMstat _lmstat; }; - - } // openspace namespace #endif // __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ diff --git a/modules/touch/include/touchinteraction.h b/modules/touch/include/touchinteraction.h index 5cfddec46e..7158973b70 100644 --- a/modules/touch/include/touchinteraction.h +++ b/modules/touch/include/touchinteraction.h @@ -237,9 +237,9 @@ private: bool _zoomOutTap; bool _lmSuccess; bool _guiON; - std::vector _selected; + std::vector _selected; SceneGraphNode* _pickingSelected = nullptr; - std::unique_ptr _solver; + DirectInputSolver _solver; glm::dquat _toSlerp; glm::dvec3 _centroid; diff --git a/modules/touch/src/directinputsolver.cpp b/modules/touch/src/directinputsolver.cpp index 43624e6af6..6ceed7dac4 100644 --- a/modules/touch/src/directinputsolver.cpp +++ b/modules/touch/src/directinputsolver.cpp @@ -24,27 +24,24 @@ #include - #include #include +namespace { + // Used in the LM algorithm + struct FunctionData { + std::vector selectedPoints; + std::vector screenPoints; + int nDOF; + const openspace::Camera* camera; + openspace::SceneGraphNode* node; + LMstat stats; + }; +} namespace openspace { -// Used in the LM algorithm -struct FunctionData { - std::vector selectedPoints; - std::vector screenPoints; - int nDOF; - const Camera* camera; - SceneGraphNode* node; - LMstat stats; -}; - - -DirectInputSolver::DirectInputSolver() - : _nDof(0) -{ +DirectInputSolver::DirectInputSolver() { levmarq_init(&_lmstat); } @@ -106,8 +103,7 @@ double distToMinimize(double* par, int x, void* fdata, LMstat* lmstat) { dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); - dvec3 rotationDiffVec3 = - centerToCamera * rotationDiffWorldSpace - centerToCamera; + dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera; camPos += rotationDiffVec3; centerToCamera = camPos - centerPos; @@ -117,7 +113,8 @@ double distToMinimize(double* par, int x, void* fdata, LMstat* lmstat) { lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, - lookUpWhenFacingCenter); + lookUpWhenFacingCenter + ); globalCamRot = normalize(quat_cast(inverse(lookAtMat))); } { // Zooming @@ -205,11 +202,9 @@ void gradient(double* g, double* par, int x, void* fdata, LMstat* lmstat) { } bool DirectInputSolver::solve(const std::vector& list, - const std::vector& selectedBodies, - std::vector *parameters, - const Camera &camera) + const std::vector& selectedBodies, + std::vector* parameters, const Camera& camera) { - int nFingers = std::min(static_cast(list.size()), 3); _nDof = std::min(nFingers * 2, 6); @@ -220,7 +215,10 @@ bool DirectInputSolver::solve(const std::vector& list, for (int i = 0; i < nFingers; ++i) { const SelectedBody& sb = selectedBodies.at(i); selectedPoints.push_back(sb.coordinates); - screenPoints.emplace_back(2 * (list[i].getX() - 0.5), -2 * (list[i].getY() - 0.5)); + screenPoints.emplace_back( + 2 * (list[i].getX() - 0.5), + -2 * (list[i].getY() - 0.5) + ); // This might be needed when we're directing the touchtable from another screen? // std::vector::const_iterator c = std::find_if( @@ -267,5 +265,17 @@ bool DirectInputSolver::solve(const std::vector& list, return result; } +int DirectInputSolver::getNDof() const { + return _nDof; +} + +const LMstat& DirectInputSolver::getLevMarqStat() { + return _lmstat; +} + +void DirectInputSolver::setLevMarqVerbosity(bool verbose) { + _lmstat.verbose = verbose; +} + } // openspace namespace diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index fa0cb44c56..eab3fa0185 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -322,7 +322,6 @@ TouchInteraction::TouchInteraction() , _zoomOutTap(false) , _lmSuccess(true) , _guiON(false) - , _solver(new DirectInputSolver()) #ifdef TOUCH_DEBUG_PROPERTIES , _debugProperties() #endif @@ -518,8 +517,8 @@ void TouchInteraction::directControl(const std::vector& list) { std::vector par(6, 0.0); par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit par.at(1) = _lastVel.orbit.y; - _lmSuccess = _solver->solve(list, _selected, &par, *_camera); - int nDof = _solver->getNDof(); + _lmSuccess = _solver.solve(list, _selected, &par, *_camera); + int nDof = _solver.getNDof(); if (_lmSuccess && !_unitTest) { // if good values were found set new camera state @@ -574,7 +573,7 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { glm::dquat camToWorldSpace = _camera->rotationQuaternion(); glm::dvec3 camPos = _camera->positionVec3(); - std::vector newSelected; + std::vector newSelected; //node & distance std::tuple currentlyPicked = { @@ -594,24 +593,32 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { long id = c.getSessionID(); for (SceneGraphNode* node : selectableNodes) { - double boundingSphereSquared = double(node->boundingSphere()) * double(node->boundingSphere()); + double boundingSphereSquared = static_cast(node->boundingSphere()) * + static_cast(node->boundingSphere()); glm::dvec3 camToSelectable = node->worldPosition() - camPos; double intersectionDist = 0.0; - bool intersected = glm::intersectRaySphere(camPos, raytrace, node->worldPosition(), - boundingSphereSquared, intersectionDist); + bool intersected = glm::intersectRaySphere( + camPos, + raytrace, + node->worldPosition(), + boundingSphereSquared, + intersectionDist + ); if (intersected) { glm::dvec3 intersectionPos = camPos + raytrace * intersectionDist; glm::dvec3 pointInModelView = glm::inverse(node->worldRotationMatrix()) * (intersectionPos - node->worldPosition()); // Add id, node and surface coordinates to the selected list - std::vector::iterator oldNode = std::find_if( + auto oldNode = std::find_if( newSelected.begin(), newSelected.end(), - [id](SelectedBody s) { return s.id == id; } + [id](const DirectInputSolver::SelectedBody& s) { return s.id == id; } ); if (oldNode != newSelected.end()) { - double oldNodeDist = glm::length(oldNode->node->worldPosition() - camPos); + double oldNodeDist = glm::length( + oldNode->node->worldPosition() - camPos + ); if (glm::length(camToSelectable) < oldNodeDist) { // new node is closer, remove added node and add the new one // instead @@ -1127,8 +1134,11 @@ void TouchInteraction::step(double dt) { else if (_zoomInLimit.value() < zoomInBounds) { // If zoom in limit is less than the estimated node radius we need to // make sure we do not get too close to possible height maps - SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle(camPos); - glm::dvec3 centerToActualSurfaceModelSpace = posHandle.centerToReferenceSurface + + SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle( + camPos + ); + glm::dvec3 centerToActualSurfaceModelSpace = + posHandle.centerToReferenceSurface + posHandle.referenceSurfaceOutDirection * posHandle.heightToSurface; glm::dvec3 centerToActualSurface = glm::dmat3(anchor->modelTransform()) * centerToActualSurfaceModelSpace; @@ -1137,9 +1147,8 @@ void TouchInteraction::step(double dt) { // Because of heightmaps we should make sure we do not go through the surface if (_zoomInLimit.value() < nodeRadius) { #ifdef TOUCH_DEBUG_PROPERTIES - LINFO(fmt::format( - "{}: Zoom In Limit should be larger than anchor center to surface, setting it to {}", - _loggerCat, zoomInBounds)); + LINFO(fmt::format("{}: Zoom In limit should be larger than anchor " + "center to surface, setting it to {}", _loggerCat, zoomInBounds)); #endif _zoomInLimit.setValue(zoomInBounds); } @@ -1159,9 +1168,12 @@ void TouchInteraction::step(double dt) { double currentPosDistance = length(centerToCamera); // Possible with other navigations performed outside touch interaction - bool currentPosViolatingZoomOutLimit = (currentPosDistance >= _zoomOutLimit.value()); - bool willNewPositionViolateZoomOutLimit = (newPosDistance >= _zoomOutLimit.value()); - bool willNewPositionViolateZoomInLimit = (newPosDistance < _zoomInLimit.value()); + bool currentPosViolatingZoomOutLimit = + (currentPosDistance >= _zoomOutLimit.value()); + bool willNewPositionViolateZoomOutLimit = + (newPosDistance >= _zoomOutLimit.value()); + bool willNewPositionViolateZoomInLimit = + (newPosDistance < _zoomInLimit.value()); if (!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){ camPos += zoomDistanceIncrement; @@ -1214,7 +1226,7 @@ void TouchInteraction::step(double dt) { void TouchInteraction::unitTest() { if (_unitTest) { - _solver->setLevMarqVerbosity(true); + _solver.setLevMarqVerbosity(true); // set _selected pos and new pos (on screen) std::vector lastFrame = { @@ -1235,7 +1247,7 @@ void TouchInteraction::unitTest() { snprintf(buffer, sizeof(char) * 32, "lmdata%i.csv", _numOfTests); _numOfTests++; std::ofstream file(buffer); - file << _solver->getLevMarqStat().data; + file << _solver.getLevMarqStat().data; // clear everything _selected.clear(); @@ -1247,7 +1259,7 @@ void TouchInteraction::unitTest() { _lastVel = _vel; _unitTest = false; - _solver->setLevMarqVerbosity(false); + _solver.setLevMarqVerbosity(false); // could be the camera copy in func } } diff --git a/modules/touch/src/win32_touch.cpp b/modules/touch/src/win32_touch.cpp index 32331c8bb3..03ded0a114 100644 --- a/modules/touch/src/win32_touch.cpp +++ b/modules/touch/src/win32_touch.cpp @@ -28,11 +28,8 @@ #include #include - #include - #include - #include #include @@ -42,7 +39,7 @@ namespace { bool gStarted{ false }; TUIO::TuioServer* gTuioServer{ nullptr }; std::unordered_map gCursorMap; -} +} // namespace namespace openspace { @@ -69,22 +66,32 @@ LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) { // native touch to screen conversion ScreenToClient(pStruct->hwnd, reinterpret_cast(&p)); - float xPos = static_cast(p.x) / static_cast(rect.right - rect.left); - float yPos = static_cast(p.y) / static_cast(rect.bottom - rect.top); + float xPos = static_cast(p.x) / + static_cast(rect.right - rect.left); + float yPos = static_cast(p.y) / + static_cast(rect.bottom - rect.top); if (pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { // Handle new touchpoint gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); - gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor(xPos, yPos); + gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor( + xPos, + yPos + ); gTuioServer->commitFrame(); } else if (pointerInfo.pointerFlags & POINTER_FLAG_UPDATE) { // Handle update of touchpoint TUIO::TuioTime frameTime = TUIO::TuioTime::getSessionTime(); - if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime) { + if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime) + { break; } gTuioServer->initFrame(frameTime); - gTuioServer->updateTuioCursor(gCursorMap[pointerInfo.pointerId], xPos, yPos); + gTuioServer->updateTuioCursor( + gCursorMap[pointerInfo.pointerId], + xPos, + yPos + ); gTuioServer->commitFrame(); } else if (pointerInfo.pointerFlags & POINTER_FLAG_UP) { @@ -139,14 +146,23 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow) const DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD; ATOM atom = ::GlobalAddAtom(MICROSOFT_TABLETPENSERVICE_PROPERTY); - ::SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast(dwHwndTabletProperty)); + ::SetProp( + hWnd, + MICROSOFT_TABLETPENSERVICE_PROPERTY, + reinterpret_cast(dwHwndTabletProperty) + ); ::GlobalDeleteAtom(atom); if (!gStarted) { gStarted = true; gTuioServer = new TUIO::TuioServer("localhost", 3333); TUIO::TuioTime::initSession(); - gTouchHook = SetWindowsHookExW(WH_GETMESSAGE, HookCallback, GetModuleHandleW(NULL), GetCurrentThreadId()); + gTouchHook = SetWindowsHookExW( + WH_GETMESSAGE, + HookCallback, + GetModuleHandleW(NULL), + GetCurrentThreadId() + ); if (!gTouchHook) { LINFO(fmt::format("Failed to setup WindowsHook for touch input redirection")); delete gTuioServer; From dfa25b28e6c3ff83efce435790268ec74fb67544 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 10:26:42 +0100 Subject: [PATCH 081/214] Disable labels on default Some small code cleanup --- .../dwarf_planets/pluto/pluto.asset | 20 +-- .../solarsystem/planets/earth/earth.asset | 10 +- .../solarsystem/planets/jupiter/jupiter.asset | 22 +-- .../scene/solarsystem/planets/mars/mars.asset | 14 +- .../solarsystem/planets/mercury/mercury.asset | 22 +-- .../solarsystem/planets/neptune/neptune.asset | 22 +-- .../solarsystem/planets/saturn/saturn.asset | 22 +-- .../solarsystem/planets/uranus/uranus.asset | 22 +-- .../solarsystem/planets/venus/venus.asset | 22 +-- data/assets/scene/solarsystem/sun/sun.asset | 10 +- modules/base/rendering/renderablelabels.cpp | 143 ++++++++++-------- modules/base/rendering/renderablelabels.h | 68 ++++----- 12 files changed, 129 insertions(+), 268 deletions(-) diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index 8f2d2f3036..db18a54cc1 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -62,18 +62,6 @@ local Pluto = { local PlutoLabel = { Identifier = "PlutoLabel", Parent = Pluto.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { Enabled = true, Type = "RenderableLabels", @@ -83,13 +71,7 @@ local PlutoLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, BlendMode = "Additive", - LabelOrientationOption = "Camera View Direction", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + LabelOrientationOption = "Camera View Direction" }, GUI = { Name = "Pluto Label", diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index 1b735b3e66..dc14382046 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -303,7 +303,7 @@ local EarthLabel = { -- -- } -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Earth", FontSize = 100.0, @@ -318,13 +318,7 @@ local EarthLabel = { FadeStartSpeed = 1.0, FadeEndUnit = "au", FadeEndDistance = 15.0, - FadeEndSpeed = 25.0, - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + FadeEndSpeed = 25.0 }, GUI = { Name = "Earth Label", diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index 1996531c87..1ce8b88fff 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -45,20 +45,8 @@ local Jupiter = { local JupiterLabel = { Identifier = "JupiterLabel", Parent = Jupiter.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Jupiter", FontSize = 100.0, @@ -66,13 +54,7 @@ local JupiterLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + BlendMode = "Additive" }, GUI = { Name = "Jupiter Label", diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index 0575f88e03..cee87159c5 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -190,20 +190,8 @@ local Mars = { local MarsLabel = { Identifier = "MarsLabel", Parent = Mars.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Mars", FontSize = 100.0, diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index 1d24fa241d..98bd538f33 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -226,20 +226,8 @@ local Mercury = { local MercuryLabel = { Identifier = "MercuryLabel", Parent = Mercury.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Mercury", FontSize = 100.0, @@ -247,13 +235,7 @@ local MercuryLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + BlendMode = "Additive" }, GUI = { Name = "Mercury Label", diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset index 5e617b7286..a7546d5f2a 100644 --- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset +++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset @@ -43,20 +43,8 @@ local Neptune = { local NeptuneLabel = { Identifier = "NeptuneLabel", Parent = Neptune.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Neptune", FontSize = 100.0, @@ -64,13 +52,7 @@ local NeptuneLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + BlendMode = "Additive" }, GUI = { Name = "Neptune Label", diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 22a223eb3a..853bd1ce8b 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -60,20 +60,8 @@ local SaturnRings = { local SaturnLabel = { Identifier = "SaturnLabel", Parent = Saturn.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Saturn", FontSize = 100.0, @@ -81,13 +69,7 @@ local SaturnLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, BlendMode = "Additive", - LabelOrientationOption = "Camera View Direction", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + LabelOrientationOption = "Camera View Direction" }, GUI = { Name = "Saturn Label", diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index f522c2fa89..758f87f998 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -45,20 +45,8 @@ local Uranus = { local UranusLabel = { Identifier = "UranusLabel", Parent = Uranus.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Uranus", FontSize = 100.0, @@ -66,13 +54,7 @@ local UranusLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + BlendMode = "Additive" }, GUI = { Name = "Neptune Label", diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 3572c07083..52cfe29303 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -67,20 +67,8 @@ local Venus = { local VenusLabel = { Identifier = "VenusLabel", Parent = Venus.Identifier, - -- Transform = { - -- Translation = { - -- Type = "SpiceTranslation", - -- Target = "EARTH", - -- Observer = "EARTH BARYCENTER" - -- }, - -- -- Rotation = { - -- -- Type = "SpiceRotation", - -- -- SourceFrame = "IAU_MOON", - -- -- DestinationFrame = "GALACTIC" - -- -- } - -- }, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Venus", FontSize = 100.0, @@ -88,13 +76,7 @@ local VenusLabel = { LabelMaxSize = 100.0, LabelMinSize = 1.0, LabelOrientationOption = "Camera View Direction", - BlendMode = "Additive", - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + BlendMode = "Additive" }, GUI = { Name = "Venus Label", diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index 0ca4e4a8be..9d44fb2462 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -31,7 +31,7 @@ local SunLabel = { Identifier = "SunLabel", Parent = Sun.Identifier, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Sun", FontSize = 100.0, @@ -46,13 +46,7 @@ local SunLabel = { FadeStartSpeed = 1.375, FadeEndUnit = "pc", FadeEndDistance = 1.326, - FadeEndSpeed = 1.0, - TransformationMatrix = { - 1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - }, + FadeEndSpeed = 1.0 }, GUI = { Name = "Sun Label", diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index a5b33f2624..5c8bbd20ae 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -193,7 +193,9 @@ documentation::Documentation RenderableLabels::Documentation() { }, { LabelOrientationOptionInfo.identifier, - new StringInListVerifier({ "Camera View Direction", "Camera Position Normal" }), + new StringInListVerifier( + { "Camera View Direction", "Camera Position Normal" } + ), Optional::Yes, LabelOrientationOptionInfo.description, }, @@ -253,13 +255,19 @@ documentation::Documentation RenderableLabels::Documentation() { }, { FadeStartUnitOptionInfo.identifier, - new StringInListVerifier({"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + new StringInListVerifier( + { "m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", + "Gpc", "Gly"} + ), Optional::Yes, FadeStartUnitOptionInfo.description, }, { FadeEndUnitOptionInfo.identifier, - new StringInListVerifier({"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", "Gpc", "Gly"}), + new StringInListVerifier( + {"m", "Km", "Mm", "Gm", "au", "Tm", "Pm", "pc", "Kpc", "Mpc", + "Gpc", "Gly"} + ), Optional::Yes, FadeEndUnitOptionInfo.description, }, @@ -311,9 +319,18 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f) , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f) , _fadeEndSpeed(FadeEndSpeedInfo, 1.f, 1.f, 100.f) - , _labelOrientationOption(LabelOrientationOptionInfo, properties::OptionProperty::DisplayType::Dropdown) - , _fadeStartUnitOption(FadeStartUnitOptionInfo, properties::OptionProperty::DisplayType::Dropdown) - , _fadeEndUnitOption(FadeEndUnitOptionInfo, properties::OptionProperty::DisplayType::Dropdown) + , _labelOrientationOption( + LabelOrientationOptionInfo, + properties::OptionProperty::DisplayType::Dropdown + ) + , _fadeStartUnitOption( + FadeStartUnitOptionInfo, + properties::OptionProperty::DisplayType::Dropdown + ) + , _fadeEndUnitOption( + FadeEndUnitOptionInfo, + properties::OptionProperty::DisplayType::Dropdown + ) { documentation::testSpecificationAndThrow( Documentation(), @@ -357,7 +374,9 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _labelOrientationOption = NormalDirection; if (dictionary.hasKeyAndValue(LabelOrientationOptionInfo.identifier)) { - const std::string o = dictionary.value(LabelOrientationOptionInfo.identifier); + const std::string o = dictionary.value( + LabelOrientationOptionInfo.identifier + ); if (o == "Camera View Direction") { _labelOrientationOption = ViewDirection; @@ -446,7 +465,9 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeStartUnitOption = AU; if (dictionary.hasKey(FadeStartUnitOptionInfo.identifier)) { - std::string unit = dictionary.value(FadeStartUnitOptionInfo.identifier); + std::string unit = dictionary.value( + FadeStartUnitOptionInfo.identifier + ); if (unit == MeterUnit) { _fadeStartUnitOption = Meter; } @@ -521,7 +542,9 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeEndUnitOption = AU; if (dictionary.hasKey(FadeEndUnitOptionInfo.identifier)) { - std::string unit = dictionary.value(FadeEndUnitOptionInfo.identifier); + std::string unit = dictionary.value( + FadeEndUnitOptionInfo.identifier + ); if (unit == MeterUnit) { _fadeEndUnitOption = Meter; } @@ -573,9 +596,6 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) } addProperty(_fadeEndSpeed); - - - //setBoundingSphere(_size); } bool RenderableLabels::isReady() const { @@ -603,8 +623,7 @@ void RenderableLabels::initializeGL() { } } -void RenderableLabels::deinitializeGL() { -} +void RenderableLabels::deinitializeGL() {} void RenderableLabels::render(const RenderData& data, RendererTasks&) { @@ -626,7 +645,13 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { float startX = _fadeStartDistance * sUnit; float endX = _fadeEndDistance * eUnit; //fadeInVariable = changedPerlinSmoothStepFunc(distanceNodeToCamera, startX, endX); - fadeInVariable = linearSmoothStepFunc(distanceNodeToCamera, startX, endX, sUnit, eUnit); + fadeInVariable = linearSmoothStepFunc( + distanceNodeToCamera, + startX, + endX, + sUnit, + eUnit + ); } glm::dmat4 modelMatrix(1.0); @@ -668,8 +693,7 @@ void RenderableLabels::setLabelText(const std::string & newText) { void RenderableLabels::renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, - const glm::dvec3& orthoUp, - float fadeInVariable) + const glm::dvec3& orthoUp, float fadeInVariable) { glm::vec4 textColor = _labelColor; @@ -704,9 +728,8 @@ void RenderableLabels::renderLabels(const RenderData& data, ); } -float RenderableLabels::changedPerlinSmoothStepFunc(const float x, - const float startX, - const float endX) const +float RenderableLabels::changedPerlinSmoothStepFunc(float x, float startX, + float endX) const { float f1 = 6.f * powf((x - startX), 5.f) - 15.f * powf((x - startX), 4.f) + 10.f * powf((x - startX), 3.f); @@ -725,11 +748,8 @@ float RenderableLabels::changedPerlinSmoothStepFunc(const float x, } } -float RenderableLabels::linearSmoothStepFunc(const float x, - const float startX, - const float endX, - const float sUnit, - const float eUnit) const +float RenderableLabels::linearSmoothStepFunc(float x, float startX, float endX, + float sUnit, float eUnit) const { float sdiv = 1.f / (sUnit * _fadeStartSpeed); float ediv = -1.f / (eUnit * _fadeEndSpeed); @@ -752,44 +772,45 @@ float RenderableLabels::getUnit(int unit) const { float scale = 0.f; switch (static_cast(unit)) { - case Meter: - scale = 1.f; - break; - case Kilometer: - scale = 1e3; - break; - case Megameter: - scale = 1e6; - break; - case Gigameter: - scale = 1e9; - break; - case AU: - scale = 149597870700.f; - break; - case Terameter: - scale = 1e12; - break; - case Petameter: - scale = 1e15; - break; - case Parsec: - scale = static_cast(PARSEC); - break; - case Kiloparsec: - scale = static_cast(1e3 * PARSEC); - break; - case Megaparsec: - scale = static_cast(1e6 * PARSEC); - break; - case Gigaparsec: - scale = static_cast(1e9 * PARSEC); - break; - case GigalightYears: - scale = static_cast(306391534.73091 * PARSEC); - break; + case Meter: + scale = 1.f; + break; + case Kilometer: + scale = 1e3; + break; + case Megameter: + scale = 1e6; + break; + case Gigameter: + scale = 1e9; + break; + case AU: + scale = 149597870700.f; + break; + case Terameter: + scale = 1e12; + break; + case Petameter: + scale = 1e15; + break; + case Parsec: + scale = static_cast(PARSEC); + break; + case Kiloparsec: + scale = static_cast(1e3 * PARSEC); + break; + case Megaparsec: + scale = static_cast(1e6 * PARSEC); + break; + case Gigaparsec: + scale = static_cast(1e9 * PARSEC); + break; + case GigalightYears: + scale = static_cast(306391534.73091 * PARSEC); + break; } return scale; } + } // namespace openspace diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index c0fa9848e9..0f5bbf6f99 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -54,22 +54,6 @@ namespace documentation { struct Documentation; } struct LinePoint; class RenderableLabels : public Renderable { -private: - enum Unit { - Meter = 0, - Kilometer = 1, - Megameter = 2, - Gigameter = 3, - AU = 4, - Terameter = 5, - Petameter = 6, - Parsec = 7, - Kiloparsec = 8, - Megaparsec = 9, - Gigaparsec = 10, - GigalightYears = 11 - }; - public: RenderableLabels(const ghoul::Dictionary& dictionary); @@ -90,37 +74,43 @@ protected: properties::OptionProperty _blendMode; private: + enum Unit { + Meter = 0, + Kilometer, + Megameter, + Gigameter, + AU, + Terameter, + Petameter, + Parsec, + Kiloparsec, + Megaparsec, + Gigaparsec, + GigalightYears + }; + void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); - float changedPerlinSmoothStepFunc( - const float x, - const float startX, - const float endX - ) const; + float changedPerlinSmoothStepFunc(float x, float startX, float endX) const; - float linearSmoothStepFunc( - const float x, - const float startX, - const float endX, - const float sUnit, - const float eUnit - ) const; + float linearSmoothStepFunc(float x, float startX, float endX, float sUnit, + float eUnit) const; float getUnit(int unit) const; - properties::Vec4Property _labelColor; - properties::FloatProperty _labelSize; - properties::FloatProperty _fontSize; - properties::FloatProperty _labelMinSize; - properties::FloatProperty _labelMaxSize; - properties::BoolProperty _pixelSizeControl; - properties::BoolProperty _enableFadingEffect; + properties::Vec4Property _labelColor; + properties::FloatProperty _labelSize; + properties::FloatProperty _fontSize; + properties::FloatProperty _labelMinSize; + properties::FloatProperty _labelMaxSize; + properties::BoolProperty _pixelSizeControl; + properties::BoolProperty _enableFadingEffect; properties::StringProperty _labelText; - properties::FloatProperty _fadeStartDistance; - properties::FloatProperty _fadeEndDistance; - properties::FloatProperty _fadeStartSpeed; - properties::FloatProperty _fadeEndSpeed; + properties::FloatProperty _fadeStartDistance; + properties::FloatProperty _fadeEndDistance; + properties::FloatProperty _fadeStartSpeed; + properties::FloatProperty _fadeEndSpeed; properties::OptionProperty _labelOrientationOption; properties::OptionProperty _fadeStartUnitOption; From bfc2da3475160f2741a2964f6df140c815fc288d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 10:38:10 +0100 Subject: [PATCH 082/214] Make a defaut keybind for toggling the labels --- data/assets/base.asset | 16 ++++++++++++++++ .../scene/solarsystem/planets/earth/earth.asset | 1 + .../solarsystem/planets/jupiter/jupiter.asset | 1 + .../scene/solarsystem/planets/mars/mars.asset | 1 + .../solarsystem/planets/mercury/mercury.asset | 1 + .../solarsystem/planets/neptune/neptune.asset | 1 + .../solarsystem/planets/saturn/saturn.asset | 1 + .../solarsystem/planets/uranus/uranus.asset | 1 + .../scene/solarsystem/planets/venus/venus.asset | 1 + data/assets/scene/solarsystem/sun/sun.asset | 1 + 10 files changed, 25 insertions(+) diff --git a/data/assets/base.asset b/data/assets/base.asset index 73e2db77ab..6ef26ab294 100644 --- a/data/assets/base.asset +++ b/data/assets/base.asset @@ -63,6 +63,22 @@ local Keybindings = { GuiPath = "/Rendering", Local = false }, + { + Key = "l", + Name = "Turn on labels", + Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', true)", + Documentation = "Turns on visibility for all solar system labels", + GuiPath = "/Rendering", + Local = false + }, + { + Key = "Shift+l", + Name = "Turn off labels", + Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', false)", + Documentation = "Turns off visibility for all solar system labels", + GuiPath = "/Rendering", + Local = false + } } asset.onInitialize(function () diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index dc14382046..c604a102ce 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -320,6 +320,7 @@ local EarthLabel = { FadeEndDistance = 15.0, FadeEndSpeed = 25.0 }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Earth Label", Path = "/Solar System/Planets/Earth" diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset index 1ce8b88fff..071a9cad9f 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/jupiter.asset @@ -56,6 +56,7 @@ local JupiterLabel = { LabelOrientationOption = "Camera View Direction", BlendMode = "Additive" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Jupiter Label", Path = "/Solar System/Planets/Jupiter" diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index cee87159c5..4c2e8dcd76 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -207,6 +207,7 @@ local MarsLabel = { 0.0, 0.0, 0.0, 1.0 }, }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Mars Label", Path = "/Solar System/Planets/Mars" diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index 98bd538f33..93924f8444 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -237,6 +237,7 @@ local MercuryLabel = { LabelOrientationOption = "Camera View Direction", BlendMode = "Additive" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Mercury Label", Path = "/Solar System/Planets/Mercury" diff --git a/data/assets/scene/solarsystem/planets/neptune/neptune.asset b/data/assets/scene/solarsystem/planets/neptune/neptune.asset index a7546d5f2a..326b2ef6c0 100644 --- a/data/assets/scene/solarsystem/planets/neptune/neptune.asset +++ b/data/assets/scene/solarsystem/planets/neptune/neptune.asset @@ -54,6 +54,7 @@ local NeptuneLabel = { LabelOrientationOption = "Camera View Direction", BlendMode = "Additive" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Neptune Label", Path = "/Solar System/Planets/Neptune" diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 853bd1ce8b..aabfe92b81 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -71,6 +71,7 @@ local SaturnLabel = { BlendMode = "Additive", LabelOrientationOption = "Camera View Direction" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Saturn Label", Path = "/Solar System/Planets/Saturn" diff --git a/data/assets/scene/solarsystem/planets/uranus/uranus.asset b/data/assets/scene/solarsystem/planets/uranus/uranus.asset index 758f87f998..db3fb11848 100644 --- a/data/assets/scene/solarsystem/planets/uranus/uranus.asset +++ b/data/assets/scene/solarsystem/planets/uranus/uranus.asset @@ -56,6 +56,7 @@ local UranusLabel = { LabelOrientationOption = "Camera View Direction", BlendMode = "Additive" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Neptune Label", Path = "/Solar System/Planets/Uranus" diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index 52cfe29303..f3e1f83fed 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -78,6 +78,7 @@ local VenusLabel = { LabelOrientationOption = "Camera View Direction", BlendMode = "Additive" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Venus Label", Path = "/Solar System/Planets/Venus" diff --git a/data/assets/scene/solarsystem/sun/sun.asset b/data/assets/scene/solarsystem/sun/sun.asset index 9d44fb2462..10c0ff4aec 100644 --- a/data/assets/scene/solarsystem/sun/sun.asset +++ b/data/assets/scene/solarsystem/sun/sun.asset @@ -48,6 +48,7 @@ local SunLabel = { FadeEndDistance = 1.326, FadeEndSpeed = 1.0 }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Sun Label", Path = "/Solar System/Sun" From 4f2883034ba39617e1fb02838d8f194f29c81033 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 10:51:38 +0100 Subject: [PATCH 083/214] Rename labels assets to globe_labels --- data/assets/scene/solarsystem/planets/earth/earth.asset | 2 +- .../earth/{earth_labels.asset => earth_globelabels.asset} | 0 .../scene/solarsystem/planets/jupiter/callisto/callisto.asset | 2 +- .../scene/solarsystem/planets/jupiter/europa/europa.asset | 2 +- .../scene/solarsystem/planets/jupiter/ganymede/ganymede.asset | 2 +- data/assets/scene/solarsystem/planets/jupiter/io/io.asset | 2 +- .../jupiter/{jupiter_labels.asset => jupiter_globelabels.asset} | 0 data/assets/scene/solarsystem/planets/mars/mars.asset | 2 +- .../planets/mars/{mars_labels.asset => mars_globelabels.asset} | 0 data/assets/scene/solarsystem/planets/mercury/mercury.asset | 2 +- .../mercury/{mercury_labels.asset => mercury_globelabels.asset} | 0 data/assets/scene/solarsystem/planets/saturn/dione/dione.asset | 2 +- .../scene/solarsystem/planets/saturn/enceladus/enceladus.asset | 2 +- .../scene/solarsystem/planets/saturn/iapetus/iapetus.asset | 2 +- data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset | 2 +- data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset | 2 +- .../saturn/{saturn_labels.asset => saturn_globelabels.asset} | 0 .../assets/scene/solarsystem/planets/saturn/tethys/tethys.asset | 2 +- data/assets/scene/solarsystem/planets/saturn/titan/titan.asset | 2 +- data/assets/scene/solarsystem/planets/venus/venus.asset | 2 +- .../venus/{venus_labels.asset => venus_globelabels.asset} | 0 21 files changed, 15 insertions(+), 15 deletions(-) rename data/assets/scene/solarsystem/planets/earth/{earth_labels.asset => earth_globelabels.asset} (100%) rename data/assets/scene/solarsystem/planets/jupiter/{jupiter_labels.asset => jupiter_globelabels.asset} (100%) rename data/assets/scene/solarsystem/planets/mars/{mars_labels.asset => mars_globelabels.asset} (100%) rename data/assets/scene/solarsystem/planets/mercury/{mercury_labels.asset => mercury_globelabels.asset} (100%) rename data/assets/scene/solarsystem/planets/saturn/{saturn_labels.asset => saturn_globelabels.asset} (100%) rename data/assets/scene/solarsystem/planets/venus/{venus_labels.asset => venus_globelabels.asset} (100%) diff --git a/data/assets/scene/solarsystem/planets/earth/earth.asset b/data/assets/scene/solarsystem/planets/earth/earth.asset index c604a102ce..aab7c67f07 100644 --- a/data/assets/scene/solarsystem/planets/earth/earth.asset +++ b/data/assets/scene/solarsystem/planets/earth/earth.asset @@ -1,7 +1,7 @@ local transforms = asset.require('./transforms') local assetHelper = asset.require('util/asset_helper') local texturesPath = asset.require('./earth_textures').TexturesPath -local labelsPath = asset.require('./earth_labels').LabelsPath +local labelsPath = asset.require('./earth_globelabels').LabelsPath asset.request('./trail') diff --git a/data/assets/scene/solarsystem/planets/earth/earth_labels.asset b/data/assets/scene/solarsystem/planets/earth/earth_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/earth/earth_labels.asset rename to data/assets/scene/solarsystem/planets/earth/earth_globelabels.asset diff --git a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset index 1a31062cd1..d0b2496e52 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/callisto/callisto.asset @@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper') asset.require("spice/base") asset.request('./trail') local kernel = asset.require('../kernels').jup310 -local labelsPath = asset.require('../jupiter_labels').LabelsPath +local labelsPath = asset.require('../jupiter_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset index 9ee299ebf6..d5e455bb9f 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/europa/europa.asset @@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper') asset.require("spice/base") asset.request('./trail') local kernel = asset.require('../kernels').jup310 -local labelsPath = asset.require('../jupiter_labels').LabelsPath +local labelsPath = asset.require('../jupiter_globelabels').LabelsPath local map_service_configs = asset.localResource("map_service_configs") diff --git a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset index 510484cebf..513136ef98 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/ganymede/ganymede.asset @@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper') asset.require("spice/base") asset.request('./trail') local kernel = asset.require('../kernels').jup310 -local labelsPath = asset.require('../jupiter_labels').LabelsPath +local labelsPath = asset.require('../jupiter_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset index ca10670c06..fb10f0b3a8 100644 --- a/data/assets/scene/solarsystem/planets/jupiter/io/io.asset +++ b/data/assets/scene/solarsystem/planets/jupiter/io/io.asset @@ -3,7 +3,7 @@ local assetHelper = asset.require('util/asset_helper') asset.require("spice/base") asset.request('./trail') local kernel = asset.require('../kernels').jup310 -local labelsPath = asset.require('../jupiter_labels').LabelsPath +local labelsPath = asset.require('../jupiter_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/jupiter/jupiter_labels.asset b/data/assets/scene/solarsystem/planets/jupiter/jupiter_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/jupiter/jupiter_labels.asset rename to data/assets/scene/solarsystem/planets/jupiter/jupiter_globelabels.asset diff --git a/data/assets/scene/solarsystem/planets/mars/mars.asset b/data/assets/scene/solarsystem/planets/mars/mars.asset index 4c2e8dcd76..ee4da17e7d 100644 --- a/data/assets/scene/solarsystem/planets/mars/mars.asset +++ b/data/assets/scene/solarsystem/planets/mars/mars.asset @@ -2,7 +2,7 @@ local transforms = asset.require('./transforms') local assetHelper = asset.require('util/asset_helper') asset.require("spice/base") asset.request('./trail') -local labelsPath = asset.require('./mars_labels').LabelsPath +local labelsPath = asset.require('./mars_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/mars/mars_labels.asset b/data/assets/scene/solarsystem/planets/mars/mars_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/mars/mars_labels.asset rename to data/assets/scene/solarsystem/planets/mars/mars_globelabels.asset diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury.asset b/data/assets/scene/solarsystem/planets/mercury/mercury.asset index 93924f8444..8eda6c5eb9 100644 --- a/data/assets/scene/solarsystem/planets/mercury/mercury.asset +++ b/data/assets/scene/solarsystem/planets/mercury/mercury.asset @@ -1,6 +1,6 @@ local assetHelper = asset.require('util/asset_helper') local transforms = asset.require('./transforms') -local labelsPath = asset.require('./mercury_labels').LabelsPath +local labelsPath = asset.require('./mercury_globelabels').LabelsPath asset.require("spice/base") diff --git a/data/assets/scene/solarsystem/planets/mercury/mercury_labels.asset b/data/assets/scene/solarsystem/planets/mercury/mercury_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/mercury/mercury_labels.asset rename to data/assets/scene/solarsystem/planets/mercury/mercury_globelabels.asset diff --git a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset index 7cdd49b5cd..ded4b6ae73 100644 --- a/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset +++ b/data/assets/scene/solarsystem/planets/saturn/dione/dione.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset index 5fa01501ba..8a66735198 100644 --- a/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/enceladus/enceladus.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset index bab9c45056..892cc2c13e 100644 --- a/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset +++ b/data/assets/scene/solarsystem/planets/saturn/iapetus/iapetus.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset index 4dbedaad48..53d9b7da21 100644 --- a/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset +++ b/data/assets/scene/solarsystem/planets/saturn/mimas/mimas.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset index 0ab5688544..008663ecf5 100644 --- a/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset +++ b/data/assets/scene/solarsystem/planets/saturn/rhea/rhea.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn_labels.asset b/data/assets/scene/solarsystem/planets/saturn/saturn_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/saturn/saturn_labels.asset rename to data/assets/scene/solarsystem/planets/saturn/saturn_globelabels.asset diff --git a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset index 1979cf4d66..fea8618180 100644 --- a/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset +++ b/data/assets/scene/solarsystem/planets/saturn/tethys/tethys.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset index 0145308ed4..a086c9eecb 100644 --- a/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset +++ b/data/assets/scene/solarsystem/planets/saturn/titan/titan.asset @@ -2,7 +2,7 @@ local transforms = asset.require('../transforms') local assetHelper = asset.require('util/asset_helper') local kernel = asset.require('../kernels').sat375 asset.request('./trail') -local labelsPath = asset.require('../saturn_labels').LabelsPath +local labelsPath = asset.require('../saturn_globelabels').LabelsPath local map_service_configs = asset.localResource("map_service_configs") diff --git a/data/assets/scene/solarsystem/planets/venus/venus.asset b/data/assets/scene/solarsystem/planets/venus/venus.asset index f3e1f83fed..e53b0e7ede 100644 --- a/data/assets/scene/solarsystem/planets/venus/venus.asset +++ b/data/assets/scene/solarsystem/planets/venus/venus.asset @@ -2,7 +2,7 @@ local assetHelper = asset.require('util/asset_helper') local transforms = asset.require('./transforms') asset.require("spice/base") asset.request('./trail') -local labelsPath = asset.require('./venus_labels').LabelsPath +local labelsPath = asset.require('./venus_globelabels').LabelsPath diff --git a/data/assets/scene/solarsystem/planets/venus/venus_labels.asset b/data/assets/scene/solarsystem/planets/venus/venus_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/planets/venus/venus_labels.asset rename to data/assets/scene/solarsystem/planets/venus/venus_globelabels.asset From fdfad19476c6bfb34cab5b6a68bfc00f95b46a3d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 11:27:53 +0100 Subject: [PATCH 084/214] Coding style fixes --- modules/globebrowsing/shaders/rings_fs.glsl | 2 +- .../globebrowsing/shaders/rings_geom_fs.glsl | 2 +- .../globebrowsing/shaders/rings_geom_vs.glsl | 4 +- modules/globebrowsing/shaders/rings_vs.glsl | 2 +- .../globebrowsing/shaders/smviewer_vs.glsl | 6 +- modules/globebrowsing/src/renderableglobe.cpp | 8 +- modules/globebrowsing/src/renderableglobe.h | 9 +- modules/globebrowsing/src/ringscomponent.cpp | 724 ++++++----- modules/globebrowsing/src/ringscomponent.h | 48 +- modules/globebrowsing/src/shadowcomponent.cpp | 1056 ++++++++--------- modules/globebrowsing/src/shadowcomponent.h | 251 ++-- 11 files changed, 1034 insertions(+), 1078 deletions(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index c31eef3ff4..fb198a952a 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2018 * + * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 88e43984a9..211d17d596 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2018 * + * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * diff --git a/modules/globebrowsing/shaders/rings_geom_vs.glsl b/modules/globebrowsing/shaders/rings_geom_vs.glsl index 6eb0ca2390..f803cd15bc 100644 --- a/modules/globebrowsing/shaders/rings_geom_vs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_vs.glsl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2018 * + * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * @@ -44,4 +44,4 @@ void main() { vs_screenSpaceDepth = positionClipSpaceZNorm.w; gl_Position = positionClipSpaceZNorm; -} \ No newline at end of file +} diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl index 5fb7d0fbeb..dfe33ed905 100644 --- a/modules/globebrowsing/shaders/rings_vs.glsl +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2018 * + * Copyright (c) 2014-2019 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * diff --git a/modules/globebrowsing/shaders/smviewer_vs.glsl b/modules/globebrowsing/shaders/smviewer_vs.glsl index a69397368e..958527c339 100644 --- a/modules/globebrowsing/shaders/smviewer_vs.glsl +++ b/modules/globebrowsing/shaders/smviewer_vs.glsl @@ -46,6 +46,6 @@ const vec2 texData[6] = vec2[] ( ); void main() { - texCoord = texData[ gl_VertexID ]; - gl_Position = vec4(posData[ gl_VertexID ], 1.0); -} \ No newline at end of file + texCoord = texData[gl_VertexID]; + gl_Position = vec4(posData[gl_VertexID], 1.0); +} diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 56477c915e..89cc1035a1 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -956,7 +956,9 @@ const glm::dmat4& RenderableGlobe::modelTransform() const { ////////////////////////////////////////////////////////////////////////////////////////// void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, - const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, + bool renderGeomOnly) +{ if (_shadersNeedRecompilation) { recompileShaders(); } @@ -1256,7 +1258,9 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, } void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& data, - const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, + bool renderGeomOnly) +{ //PerfMeasure("globally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_globalRenderer.program; diff --git a/modules/globebrowsing/src/renderableglobe.h b/modules/globebrowsing/src/renderableglobe.h index d21445e1f9..8670263749 100644 --- a/modules/globebrowsing/src/renderableglobe.h +++ b/modules/globebrowsing/src/renderableglobe.h @@ -189,8 +189,7 @@ private: float getHeight(const glm::dvec3& position) const; void renderChunks(const RenderData& data, RendererTasks& rendererTask, - const ShadowComponent::ShadowMapData& shadowData = {}, - const bool renderGeomOnly = false + const ShadowComponent::ShadowMapData& shadowData = {}, bool renderGeomOnly = false ); /** @@ -202,8 +201,7 @@ private: * tile will lead to jagging. We only render global chunks for lower chunk levels. */ void renderChunkGlobally(const Chunk& chunk, const RenderData& data, - const ShadowComponent::ShadowMapData& shadowData = {}, - const bool renderGeomOnly = false + const ShadowComponent::ShadowMapData& shadowData = {}, bool renderGeomOnly = false ); /** @@ -218,8 +216,7 @@ private: * chunks for higher chunk levels. */ void renderChunkLocally(const Chunk& chunk, const RenderData& data, - const ShadowComponent::ShadowMapData& shadowData = {}, - const bool renderGeomOnly = false + const ShadowComponent::ShadowMapData& shadowData = {}, bool renderGeomOnly = false ); void debugRenderChunk(const Chunk& chunk, const glm::dmat4& mvp, diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index c9f20cdb41..3195237b20 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -1,56 +1,49 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2018 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include + #include #include - #include #include -#include - #include -#include #include - +#include #include #include - +#include #include #include -#include - -#include -#include -#include -#include -#include -#include - #include #include - +#include +#include +#include +#include +#include +#include #include #include #include @@ -120,371 +113,370 @@ namespace { namespace openspace { - documentation::Documentation RingsComponent::Documentation() { - using namespace documentation; - return { - "Rings Component", - "globebrowsing_rings_component", +documentation::Documentation RingsComponent::Documentation() { + using namespace documentation; + return { + "Rings Component", + "globebrowsing_rings_component", + { { - { - TextureInfo.identifier, - new StringVerifier, - Optional::Yes, - TextureInfo.description - }, - { - SizeInfo.identifier, - new DoubleVerifier, - Optional::Yes, - SizeInfo.description - }, - { - OffsetInfo.identifier, - new DoubleVector2Verifier, - Optional::Yes, - OffsetInfo.description - }, - { - NightFactorInfo.identifier, - new DoubleVerifier, - Optional::Yes, - NightFactorInfo.description - }, - { - TransparencyInfo.identifier, - new DoubleVerifier, - Optional::Yes, - TransparencyInfo.description - }, - { - ZFightingPercentageInfo.identifier, - new DoubleVerifier, - Optional::Yes, - ZFightingPercentageInfo.description - }, - { - NumberShadowSamplesInfo.identifier, - new IntVerifier, - Optional::Yes, - NumberShadowSamplesInfo.description - } + TextureInfo.identifier, + new StringVerifier, + Optional::Yes, + TextureInfo.description + }, + { + SizeInfo.identifier, + new DoubleVerifier, + Optional::Yes, + SizeInfo.description + }, + { + OffsetInfo.identifier, + new DoubleVector2Verifier, + Optional::Yes, + OffsetInfo.description + }, + { + NightFactorInfo.identifier, + new DoubleVerifier, + Optional::Yes, + NightFactorInfo.description + }, + { + TransparencyInfo.identifier, + new DoubleVerifier, + Optional::Yes, + TransparencyInfo.description + }, + { + ZFightingPercentageInfo.identifier, + new DoubleVerifier, + Optional::Yes, + ZFightingPercentageInfo.description + }, + { + NumberShadowSamplesInfo.identifier, + new IntVerifier, + Optional::Yes, + NumberShadowSamplesInfo.description } - }; - } + } + }; +} - RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) - : properties::PropertyOwner({ "Rings" }) - , _texturePath(TextureInfo) - , _size(SizeInfo, 1.f, 0.f, 1e25f) - , _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f)) - , _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f) - , _transparency(TransparencyInfo, 0.15f, 0.f, 1.f) - , _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true) - , _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f) - , _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 20) - , _ringsDictionary(dictionary) - { - using ghoul::filesystem::File; +RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) + : properties::PropertyOwner({ "Rings" }) + , _texturePath(TextureInfo) + , _size(SizeInfo, 1.f, 0.f, 1e25f) + , _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f)) + , _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f) + , _transparency(TransparencyInfo, 0.15f, 0.f, 1.f) + , _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true) + , _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f) + , _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 20) + , _ringsDictionary(dictionary) +{ + using ghoul::filesystem::File; - if (dictionary.hasKey("Rings")) { - dictionary.getValue("Rings", _ringsDictionary); - } + if (dictionary.hasKey("Rings")) { + // @TODO (abock, 2019-12-16) It would be better to not store the dictionary long + // term and rather extract the values directly here. This would require a bit of + // a rewrite in the RenderableGlobe class to not create the RingsComponent in the + // class-initializer list though + dictionary.getValue("Rings", _ringsDictionary); + } - documentation::testSpecificationAndThrow( - Documentation(), - _ringsDictionary, - "RingsComponent" + documentation::testSpecificationAndThrow( + Documentation(), + _ringsDictionary, + "RingsComponent" + ); +} + +void RingsComponent::initialize() { + using ghoul::filesystem::File; + + addProperty(_enabled); + + _size = static_cast(_ringsDictionary.value(SizeInfo.identifier)); + //setBoundingSphere(_size); + _size.onChange([&]() { _planeIsDirty = true; }); + addProperty(_size); + + _texturePath = absPath( + _ringsDictionary.value(TextureInfo.identifier) + ); + _textureFile = std::make_unique(_texturePath); + + if (_ringsDictionary.hasKeyAndValue(OffsetInfo.identifier)) { + _offset = _ringsDictionary.value(OffsetInfo.identifier); + } + addProperty(_offset); + + _texturePath.onChange([&]() { loadTexture(); }); + addProperty(_texturePath); + + _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); + + if (_ringsDictionary.hasKeyAndValue(NightFactorInfo.identifier)) { + _nightFactor = static_cast( + _ringsDictionary.value(NightFactorInfo.identifier) + ); + } + addProperty(_nightFactor); + + if (_ringsDictionary.hasKeyAndValue(TransparencyInfo.identifier)) { + _transparency = static_cast( + _ringsDictionary.value(TransparencyInfo.identifier) ); } - void RingsComponent::initialize() - { - using ghoul::filesystem::File; - - addProperty(_enabled); - - _size = static_cast(_ringsDictionary.value(SizeInfo.identifier)); - //setBoundingSphere(_size); - _size.onChange([&]() { _planeIsDirty = true; }); - addProperty(_size); - - _texturePath = absPath(_ringsDictionary.value(TextureInfo.identifier)); - _textureFile = std::make_unique(_texturePath); - - if (_ringsDictionary.hasKeyAndValue(OffsetInfo.identifier)) { - _offset = _ringsDictionary.value(OffsetInfo.identifier); - } - addProperty(_offset); - - _texturePath.onChange([&]() { loadTexture(); }); - addProperty(_texturePath); - - _textureFile->setCallback([&](const File&) { _textureIsDirty = true; }); - - if (_ringsDictionary.hasKeyAndValue(NightFactorInfo.identifier)) { - _nightFactor = static_cast( - _ringsDictionary.value(NightFactorInfo.identifier) - ); - } - addProperty(_nightFactor); - - if (_ringsDictionary.hasKeyAndValue(TransparencyInfo.identifier)) { - _transparency = static_cast( - _ringsDictionary.value(TransparencyInfo.identifier) - ); - } - - // Shadow Mapping Quality Controls - if (_ringsDictionary.hasKey(ZFightingPercentageInfo.identifier)) { - _zFightingPercentage = _ringsDictionary.value( - ZFightingPercentageInfo.identifier - ); - } - addProperty(_zFightingPercentage); - - if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) { - _nShadowSamples = _ringsDictionary.value( - NumberShadowSamplesInfo.identifier - ); - } - addProperty(_nShadowSamples); - - addProperty(_transparency); + // Shadow Mapping Quality Controls + if (_ringsDictionary.hasKey(ZFightingPercentageInfo.identifier)) { + _zFightingPercentage = _ringsDictionary.value( + ZFightingPercentageInfo.identifier + ); } + addProperty(_zFightingPercentage); - bool RingsComponent::isReady() const { - return (_shader || _geometryOnlyShader) && _texture; + if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) { + _nShadowSamples = _ringsDictionary.value(NumberShadowSamplesInfo.identifier); } + addProperty(_nShadowSamples); - void RingsComponent::initializeGL() { - _shader = global::renderEngine.buildRenderProgram( - "RingsProgram", - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl") + addProperty(_transparency); +} + +bool RingsComponent::isReady() const { + return (_shader || _geometryOnlyShader) && _texture; +} + +void RingsComponent::initializeGL() { + _shader = global::renderEngine.buildRenderProgram( + "RingsProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl") + ); + + _geometryOnlyShader = global::renderEngine.buildRenderProgram( + "RingsGeomOnlyProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_fs.glsl") + ); + + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + ghoul::opengl::updateUniformLocations( + *_geometryOnlyShader, + _geomUniformCache, + GeomUniformNames + ); + + glGenVertexArrays(1, &_quad); + glGenBuffers(1, &_vertexPositionBuffer); + + createPlane(); + loadTexture(); +} + +void RingsComponent::deinitializeGL() { + glDeleteVertexArrays(1, &_quad); + _quad = 0; + + glDeleteBuffers(1, &_vertexPositionBuffer); + _vertexPositionBuffer = 0; + + _textureFile = nullptr; + _texture = nullptr; + + global::renderEngine.removeRenderProgram(_shader.get()); + _shader = nullptr; + + global::renderEngine.removeRenderProgram(_geometryOnlyShader.get()); + _geometryOnlyShader = nullptr; +} + +void RingsComponent::draw(const RenderData& data, + const RingsComponent::RenderPass renderPass, + const ShadowComponent::ShadowMapData& shadowData) +{ + if (renderPass == GeometryAndShading) { + _shader->activate(); + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->activate(); + } + + const glm::dmat4 modelTransform = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * + glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); + + const glm::dmat4 modelViewProjectionTransform = + glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() + * modelTransform; + + ghoul::opengl::TextureUnit ringTextureUnit; + if (renderPass == GeometryAndShading) { + _shader->setUniform( + _uniformCache.modelViewProjectionMatrix, + modelViewProjectionTransform + ); + _shader->setUniform(_uniformCache.textureOffset, _offset); + _shader->setUniform(_uniformCache.transparency, _transparency); + _shader->setUniform(_uniformCache.nightFactor, _nightFactor); + _shader->setUniform(_uniformCache.sunPosition, _sunPosition); + _shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); + _shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage); + + ringTextureUnit.activate(); + _texture->bind(); + _shader->setUniform(_uniformCache.ringTexture, ringTextureUnit); + + // Adding the model transformation to the final shadow matrix so we have a + // complete transformation from the model coordinates to the clip space of + // the light position. + _shader->setUniform( + _uniformCache.shadowMatrix, + shadowData.shadowMatrix * modelTransform ); - _geometryOnlyShader = global::renderEngine.buildRenderProgram( - "RingsGeomOnlyProgram", - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_vs.glsl"), - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_geom_fs.glsl") - ); + ghoul::opengl::TextureUnit shadowMapUnit; + shadowMapUnit.activate(); + glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); + + _shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit); + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->setUniform( + _geomUniformCache.modelViewProjectionMatrix, + modelViewProjectionTransform + ); + _geometryOnlyShader->setUniform(_geomUniformCache.textureOffset, _offset); + + ringTextureUnit.activate(); + _texture->bind(); + _shader->setUniform(_geomUniformCache.ringTexture, ringTextureUnit); + } + + glEnable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glBindVertexArray(_quad); + glDrawArrays(GL_TRIANGLES, 0, 6); + + glEnable(GL_CULL_FACE); + + if (renderPass == GeometryAndShading) { + _shader->deactivate(); + } + else if (renderPass == GeometryOnly) { + _geometryOnlyShader->deactivate(); + } +} + +void RingsComponent::update(const UpdateData& data) { + if (_shader->isDirty()) { + _shader->rebuildFromFile(); ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + } + + if (_geometryOnlyShader->isDirty()) { + _geometryOnlyShader->rebuildFromFile(); ghoul::opengl::updateUniformLocations( *_geometryOnlyShader, _geomUniformCache, GeomUniformNames ); + } - glGenVertexArrays(1, &_quad); - glGenBuffers(1, &_vertexPositionBuffer); - + if (_planeIsDirty) { createPlane(); + _planeIsDirty = false; + } + + if (_textureIsDirty) { loadTexture(); + _textureIsDirty = false; } - void RingsComponent::deinitializeGL() { - glDeleteVertexArrays(1, &_quad); - _quad = 0; + _sunPosition = glm::normalize( + global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition() - + data.modelTransform.translation + ); +} - glDeleteBuffers(1, &_vertexPositionBuffer); - _vertexPositionBuffer = 0; - - _textureFile = nullptr; - _texture = nullptr; - - global::renderEngine.removeRenderProgram(_shader.get()); - _shader = nullptr; - - global::renderEngine.removeRenderProgram(_geometryOnlyShader.get()); - _geometryOnlyShader = nullptr; - } - - void RingsComponent::draw( - const RenderData& data, - const RingsComponent::RenderPass renderPass, - const ShadowComponent::ShadowMapData& shadowData - ) { - - if (renderPass == GeometryAndShading) { - _shader->activate(); - } - else if (renderPass == GeometryOnly) { - _geometryOnlyShader->activate(); - } - - const glm::dmat4 modelTransform = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * - glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)); - - const glm::dmat4 modelViewProjectionTransform = - glm::dmat4(data.camera.projectionMatrix()) * data.camera.combinedViewMatrix() - * modelTransform; - - ghoul::opengl::TextureUnit ringTextureUnit; - if (renderPass == GeometryAndShading) { - _shader->setUniform( - _uniformCache.modelViewProjectionMatrix, - modelViewProjectionTransform - ); - _shader->setUniform(_uniformCache.textureOffset, _offset); - _shader->setUniform(_uniformCache.transparency, _transparency); - _shader->setUniform(_uniformCache.nightFactor, _nightFactor); - _shader->setUniform(_uniformCache.sunPosition, _sunPosition); - _shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); - _shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage); - - ringTextureUnit.activate(); - _texture->bind(); - _shader->setUniform(_uniformCache.ringTexture, ringTextureUnit); - - // Adding the model transformation to the final shadow matrix so we have a - // complete transformation from the model coordinates to the clip space of - // the light position. - _shader->setUniform( - _uniformCache.shadowMatrix, - shadowData.shadowMatrix * modelTransform - ); - - ghoul::opengl::TextureUnit shadowMapUnit; - shadowMapUnit.activate(); - glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); - - _shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit); - - } - else if (renderPass == GeometryOnly) { - _geometryOnlyShader->setUniform( - _geomUniformCache.modelViewProjectionMatrix, - modelViewProjectionTransform - ); - _geometryOnlyShader->setUniform( - _geomUniformCache.textureOffset, - _offset - ); - - ringTextureUnit.activate(); - _texture->bind(); - _shader->setUniform(_geomUniformCache.ringTexture, ringTextureUnit); - } - - glEnable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - - glBindVertexArray(_quad); - glDrawArrays(GL_TRIANGLES, 0, 6); - - glEnable(GL_CULL_FACE); - - if (renderPass == GeometryAndShading) { - _shader->deactivate(); - } - else if (renderPass == GeometryOnly) { - _geometryOnlyShader->deactivate(); - } - } - - void RingsComponent::update(const UpdateData& data) { - if (_shader->isDirty()) { - _shader->rebuildFromFile(); - ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); - } - - if (_geometryOnlyShader->isDirty()) { - _geometryOnlyShader->rebuildFromFile(); - ghoul::opengl::updateUniformLocations( - *_geometryOnlyShader, - _geomUniformCache, - GeomUniformNames - ); - } - - if (_planeIsDirty) { - createPlane(); - _planeIsDirty = false; - } - - if (_textureIsDirty) { - loadTexture(); - _textureIsDirty = false; - } - - _sunPosition = glm::normalize( - global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition() - - data.modelTransform.translation +void RingsComponent::loadTexture() { + if (!_texturePath.value().empty()) { + using namespace ghoul::io; + using namespace ghoul::opengl; + std::unique_ptr texture = TextureReader::ref().loadTexture( + absPath(_texturePath) ); - } - void RingsComponent::loadTexture() { - if (!_texturePath.value().empty()) { - using namespace ghoul::io; - using namespace ghoul::opengl; - std::unique_ptr texture = TextureReader::ref().loadTexture( - absPath(_texturePath) + if (texture) { + LDEBUGC( + "RingsComponent", + fmt::format("Loaded texture from '{}'", absPath(_texturePath)) ); + _texture = std::move(texture); - if (texture) { - LDEBUGC( - "RingsComponent", - fmt::format("Loaded texture from '{}'", absPath(_texturePath)) - ); - _texture = std::move(texture); + _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - _texture->uploadTexture(); - _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); - - _textureFile = std::make_unique(_texturePath); - _textureFile->setCallback( - [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } - ); - } + _textureFile = std::make_unique(_texturePath); + _textureFile->setCallback( + [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + ); } } +} - void RingsComponent::createPlane() { - const GLfloat size = _size; +void RingsComponent::createPlane() { + const GLfloat size = _size; - struct VertexData { - GLfloat x; - GLfloat y; - GLfloat s; - GLfloat t; - }; + struct VertexData { + GLfloat x; + GLfloat y; + GLfloat s; + GLfloat t; + }; - VertexData data[] = { - { -size, -size, 0.f, 0.f }, - { size, size, 1.f, 1.f }, - { -size, size, 0.f, 1.f }, - { -size, -size, 0.f, 0.f }, - { size, -size, 1.f, 0.f }, - { size, size, 1.f, 1.f }, - }; + VertexData data[] = { + { -size, -size, 0.f, 0.f }, + { size, size, 1.f, 1.f }, + { -size, size, 0.f, 1.f }, + { -size, -size, 0.f, 0.f }, + { size, -size, 1.f, 0.f }, + { size, size, 1.f, 1.f }, + }; - glBindVertexArray(_quad); - glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer( - 0, - 2, - GL_FLOAT, - GL_FALSE, - sizeof(VertexData), - nullptr - ); - glEnableVertexAttribArray(1); - glVertexAttribPointer( - 1, - 2, - GL_FLOAT, - GL_FALSE, - sizeof(VertexData), - reinterpret_cast(offsetof(VertexData, s)) // NOLINT - ); - } + glBindVertexArray(_quad); + glBindBuffer(GL_ARRAY_BUFFER, _vertexPositionBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer( + 0, + 2, + GL_FLOAT, + GL_FALSE, + sizeof(VertexData), + nullptr + ); + glEnableVertexAttribArray(1); + glVertexAttribPointer( + 1, + 2, + GL_FLOAT, + GL_FALSE, + sizeof(VertexData), + reinterpret_cast(offsetof(VertexData, s)) // NOLINT + ); +} + +bool RingsComponent::isEnabled() const { + return _enabled; +} - bool RingsComponent::isEnabled() const { - return _enabled; - } } // namespace openspace diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index 4804af9ae3..f2e277b3a4 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -1,26 +1,26 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2018 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #ifndef __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__ #define __OPENSPACE_MODULE_GLOBEBROWSING___RINGSCOMPONENT___H__ @@ -28,14 +28,12 @@ #include #include - +#include #include #include #include #include #include -#include - #include #include #include diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index da2d166bd6..2d16428728 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -1,64 +1,54 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2018 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include + #include #include - #include #include -#include - #include -#include #include - +#include +#include #include #include -#include - #include #include - #include - +#include #include #include #include - -#include +#include #include #include -#include #include #include - #include #include - #include - #include #include #include @@ -85,8 +75,7 @@ namespace { "The depth map size in pixels. You must entry the width and height values." }; - void checkFrameBufferState(const std::string& codePosition) - { + void checkFrameBufferState(const std::string& codePosition) { if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LERROR("Framework not built. " + codePosition); GLenum fbErr = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -152,530 +141,510 @@ namespace { namespace openspace { - documentation::Documentation ShadowComponent::Documentation() { - using namespace documentation; - return { - "ShadowsRing Component", - "globebrowsing_shadows_component", +documentation::Documentation ShadowComponent::Documentation() { + using namespace documentation; + return { + "ShadowsRing Component", + "globebrowsing_shadows_component", + { { - { - DistanceFractionInfo.identifier, - new DoubleVerifier, - Optional::Yes, - DistanceFractionInfo.description - }, - { - DepthMapSizeInfo.identifier, - new Vector2ListVerifier, - Optional::Yes, - DepthMapSizeInfo.description - } + DistanceFractionInfo.identifier, + new DoubleVerifier, + Optional::Yes, + DistanceFractionInfo.description + }, + { + DepthMapSizeInfo.identifier, + new Vector2ListVerifier, + Optional::Yes, + DepthMapSizeInfo.description } - }; + } + }; +} + +ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) + : properties::PropertyOwner({ "Shadows Component" }) + , _saveDepthTexture(SaveDepthTextureInfo) + , _distanceFraction(DistanceFractionInfo, 20, 1, 10000) + , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) + , _shadowMapDictionary(dictionary) +{ + using ghoul::filesystem::File; + + if (dictionary.hasKey("Shadows")) { + // @TODO (abock, 2019-12-16) It would be better to not store the dictionary long + // term and rather extract the values directly here. This would require a bit of + // a rewrite in the RenderableGlobe class to not create the ShadowComponent in the + // class-initializer list though + dictionary.getValue("Shadows", _shadowMapDictionary); } - ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) - : properties::PropertyOwner({ "Shadows Component" }) - , _saveDepthTexture(SaveDepthTextureInfo) - , _distanceFraction(DistanceFractionInfo, 20, 1, 10000) - , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) - , _shadowMapDictionary(dictionary) - , _shadowDepthTextureHeight(4096) - , _shadowDepthTextureWidth(4096) - , _shadowDepthTexture(-1) - , _positionInLightSpaceTexture(-1) - , _shadowFBO(-1) - , _firstPassSubroutine(-1) - , _secondPassSubroutine(1) - , _defaultFBO(-1) - , _sunPosition(0.0) - , _shadowMatrix(1.0) - , _executeDepthTextureSave(false) - { - using ghoul::filesystem::File; + documentation::testSpecificationAndThrow( + Documentation(), + _shadowMapDictionary, + "ShadowComponent" + ); - if (dictionary.hasKey("Shadows")) { - dictionary.getValue("Shadows", _shadowMapDictionary); - } - - documentation::testSpecificationAndThrow( - Documentation(), - _shadowMapDictionary, - "ShadowComponent" + if (_shadowMapDictionary.hasKey(DistanceFractionInfo.identifier)) { + _distanceFraction = static_cast( + _shadowMapDictionary.value(DistanceFractionInfo.identifier) ); - - if (_shadowMapDictionary.hasKey(DistanceFractionInfo.identifier)) { - _distanceFraction = static_cast( - _shadowMapDictionary.value(DistanceFractionInfo.identifier) - ); - } - _saveDepthTexture.onChange([&]() { - _executeDepthTextureSave = true; - }); - - - if (_shadowMapDictionary.hasKey(DepthMapSizeInfo.identifier)) { - glm::vec2 depthMapSize = - _shadowMapDictionary.value(DepthMapSizeInfo.identifier); - _shadowDepthTextureWidth = depthMapSize.x; - _shadowDepthTextureHeight = depthMapSize.y; - _dynamicDepthTextureRes = false; - } - else { - glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); - _shadowDepthTextureWidth = renderingResolution.x * 2; - _shadowDepthTextureHeight = renderingResolution.y * 2; - _dynamicDepthTextureRes = true; - } - - _saveDepthTexture.onChange([&]() { - _executeDepthTextureSave = true; - }); - - _viewDepthMap = false; - - addProperty(_enabled); - addProperty(_saveDepthTexture); - addProperty(_distanceFraction); } + _saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; }); - void ShadowComponent::initialize() - { - using ghoul::filesystem::File; + + if (_shadowMapDictionary.hasKey(DepthMapSizeInfo.identifier)) { + glm::vec2 depthMapSize = + _shadowMapDictionary.value(DepthMapSizeInfo.identifier); + _shadowDepthTextureWidth = depthMapSize.x; + _shadowDepthTextureHeight = depthMapSize.y; + _dynamicDepthTextureRes = false; } - - bool ShadowComponent::isReady() const { - return true; - } - - void ShadowComponent::initializeGL() { - createDepthTexture(); - createShadowFBO(); - } - - void ShadowComponent::deinitializeGL() { - glDeleteTextures(1, &_shadowDepthTexture); - glDeleteTextures(1, &_positionInLightSpaceTexture); - glDeleteFramebuffers(1, &_shadowFBO); - checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer"); - } - - RenderData ShadowComponent::begin(const RenderData& data) { - // =========================================== - // Builds light's ModelViewProjectionMatrix: - // =========================================== - - glm::dvec3 diffVector = glm::dvec3(_sunPosition) - data.modelTransform.translation; - double originalLightDistance = glm::length(diffVector); - glm::dvec3 lightDirection = glm::normalize(diffVector); - - // Percentage of the original light source distance (to avoid artifacts) - /*double multiplier = originalLightDistance * - (static_cast(_distanceFraction)/1.0E5);*/ - - double multiplier = originalLightDistance * - (static_cast(_distanceFraction) / 1E17); - - // New light source position - /*glm::dvec3 lightPosition = data.modelTransform.translation + - (lightDirection * multiplier);*/ - glm::dvec3 lightPosition = data.modelTransform.translation + - (diffVector * multiplier); - - //// Light Position - //glm::dvec3 lightPosition = glm::dvec3(_sunPosition); - - //=============== Manually Created Camera Matrix =================== - //================================================================== - // camera Z - glm::dvec3 cameraZ = lightDirection; - - // camera X - glm::dvec3 upVector = glm::dvec3(0.0, 1.0, 0.0); - glm::dvec3 cameraX = glm::normalize(glm::cross(upVector, cameraZ)); - - // camera Y - glm::dvec3 cameraY = glm::cross(cameraZ, cameraX); - - // init 4x4 matrix - glm::dmat4 cameraRotationMatrix(1.0); - - double* matrix = glm::value_ptr(cameraRotationMatrix); - matrix[0] = cameraX.x; - matrix[4] = cameraX.y; - matrix[8] = cameraX.z; - matrix[1] = cameraY.x; - matrix[5] = cameraY.y; - matrix[9] = cameraY.z; - matrix[2] = cameraZ.x; - matrix[6] = cameraZ.y; - matrix[10] = cameraZ.z; - - // set translation part - // We aren't setting the position here because it is set in - // the camera->setPosition() - //matrix[12] = -glm::dot(cameraX, lightPosition); - //matrix[13] = -glm::dot(cameraY, lightPosition); - //matrix[14] = -glm::dot(cameraZ, lightPosition); - - - _lightCamera = std::move(std::unique_ptr(new Camera(data.camera))); - _lightCamera->setPositionVec3(lightPosition); - _lightCamera->setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); - //======================================================================= - //======================================================================= - - - //============= Light Matrix by Camera Matrices Composition ============= - //======================================================================= - glm::dmat4 lightProjectionMatrix = glm::dmat4(_lightCamera->projectionMatrix()); - - // The model transformation missing in the final shadow matrix is add when rendering each - // object (using its transformations provided by the RenderData structure) - _shadowData.shadowMatrix = - _toTextureCoordsMatrix * - lightProjectionMatrix * - _lightCamera->combinedViewMatrix(); - - - // Saves current state - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); - glGetIntegerv(GL_VIEWPORT, _mViewport); - _faceCulling = glIsEnabled(GL_CULL_FACE); - glGetIntegerv(GL_CULL_FACE_MODE, &_faceToCull); - _polygonOffSet = glIsEnabled(GL_POLYGON_OFFSET_FILL); - glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &_polygonOffSetFactor); - glGetFloatv(GL_POLYGON_OFFSET_UNITS, &_polygonOffSetUnits); - glGetFloatv(GL_COLOR_CLEAR_VALUE, _colorClearValue); - glGetFloatv(GL_DEPTH_CLEAR_VALUE, &_depthClearValue); - _depthIsEnabled = glIsEnabled(GL_DEPTH_TEST); - glGetIntegerv(GL_DEPTH_FUNC, &_depthFunction); - _blendIsEnabled = glIsEnabled(GL_BLEND); - - - glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); - GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; - glDrawBuffers(3, drawBuffers); - glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight); - glClearDepth(1.0f); - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - /*glEnable(GL_CULL_FACE); - checkGLError("begin() -- enabled cull face"); - glCullFace(GL_FRONT); - checkGLError("begin() -- set cullface to front");*/ - /*glEnable(GL_POLYGON_OFFSET_FILL); - checkGLError("begin() -- enabled polygon offset fill"); - glPolygonOffset(2.5f, 10.0f); - checkGLError("begin() -- set values for polygon offset");*/ - - RenderData lightRenderData{ - *_lightCamera, - data.time, - data.doPerformanceMeasurement, - data.renderBinMask, - data.modelTransform - }; - - return lightRenderData; - } - - void ShadowComponent::end() { - if (_executeDepthTextureSave) { - saveDepthBuffer(); - _executeDepthTextureSave = false; - } - - // Restores system state - glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); - GLenum drawBuffers[] = { - GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 - }; - glDrawBuffers(3, drawBuffers); - glViewport( - _mViewport[0], - _mViewport[1], - _mViewport[2], - _mViewport[3] - ); - - if (_faceCulling) { - glEnable(GL_CULL_FACE); - glCullFace(_faceToCull); - } - else { - glDisable(GL_CULL_FACE); - } - - if (_depthIsEnabled) { - glEnable(GL_DEPTH_TEST); - } - else { - glDisable(GL_DEPTH_TEST); - } - - glDepthFunc(_depthFunction); - - if (_polygonOffSet) { - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(_polygonOffSetFactor, _polygonOffSetUnits); - } - else { - glDisable(GL_POLYGON_OFFSET_FILL); - } - - glClearColor( - _colorClearValue[0], - _colorClearValue[1], - _colorClearValue[2], - _colorClearValue[3] - ); - glClearDepth(_depthClearValue); - - if (_blendIsEnabled) { - glEnable(GL_BLEND); - } - - if (_viewDepthMap) { - if (!_renderDMProgram) { - _renderDMProgram = global::renderEngine.buildRenderProgram( - "ShadowMappingDebuggingProgram", - absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_vs.glsl"), - absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_fs.glsl") - ); - } - - if (!_quadVAO) { - glGenVertexArrays(1, &_quadVAO); - } - - _renderDMProgram->activate(); - - ghoul::opengl::TextureUnit shadowMapUnit; - shadowMapUnit.activate(); - glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - - _renderDMProgram->setUniform("shadowMapTexture", shadowMapUnit); - - glBindVertexArray(_quadVAO); - glDrawArrays(GL_TRIANGLES, 0, 6); - - _renderDMProgram->deactivate(); - } - } - - void ShadowComponent::update(const UpdateData& /*data*/) { - _sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition(); - + else { glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); - if (_dynamicDepthTextureRes && ((_shadowDepthTextureWidth != renderingResolution.x) || - (_shadowDepthTextureHeight != renderingResolution.y))) { - _shadowDepthTextureWidth = renderingResolution.x * 2; - _shadowDepthTextureHeight = renderingResolution.y * 2; - updateDepthTexture(); + _shadowDepthTextureWidth = renderingResolution.x * 2; + _shadowDepthTextureHeight = renderingResolution.y * 2; + _dynamicDepthTextureRes = true; + } + + _saveDepthTexture.onChange([&]() { _executeDepthTextureSave = true; }); + + _viewDepthMap = false; + + addProperty(_enabled); + addProperty(_saveDepthTexture); + addProperty(_distanceFraction); +} + +void ShadowComponent::initialize() {} + +bool ShadowComponent::isReady() const { + return true; +} + +void ShadowComponent::initializeGL() { + createDepthTexture(); + createShadowFBO(); +} + +void ShadowComponent::deinitializeGL() { + glDeleteTextures(1, &_shadowDepthTexture); + glDeleteTextures(1, &_positionInLightSpaceTexture); + glDeleteFramebuffers(1, &_shadowFBO); + checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer"); +} + +RenderData ShadowComponent::begin(const RenderData& data) { + // =========================================== + // Builds light's ModelViewProjectionMatrix: + // =========================================== + + glm::dvec3 diffVector = glm::dvec3(_sunPosition) - data.modelTransform.translation; + double originalLightDistance = glm::length(diffVector); + glm::dvec3 lightDirection = glm::normalize(diffVector); + + // Percentage of the original light source distance (to avoid artifacts) + /*double multiplier = originalLightDistance * + (static_cast(_distanceFraction)/1.0E5);*/ + + double multiplier = originalLightDistance * + (static_cast(_distanceFraction) / 1E17); + + // New light source position + /*glm::dvec3 lightPosition = data.modelTransform.translation + + (lightDirection * multiplier);*/ + glm::dvec3 lightPosition = data.modelTransform.translation + + (diffVector * multiplier); + + //// Light Position + //glm::dvec3 lightPosition = glm::dvec3(_sunPosition); + + //=============== Manually Created Camera Matrix =================== + //================================================================== + // camera Z + glm::dvec3 cameraZ = lightDirection; + + // camera X + glm::dvec3 upVector = glm::dvec3(0.0, 1.0, 0.0); + glm::dvec3 cameraX = glm::normalize(glm::cross(upVector, cameraZ)); + + // camera Y + glm::dvec3 cameraY = glm::cross(cameraZ, cameraX); + + // init 4x4 matrix + glm::dmat4 cameraRotationMatrix(1.0); + + double* matrix = glm::value_ptr(cameraRotationMatrix); + matrix[0] = cameraX.x; + matrix[4] = cameraX.y; + matrix[8] = cameraX.z; + matrix[1] = cameraY.x; + matrix[5] = cameraY.y; + matrix[9] = cameraY.z; + matrix[2] = cameraZ.x; + matrix[6] = cameraZ.y; + matrix[10] = cameraZ.z; + + // set translation part + // We aren't setting the position here because it is set in + // the camera->setPosition() + //matrix[12] = -glm::dot(cameraX, lightPosition); + //matrix[13] = -glm::dot(cameraY, lightPosition); + //matrix[14] = -glm::dot(cameraZ, lightPosition); + + + _lightCamera = std::move(std::unique_ptr(new Camera(data.camera))); + _lightCamera->setPositionVec3(lightPosition); + _lightCamera->setRotation(glm::dquat(glm::inverse(cameraRotationMatrix))); + //======================================================================= + //======================================================================= + + + //============= Light Matrix by Camera Matrices Composition ============= + //======================================================================= + glm::dmat4 lightProjectionMatrix = glm::dmat4(_lightCamera->projectionMatrix()); + + // The model transformation missing in the final shadow matrix is add when rendering each + // object (using its transformations provided by the RenderData structure) + _shadowData.shadowMatrix = + _toTextureCoordsMatrix * lightProjectionMatrix * + _lightCamera->combinedViewMatrix(); + + + // Saves current state + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + glGetIntegerv(GL_VIEWPORT, _mViewport); + _faceCulling = glIsEnabled(GL_CULL_FACE); + glGetIntegerv(GL_CULL_FACE_MODE, &_faceToCull); + _polygonOffSet = glIsEnabled(GL_POLYGON_OFFSET_FILL); + glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &_polygonOffSetFactor); + glGetFloatv(GL_POLYGON_OFFSET_UNITS, &_polygonOffSetUnits); + glGetFloatv(GL_COLOR_CLEAR_VALUE, _colorClearValue); + glGetFloatv(GL_DEPTH_CLEAR_VALUE, &_depthClearValue); + _depthIsEnabled = glIsEnabled(GL_DEPTH_TEST); + glGetIntegerv(GL_DEPTH_FUNC, &_depthFunction); + _blendIsEnabled = glIsEnabled(GL_BLEND); + + + glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); + GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + glDrawBuffers(3, drawBuffers); + glViewport(0, 0, _shadowDepthTextureWidth, _shadowDepthTextureHeight); + glClearDepth(1.0f); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + /*glEnable(GL_CULL_FACE); + checkGLError("begin() -- enabled cull face"); + glCullFace(GL_FRONT); + checkGLError("begin() -- set cullface to front");*/ + /*glEnable(GL_POLYGON_OFFSET_FILL); + checkGLError("begin() -- enabled polygon offset fill"); + glPolygonOffset(2.5f, 10.0f); + checkGLError("begin() -- set values for polygon offset");*/ + + RenderData lightRenderData{ + *_lightCamera, + data.time, + data.doPerformanceMeasurement, + data.renderBinMask, + data.modelTransform + }; + + return lightRenderData; +} + +void ShadowComponent::end() { + if (_executeDepthTextureSave) { + saveDepthBuffer(); + _executeDepthTextureSave = false; + } + + // Restores system state + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + GLenum drawBuffers[] = { + GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 + }; + glDrawBuffers(3, drawBuffers); + glViewport(_mViewport[0], _mViewport[1], _mViewport[2], _mViewport[3]); + + if (_faceCulling) { + glEnable(GL_CULL_FACE); + glCullFace(_faceToCull); + } + else { + glDisable(GL_CULL_FACE); + } + + if (_depthIsEnabled) { + glEnable(GL_DEPTH_TEST); + } + else { + glDisable(GL_DEPTH_TEST); + } + + glDepthFunc(_depthFunction); + + if (_polygonOffSet) { + glEnable(GL_POLYGON_OFFSET_FILL); + glPolygonOffset(_polygonOffSetFactor, _polygonOffSetUnits); + } + else { + glDisable(GL_POLYGON_OFFSET_FILL); + } + + glClearColor( + _colorClearValue[0], + _colorClearValue[1], + _colorClearValue[2], + _colorClearValue[3] + ); + glClearDepth(_depthClearValue); + + if (_blendIsEnabled) { + glEnable(GL_BLEND); + } + + if (_viewDepthMap) { + if (!_renderDMProgram) { + _renderDMProgram = global::renderEngine.buildRenderProgram( + "ShadowMappingDebuggingProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/smviewer_fs.glsl") + ); } - } - void ShadowComponent::createDepthTexture() { - glGenTextures(1, &_shadowDepthTexture); - updateDepthTexture(); - - checkGLError("createDepthTexture() -- Depth texture created"); - - _shadowData.shadowDepthTexture = _shadowDepthTexture; - //_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; - } + if (!_quadVAO) { + glGenVertexArrays(1, &_quadVAO); + } - void ShadowComponent::createShadowFBO() { - // Saves current FBO first - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); - - glGenFramebuffers(1, &_shadowFBO); - glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); - glFramebufferTexture( - GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - _shadowDepthTexture, - 0 - ); + _renderDMProgram->activate(); - /*glFramebufferTexture( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - _positionInLightSpaceTexture, - 0 - );*/ - - checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); - //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; - GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE }; - glDrawBuffers(3, drawBuffers); - - checkFrameBufferState("createShadowFBO()"); - - // Restores system state - glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); - } - - void ShadowComponent::updateDepthTexture() { + ghoul::opengl::TextureUnit shadowMapUnit; + shadowMapUnit.activate(); glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - /* - glTexStorage2D( - GL_TEXTURE_2D, - 1, - GL_DEPTH_COMPONENT32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight - ); - */ - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_DEPTH_COMPONENT32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - 0, - GL_DEPTH_COMPONENT, - GL_FLOAT, - 0 - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, ShadowBorder); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + _renderDMProgram->setUniform("shadowMapTexture", shadowMapUnit); - /*glGenTextures(1, &_positionInLightSpaceTexture); - glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGB32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - 0, - GL_RGBA, - GL_FLOAT, - nullptr - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ - - glBindTexture(GL_TEXTURE_2D, 0); + glBindVertexArray(_quadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + + _renderDMProgram->deactivate(); } +} - void ShadowComponent::saveDepthBuffer() { - int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight; - GLubyte * buffer = new GLubyte[size]; +void ShadowComponent::update(const UpdateData& /*data*/) { + _sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition(); + + glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); + if (_dynamicDepthTextureRes && ((_shadowDepthTextureWidth != renderingResolution.x) || + (_shadowDepthTextureHeight != renderingResolution.y))) { + _shadowDepthTextureWidth = renderingResolution.x * 2; + _shadowDepthTextureHeight = renderingResolution.y * 2; + updateDepthTexture(); + } +} - glReadPixels( - 0, - 0, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - GL_DEPTH_COMPONENT, - GL_UNSIGNED_BYTE, - buffer - ); +void ShadowComponent::createDepthTexture() { + glGenTextures(1, &_shadowDepthTexture); + updateDepthTexture(); + + checkGLError("createDepthTexture() -- Depth texture created"); + + _shadowData.shadowDepthTexture = _shadowDepthTexture; + //_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; +} - checkGLError("readDepthBuffer To buffer"); - std::fstream ppmFile; +void ShadowComponent::createShadowFBO() { + // Saves current FBO first + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + + glGenFramebuffers(1, &_shadowFBO); + glBindFramebuffer(GL_FRAMEBUFFER, _shadowFBO); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + _shadowDepthTexture, + 0 + ); - ppmFile.open("depthBufferShadowMapping.ppm", std::fstream::out); - if (ppmFile.is_open()) { + /*glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + _positionInLightSpaceTexture, + 0 + );*/ + + checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); + //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; + GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE }; + glDrawBuffers(3, drawBuffers); - ppmFile << "P3" << std::endl; - ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight - << std::endl; - ppmFile << "255" << std::endl; + checkFrameBufferState("createShadowFBO()"); - std::cout << "\n\nSaving depth texture to file depthBufferShadowMapping.ppm\n\n"; - int k = 0; - for (int i = 0; i < _shadowDepthTextureWidth; i++) { - for (int j = 0; j < _shadowDepthTextureHeight; j++, k++) { - unsigned int val = static_cast(buffer[k]); - ppmFile << val << " " << val << " " << val << " "; - } - ppmFile << std::endl; + // Restores system state + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); +} + +void ShadowComponent::updateDepthTexture() { + glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); + /* + glTexStorage2D( + GL_TEXTURE_2D, + 1, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight + ); + */ + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + 0 + ); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, ShadowBorder); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + + /*glGenTextures(1, &_positionInLightSpaceTexture); + glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGB32F, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void ShadowComponent::saveDepthBuffer() { + int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight; + GLubyte* buffer = new GLubyte[size]; + + glReadPixels( + 0, + 0, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + GL_DEPTH_COMPONENT, + GL_UNSIGNED_BYTE, + buffer + ); + + checkGLError("readDepthBuffer To buffer"); + std::fstream ppmFile; + + ppmFile.open("depthBufferShadowMapping.ppm", std::fstream::out); + if (ppmFile.is_open()) { + + ppmFile << "P3" << std::endl; + ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight + << std::endl; + ppmFile << "255" << std::endl; + + std::cout << "\n\nSaving depth texture to file depthBufferShadowMapping.ppm\n\n"; + int k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++, k++) { + unsigned int val = static_cast(buffer[k]); + ppmFile << val << " " << val << " " << val << " "; } - - ppmFile.close(); - - std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n"; + ppmFile << std::endl; } - delete[] buffer; + ppmFile.close(); - GLfloat * bBuffer = new GLfloat[size * 4]; - - glReadBuffer(GL_COLOR_ATTACHMENT3); - glReadPixels( - 0, - 0, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - GL_RGBA, - GL_FLOAT, - bBuffer - ); - - checkGLError("readPositionBuffer To buffer"); - ppmFile.clear(); - - ppmFile.open("positionBufferShadowMapping.ppm", std::fstream::out); - if (ppmFile.is_open()) { - - ppmFile << "P3" << std::endl; - ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight - << std::endl; - ppmFile << "255" << std::endl; - - std::cout << "\n\nSaving texture position to positionBufferShadowMapping.ppm\n\n"; - - float biggestValue = 0.f; - - int k = 0; - for (int i = 0; i < _shadowDepthTextureWidth; i++) { - for (int j = 0; j < _shadowDepthTextureHeight; j++) { - biggestValue = bBuffer[k] > biggestValue ? - bBuffer[k] : biggestValue; - k += 4; - } - } - - biggestValue /= 255.f; - - k = 0; - for (int i = 0; i < _shadowDepthTextureWidth; i++) { - for (int j = 0; j < _shadowDepthTextureHeight; j++) { - ppmFile << static_cast(bBuffer[k] / biggestValue) << " " - << static_cast(bBuffer[k + 1] / biggestValue) << " " - << static_cast(bBuffer[k + 2] / biggestValue) << " "; - k += 4; - } - ppmFile << std::endl; - } - - ppmFile.close(); - - std::cout << "Texture saved to file positionBufferShadowMapping.ppm\n\n"; - } - - delete[] bBuffer; + std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n"; } - void ShadowComponent::checkGLError(const std::string & where) const { - const GLenum error = glGetError(); - switch (error) { + delete[] buffer; + + GLfloat* bBuffer = new GLfloat[size * 4]; + + glReadBuffer(GL_COLOR_ATTACHMENT3); + glReadPixels( + 0, + 0, + _shadowDepthTextureWidth, + _shadowDepthTextureHeight, + GL_RGBA, + GL_FLOAT, + bBuffer + ); + + checkGLError("readPositionBuffer To buffer"); + ppmFile.clear(); + + ppmFile.open("positionBufferShadowMapping.ppm", std::fstream::out); + if (ppmFile.is_open()) { + + ppmFile << "P3" << std::endl; + ppmFile << _shadowDepthTextureWidth << " " << _shadowDepthTextureHeight + << std::endl; + ppmFile << "255" << std::endl; + + std::cout << "\n\nSaving texture position to positionBufferShadowMapping.ppm\n\n"; + + float biggestValue = 0.f; + + int k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++) { + biggestValue = bBuffer[k] > biggestValue ? + bBuffer[k] : biggestValue; + k += 4; + } + } + + biggestValue /= 255.f; + + k = 0; + for (int i = 0; i < _shadowDepthTextureWidth; i++) { + for (int j = 0; j < _shadowDepthTextureHeight; j++) { + ppmFile << static_cast(bBuffer[k] / biggestValue) << " " + << static_cast(bBuffer[k + 1] / biggestValue) << " " + << static_cast(bBuffer[k + 2] / biggestValue) << " "; + k += 4; + } + ppmFile << std::endl; + } + + ppmFile.close(); + + std::cout << "Texture saved to file positionBufferShadowMapping.ppm\n\n"; + } + + delete[] bBuffer; +} + +void ShadowComponent::checkGLError(const std::string & where) const { + const GLenum error = glGetError(); + switch (error) { case GL_NO_ERROR: break; case GL_INVALID_ENUM: @@ -717,18 +686,19 @@ namespace openspace { "OpenGL Invalid State", fmt::format("Unknown error code: {0:x}", static_cast(error)) ); - } } +} - bool ShadowComponent::isEnabled() const { - return _enabled; - } +bool ShadowComponent::isEnabled() const { + return _enabled; +} - ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const { - return _shadowData; - } +ShadowComponent::ShadowMapData ShadowComponent::shadowMapData() const { + return _shadowData; +} + +void ShadowComponent::setViewDepthMap(bool enable) { + _viewDepthMap = enable; +} - void ShadowComponent::setViewDepthMap(bool enable) { - _viewDepthMap = enable; - } } // namespace openspace diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 602a480f00..d1505a3e31 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -1,46 +1,43 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2018 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #ifndef __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ #define __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ #include +#include +#include #include #include #include #include #include -#include -#include - #include - #include #include #include - #include #include @@ -58,111 +55,109 @@ namespace openspace { struct RenderData; struct UpdateData; - namespace documentation { struct Documentation; } +namespace documentation { struct Documentation; } - static const GLfloat ShadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; +static const GLfloat ShadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; - class ShadowComponent : public properties::PropertyOwner { - public: - struct ShadowMapData { - glm::dmat4 shadowMatrix; - GLuint shadowDepthTexture; - }; - public: - ShadowComponent(const ghoul::Dictionary& dictionary); - - void initialize(); - void initializeGL(); - void deinitializeGL(); - //bool deinitialize(); - - bool isReady() const; - - RenderData begin(const RenderData& data); - void end(); - void update(const UpdateData& data); - - static documentation::Documentation Documentation(); - - bool isEnabled() const; - - ShadowComponent::ShadowMapData shadowMapData() const; - - void setViewDepthMap(bool enable); - - private: - void createDepthTexture(); - void createShadowFBO(); - void updateDepthTexture(); - - // Debug - void saveDepthBuffer(); - void checkGLError(const std::string & where) const; - - private: - - ShadowMapData _shadowData; - - // Texture coords in [0, 1], while clip coords in [-1, 1] - const glm::dmat4 _toTextureCoordsMatrix = glm::dmat4( - glm::dvec4(0.5, 0.0, 0.0, 0.0), - glm::dvec4(0.0, 0.5, 0.0, 0.0), - glm::dvec4(0.0, 0.0, 1.0, 0.0), - glm::dvec4(0.5, 0.5, 0.0, 1.0) - ); - - // DEBUG - properties::TriggerProperty _saveDepthTexture; - properties::IntProperty _distanceFraction; - properties::BoolProperty _enabled; - - ghoul::Dictionary _shadowMapDictionary; - - int _shadowDepthTextureHeight; - int _shadowDepthTextureWidth; - bool _dynamicDepthTextureRes = true; - - GLuint _shadowDepthTexture; - GLuint _positionInLightSpaceTexture; - GLuint _shadowFBO; - GLuint _firstPassSubroutine; - GLuint _secondPassSubroutine; - GLint _defaultFBO; - GLint _mViewport[4]; - - GLboolean _faceCulling; - GLboolean _polygonOffSet; - GLboolean _depthIsEnabled; - GLboolean _blendIsEnabled = false; - - GLenum _faceToCull; - GLenum _depthFunction; - - GLfloat _polygonOffSetFactor; - GLfloat _polygonOffSetUnits; - GLfloat _colorClearValue[4]; - GLfloat _depthClearValue; - - glm::vec3 _sunPosition; - - glm::dmat4 _shadowMatrix; - - glm::dvec3 _cameraPos; - glm::dvec3 _cameraFocus; - glm::dquat _cameraRotation; - - std::stringstream _serializedCamera; - - std::unique_ptr _lightCamera; - - // DEBUG - bool _executeDepthTextureSave = false; - bool _viewDepthMap = false; - std::unique_ptr _renderDMProgram; - GLuint _quadVAO = 0u; - +class ShadowComponent : public properties::PropertyOwner { +public: + struct ShadowMapData { + glm::dmat4 shadowMatrix; + GLuint shadowDepthTexture; }; + ShadowComponent(const ghoul::Dictionary& dictionary); + + void initialize(); + void initializeGL(); + void deinitializeGL(); + //bool deinitialize(); + + bool isReady() const; + + RenderData begin(const RenderData& data); + void end(); + void update(const UpdateData& data); + + static documentation::Documentation Documentation(); + + bool isEnabled() const; + + ShadowComponent::ShadowMapData shadowMapData() const; + + void setViewDepthMap(bool enable); + +private: + void createDepthTexture(); + void createShadowFBO(); + void updateDepthTexture(); + + // Debug + void saveDepthBuffer(); + void checkGLError(const std::string & where) const; + + ShadowMapData _shadowData; + + // Texture coords in [0, 1], while clip coords in [-1, 1] + const glm::dmat4 _toTextureCoordsMatrix = glm::dmat4( + glm::dvec4(0.5, 0.0, 0.0, 0.0), + glm::dvec4(0.0, 0.5, 0.0, 0.0), + glm::dvec4(0.0, 0.0, 1.0, 0.0), + glm::dvec4(0.5, 0.5, 0.0, 1.0) + ); + + // DEBUG + properties::TriggerProperty _saveDepthTexture; + properties::IntProperty _distanceFraction; + properties::BoolProperty _enabled; + + ghoul::Dictionary _shadowMapDictionary; + + int _shadowDepthTextureHeight = 4096; + int _shadowDepthTextureWidth = 4096; + bool _dynamicDepthTextureRes = true; + + // All of these initializations should probably be 0 since they are GLuints? + GLuint _shadowDepthTexture = -1; + GLuint _positionInLightSpaceTexture = -1; + GLuint _shadowFBO = -1; + GLuint _firstPassSubroutine = -1; + GLuint _secondPassSubroutine = 1; + GLint _defaultFBO = -1; + GLint _mViewport[4]; + + GLboolean _faceCulling; + GLboolean _polygonOffSet; + GLboolean _depthIsEnabled; + GLboolean _blendIsEnabled = false; + + GLenum _faceToCull; + GLenum _depthFunction; + + GLfloat _polygonOffSetFactor; + GLfloat _polygonOffSetUnits; + GLfloat _colorClearValue[4]; + GLfloat _depthClearValue; + + glm::vec3 _sunPosition; + + glm::dmat4 _shadowMatrix = glm::dmat4(1.0); + + glm::dvec3 _cameraPos = glm::dvec3(0.0); + glm::dvec3 _cameraFocus; + glm::dquat _cameraRotation; + + std::stringstream _serializedCamera; + + std::unique_ptr _lightCamera; + + // DEBUG + bool _executeDepthTextureSave = false; + bool _viewDepthMap = false; + std::unique_ptr _renderDMProgram; + GLuint _quadVAO = 0u; +}; + } // namespace openspace #endif // __OPENSPACE_MODULE_GLOBEBROWSING___SHADOWCOMPONENT___H__ From f90fe90aae2e6d52f98a76134bb2b2d7427bc9f7 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 11:34:41 +0100 Subject: [PATCH 085/214] Also include Pluto in the change of labels to globelabels --- .../assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset | 5 +++-- .../pluto/{pluto_labels.asset => pluto_globelabels.asset} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename data/assets/scene/solarsystem/dwarf_planets/pluto/{pluto_labels.asset => pluto_globelabels.asset} (100%) diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset index db18a54cc1..ce98ef30f8 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto.asset @@ -2,7 +2,7 @@ local assetHelper = asset.require('util/asset_helper') local transforms = asset.require('./transforms') asset.require("spice/base") asset.request('./trail') -local labelsPath = asset.require('./pluto_labels').LabelsPath +local labelsPath = asset.require('./pluto_globelabels').LabelsPath @@ -63,7 +63,7 @@ local PlutoLabel = { Identifier = "PlutoLabel", Parent = Pluto.Identifier, Renderable = { - Enabled = true, + Enabled = false, Type = "RenderableLabels", LabelText = "Pluto", FontSize = 100.0, @@ -73,6 +73,7 @@ local PlutoLabel = { BlendMode = "Additive", LabelOrientationOption = "Camera View Direction" }, + Tag = { "solarsystem_labels" }, GUI = { Name = "Pluto Label", Path = "/Solar System/Dwarf Planets/Pluto" diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_labels.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_globelabels.asset similarity index 100% rename from data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_labels.asset rename to data/assets/scene/solarsystem/dwarf_planets/pluto/pluto_globelabels.asset From 04bd649bfe14820082ee8702745aa1d8bab4ab96 Mon Sep 17 00:00:00 2001 From: liuloppan Date: Mon, 16 Dec 2019 13:50:44 +0100 Subject: [PATCH 086/214] Update to use pluto_globelabels Update to use the renamed filename --- data/assets/scene/solarsystem/dwarf_planets/pluto/charon.asset | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon.asset b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon.asset index c9c58a820f..87139c2b9e 100644 --- a/data/assets/scene/solarsystem/dwarf_planets/pluto/charon.asset +++ b/data/assets/scene/solarsystem/dwarf_planets/pluto/charon.asset @@ -2,7 +2,7 @@ local assetHelper = asset.require('util/asset_helper') local transforms = asset.require('./transforms') asset.require("spice/base") asset.request('./trail') -local labelsPath = asset.require('./pluto_labels').LabelsPath +local labelsPath = asset.require('./pluto_globelabels').LabelsPath From 8feb6d1d2b14f0780991c8cfdea850776364f08d Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 17 Dec 2019 10:57:37 +0100 Subject: [PATCH 087/214] Small cleanup Make sure OpenSpace compiles in debug mode --- apps/OpenSpace/main.cpp | 23 ++++++++++++---------- modules/webbrowser/src/browserinstance.cpp | 11 ++++++++--- scripts/convertProfileToScene.lua | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index b18ba85ab0..80e24ffba6 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -1206,16 +1206,19 @@ int main(int argc, char** argv) { i += replace.length(); } - std::string setProfileFilenameInLuaState = "\ - openspace = {}\n\ - openspace.profile = {}\n\ - function openspace.profile.getFilename()\n\ - return \"" + global::configuration.profile + ".profile\"\ - end\n\ - function openspace.profile.getPath()\n\ - return \"" + outputScenePath + "\"\ - end\ - "; + std::string setProfileFilenameInLuaState = fmt::format(R"( + openspace = {{}} + openspace.profile = {{}} + function openspace.profile.getFilename() + return "{}.profile" + end + function openspace.profile.getPath() + return "{}" + end + )", + global::configuration.profile, outputScenePath + ); + ghoul::lua::runScript(lState, setProfileFilenameInLuaState); ghoul::lua::runScriptFile(lState, absPath(ProfileToSceneConverter)); } diff --git a/modules/webbrowser/src/browserinstance.cpp b/modules/webbrowser/src/browserinstance.cpp index 3622a4583e..f57a45a877 100644 --- a/modules/webbrowser/src/browserinstance.cpp +++ b/modules/webbrowser/src/browserinstance.cpp @@ -83,9 +83,14 @@ void BrowserInstance::initialize() { void BrowserInstance::loadUrl(std::string url) { ghoul_assert(_isInitialized, "BrowserInstance should be initialized"); - LDEBUG(fmt::format("Loading URL: {}", url)); - CefString cefUrl = std::move(url); - _browser->GetMainFrame()->LoadURL(cefUrl); + if (!url.empty()) { + LDEBUG(fmt::format("Loading URL: {}", url)); + CefString cefUrl = std::move(url); + _browser->GetMainFrame()->LoadURL(cefUrl); + } + else { + LWARNING("Provided browser URL is empty"); + } } bool BrowserInstance::loadLocalPath(std::string path) { diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index 1b6b90f008..e27dec9ad5 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -18,7 +18,7 @@ function printError(message) print("Error @ line "..lineIndex..": "..message) end -function splitByTab (inputstr) +function splitByTab(inputstr) sep = "\t" t = {} for match in (inputstr..sep):gmatch("(.-)"..sep) do From 3051d71fea98591bf26eeae27b4564402da7e112 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 17 Dec 2019 11:05:14 +0100 Subject: [PATCH 088/214] Small code cleanup --- .../digitaluniverse/shaders/billboard_fs.glsl | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/modules/digitaluniverse/shaders/billboard_fs.glsl b/modules/digitaluniverse/shaders/billboard_fs.glsl index 0db1fa3fe4..90fe9d0696 100644 --- a/modules/digitaluniverse/shaders/billboard_fs.glsl +++ b/modules/digitaluniverse/shaders/billboard_fs.glsl @@ -35,12 +35,11 @@ uniform sampler2D spriteTexture; uniform bool hasColorMap; uniform float fadeInValue; -Fragment getFragment() { - +Fragment getFragment() { vec4 textureColor = texture(spriteTexture, texCoord); - if (textureColor.a == 0.f || gs_colorMap.a == 0.f || - ta == 0.f || fadeInValue == 0.f) { + if (textureColor.a == 0.f || gs_colorMap.a == 0.f || ta == 0.f || fadeInValue == 0.f) + { discard; } @@ -48,10 +47,11 @@ Fragment getFragment() { if (hasColorMap) { fullColor = vec4( - gs_colorMap.rgb * textureColor.rgb, + gs_colorMap.rgb * textureColor.rgb, gs_colorMap.a * textureColor.a * alphaValue - ); - } else { + ); + } + else { fullColor = vec4(color.rgb * textureColor.rgb, textureColor.a * alphaValue); } @@ -63,14 +63,13 @@ Fragment getFragment() { } Fragment frag; - frag.color = fullColor; - frag.depth = vs_screenSpaceDepth; + frag.color = fullColor; + frag.depth = vs_screenSpaceDepth; // Setting the position of the billboards to not interact // with the ATM. - frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); - frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + frag.gPosition = vec4(-1e32, -1e32, -1e32, 1.0); + frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); //frag.disableLDR2HDR = true; - return frag; -} \ No newline at end of file +} From bd8ade16f42adee40530b19107db4bbf2800596b Mon Sep 17 00:00:00 2001 From: GPayne Date: Wed, 18 Dec 2019 17:53:17 -0600 Subject: [PATCH 089/214] Fixed order of parsing elements from csv file --- modules/space/rendering/renderablesmallbody.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 82185536d5..ef939a6ab3 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -280,8 +280,9 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { std::getline(file, ignore, ','); std::getline(file, ignore, ','); - // Ignore date + // Epoch std::getline(file, ignore, ','); + keplerElements.epoch = epochFromYMDdSubstring(ignore); // Eccentricity (unit-less) std::getline(file, ignore, ','); @@ -308,10 +309,6 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { std::getline(file, ignore, ','); keplerElements.meanAnomaly = std::stod(ignore); - // Epoch (MJD) - std::getline(file, ignore, ','); - keplerElements.epoch = epochFromYMDdSubstring(ignore); - // Period (days) std::getline(file, ignore); keplerElements.period = std::stod(ignore); @@ -324,13 +321,13 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { catch (std::invalid_argument&) { LERROR(fmt::format( "invalid_argument exception on line {} of {}", - csvLine - 1, filename + csvLine + 1, filename )); } catch (std::out_of_range&) { LERROR(fmt::format( "out_of_range exception on line {} of {}", - csvLine - 1, filename + csvLine + 1, filename )); } From 2d0eb703a49772a7e7e7a79c90e7887dc4b36a51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20S=C3=B6derman?= Date: Fri, 20 Dec 2019 08:07:28 +0100 Subject: [PATCH 090/214] fix case sensitive include file for linux compile --- modules/base/rendering/renderablelabels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 5c8bbd20ae..d070d0f974 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -22,7 +22,7 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include #include #include From b2861183ae59fd8a86d1d8935bf6742d7bcb6f87 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Fri, 20 Dec 2019 10:15:12 +0100 Subject: [PATCH 091/214] Distance label hack, needs cleanup and replacement --- modules/base/rendering/renderablelabels.cpp | 43 ++++++++++++++++++- modules/base/rendering/renderablelabels.h | 1 + modules/base/rendering/renderablenodeline.cpp | 22 +++++++--- modules/base/rendering/renderablenodeline.h | 16 +++++-- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index 5c8bbd20ae..d5a51afea1 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -46,6 +46,11 @@ #include #include +#include +#include +#include +#include + namespace { constexpr const char* _loggerCat = "base::RenderableLabels"; @@ -175,6 +180,13 @@ namespace { "Fade-In/-Out ending speed.", "Fade-In/-Out ending speed." }; + + constexpr openspace::properties::Property::PropertyInfo NodeLineInfo = { + "NodeLine", + "Node Line", + "Optional property to track a nodeline. When tracking the label text will be updating the distance " + "from the nodeline start and end. " + }; } // namespace namespace openspace { @@ -315,6 +327,7 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) , _pixelSizeControl(PixelSizeControlInfo, false) , _enableFadingEffect(EnableFadingEffectInfo, false) , _labelText(LabelTextInfo) + , _nodeLine(NodeLineInfo) , _fadeStartDistance(FadeStartDistInfo, 1.f, 0.f, 100.f) , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f) , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f) @@ -447,6 +460,11 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeStartDistance = dictionary.value(FadeStartDistInfo.identifier); } + if (dictionary.hasKey(NodeLineInfo.identifier)) { + _nodeLine = dictionary.value(NodeLineInfo.identifier); + addProperty(_nodeLine); + } + addProperty(_fadeStartDistance); _fadeStartUnitOption.addOption(Meter, MeterUnit); @@ -683,7 +701,30 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { //} } -void RenderableLabels::update(const UpdateData&) { +void RenderableLabels::update(const UpdateData& data) { + + if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { + + // Calculate distance + SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); + RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); + double myDistance = nodeline->getDistance(); + + // format string + float scale = getUnit(Kilometer); + std::string distanceText = std::to_string(std::round(myDistance / scale)); + int pos = distanceText.find("."); + std::string subStr = distanceText.substr(pos); + distanceText.erase(pos, subStr.size()); + std::string finalText = distanceText + " " + KilometerUnit; + setLabelText(finalText); + + // Update placement of label with transformation matrix + glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); + glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); + glm::dvec3 goalPos = start + (end - start) / 2.0; + _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); + } } void RenderableLabels::setLabelText(const std::string & newText) { diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 0f5bbf6f99..7b97b80a98 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -107,6 +107,7 @@ private: properties::BoolProperty _pixelSizeControl; properties::BoolProperty _enableFadingEffect; properties::StringProperty _labelText; + properties::StringProperty _nodeLine; properties::FloatProperty _fadeStartDistance; properties::FloatProperty _fadeEndDistance; properties::FloatProperty _fadeStartSpeed; diff --git a/modules/base/rendering/renderablenodeline.cpp b/modules/base/rendering/renderablenodeline.cpp index 56bbdd53a0..36fbbe5a50 100644 --- a/modules/base/rendering/renderablenodeline.cpp +++ b/modules/base/rendering/renderablenodeline.cpp @@ -43,13 +43,13 @@ namespace { constexpr openspace::properties::Property::PropertyInfo StartNodeInfo = { "StartNode", "Start Node", - "The identifier of the node the line starts from. " + "The identifier of the node the line starts from. Defaults to 'Root' if not specified. " }; constexpr openspace::properties::Property::PropertyInfo EndNodeInfo = { "EndNode", "End Node", - "The identifier of the node the line ends at. " + "The identifier of the node the line ends at. Defaults to 'Root' if not specified. " }; constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { @@ -76,13 +76,13 @@ documentation::Documentation RenderableNodeLine::Documentation() { { StartNodeInfo.identifier, new StringVerifier, - Optional::No, + Optional::Yes, StartNodeInfo.description }, { EndNodeInfo.identifier, new StringVerifier, - Optional::No, + Optional::Yes, EndNodeInfo.description }, { @@ -114,8 +114,13 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) "RenderableNodeLine" ); - _start = dictionary.value(StartNodeInfo.identifier); - _end = dictionary.value(EndNodeInfo.identifier); + if (dictionary.hasKey(StartNodeInfo.identifier)) { + _start = dictionary.value(StartNodeInfo.identifier); + } + + if (dictionary.hasKey(EndNodeInfo.identifier)) { + _end = dictionary.value(EndNodeInfo.identifier); + } if (dictionary.hasKey(LineColorInfo.identifier)) { _lineColor = dictionary.value(LineColorInfo.identifier); @@ -131,6 +136,11 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) addProperty(_opacity); } +double RenderableNodeLine::getDistance() +{ + return glm::distance(_startPos, _endPos); +} + void RenderableNodeLine::initializeGL() { _program = BaseModule::ProgramObjectManager.request( ProgramName, diff --git a/modules/base/rendering/renderablenodeline.h b/modules/base/rendering/renderablenodeline.h index d8866def1b..2792f986d5 100644 --- a/modules/base/rendering/renderablenodeline.h +++ b/modules/base/rendering/renderablenodeline.h @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -50,7 +51,18 @@ public: ~RenderableNodeLine() = default; static documentation::Documentation Documentation(); - + + // Identifier of the optional distance label + std::string _distanceLabelId; + //SceneGraphNode* distanceLabelNode = nullptr; + //RenderableLabels* distanceLabel; + + // Get the distance between the start and end node + double getDistance(); + + properties::StringProperty _start; + properties::StringProperty _end; + private: void initializeGL() override; void deinitializeGL() override; @@ -75,8 +87,6 @@ private: glm::dvec3 _startPos; glm::dvec3 _endPos; - properties::StringProperty _start; - properties::StringProperty _end; properties::Vec3Property _lineColor; properties::FloatProperty _lineWidth; }; From 797c674f127dadc195d445cb48c84b55c7911ade Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 20 Dec 2019 14:12:25 -0700 Subject: [PATCH 092/214] Moved profile-to-asset conversion to openspaceengine and using temp dir --- apps/OpenSpace/main.cpp | 39 ---------------------------------- src/engine/openspaceengine.cpp | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 80e24ffba6..0c2db5f9e4 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -84,9 +84,6 @@ constexpr const char* _loggerCat = "main"; constexpr const char* SpoutTag = "Spout"; constexpr const char* OpenVRTag = "OpenVR"; -constexpr const char* ProfileToSceneConverter - = "${BASE}/scripts/convertProfileToScene.lua"; - sgct::Engine* SgctEngine; sgct::SharedVector _synchronizationBuffer; @@ -1187,42 +1184,6 @@ int main(int argc, char** argv) { parseLuaState(global::configuration); } - // Convert profile to scene file (if was provided in configuration file) - if (!global::configuration.profile.empty()) { - LINFO(fmt::format("Run Lua script to convert {}.profile to scene", - global::configuration.profile)); - ghoul::lua::LuaState lState; - - // Get path where .scene files reside. Need to add extra escape slashes to - // accomodate lua parser. - std::string outputScenePath = absPath("${BASE}/data/assets"); - std::string search = "\\"; - std::string replace = "\\\\"; - for (std::string::size_type i = outputScenePath.find(search); - i != std::string::npos; - i = outputScenePath.find(search, i)) - { - outputScenePath.replace(i, search.length(), replace); - i += replace.length(); - } - - std::string setProfileFilenameInLuaState = fmt::format(R"( - openspace = {{}} - openspace.profile = {{}} - function openspace.profile.getFilename() - return "{}.profile" - end - function openspace.profile.getPath() - return "{}" - end - )", - global::configuration.profile, outputScenePath - ); - - ghoul::lua::runScript(lState, setProfileFilenameInLuaState); - ghoul::lua::runScriptFile(lState, absPath(ProfileToSceneConverter)); - } - // Determining SGCT configuration file LDEBUG("SGCT Configuration file: " + global::configuration.windowConfiguration); diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index d62d07937d..e393807bc2 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -98,6 +98,9 @@ namespace { constexpr const char* _loggerCat = "OpenSpaceEngine"; constexpr const int CacheVersion = 1; + constexpr const char* ProfileToSceneConverter + = "${BASE}/scripts/convertProfileToScene.lua"; + } // namespace namespace openspace { @@ -292,6 +295,42 @@ void OpenSpaceEngine::initialize() { LDEBUG("Registering Lua libraries"); registerCoreClasses(global::scriptEngine); + // Convert profile to scene file (if was provided in configuration file) + if (!global::configuration.profile.empty()) { + LINFO(fmt::format("Run Lua script to convert {}.profile to scene", + global::configuration.profile)); + ghoul::lua::LuaState lState; + + // Get path where .scene files reside. Need to add extra escape slashes to + // accomodate lua parser. + std::string outputScenePath = absPath("${TEMPORARY}"); + std::string search = "\\"; + std::string replace = "\\\\"; + for (std::string::size_type i = outputScenePath.find(search); + i != std::string::npos; + i = outputScenePath.find(search, i)) + { + outputScenePath.replace(i, search.length(), replace); + i += replace.length(); + } + + std::string setProfileFilenameInLuaState = fmt::format(R"( + openspace = {{}} + openspace.profile = {{}} + function openspace.profile.getFilename() + return "{}.profile" + end + function openspace.profile.getPath() + return "{}" + end + )", + global::configuration.profile, outputScenePath + ); + + ghoul::lua::runScript(lState, setProfileFilenameInLuaState); + ghoul::lua::runScriptFile(lState, absPath(ProfileToSceneConverter)); + } + // Set up asset loader std::unique_ptr w = std::make_unique(); From 1343b206ab7935362b0b86aefdae6b2f169fa395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eric=20S=C3=B6derman?= Date: Tue, 24 Dec 2019 23:50:53 +0100 Subject: [PATCH 093/214] support curl version < 7.32.0, i.e. rhel/centos 7 --- src/engine/downloadmanager.cpp | 4 ++++ src/util/httprequest.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/engine/downloadmanager.cpp b/src/engine/downloadmanager.cpp index 5025b2e85e..fb3581e34d 100644 --- a/src/engine/downloadmanager.cpp +++ b/src/engine/downloadmanager.cpp @@ -187,8 +187,12 @@ std::shared_ptr DownloadManager::downloadFile( std::chrono::system_clock::now(), &progressCb }; + #if LIBCURL_VERSION_NUM >= 0x072000 + // xferinfo was introduced in 7.32.0, if a lower curl version is used the progress + // will not be shown for downloads on the splash screen curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo); // NOLINT curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &p); // NOLINT + #endif curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); // NOLINT CURLcode res = curl_easy_perform(curl); diff --git a/src/util/httprequest.cpp b/src/util/httprequest.cpp index 71b6877fbe..d5c8433884 100644 --- a/src/util/httprequest.cpp +++ b/src/util/httprequest.cpp @@ -124,9 +124,13 @@ void HttpRequest::perform(RequestOptions opt) { curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlfunctions::writeCallback); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); // NOLINT + #if LIBCURL_VERSION_NUM >= 0x072000 + // xferinfo was introduced in 7.32.0, if a lower curl version is used the progress + // will not be shown for downloads on the splash screen curl_easy_setopt(curl, CURLOPT_XFERINFODATA, this); // NOLINT // NOLINTNEXTLINE curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curlfunctions::progressCallback); + #endif if (opt.requestTimeoutSeconds > 0) { curl_easy_setopt(curl, CURLOPT_TIMEOUT, opt.requestTimeoutSeconds); // NOLINT From 02bf704c0217a93c1f8b5bc6a1360b09859e6d03 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 26 Dec 2019 19:01:01 +0100 Subject: [PATCH 094/214] Update Kameleon repository --- modules/kameleon/ext/kameleon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/kameleon/ext/kameleon b/modules/kameleon/ext/kameleon index 1b4549edc7..338d482c86 160000 --- a/modules/kameleon/ext/kameleon +++ b/modules/kameleon/ext/kameleon @@ -1 +1 @@ -Subproject commit 1b4549edc74ef371730ef9d39c1ffa0efe90a985 +Subproject commit 338d482c8617bfacda0a5af8f3f6bb23163d436f From c8106da25b5b9d79afb1f21d0910d177350e7076 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 27 Dec 2019 17:21:00 +0100 Subject: [PATCH 095/214] First version of galaxy caching --- modules/galaxy/rendering/renderablegalaxy.cpp | 216 ++++++++++++++---- modules/galaxy/rendering/renderablegalaxy.h | 14 +- 2 files changed, 179 insertions(+), 51 deletions(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 71edb8d372..17f95d1a48 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -34,7 +34,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -46,6 +48,8 @@ #include namespace { + constexpr int8_t CurrentCacheVersion = 1; + constexpr const char* GlslRaycastPath = "${MODULES}/galaxy/shaders/galaxyraycast.glsl"; constexpr const char* GlslBoundsVsPath = @@ -118,14 +122,16 @@ namespace { "" // @TODO Missing documentation }; - constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = { + constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = + { "Downscale", "Downscale Factor Volume Rendering", "This value set the downscaling factor" " when rendering the current volume." }; - constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo = { + constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo = + { "Steps", "Number of RayCasting Steps", "This value set the number of integration steps during the raycasting procedure." @@ -134,7 +140,7 @@ namespace { namespace openspace { - RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) +RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _volumeRenderingEnabled(VolumeRenderingEnabledInfo, true) , _starRenderingEnabled(StarRenderingEnabledInfo, true) @@ -164,7 +170,7 @@ namespace openspace { if (dictionary.hasKeyAndValue(VolumeRenderingEnabledInfo.identifier)) { _volumeRenderingEnabled = dictionary.value( VolumeRenderingEnabledInfo.identifier - ); + ); } if (dictionary.hasKeyAndValue(StarRenderingEnabledInfo.identifier)) { @@ -248,9 +254,7 @@ namespace openspace { LINFO("Number of raycasting steps not specified. Using default value."); } - _downScaleVolumeRendering.setVisibility( - openspace::properties::Property::Visibility::Developer - ); + _downScaleVolumeRendering.setVisibility(properties::Property::Visibility::Developer); if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { _downScaleVolumeRendering = volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); @@ -272,7 +276,7 @@ namespace openspace { if (pointsDictionary.hasKeyAndValue(EnabledPointsRatioInfo.identifier)) { _enabledPointsRatio = static_cast( pointsDictionary.value(EnabledPointsRatioInfo.identifier) - ); + ); } std::string pointSpreadFunctionTexturePath; @@ -292,6 +296,7 @@ void RenderableGalaxy::initializeGL() { _aspect = static_cast(_volumeDimensions); _aspect /= std::max(std::max(_aspect.x, _aspect.y), _aspect.z); + // The volume volume::RawVolumeReader> reader( _volumeFilename, _volumeDimensions @@ -304,10 +309,11 @@ void RenderableGalaxy::initializeGL() { GL_RGBA, GL_UNSIGNED_BYTE, ghoul::opengl::Texture::FilterMode::Linear, - ghoul::opengl::Texture::WrappingMode::ClampToEdge); + ghoul::opengl::Texture::WrappingMode::ClampToEdge + ); - _texture->setPixelData(reinterpret_cast( - _volume->data()), + _texture->setPixelData( + reinterpret_cast(_volume->data()), ghoul::opengl::Texture::TakeOwnership::No ); @@ -374,7 +380,7 @@ void RenderableGalaxy::initializeGL() { _pointSpreadFunctionFile = std::make_unique( _pointSpreadFunctionTexturePath - ); + ); } ghoul::opengl::updateUniformLocations( @@ -395,48 +401,40 @@ void RenderableGalaxy::initializeGL() { GLint positionAttrib = _pointsProgram->attributeLocation("in_position"); GLint colorAttrib = _pointsProgram->attributeLocation("in_color"); - std::ifstream pointFile(_pointsFilename, std::ios::in); std::vector pointPositions; std::vector pointColors; - int64_t nPoints; - // Read header for OFF (Object File Format) - std::string line; - std::getline(pointFile, line); + std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename( + _pointsFilename, + ghoul::filesystem::CacheManager::Persistent::Yes + ); + const bool hasCachedFile = FileSys.fileExists(cachedPointsFile); + if (hasCachedFile) { + LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'", + cachedPointsFile, _pointsFilename + )); - // Read point count - std::getline(pointFile, line); - std::istringstream iss(line); - iss >> nPoints; - - // Prepare point reading - _nPoints = static_cast(nPoints); - float maxdist = 0; - - // Read points - float x, y, z, r, g, b, a; - for (size_t i = 0; - i < static_cast(_nPoints * _enabledPointsRatio.maxValue()) + 1; - ++i) - { - std::getline(pointFile, line); - std::istringstream issp(line); - issp >> x >> y >> z >> r >> g >> b >> a; - - //Convert klioparsec to meters - glm::vec3 position = glm::vec3(x, y, z); - position *= (openspace::distanceconstants::Parsec * 100); - - maxdist = std::max(maxdist, glm::length(position)); - - pointPositions.emplace_back(position); - pointColors.emplace_back(r, g, b); + Result res = loadCachedFile(cachedPointsFile); + if (res.success) { + pointPositions = std::move(res.positions); + pointColors = std::move(res.color); + } + else { + FileSys.cacheManager()->removeCacheFile(_pointsFilename); + Result res = loadPointFile(_pointsFilename); + pointPositions = std::move(res.positions); + pointColors = std::move(res.color); + saveCachedFile(cachedPointsFile, pointPositions, pointColors); + } + } + else { + Result res = loadPointFile(_pointsFilename); + ghoul_assert(res.success, "Point file loading failed"); + pointPositions = std::move(res.positions); + pointColors = std::move(res.color); + saveCachedFile(cachedPointsFile, pointPositions, pointColors); } - - pointFile.close(); - - std::cout << maxdist << std::endl; glGenVertexArrays(1, &_pointsVao); glGenBuffers(1, &_positionVbo); @@ -736,4 +734,126 @@ float RenderableGalaxy::safeLength(const glm::vec3& vector) const { return glm::length(vector / maxComponent) * maxComponent; } +RenderableGalaxy::Result RenderableGalaxy::loadPointFile(const std::string& file) { + std::vector pointPositions; + std::vector pointColors; + int64_t nPoints; + + std::ifstream pointFile(_pointsFilename, std::ios::in); + + // Read header for OFF (Object File Format) + std::string line; + std::getline(pointFile, line); + + // Read point count + std::getline(pointFile, line); + std::istringstream iss(line); + iss >> nPoints; + + // Prepare point reading + _nPoints = static_cast(nPoints); + + // Read points + float x, y, z, r, g, b, a; + for (size_t i = 0; + i < static_cast(_nPoints * _enabledPointsRatio.maxValue()) + 1; + ++i) + { + std::getline(pointFile, line); + std::istringstream issp(line); + issp >> x >> y >> z >> r >> g >> b >> a; + + // Convert kiloparsec to meters + glm::vec3 position = glm::vec3(x, y, z); + position *= (distanceconstants::Parsec * 100); + + pointPositions.emplace_back(position); + pointColors.emplace_back(r, g, b); + } + + Result res; + res.success = true; + res.positions = std::move(pointPositions); + res.color = std::move(pointColors); + return res; +} + +RenderableGalaxy::Result RenderableGalaxy::loadCachedFile(const std::string& file) { + std::ifstream fileStream(file, std::ifstream::binary); + if (!fileStream.good()) { + LERROR(fmt::format("Error opening file '{}' for loading cache file", file)); + return { false, {}, {} }; + } + + int8_t cacheVersion; + fileStream.read(reinterpret_cast(&cacheVersion), sizeof(int8_t)); + if (cacheVersion != CurrentCacheVersion) { + LINFO(fmt::format("Removing cache file '{}' as the version changed")); + return { false, {}, {} }; + } + + int64_t nPoints; + fileStream.read(reinterpret_cast(&nPoints), sizeof(int64_t)); + _nPoints = static_cast(nPoints); + + float enabledPointsRatio; + fileStream.read(reinterpret_cast(&enabledPointsRatio), sizeof(float)); + _enabledPointsRatio = enabledPointsRatio; + + uint64_t nPositions; + fileStream.read(reinterpret_cast(&nPositions), sizeof(uint64_t)); + std::vector positions; + positions.resize(nPositions); + fileStream.read( + reinterpret_cast(positions.data()), + nPositions * sizeof(glm::vec3) + ); + + uint64_t nColors; + fileStream.read(reinterpret_cast(&nColors), sizeof(uint64_t)); + std::vector colors; + colors.resize(nColors); + fileStream.read( + reinterpret_cast(colors.data()), + nColors * sizeof(glm::vec3) + ); + + Result result; + result.success = true; + result.positions = std::move(positions); + result.color = std::move(colors); + return result; +} + +void RenderableGalaxy::saveCachedFile(const std::string& file, + const std::vector& positions, + const std::vector& colors) +{ + int64_t nPoints = static_cast(_nPoints); + float pointsRatio = _enabledPointsRatio; + + std::ofstream fileStream(file, std::ofstream::binary); + + if (!fileStream.good()) { + LERROR(fmt::format("Error opening file '{}' for save cache file", file)); + return; + } + + fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); + fileStream.write(reinterpret_cast(&nPoints), sizeof(int64_t)); + fileStream.write(reinterpret_cast(&pointsRatio), sizeof(float)); + uint64_t nPositions = static_cast(positions.size()); + fileStream.write(reinterpret_cast(&nPositions), sizeof(uint64_t)); + fileStream.write( + reinterpret_cast(positions.data()), + positions.size() * sizeof(glm::vec3) + ); + uint64_t nColors = static_cast(colors.size()); + fileStream.write(reinterpret_cast(&nColors), sizeof(uint64_t)); + fileStream.write( + reinterpret_cast(colors.data()), + colors.size() * sizeof(glm::vec3) + ); +} + } // namespace openspace diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index d074bd848b..0ed16f2225 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -33,9 +33,7 @@ #include #include -namespace ghoul::opengl { - class ProgramObject; -} // namespace ghoul::opengl +namespace ghoul::opengl { class ProgramObject; } namespace openspace { @@ -60,6 +58,16 @@ private: void renderBillboards(const RenderData& data); float safeLength(const glm::vec3& vector) const; + struct Result { + bool success; + std::vector positions; + std::vector color; + }; + Result loadPointFile(const std::string& file); + Result loadCachedFile(const std::string& file); + void saveCachedFile(const std::string& file, const std::vector& positions, + const std::vector& colors); + glm::vec3 _volumeSize; glm::vec3 _pointScaling; properties::BoolProperty _volumeRenderingEnabled; From 5f200d439450658381975b606c8c980c93c00a5b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 27 Dec 2019 19:51:33 +0100 Subject: [PATCH 096/214] Some cleanup --- modules/galaxy/rendering/renderablegalaxy.cpp | 689 +++++++++--------- modules/galaxy/rendering/renderablegalaxy.h | 2 - 2 files changed, 357 insertions(+), 334 deletions(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 17f95d1a48..ecdd0c276f 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -51,17 +51,18 @@ namespace { constexpr int8_t CurrentCacheVersion = 1; constexpr const char* GlslRaycastPath = - "${MODULES}/galaxy/shaders/galaxyraycast.glsl"; + "${MODULE_GALAXY}/shaders/galaxyraycast.glsl"; constexpr const char* GlslBoundsVsPath = - "${MODULES}/galaxy/shaders/raycasterbounds_vs.glsl"; + "${MODULE_GALAXY}/shaders/raycasterbounds_vs.glsl"; constexpr const char* GlslBoundsFsPath = - "${MODULES}/galaxy/shaders/raycasterbounds_fs.glsl"; - constexpr const char* _loggerCat = "Renderable Galaxy"; + "${MODULE_GALAXY}/shaders/raycasterbounds_fs.glsl"; + constexpr const char* _loggerCat = "Renderable Galaxy"; constexpr const std::array UniformNamesPoints = { "modelMatrix", "cameraViewProjectionMatrix", "eyePosition", "opacityCoefficient" }; + constexpr const std::array UniformNamesBillboards = { "modelMatrix", "cameraViewProjectionMatrix", "cameraUp", "eyePosition", "psfTexture" @@ -136,6 +137,35 @@ namespace { "Number of RayCasting Steps", "This value set the number of integration steps during the raycasting procedure." }; + + void saveCachedFile(const std::string& file, const std::vector& positions, + const std::vector& colors, int64_t nPoints, + float pointsRatio) + { + std::ofstream fileStream(file, std::ofstream::binary); + + if (!fileStream.good()) { + LERROR(fmt::format("Error opening file '{}' for save cache file", file)); + return; + } + + fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); + fileStream.write(reinterpret_cast(&nPoints), sizeof(int64_t)); + fileStream.write(reinterpret_cast(&pointsRatio), sizeof(float)); + uint64_t nPositions = static_cast(positions.size()); + fileStream.write(reinterpret_cast(&nPositions), sizeof(uint64_t)); + fileStream.write( + reinterpret_cast(positions.data()), + positions.size() * sizeof(glm::vec3) + ); + uint64_t nColors = static_cast(colors.size()); + fileStream.write(reinterpret_cast(&nColors), sizeof(uint64_t)); + fileStream.write( + reinterpret_cast(colors.data()), + colors.size() * sizeof(glm::vec3) + ); + } + } // namespace namespace openspace { @@ -246,8 +276,8 @@ RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) } if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) { - _numberOfRayCastingSteps = static_cast( - volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier) + _numberOfRayCastingSteps = static_cast( + volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier) ); } else { @@ -349,123 +379,137 @@ void RenderableGalaxy::initializeGL() { addProperty(_numberOfRayCastingSteps); // initialize points. - if (!_pointsFilename.empty()) { - _pointsProgram = global::renderEngine.buildRenderProgram( - "Galaxy points", - absPath("${MODULE_GALAXY}/shaders/points_vs.glsl"), - absPath("${MODULE_GALAXY}/shaders/points_fs.glsl") - ); - _billboardsProgram = global::renderEngine.buildRenderProgram( - "Galaxy billboard", - absPath("${MODULE_GALAXY}/shaders/billboard_vs.glsl"), - absPath("${MODULE_GALAXY}/shaders/billboard_fs.glsl"), - absPath("${MODULE_GALAXY}/shaders/billboard_ge.glsl") + if (_pointsFilename.empty()) { + return; + } + + _pointsProgram = global::renderEngine.buildRenderProgram( + "Galaxy points", + absPath("${MODULE_GALAXY}/shaders/points_vs.glsl"), + absPath("${MODULE_GALAXY}/shaders/points_fs.glsl") + ); + _billboardsProgram = global::renderEngine.buildRenderProgram( + "Galaxy billboard", + absPath("${MODULE_GALAXY}/shaders/billboard_vs.glsl"), + absPath("${MODULE_GALAXY}/shaders/billboard_fs.glsl"), + absPath("${MODULE_GALAXY}/shaders/billboard_ge.glsl") + ); + + if (!_pointSpreadFunctionTexturePath.empty()) { + _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( + absPath(_pointSpreadFunctionTexturePath) ); - if (!_pointSpreadFunctionTexturePath.empty()) { - _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( + if (_pointSpreadFunctionTexture) { + LDEBUG(fmt::format( + "Loaded texture from '{}'", absPath(_pointSpreadFunctionTexturePath) - ); - - if (_pointSpreadFunctionTexture) { - LDEBUG(fmt::format( - "Loaded texture from '{}'", - absPath(_pointSpreadFunctionTexturePath) - )); - _pointSpreadFunctionTexture->uploadTexture(); - } - _pointSpreadFunctionTexture->setFilter( - ghoul::opengl::Texture::FilterMode::AnisotropicMipMap - ); - - _pointSpreadFunctionFile = std::make_unique( - _pointSpreadFunctionTexturePath - ); - } - - ghoul::opengl::updateUniformLocations( - *_pointsProgram, - _uniformCachePoints, - UniformNamesPoints - ); - ghoul::opengl::updateUniformLocations( - *_billboardsProgram, - _uniformCacheBillboards, - UniformNamesBillboards - ); - - _pointsProgram->setIgnoreUniformLocationError( - ghoul::opengl::ProgramObject::IgnoreError::Yes - ); - - GLint positionAttrib = _pointsProgram->attributeLocation("in_position"); - GLint colorAttrib = _pointsProgram->attributeLocation("in_color"); - - - std::vector pointPositions; - std::vector pointColors; - - std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename( - _pointsFilename, - ghoul::filesystem::CacheManager::Persistent::Yes - ); - const bool hasCachedFile = FileSys.fileExists(cachedPointsFile); - if (hasCachedFile) { - LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'", - cachedPointsFile, _pointsFilename )); - - Result res = loadCachedFile(cachedPointsFile); - if (res.success) { - pointPositions = std::move(res.positions); - pointColors = std::move(res.color); - } - else { - FileSys.cacheManager()->removeCacheFile(_pointsFilename); - Result res = loadPointFile(_pointsFilename); - pointPositions = std::move(res.positions); - pointColors = std::move(res.color); - saveCachedFile(cachedPointsFile, pointPositions, pointColors); - } + _pointSpreadFunctionTexture->uploadTexture(); } - else { - Result res = loadPointFile(_pointsFilename); - ghoul_assert(res.success, "Point file loading failed"); + _pointSpreadFunctionTexture->setFilter( + ghoul::opengl::Texture::FilterMode::AnisotropicMipMap + ); + + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath + ); + } + + ghoul::opengl::updateUniformLocations( + *_pointsProgram, + _uniformCachePoints, + UniformNamesPoints + ); + ghoul::opengl::updateUniformLocations( + *_billboardsProgram, + _uniformCacheBillboards, + UniformNamesBillboards + ); + + _pointsProgram->setIgnoreUniformLocationError( + ghoul::opengl::ProgramObject::IgnoreError::Yes + ); + + GLint positionAttrib = _pointsProgram->attributeLocation("in_position"); + GLint colorAttrib = _pointsProgram->attributeLocation("in_color"); + + + std::vector pointPositions; + std::vector pointColors; + + std::string cachedPointsFile = FileSys.cacheManager()->cachedFilename( + _pointsFilename, + ghoul::filesystem::CacheManager::Persistent::Yes + ); + const bool hasCachedFile = FileSys.fileExists(cachedPointsFile); + if (hasCachedFile) { + LINFO(fmt::format("Cached file '{}' used for galaxy point file '{}'", + cachedPointsFile, _pointsFilename + )); + + Result res = loadCachedFile(cachedPointsFile); + if (res.success) { pointPositions = std::move(res.positions); pointColors = std::move(res.color); - saveCachedFile(cachedPointsFile, pointPositions, pointColors); } - - glGenVertexArrays(1, &_pointsVao); - glGenBuffers(1, &_positionVbo); - glGenBuffers(1, &_colorVbo); - - glBindVertexArray(_pointsVao); - glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); - glBufferData(GL_ARRAY_BUFFER, - pointPositions.size() * sizeof(glm::vec3), - pointPositions.data(), - GL_STATIC_DRAW - ); - - glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); - glBufferData(GL_ARRAY_BUFFER, - pointColors.size() * sizeof(glm::vec3), - pointColors.data(), - GL_STATIC_DRAW - ); - - glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); - glEnableVertexAttribArray(positionAttrib); - glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); - glEnableVertexAttribArray(colorAttrib); - glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); + else { + FileSys.cacheManager()->removeCacheFile(_pointsFilename); + Result res = loadPointFile(_pointsFilename); + pointPositions = std::move(res.positions); + pointColors = std::move(res.color); + saveCachedFile( + cachedPointsFile, + pointPositions, + pointColors, + _nPoints, + _enabledPointsRatio + ); + } } + else { + Result res = loadPointFile(_pointsFilename); + ghoul_assert(res.success, "Point file loading failed"); + pointPositions = std::move(res.positions); + pointColors = std::move(res.color); + saveCachedFile( + cachedPointsFile, + pointPositions, + pointColors, + _nPoints, + _enabledPointsRatio + ); + } + + glGenVertexArrays(1, &_pointsVao); + glGenBuffers(1, &_positionVbo); + glGenBuffers(1, &_colorVbo); + + glBindVertexArray(_pointsVao); + glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); + glBufferData(GL_ARRAY_BUFFER, + pointPositions.size() * sizeof(glm::vec3), + pointPositions.data(), + GL_STATIC_DRAW + ); + + glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); + glBufferData(GL_ARRAY_BUFFER, + pointColors.size() * sizeof(glm::vec3), + pointColors.data(), + GL_STATIC_DRAW + ); + + glBindBuffer(GL_ARRAY_BUFFER, _positionVbo); + glEnableVertexAttribArray(positionAttrib); + glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + + glBindBuffer(GL_ARRAY_BUFFER, _colorVbo); + glEnableVertexAttribArray(colorAttrib); + glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); } void RenderableGalaxy::deinitializeGL() { @@ -473,6 +517,10 @@ void RenderableGalaxy::deinitializeGL() { global::raycasterManager.detachRaycaster(*_raycaster); _raycaster = nullptr; } + + glDeleteVertexArrays(1, &_pointsVao); + glDeleteBuffers(1, &_positionVbo); + glDeleteBuffers(1, &_colorVbo); } bool RenderableGalaxy::isReady() const { @@ -480,43 +528,44 @@ bool RenderableGalaxy::isReady() const { } void RenderableGalaxy::update(const UpdateData& data) { - if (_raycaster) { - //glm::mat4 transform = glm::translate(, static_cast(_translation)); - const glm::vec3 eulerRotation = static_cast(_rotation); - glm::mat4 transform = glm::rotate( - glm::mat4(1.0), - eulerRotation.x, - glm::vec3(1, 0, 0) - ); - transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); - transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); - - glm::mat4 volumeTransform = glm::scale(transform, _volumeSize); - _pointTransform = transform; - //_pointTransform = glm::scale(transform, _pointScaling); - - const glm::vec4 translation = glm::vec4(_translation.value()*_volumeSize, 0.0); - - // Todo: handle floating point overflow, to actually support translation. - - volumeTransform[3] += translation; - _pointTransform[3] += translation; - - _raycaster->setDownscaleRender(_downScaleVolumeRendering); - _raycaster->setMaxSteps(_numberOfRayCastingSteps); - _raycaster->setStepSize(_stepSize); - _raycaster->setAspect(_aspect); - _raycaster->setModelTransform(volumeTransform); - _raycaster->setAbsorptionMultiplier(_absorptionMultiply); - _raycaster->setEmissionMultiplier(_emissionMultiply); - _raycaster->setTime(data.time.j2000Seconds()); + if (!_raycaster) { + return; } + //glm::mat4 transform = glm::translate(, static_cast(_translation)); + const glm::vec3 eulerRotation = static_cast(_rotation); + glm::mat4 transform = glm::rotate( + glm::mat4(1.0), + eulerRotation.x, + glm::vec3(1, 0, 0) + ); + transform = glm::rotate(transform, eulerRotation.y, glm::vec3(0, 1, 0)); + transform = glm::rotate(transform, eulerRotation.z, glm::vec3(0, 0, 1)); + + glm::mat4 volumeTransform = glm::scale(transform, _volumeSize); + _pointTransform = transform; + //_pointTransform = glm::scale(transform, _pointScaling); + + const glm::vec4 translation = glm::vec4(_translation.value()*_volumeSize, 0.0); + + // Todo: handle floating point overflow, to actually support translation. + + volumeTransform[3] += translation; + _pointTransform[3] += translation; + + _raycaster->setDownscaleRender(_downScaleVolumeRendering); + _raycaster->setMaxSteps(_numberOfRayCastingSteps); + _raycaster->setStepSize(_stepSize); + _raycaster->setAspect(_aspect); + _raycaster->setModelTransform(volumeTransform); + _raycaster->setAbsorptionMultiplier(_absorptionMultiply); + _raycaster->setEmissionMultiplier(_emissionMultiply); + _raycaster->setTime(data.time.j2000Seconds()); } void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { // Render the volume if (_raycaster && _volumeRenderingEnabled) { - RaycasterTask task{ _raycaster.get(), data }; + RaycasterTask task { _raycaster.get(), data }; const glm::vec3 position = data.camera.positionVec3(); const float length = safeLength(position); @@ -533,15 +582,19 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { float opacityCoefficient = 1.f; if (length < lowerRampStart) { opacityCoefficient = 0.f; // camera really close - } else if (length < lowerRampEnd) { + } + else if (length < lowerRampEnd) { opacityCoefficient = (length - lowerRampStart) / (lowerRampEnd - lowerRampStart); - } else if (length < upperRampStart) { + } + else if (length < upperRampStart) { opacityCoefficient = 1.f; // sweet spot (max) - } else if (length < upperRampEnd) { + } + else if (length < upperRampEnd) { opacityCoefficient = 1.f - (length - upperRampStart) / (upperRampEnd - upperRampStart); //fade out - } else { + } + else { opacityCoefficient = 0; } @@ -568,163 +621,166 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { } void RenderableGalaxy::renderPoints(const RenderData& data) { - if (_pointsProgram) { - // Saving current OpenGL state - GLenum blendEquationRGB; - GLenum blendEquationAlpha; - GLenum blendDestAlpha; - GLenum blendDestRGB; - GLenum blendSrcAlpha; - GLenum blendSrcRGB; - GLboolean depthMask; - - glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); - glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); - glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); - glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); - - glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDepthMask(false); - glDisable(GL_DEPTH_TEST); - - _pointsProgram->activate(); - - glm::dmat4 rotMatrix = glm::rotate( - glm::dmat4(1.0), - glm::pi(), - glm::dvec3(1.0, 0.0, 0.0)) * - glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) * - glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0) - ); - - glm::dmat4 modelMatrix = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * rotMatrix * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - - glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); - - glm::dmat4 cameraViewProjectionMatrix = projectionMatrix * - data.camera.combinedViewMatrix(); - - _pointsProgram->setUniform(_uniformCachePoints.modelMatrix, modelMatrix); - _pointsProgram->setUniform( - _uniformCachePoints.cameraViewProjectionMatrix, - cameraViewProjectionMatrix - ); - - glm::dvec3 eyePosition = glm::dvec3( - glm::inverse(data.camera.combinedViewMatrix()) * - glm::dvec4(0.0, 0.0, 0.0, 1.0) - ); - _pointsProgram->setUniform(_uniformCachePoints.eyePosition, eyePosition); - _pointsProgram->setUniform( - _uniformCachePoints.opacityCoefficient, - _opacityCoefficient - ); - - glBindVertexArray(_pointsVao); - glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); - - glBindVertexArray(0); - - _pointsProgram->deactivate(); - - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Restores OpenGL blending state - glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); - glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); - glDepthMask(depthMask); + if (!_pointsProgram) { + return; } + // Saving current OpenGL state + GLenum blendEquationRGB; + GLenum blendEquationAlpha; + GLenum blendDestAlpha; + GLenum blendDestRGB; + GLenum blendSrcAlpha; + GLenum blendSrcRGB; + GLboolean depthMask; + + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); + + glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + + _pointsProgram->activate(); + + glm::dmat4 rotMatrix = glm::rotate( + glm::dmat4(1.0), + glm::pi(), + glm::dvec3(1.0, 0.0, 0.0)) * + glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) * + glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0) + ); + + glm::dmat4 modelMatrix = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * rotMatrix * + glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); + + glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); + + glm::dmat4 cameraViewProjectionMatrix = projectionMatrix * + data.camera.combinedViewMatrix(); + + _pointsProgram->setUniform(_uniformCachePoints.modelMatrix, modelMatrix); + _pointsProgram->setUniform( + _uniformCachePoints.cameraViewProjectionMatrix, + cameraViewProjectionMatrix + ); + + glm::dvec3 eyePosition = glm::dvec3( + glm::inverse(data.camera.combinedViewMatrix()) * + glm::dvec4(0.0, 0.0, 0.0, 1.0) + ); + _pointsProgram->setUniform(_uniformCachePoints.eyePosition, eyePosition); + _pointsProgram->setUniform( + _uniformCachePoints.opacityCoefficient, + _opacityCoefficient + ); + + glBindVertexArray(_pointsVao); + glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); + + glBindVertexArray(0); + + _pointsProgram->deactivate(); + + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Restores OpenGL blending state + glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); + glDepthMask(depthMask); } void RenderableGalaxy::renderBillboards(const RenderData& data) { - if (_billboardsProgram) { - // Saving current OpenGL state - GLenum blendEquationRGB; - GLenum blendEquationAlpha; - GLenum blendDestAlpha; - GLenum blendDestRGB; - GLenum blendSrcAlpha; - GLenum blendSrcRGB; - GLboolean depthMask; - - glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); - glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); - glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); - glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); - glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); - glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); - - glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDepthMask(false); - glDisable(GL_DEPTH_TEST); - - _billboardsProgram->activate(); - - glm::dmat4 rotMatrix = glm::rotate( - glm::dmat4(1.0), - glm::pi(), - glm::dvec3(1.0, 0.0, 0.0)) * - glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) * - glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0) - ); - - glm::dmat4 modelMatrix = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * rotMatrix * - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); - - glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); - - glm::dmat4 cameraViewProjectionMatrix = projectionMatrix * - data.camera.combinedViewMatrix(); - - _billboardsProgram->setUniform(_uniformCacheBillboards.modelMatrix, modelMatrix); - _billboardsProgram->setUniform( - _uniformCacheBillboards.cameraViewProjectionMatrix, - cameraViewProjectionMatrix - ); - - glm::dvec3 eyePosition = glm::dvec3( - glm::inverse(data.camera.combinedViewMatrix()) * - glm::dvec4(0.0, 0.0, 0.0, 1.0) - ); - _billboardsProgram->setUniform(_uniformCacheBillboards.eyePosition, eyePosition); - - glm::dvec3 cameraUp = data.camera.lookUpVectorWorldSpace(); - _billboardsProgram->setUniform(_uniformCacheBillboards.cameraUp, cameraUp); - - ghoul::opengl::TextureUnit psfUnit; - psfUnit.activate(); - _pointSpreadFunctionTexture->bind(); - _billboardsProgram->setUniform(_uniformCacheBillboards.psfTexture, psfUnit); - - glBindVertexArray(_pointsVao); - glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); - - glBindVertexArray(0); - - _billboardsProgram->deactivate(); - - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Restores OpenGL blending state - glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); - glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); - glDepthMask(depthMask); + if (!_billboardsProgram) { + return; } + + // Saving current OpenGL state + GLenum blendEquationRGB; + GLenum blendEquationAlpha; + GLenum blendDestAlpha; + GLenum blendDestRGB; + GLenum blendSrcAlpha; + GLenum blendSrcRGB; + GLboolean depthMask; + + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); + + glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDepthMask(false); + glDisable(GL_DEPTH_TEST); + + _billboardsProgram->activate(); + + glm::dmat4 rotMatrix = glm::rotate( + glm::dmat4(1.0), + glm::pi(), + glm::dvec3(1.0, 0.0, 0.0)) * + glm::rotate(glm::dmat4(1.0), 3.1248, glm::dvec3(0.0, 1.0, 0.0)) * + glm::rotate(glm::dmat4(1.0), 4.45741, glm::dvec3(0.0, 0.0, 1.0) + ); + + glm::dmat4 modelMatrix = + glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * + glm::dmat4(data.modelTransform.rotation) * rotMatrix * + glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); + + glm::dmat4 projectionMatrix = glm::dmat4(data.camera.projectionMatrix()); + + glm::dmat4 cameraViewProjectionMatrix = projectionMatrix * + data.camera.combinedViewMatrix(); + + _billboardsProgram->setUniform(_uniformCacheBillboards.modelMatrix, modelMatrix); + _billboardsProgram->setUniform( + _uniformCacheBillboards.cameraViewProjectionMatrix, + cameraViewProjectionMatrix + ); + + glm::dvec3 eyePosition = glm::dvec3( + glm::inverse(data.camera.combinedViewMatrix()) * + glm::dvec4(0.0, 0.0, 0.0, 1.0) + ); + _billboardsProgram->setUniform(_uniformCacheBillboards.eyePosition, eyePosition); + + glm::dvec3 cameraUp = data.camera.lookUpVectorWorldSpace(); + _billboardsProgram->setUniform(_uniformCacheBillboards.cameraUp, cameraUp); + + ghoul::opengl::TextureUnit psfUnit; + psfUnit.activate(); + _pointSpreadFunctionTexture->bind(); + _billboardsProgram->setUniform(_uniformCacheBillboards.psfTexture, psfUnit); + + glBindVertexArray(_pointsVao); + glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); + + glBindVertexArray(0); + + _billboardsProgram->deactivate(); + + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Restores OpenGL blending state + glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); + glDepthMask(depthMask); } float RenderableGalaxy::safeLength(const glm::vec3& vector) const { @@ -825,35 +881,4 @@ RenderableGalaxy::Result RenderableGalaxy::loadCachedFile(const std::string& fil return result; } -void RenderableGalaxy::saveCachedFile(const std::string& file, - const std::vector& positions, - const std::vector& colors) -{ - int64_t nPoints = static_cast(_nPoints); - float pointsRatio = _enabledPointsRatio; - - std::ofstream fileStream(file, std::ofstream::binary); - - if (!fileStream.good()) { - LERROR(fmt::format("Error opening file '{}' for save cache file", file)); - return; - } - - fileStream.write(reinterpret_cast(&CurrentCacheVersion), sizeof(int8_t)); - fileStream.write(reinterpret_cast(&nPoints), sizeof(int64_t)); - fileStream.write(reinterpret_cast(&pointsRatio), sizeof(float)); - uint64_t nPositions = static_cast(positions.size()); - fileStream.write(reinterpret_cast(&nPositions), sizeof(uint64_t)); - fileStream.write( - reinterpret_cast(positions.data()), - positions.size() * sizeof(glm::vec3) - ); - uint64_t nColors = static_cast(colors.size()); - fileStream.write(reinterpret_cast(&nColors), sizeof(uint64_t)); - fileStream.write( - reinterpret_cast(colors.data()), - colors.size() * sizeof(glm::vec3) - ); -} - } // namespace openspace diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 0ed16f2225..2f8c4ff570 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -65,8 +65,6 @@ private: }; Result loadPointFile(const std::string& file); Result loadCachedFile(const std::string& file); - void saveCachedFile(const std::string& file, const std::vector& positions, - const std::vector& colors); glm::vec3 _volumeSize; glm::vec3 _pointScaling; From ce7795a67b22a06b5022dc008dae9ee5ff67d9a6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 27 Dec 2019 20:10:48 +0100 Subject: [PATCH 097/214] Do not assume that the GuiName or a DashboardItem is provided (closes #1006) Do not try to load an empty URL as it triggers an assert --- modules/cefwebgui/cefwebguimodule.cpp | 4 +++- src/rendering/dashboarditem.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/cefwebgui/cefwebguimodule.cpp b/modules/cefwebgui/cefwebguimodule.cpp index 44c3ffa24b..e0a1de88e7 100644 --- a/modules/cefwebgui/cefwebguimodule.cpp +++ b/modules/cefwebgui/cefwebguimodule.cpp @@ -103,7 +103,9 @@ void CefWebGuiModule::startOrStopGui() { new GUIKeyboardHandler ); _instance->initialize(); - _instance->loadUrl(_url); + if (!_url.value().empty()) { + _instance->loadUrl(_url); + } } if (_visible) { webBrowserModule->attachEventHandler(_instance.get()); diff --git a/src/rendering/dashboarditem.cpp b/src/rendering/dashboarditem.cpp index d7ee5306cd..42fef0b961 100644 --- a/src/rendering/dashboarditem.cpp +++ b/src/rendering/dashboarditem.cpp @@ -111,8 +111,10 @@ DashboardItem::DashboardItem(const ghoul::Dictionary& dictionary) std::string identifier = dictionary.value(IdentifierInfo.identifier); setIdentifier(std::move(identifier)); - std::string guiName = dictionary.value(GuiNameInfo.identifier); - setGuiName(std::move(guiName)); + if (dictionary.hasKeyAndValue(GuiNameInfo.identifier)) { + std::string guiName = dictionary.value(GuiNameInfo.identifier); + setGuiName(std::move(guiName)); + } addProperty(_isEnabled); } From a51cee1f3622e0e2ad79d2f14000e017060d47d6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 27 Dec 2019 21:25:22 +0100 Subject: [PATCH 098/214] Add a method for creating a unique name for screenspace renderable (closes #652) --- .../rendering/screenspacerenderable.h | 2 ++ .../base/rendering/screenspacedashboard.cpp | 23 ++++++------------- .../base/rendering/screenspaceimagelocal.cpp | 23 ++++++------------- .../base/rendering/screenspaceimageonline.cpp | 23 ++++++------------- modules/spout/renderableplanespout.cpp | 6 ++--- modules/spout/screenspacespout.cpp | 23 ++++++------------- modules/webbrowser/src/screenspacebrowser.cpp | 15 +++++++----- src/rendering/screenspacerenderable.cpp | 23 +++++++++++++++++-- 8 files changed, 63 insertions(+), 75 deletions(-) diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index d5dfabef94..abb4a498c9 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -75,6 +75,8 @@ public: protected: void createShaders(); + std::string makeUniqueIdentifier(std::string name); + glm::mat4 scaleMatrix(); glm::mat4 globalRotationMatrix(); glm::mat4 translationMatrix(); diff --git a/modules/base/rendering/screenspacedashboard.cpp b/modules/base/rendering/screenspacedashboard.cpp index d86376d06f..c0530f8491 100644 --- a/modules/base/rendering/screenspacedashboard.cpp +++ b/modules/base/rendering/screenspacedashboard.cpp @@ -151,24 +151,15 @@ ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary) "ScreenSpaceDashboard" ); - int iIdentifier = 0; - if (_identifier.empty()) { - static int id = 0; - iIdentifier = id; - - if (iIdentifier == 0) { - setIdentifier("ScreenSpaceDashboard"); - } - else { - setIdentifier("ScreenSpaceDashboard" + std::to_string(iIdentifier)); - } - ++id; + std::string identifier; + if (dictionary.hasKeyAndValue(KeyIdentifier)) { + identifier = dictionary.value(KeyIdentifier); } - - if (_guiName.empty()) { - // Adding an extra space to the user-facing name as it looks nicer - setGuiName("ScreenSpaceDashboard " + std::to_string(iIdentifier)); + else { + identifier = "ScreenSpaceDashboard"; } + identifier = makeUniqueIdentifier(identifier); + setIdentifier(std::move(identifier)); if (dictionary.hasKey(UseMainInfo.identifier)) { _useMainDashboard = dictionary.value(UseMainInfo.identifier); diff --git a/modules/base/rendering/screenspaceimagelocal.cpp b/modules/base/rendering/screenspaceimagelocal.cpp index 392a8952d0..6e0896ab21 100644 --- a/modules/base/rendering/screenspaceimagelocal.cpp +++ b/modules/base/rendering/screenspaceimagelocal.cpp @@ -78,24 +78,15 @@ ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary "ScreenSpaceImageLocal" ); - int iIdentifier = 0; - if (_identifier.empty()) { - static int id = 0; - iIdentifier = id; - - if (iIdentifier == 0) { - setIdentifier("ScreenSpaceImageLocal"); - } - else { - setIdentifier("ScreenSpaceImageLocal" + std::to_string(iIdentifier)); - } - ++id; + std::string identifier; + if (dictionary.hasKeyAndValue(KeyIdentifier)) { + identifier = dictionary.value(KeyIdentifier); } - - if (_guiName.empty()) { - // Adding an extra space to the user-facing name as it looks nicer - setGuiName("ScreenSpaceImageLocal " + std::to_string(iIdentifier)); + else { + identifier = "ScreenSpaceImageLocal"; } + identifier = makeUniqueIdentifier(identifier); + setIdentifier(identifier); _texturePath.onChange([this]() { if (!FileSys.fileExists(FileSys.absolutePath(_texturePath))) { diff --git a/modules/base/rendering/screenspaceimageonline.cpp b/modules/base/rendering/screenspaceimageonline.cpp index 83026445cc..b3df9654b4 100644 --- a/modules/base/rendering/screenspaceimageonline.cpp +++ b/modules/base/rendering/screenspaceimageonline.cpp @@ -80,24 +80,15 @@ ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictiona "ScreenSpaceImageOnline" ); - int iIdentifier = 0; - if (_identifier.empty()) { - static int id = 0; - iIdentifier = id; - - if (iIdentifier == 0) { - setIdentifier("ScreenSpaceImageOnline"); - } - else { - setIdentifier("ScreenSpaceImageOnline" + std::to_string(iIdentifier)); - } - ++id; + std::string identifier; + if (dictionary.hasKeyAndValue(KeyIdentifier)) { + identifier = dictionary.value(KeyIdentifier); } - - if (_guiName.empty()) { - // Adding an extra space to the user-facing name as it looks nicer - setGuiName("ScreenSpaceImageOnline " + std::to_string(iIdentifier)); + else { + identifier = "ScreenSpaceImageOnline"; } + identifier = makeUniqueIdentifier(identifier); + setIdentifier(std::move(identifier)); _texturePath.onChange([this]() { _textureIsDirty = true; }); addProperty(_texturePath); diff --git a/modules/spout/renderableplanespout.cpp b/modules/spout/renderableplanespout.cpp index f3c2eb2dac..c398898adc 100644 --- a/modules/spout/renderableplanespout.cpp +++ b/modules/spout/renderableplanespout.cpp @@ -101,17 +101,17 @@ RenderablePlaneSpout::RenderablePlaneSpout(const ghoul::Dictionary& dictionary) iIdentifier = id; if (iIdentifier == 0) { - setIdentifier("ScreenSpaceSpout"); + setIdentifier("RenderablePlaneSpout"); } else { - setIdentifier("ScreenSpaceSpout" + std::to_string(iIdentifier)); + setIdentifier("RenderablePlaneSpout" + std::to_string(iIdentifier)); } ++id; } if (_guiName.empty()) { // Adding an extra space to the user-facing name as it looks nicer - setGuiName("ScreenSpaceSpout " + std::to_string(iIdentifier)); + setGuiName("RenderablePlaneSpout " + std::to_string(iIdentifier)); } if (dictionary.hasKey(NameInfo.identifier)) { diff --git a/modules/spout/screenspacespout.cpp b/modules/spout/screenspacespout.cpp index 5d8f23f430..b3204f0135 100644 --- a/modules/spout/screenspacespout.cpp +++ b/modules/spout/screenspacespout.cpp @@ -93,24 +93,15 @@ ScreenSpaceSpout::ScreenSpaceSpout(const ghoul::Dictionary& dictionary) "ScreenSpaceSpout" ); - int iIdentifier = 0; - if (_identifier.empty()) { - static int id = 0; - iIdentifier = id; - - if (iIdentifier == 0) { - setIdentifier("ScreenSpaceSpout"); - } - else { - setIdentifier("ScreenSpaceSpout" + std::to_string(iIdentifier)); - } - ++id; + std::string identifier; + if (dictionary.hasKeyAndValue(KeyIdentifier)) { + identifier = dictionary.value(KeyIdentifier); } - - if (_guiName.empty()) { - // Adding an extra space to the user-facing name as it looks nicer - setGuiName("ScreenSpaceSpout " + std::to_string(iIdentifier)); + else { + identifier = "ScreenSpaceSpout"; } + identifier = makeUniqueIdentifier(identifier); + setIdentifier(std::move(identifier)); if (dictionary.hasKey(NameInfo.identifier)) { _spoutName = dictionary.value(NameInfo.identifier); diff --git a/modules/webbrowser/src/screenspacebrowser.cpp b/modules/webbrowser/src/screenspacebrowser.cpp index 1c69bb0b4c..72621a96cc 100644 --- a/modules/webbrowser/src/screenspacebrowser.cpp +++ b/modules/webbrowser/src/screenspacebrowser.cpp @@ -72,13 +72,16 @@ ScreenSpaceBrowser::ScreenSpaceBrowser(const ghoul::Dictionary &dictionary) , _dimensions(DimensionsInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(3000.f)) , _reload(ReloadInfo) { - if (dictionary.hasKey(KeyIdentifier)) { - setIdentifier(dictionary.value(KeyIdentifier)); - } else { - static int id = 0; - setIdentifier("ScreenSpaceBrowser " + std::to_string(id)); - ++id; + + std::string identifier; + if (dictionary.hasKeyAndValue(KeyIdentifier)) { + identifier = dictionary.value(KeyIdentifier); } + else { + identifier = "ScreenSpaceBrowser"; + } + identifier = makeUniqueIdentifier(identifier); + setIdentifier(identifier); if (dictionary.hasKeyAndValue(UrlInfo.identifier)) { _url = dictionary.value(UrlInfo.identifier); diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 9a3b01f0dc..6fe7813bc8 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -206,8 +206,6 @@ namespace { wrap(elevation, -glm::pi(), glm::pi()) ); } - - } // namespace namespace openspace { @@ -314,6 +312,27 @@ std::unique_ptr ScreenSpaceRenderable::createFromDictiona ); } +std::string ScreenSpaceRenderable::makeUniqueIdentifier(std::string name) { + std::vector r = global::renderEngine.screenSpaceRenderables(); + + auto nameTaken = [&r](const std::string& name) { + bool nameTaken = std::any_of( + r.begin(), + r.end(), + [&name](ScreenSpaceRenderable* r) { return r->identifier() == name; } + ); + return nameTaken; + }; + + std::string baseName = name; + int i = 1; + while (nameTaken(name)) { + name = baseName + std::to_string(i); + i++; + } + return name; +} + ScreenSpaceRenderable::ScreenSpaceRenderable(const ghoul::Dictionary& dictionary) : properties::PropertyOwner({ "" }) , _enabled(EnabledInfo, true) From 207db3c82486d526cae0291f98f06898dc65260b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 27 Dec 2019 23:29:28 +0100 Subject: [PATCH 099/214] Remove PowerScaledCoordinates and rename PowerScaledSphere to Sphere (closes #4) --- include/openspace/properties/property.h | 4 +- include/openspace/util/camera.h | 2 - .../openspace/util/powerscaledcoordinate.h | 114 ------- .../util/{powerscaledsphere.h => sphere.h} | 18 +- include/openspace/util/updatestructures.h | 1 - .../rendering/atmospheredeferredcaster.cpp | 1 - modules/base/rendering/renderablesphere.cpp | 6 +- modules/base/rendering/renderablesphere.h | 4 +- modules/base/shaders/imageplane_vs.glsl | 4 +- modules/iswa/rendering/datasphere.cpp | 4 +- modules/iswa/rendering/datasphere.h | 4 +- modules/iswa/rendering/iswacygnet.cpp | 6 +- .../space/rendering/simplespheregeometry.cpp | 6 +- .../space/rendering/simplespheregeometry.h | 4 +- .../rendering/renderablemodelprojection.cpp | 6 +- .../rendering/renderableplaneprojection.cpp | 30 +- .../rendering/toyvolumeraycaster.cpp | 1 - .../volume/rendering/basicvolumeraycaster.cpp | 1 - src/CMakeLists.txt | 6 +- src/util/powerscaledcoordinate.cpp | 322 ------------------ .../{powerscaledsphere.cpp => sphere.cpp} | 17 +- tests/main.cpp | 1 - tests/test_powerscalecoordinates.inl | 63 ---- 23 files changed, 56 insertions(+), 569 deletions(-) delete mode 100644 include/openspace/util/powerscaledcoordinate.h rename include/openspace/util/{powerscaledsphere.h => sphere.h} (86%) delete mode 100644 src/util/powerscaledcoordinate.cpp rename src/util/{powerscaledsphere.cpp => sphere.cpp} (93%) delete mode 100644 tests/test_powerscalecoordinates.inl diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index 6d7bbc3d3f..1b2f9fdbec 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -395,9 +395,7 @@ public: /** * Default view options that can be used in the Property::setViewOption method. The * values are: Property::ViewOptions::Color = \c color, - * Property::ViewOptions::LightPosition = \c lightPosition, - * Property::ViewOptions::PowerScaledScalar = \c powerScaledScalar, and - * Property::ViewOptions::PowerScaledCoordinate = \c powerScaledCoordinate. + * Property::ViewOptions::LightPosition = \c lightPosition */ struct ViewOptions { static const char* Color; diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 8131d04191..8335329b31 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -25,7 +25,6 @@ #ifndef __OPENSPACE_CORE___CAMERA___H__ #define __OPENSPACE_CORE___CAMERA___H__ -#include #include #include #include @@ -36,7 +35,6 @@ class SceneGraphNode; /** * This class still needs some more love. Suggested improvements: - * - Remove psc from the camera class interface. * - Accessors should return constant references to double precision class members. * - Remove the scaling variable (What is it used for?) * - Remove the maxFov and sinMaxfov variables. Redundant since the fov is embedded diff --git a/include/openspace/util/powerscaledcoordinate.h b/include/openspace/util/powerscaledcoordinate.h deleted file mode 100644 index 64f258940c..0000000000 --- a/include/openspace/util/powerscaledcoordinate.h +++ /dev/null @@ -1,114 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2019 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#ifndef __OPENSPACE_CORE___POWERSCALEDCOORDINATE___H__ -#define __OPENSPACE_CORE___POWERSCALEDCOORDINATE___H__ - -#include - -namespace openspace { - -class PowerScaledScalar; - -class PowerScaledCoordinate { -public: - // constructors - PowerScaledCoordinate() = default; - - PowerScaledCoordinate(PowerScaledCoordinate&& rhs); - PowerScaledCoordinate(const PowerScaledCoordinate& rhs); - - // Sets the power scaled coordinates directly - PowerScaledCoordinate(glm::vec4 v); - PowerScaledCoordinate(float f1, float f2, float f3, float f4); - // Sets the power scaled coordinates with w = 0 - PowerScaledCoordinate(glm::vec3 v); - - static PowerScaledCoordinate CreatePowerScaledCoordinate(double d1, double d2, - double d3); - - // get functions - // return the full, unmodified PSC - const glm::vec4& vec4() const; - - // returns the rescaled, "normal" coordinates - glm::vec3 vec3() const; - - // return the full psc as dvec4() - glm::dvec4 dvec4() const; - - // rescaled return as dvec3 - glm::dvec3 dvec3() const; - - // length of the vector as a pss - float length() const; - glm::vec3 direction() const; - - // operator overloading - PowerScaledCoordinate& operator=(const PowerScaledCoordinate& rhs); - PowerScaledCoordinate& operator=(PowerScaledCoordinate&& rhs); - PowerScaledCoordinate& operator+=(const PowerScaledCoordinate& rhs); - PowerScaledCoordinate operator+(const PowerScaledCoordinate& rhs) const; - PowerScaledCoordinate& operator-=(const PowerScaledCoordinate& rhs); - PowerScaledCoordinate operator-(const PowerScaledCoordinate& rhs) const; - float& operator[](unsigned int idx); - float operator[](unsigned int idx) const; - double dot(const PowerScaledCoordinate& rhs) const; - double angle(const PowerScaledCoordinate& rhs) const; - - // scalar operators - PowerScaledCoordinate operator*(const double& rhs) const; - PowerScaledCoordinate operator*(const float& rhs) const; - PowerScaledCoordinate operator*(const glm::mat4& matrix) const; - - - // comparison - bool operator==(const PowerScaledCoordinate& other) const; - bool operator!=(const PowerScaledCoordinate& other) const; - bool operator<(const PowerScaledCoordinate& other) const; - bool operator>(const PowerScaledCoordinate& other) const; - bool operator<=(const PowerScaledCoordinate& other) const; - bool operator>=(const PowerScaledCoordinate& other) const; - - // glm integration - PowerScaledCoordinate& operator=(const glm::dvec4& rhs); - PowerScaledCoordinate& operator=(const glm::vec4& rhs); - PowerScaledCoordinate& operator=(const glm::dvec3& rhs); - PowerScaledCoordinate& operator=(const glm::vec3& rhs); - - friend std::ostream& operator<<(std::ostream& os, const PowerScaledCoordinate& rhs); - - // allow the power scaled scalars to access private members - friend class PowerScaledScalar; - -private: - // internal glm vector - glm::vec4 _vec = glm::vec4(0.f); -}; - -typedef PowerScaledCoordinate psc; - -} // namespace openspace - -#endif // __OPENSPACE_CORE___POWERSCALEDCOORDINATE___H__ diff --git a/include/openspace/util/powerscaledsphere.h b/include/openspace/util/sphere.h similarity index 86% rename from include/openspace/util/powerscaledsphere.h rename to include/openspace/util/sphere.h index 8be00b6f0b..47ff24e061 100644 --- a/include/openspace/util/powerscaledsphere.h +++ b/include/openspace/util/sphere.h @@ -22,22 +22,20 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#ifndef __OPENSPACE_CORE___POWERSCALEDSPHERE___H__ -#define __OPENSPACE_CORE___POWERSCALEDSPHERE___H__ +#ifndef __OPENSPACE_CORE___SPHERE___H__ +#define __OPENSPACE_CORE___SPHERE___H__ #include #include namespace openspace { -class PowerScaledSphere; - -class PowerScaledSphere { +class Sphere { public: - PowerScaledSphere(float radius, int segments = 8); - PowerScaledSphere(glm::vec3 radius, int segments); - PowerScaledSphere(const PowerScaledSphere& cpy); - ~PowerScaledSphere(); + Sphere(float radius, int segments = 8); + Sphere(glm::vec3 radius, int segments); + Sphere(const Sphere& cpy); + ~Sphere(); bool initialize(); @@ -62,4 +60,4 @@ public: } // namespace openspace -#endif // __OPENSPACE_CORE___POWERSCALEDSPHERE___H__ +#endif // __OPENSPACE_CORE___SPHERE___H__ diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index f6ecef64a4..406181eebc 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -26,7 +26,6 @@ #define __OPENSPACE_CORE___UPDATESTRUCTURES___H__ #include -#include #include namespace openspace { diff --git a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp index 3e5dec47ad..3cb7b040ff 100644 --- a/modules/atmosphere/rendering/atmospheredeferredcaster.cpp +++ b/modules/atmosphere/rendering/atmospheredeferredcaster.cpp @@ -60,7 +60,6 @@ #include #include -#include #include #include #include diff --git a/modules/base/rendering/renderablesphere.cpp b/modules/base/rendering/renderablesphere.cpp index 1d653791fd..c3ffa2dc70 100644 --- a/modules/base/rendering/renderablesphere.cpp +++ b/modules/base/rendering/renderablesphere.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -304,7 +304,7 @@ bool RenderableSphere::isReady() const { } void RenderableSphere::initializeGL() { - _sphere = std::make_unique(_size, _segments); + _sphere = std::make_unique(_size, _segments); _sphere->initialize(); _shader = BaseModule::ProgramObjectManager.request( @@ -467,7 +467,7 @@ void RenderableSphere::update(const UpdateData&) { } if (_sphereIsDirty) { - _sphere = std::make_unique(_size, _segments); + _sphere = std::make_unique(_size, _segments); _sphere->initialize(); _sphereIsDirty = false; } diff --git a/modules/base/rendering/renderablesphere.h b/modules/base/rendering/renderablesphere.h index b7ff144fbd..e8e195eb71 100644 --- a/modules/base/rendering/renderablesphere.h +++ b/modules/base/rendering/renderablesphere.h @@ -40,7 +40,7 @@ namespace ghoul::opengl { namespace openspace { -class PowerScaledSphere; +class Sphere; struct RenderData; struct UpdateData; @@ -80,7 +80,7 @@ private: ghoul::opengl::ProgramObject* _shader = nullptr; std::unique_ptr _texture; - std::unique_ptr _sphere; + std::unique_ptr _sphere; UniformCache(opacity, modelViewProjection, modelViewRotation, colorTexture, _mirrorTexture) _uniformCache; diff --git a/modules/base/shaders/imageplane_vs.glsl b/modules/base/shaders/imageplane_vs.glsl index 0962157b38..995c35950c 100644 --- a/modules/base/shaders/imageplane_vs.glsl +++ b/modules/base/shaders/imageplane_vs.glsl @@ -22,6 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ +// @TODO (abock, 2019-12-27) Move this file to the spacecraftinstruments module + #version __CONTEXT__ #include "PowerScaling/powerScaling_vs.hglsl" @@ -36,7 +38,7 @@ uniform mat4 modelViewProjectionTransform; void main() { - vec4 position = vec4(in_position.xyz * pow(10, in_position.w), 1); + vec4 position = vec4(in_position.xyz, 1); vec4 positionClipSpace = modelViewProjectionTransform * position; vec4 positionScreenSpace = z_normalization(positionClipSpace); diff --git a/modules/iswa/rendering/datasphere.cpp b/modules/iswa/rendering/datasphere.cpp index 10cdc263a2..cb68d437c7 100644 --- a/modules/iswa/rendering/datasphere.cpp +++ b/modules/iswa/rendering/datasphere.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include @@ -88,7 +88,7 @@ void DataSphere::initializeGL() { bool DataSphere::createGeometry() { const float radius = 6.371f * _radius * glm::pow(10.f, 6.f); int segments = 100; - _sphere = std::make_unique(radius, segments); + _sphere = std::make_unique(radius, segments); _sphere->initialize(); return true; } diff --git a/modules/iswa/rendering/datasphere.h b/modules/iswa/rendering/datasphere.h index 2ec89762ea..66b5948a93 100644 --- a/modules/iswa/rendering/datasphere.h +++ b/modules/iswa/rendering/datasphere.h @@ -29,7 +29,7 @@ namespace openspace { -class PowerScaledSphere; +class Sphere; /** * DataSphere is a concrete IswaCygnet with data files as its input source. The class @@ -53,7 +53,7 @@ protected: void setUniforms() override; std::vector textureData() override; - std::unique_ptr _sphere; + std::unique_ptr _sphere; float _radius; }; diff --git a/modules/iswa/rendering/iswacygnet.cpp b/modules/iswa/rendering/iswacygnet.cpp index 663ba6dca4..967613f9bf 100644 --- a/modules/iswa/rendering/iswacygnet.cpp +++ b/modules/iswa/rendering/iswacygnet.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -157,12 +156,13 @@ void IswaCygnet::render(const RenderData& data, RendererTasks&) { } transform = transform * _rotation; - psc position = + glm::vec4 pposition = static_cast(glm::dvec4(data.modelTransform.translation, 0.0)) + transform * glm::vec4( _data.spatialScale.x * _data.offset, _data.spatialScale.w ); + glm::vec3 position = glm::vec3(pposition) * pow(10.f, pposition.w); // Activate shader _shader->activate(); @@ -173,7 +173,7 @@ void IswaCygnet::render(const RenderData& data, RendererTasks&) { _shader->setUniform("ModelTransform", transform); _shader->setUniform("campos", glm::vec4(data.camera.positionVec3(), 1.f)); - _shader->setUniform("objpos", glm::vec4(position.vec3(), 0.f)); + _shader->setUniform("objpos", glm::vec4(position, 0.f)); _shader->setUniform("camrot", glm::mat4(data.camera.viewRotationMatrix())); _shader->setUniform("scaling", glm::vec2(1.f, 0.f)); diff --git a/modules/space/rendering/simplespheregeometry.cpp b/modules/space/rendering/simplespheregeometry.cpp index 347752cc3c..4b8fcdd514 100644 --- a/modules/space/rendering/simplespheregeometry.cpp +++ b/modules/space/rendering/simplespheregeometry.cpp @@ -25,9 +25,9 @@ #include #include -#include #include -#include +#include +#include namespace { constexpr openspace::properties::Property::PropertyInfo RadiusInfo = { @@ -124,7 +124,7 @@ void SimpleSphereGeometry::createSphere() { const glm::vec3 radius = _radius.value(); delete _sphere; - _sphere = new PowerScaledSphere(radius, _segments); + _sphere = new Sphere(radius, _segments); _sphere->initialize(); } diff --git a/modules/space/rendering/simplespheregeometry.h b/modules/space/rendering/simplespheregeometry.h index 8148ec052e..abed585ab9 100644 --- a/modules/space/rendering/simplespheregeometry.h +++ b/modules/space/rendering/simplespheregeometry.h @@ -32,7 +32,7 @@ namespace openspace { class Renderable; - class PowerScaledSphere; + class Sphere; } // namespace openspace namespace openspace::documentation { struct Documentation; } @@ -57,7 +57,7 @@ private: properties::Vec3Property _radius; properties::IntProperty _segments; - PowerScaledSphere* _sphere; + Sphere* _sphere; }; } // namespace openspace::planetgeometry diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp index 8dba28ee8d..556c946e1f 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp @@ -461,11 +461,7 @@ void RenderableModelProjection::attitudeParameters(double time) { lightTime ); - // @TODO: Remove this and replace with cpos = p * 1000 ? - psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - - position[3] += 4; - const glm::vec3 cpos = position.vec3(); + const glm::vec3 cpos = p * 10000.0; const float distance = glm::length(cpos); const float radius = boundingSphere(); diff --git a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp index 48508ce2f8..85eed498c2 100644 --- a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp @@ -227,8 +227,7 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime ); // The apparent position, CN+S, makes image align best with target - // @TODO: Remove these powerscaled coordinates - psc projection[4]; + glm::dvec3 projection[4]; for (size_t j = 0; j < bounds.size(); ++j) { bounds[j] = SpiceManager::ref().frameTransformationMatrix( frame, @@ -246,12 +245,8 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime currentTime ) * cornerPosition; - projection[j] = PowerScaledCoordinate::CreatePowerScaledCoordinate( - cornerPosition[0], - cornerPosition[1], - cornerPosition[2] - ); - projection[j][3] += 3; + // km -> m + projection[j] = cornerPosition * 1000.0; } if (!_moving) { @@ -264,21 +259,28 @@ void RenderablePlaneProjection::updatePlane(const Image& img, double currentTime } } + glm::vec3 p[4] = { + glm::vec3(projection[0]), + glm::vec3(projection[1]), + glm::vec3(projection[2]), + glm::vec3(projection[3]) + + }; const GLfloat vertex_data[] = { // square of two triangles drawn within fov in target coordinates // x y z w s t // Lower left 1 - projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 0, + p[1].x, p[1].y, p[1].z, 0.f, 0.f, 0.f, // Upper right 2 - projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 1, + p[3].x, p[3].y, p[3].z, 0.f, 1.f, 1.f, // Upper left 3 - projection[2][0], projection[2][1], projection[2][2], projection[2][3], 0, 1, + p[2].x, p[2].y, p[2].z, 0.f, 0.f, 1.f, // Lower left 4 = 1 - projection[1][0], projection[1][1], projection[1][2], projection[1][3], 0, 0, + p[1].x, p[1].y, p[1].z, 0.f, 0.f, 0.f, // Lower right 5 - projection[0][0], projection[0][1], projection[0][2], projection[0][3], 1, 0, + p[0].x, p[0].y, p[0].z, 0.f, 1.f, 0.f, // Upper left 6 = 2 - projection[3][0], projection[3][1], projection[3][2], projection[3][3], 1, 1, + p[3].x, p[3].y, p[3].z, 0.f, 1.f, 1.f, }; glBindVertexArray(_quad); diff --git a/modules/toyvolume/rendering/toyvolumeraycaster.cpp b/modules/toyvolume/rendering/toyvolumeraycaster.cpp index 2f5f82f0ac..97d71c05bf 100644 --- a/modules/toyvolume/rendering/toyvolumeraycaster.cpp +++ b/modules/toyvolume/rendering/toyvolumeraycaster.cpp @@ -24,7 +24,6 @@ #include -#include #include #include #include diff --git a/modules/volume/rendering/basicvolumeraycaster.cpp b/modules/volume/rendering/basicvolumeraycaster.cpp index f81912cfeb..b404d97bb3 100644 --- a/modules/volume/rendering/basicvolumeraycaster.cpp +++ b/modules/volume/rendering/basicvolumeraycaster.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6bae69e26..bba42b68da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -177,11 +177,10 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/util/httprequest.cpp ${OPENSPACE_BASE_DIR}/src/util/keys.cpp ${OPENSPACE_BASE_DIR}/src/util/openspacemodule.cpp - ${OPENSPACE_BASE_DIR}/src/util/powerscaledcoordinate.cpp - ${OPENSPACE_BASE_DIR}/src/util/powerscaledsphere.cpp ${OPENSPACE_BASE_DIR}/src/util/progressbar.cpp ${OPENSPACE_BASE_DIR}/src/util/resourcesynchronization.cpp ${OPENSPACE_BASE_DIR}/src/util/screenlog.cpp + ${OPENSPACE_BASE_DIR}/src/util/sphere.cpp ${OPENSPACE_BASE_DIR}/src/util/spicemanager.cpp ${OPENSPACE_BASE_DIR}/src/util/spicemanager_lua.inl ${OPENSPACE_BASE_DIR}/src/util/syncbuffer.cpp @@ -371,11 +370,10 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/util/keys.h ${OPENSPACE_BASE_DIR}/include/openspace/util/mouse.h ${OPENSPACE_BASE_DIR}/include/openspace/util/openspacemodule.h - ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledcoordinate.h - ${OPENSPACE_BASE_DIR}/include/openspace/util/powerscaledsphere.h ${OPENSPACE_BASE_DIR}/include/openspace/util/progressbar.h ${OPENSPACE_BASE_DIR}/include/openspace/util/resourcesynchronization.h ${OPENSPACE_BASE_DIR}/include/openspace/util/screenlog.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/sphere.h ${OPENSPACE_BASE_DIR}/include/openspace/util/spicemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/util/syncable.h ${OPENSPACE_BASE_DIR}/include/openspace/util/syncbuffer.h diff --git a/src/util/powerscaledcoordinate.cpp b/src/util/powerscaledcoordinate.cpp deleted file mode 100644 index e5d1f5df75..0000000000 --- a/src/util/powerscaledcoordinate.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2019 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include - -#include -#include - -namespace { - constexpr const double k = 10.0; -} // namespace - -namespace openspace { - -PowerScaledCoordinate::PowerScaledCoordinate(PowerScaledCoordinate&& rhs) { - _vec = std::move(rhs._vec); -} - -PowerScaledCoordinate::PowerScaledCoordinate(glm::vec4 v) { - _vec = std::move(v); -} - -PowerScaledCoordinate::PowerScaledCoordinate(glm::vec3 v) { - _vec = glm::vec4(v, 0.f); -} - -PowerScaledCoordinate::PowerScaledCoordinate(float f1, float f2, float f3, float f4) { - _vec = glm::vec4(f1, f2, f3, f4); -} - -PowerScaledCoordinate::PowerScaledCoordinate(const PowerScaledCoordinate& rhs) { - _vec = rhs._vec; -} - -PowerScaledCoordinate -PowerScaledCoordinate::CreatePowerScaledCoordinate(double d1, double d2, double d3) -{ - char buff[600]; - - // find the number with maximum number of digits - double ad1 = std::abs(d1); - double ad2 = std::abs(d2); - double ad3 = std::abs(d3); - double max = (ad2 > ad1) ? ad2 : (ad3 > ad1) ? ad3 : ad1; - - // find out how many digits - // TODO: profile the next two lines and replace with something more efficient (ab) -#ifdef _MSC_VER - sprintf_s(buff, 600, "%.0f", max); - //sprintf(buff, "%.0f", max); -#else - sprintf(buff, "%.0f", max); -#endif - size_t digits = strlen(buff); - - //digits += 3; - - // rescale and return - double tp = 1.0 / pow(k, digits); - return PowerScaledCoordinate( - static_cast(d1 * tp), - static_cast(d2 * tp), - static_cast(d3 * tp), - static_cast(digits)); -} - -const glm::vec4& PowerScaledCoordinate::vec4() const -{ - return _vec; -} - -glm::vec3 PowerScaledCoordinate::vec3() const -{ - return glm::vec3(_vec[0] * pow(k, _vec[3]), _vec[1] * pow(k, _vec[3]), - _vec[2] * pow(k, _vec[3])); -} - -glm::dvec4 PowerScaledCoordinate::dvec4() const -{ - //return _vec; - return glm::dvec4(_vec); -} - -glm::dvec3 PowerScaledCoordinate::dvec3() const -{ - double p = pow(static_cast(k), static_cast(_vec[3])); - return glm::dvec3( static_cast(_vec[0]) * p, static_cast(_vec[1]) * p, - static_cast(_vec[2]) * p); -} - -float PowerScaledCoordinate::length() const -{ - return glm::length(glm::vec3(_vec[0], _vec[1], _vec[2])) * std::pow(10, _vec[3]); -} - -glm::vec3 PowerScaledCoordinate::direction() const -{ - glm::vec3 tmp(_vec[0], _vec[1], _vec[2]); - return glm::normalize(glm::vec3(_vec[0], _vec[1], _vec[2])); -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(const PowerScaledCoordinate& rhs) -{ - if (this != &rhs) { - _vec = rhs._vec; - } - return *this; // Return a reference to myself. -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(const glm::vec4& rhs) { - _vec = rhs; - return *this; // Return a reference to myself. -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(const glm::vec3& rhs) { - _vec = glm::vec4(rhs[0], rhs[1], rhs[2], 0.0); - return *this; // Return a reference to myself. -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(const glm::dvec4& rhs) { - _vec = glm::vec4(rhs); - return *this; // Return a reference to myself. -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(const glm::dvec3& rhs) { - _vec = glm::vec4(rhs[0], rhs[1], rhs[2], 0.0); - return *this; // Return a reference to myself. -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator=(PowerScaledCoordinate&& rhs) { - _vec = std::move(rhs._vec); - return *this; -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator+=(const PowerScaledCoordinate& rhs) -{ - double ds = _vec[3] - rhs._vec[3]; - if (ds >= 0.0) { - double p = pow(k, -ds); - *this = PowerScaledCoordinate(static_cast(rhs._vec[0] * p + _vec[0]), - static_cast(rhs._vec[1] * p + _vec[1]), - static_cast(rhs._vec[2] * p + _vec[2]), - _vec[3]); - } else { - double p = pow(k, ds); - *this = PowerScaledCoordinate(static_cast(rhs._vec[0] + _vec[0] * p), - static_cast(rhs._vec[1] + _vec[1] * p), - static_cast(rhs._vec[2] + _vec[2] * p), - rhs._vec[3]); - } - - return *this; -} - -PowerScaledCoordinate PowerScaledCoordinate:: - operator+(const PowerScaledCoordinate& rhs) const -{ - return PowerScaledCoordinate(*this) += rhs; -} - -PowerScaledCoordinate& PowerScaledCoordinate::operator-=(const PowerScaledCoordinate& rhs) -{ - double ds = this->_vec[3] - rhs._vec[3]; - if (ds >= 0.0) { - double p = pow(k, -ds); - *this = PowerScaledCoordinate(static_cast(-rhs._vec[0] * p + _vec[0]), - static_cast(-rhs._vec[1] * p + _vec[1]), - static_cast(-rhs._vec[2] * p + _vec[2]), - _vec[3]); - } else { - double p = pow(k, ds); - *this = PowerScaledCoordinate(static_cast(-rhs._vec[0] + _vec[0] * p), - static_cast(-rhs._vec[1] + _vec[1] * p), - static_cast(-rhs._vec[2] + _vec[2] * p), - rhs._vec[3]); - } - - return *this; -} - -PowerScaledCoordinate PowerScaledCoordinate::operator*(const double& rhs) const -{ - return PowerScaledCoordinate(static_cast(_vec[0] * rhs), - static_cast(_vec[1] * rhs), - static_cast(_vec[2] * rhs), _vec[3]); -} - -PowerScaledCoordinate PowerScaledCoordinate::operator*(const float& rhs) const -{ - return PowerScaledCoordinate(_vec[0] * rhs, _vec[1] * rhs, _vec[2] * rhs, _vec[3]); -} - -PowerScaledCoordinate PowerScaledCoordinate::operator*(const glm::mat4& matrix) const -{ - return matrix * _vec; -} - -PowerScaledCoordinate PowerScaledCoordinate:: - operator-(const PowerScaledCoordinate& rhs) const -{ - return PowerScaledCoordinate(*this) -= rhs; -} - -float& PowerScaledCoordinate::operator[](unsigned int idx) -{ - return _vec[idx]; -} - -float PowerScaledCoordinate::operator[](unsigned int idx) const -{ - return _vec[idx]; -} - -double PowerScaledCoordinate::dot(const PowerScaledCoordinate& rhs) const -{ - double ds = _vec[3] - rhs._vec[3]; - if (ds >= 0.0) { - double p = pow(k, -ds); - glm::dvec3 uPowerScaledCoordinatealed(rhs._vec[0] * p, rhs._vec[1] * p, - rhs._vec[2] * p); - glm::dvec3 shortened(_vec[0], _vec[1], _vec[2]); - return glm::dot(uPowerScaledCoordinatealed, shortened); - } else { - double p = pow(k, ds); - glm::dvec3 uPowerScaledCoordinatealed(_vec[0] * p, _vec[1] * p, _vec[2] * p); - glm::dvec3 shortened(rhs._vec[0], rhs._vec[1], rhs._vec[2]); - return glm::dot(uPowerScaledCoordinatealed, shortened); - } -} - -double PowerScaledCoordinate::angle(const PowerScaledCoordinate& rhs) const -{ - glm::dvec3 uPowerScaledCoordinatealed(rhs._vec[0], rhs._vec[1], rhs._vec[2]); - glm::dvec3 shortened(_vec[0], _vec[1], _vec[2]); - uPowerScaledCoordinatealed = glm::normalize(uPowerScaledCoordinatealed); - shortened = glm::normalize(shortened); - - return acos(glm::dot(uPowerScaledCoordinatealed, shortened)); -} - -bool PowerScaledCoordinate::operator==(const PowerScaledCoordinate& other) const -{ - return _vec == other._vec; -} - -bool PowerScaledCoordinate::operator!=(const PowerScaledCoordinate& other) const -{ - return _vec != other._vec; -} - -bool PowerScaledCoordinate::operator<(const PowerScaledCoordinate& other) const -{ - double ds = _vec[3] - other._vec[3]; - if (ds >= 0) { - double p = pow(k, -ds); - glm::dvec3 upscaled(other._vec[0] * p, other._vec[1] * p, - other._vec[2] * p); - glm::dvec3 shortened(_vec[0], _vec[1], _vec[2]); - return glm::length(shortened) < glm::length(upscaled); - } else { - double p = pow(k, ds); - glm::dvec3 upscaled(_vec[0] * p, _vec[1] * p, _vec[2] * p); - glm::dvec3 shortened(other._vec[0], other._vec[1], other._vec[2]); - return glm::length(shortened) < glm::length(upscaled); - } -} - -bool PowerScaledCoordinate::operator>(const PowerScaledCoordinate& other) const -{ - double ds = this->_vec[3] - other._vec[3]; - if (ds >= 0) { - double p = pow(k, -ds); - glm::dvec3 upscaled(other._vec[0] * p, other._vec[1] * p, - other._vec[2] * p); - glm::dvec3 shortened(_vec[0], _vec[1], _vec[2]); - return glm::length(shortened) > glm::length(upscaled); - } else { - double p = pow(k, ds); - glm::dvec3 upscaled(_vec[0] * p, _vec[1] * p, _vec[2] * p); - glm::dvec3 shortened(other._vec[0], other._vec[1], other._vec[2]); - return glm::length(shortened) > glm::length(upscaled); - } -} - -bool PowerScaledCoordinate::operator<=(const PowerScaledCoordinate& other) const -{ - return *this < other || *this == other; -} - -bool PowerScaledCoordinate::operator>=(const PowerScaledCoordinate& other) const -{ - return *this > other || *this == other; -} - -std::ostream& operator<<(::std::ostream& os, const PowerScaledCoordinate& rhs) -{ - os << "(" << rhs[0] << ", " << rhs[1] << ", " << rhs[2] << "; " << rhs[3] << ")"; - return os; -} - -} // namespace openspace diff --git a/src/util/powerscaledsphere.cpp b/src/util/sphere.cpp similarity index 93% rename from src/util/powerscaledsphere.cpp rename to src/util/sphere.cpp index 25319ddba1..cbd3cfc4dc 100644 --- a/src/util/powerscaledsphere.cpp +++ b/src/util/sphere.cpp @@ -22,9 +22,8 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ -#include +#include -#include #include #include @@ -34,12 +33,12 @@ namespace { namespace openspace { -PowerScaledSphere::PowerScaledSphere(float radius, int segments) - : PowerScaledSphere(glm::vec3(radius), segments) +Sphere::Sphere(float radius, int segments) + : Sphere(glm::vec3(radius), segments) {} // Alternative Constructor for using accurate triaxial ellipsoid -PowerScaledSphere::PowerScaledSphere(glm::vec3 radius, int segments) +Sphere::Sphere(glm::vec3 radius, int segments) : _isize(6 * segments * segments) , _vsize((segments + 1) * (segments + 1)) , _varray(new Vertex[_vsize]) @@ -110,7 +109,7 @@ PowerScaledSphere::PowerScaledSphere(glm::vec3 radius, int segments) } } -PowerScaledSphere::PowerScaledSphere(const PowerScaledSphere& cpy) +Sphere::Sphere(const Sphere& cpy) : _vaoID(cpy._vaoID) , _vBufferID(cpy._vBufferID) , _iBufferID(cpy._iBufferID) @@ -125,7 +124,7 @@ PowerScaledSphere::PowerScaledSphere(const PowerScaledSphere& cpy) std::memcpy(_iarray, cpy._iarray, _isize * sizeof(int)); } -PowerScaledSphere::~PowerScaledSphere() { +Sphere::~Sphere() { delete[] _varray; delete[] _iarray; @@ -137,7 +136,7 @@ PowerScaledSphere::~PowerScaledSphere() { glDeleteVertexArrays(1, &_vaoID); } -bool PowerScaledSphere::initialize() { +bool Sphere::initialize() { // Initialize and upload to graphics card if (_vaoID == 0) { glGenVertexArrays(1, &_vaoID); @@ -197,7 +196,7 @@ bool PowerScaledSphere::initialize() { return true; } -void PowerScaledSphere::render() { +void Sphere::render() { glBindVertexArray(_vaoID); // select first VAO glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID); glDrawElements(GL_TRIANGLES, _isize, GL_UNSIGNED_INT, nullptr); diff --git a/tests/main.cpp b/tests/main.cpp index b5c3cd717f..8fa9ef3765 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -66,7 +66,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/test_powerscalecoordinates.inl b/tests/test_powerscalecoordinates.inl deleted file mode 100644 index 23b22a70a9..0000000000 --- a/tests/test_powerscalecoordinates.inl +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************************************** - * * - * OpenSpace * - * * - * Copyright (c) 2014-2019 * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this * - * software and associated documentation files (the "Software"), to deal in the Software * - * without restriction, including without limitation the rights to use, copy, modify, * - * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * - * permit persons to whom the Software is furnished to do so, subject to the following * - * conditions: * - * * - * The above copyright notice and this permission notice shall be included in all copies * - * or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * - * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * - ****************************************************************************************/ - -#include - -#include - -class PowerscaleCoordinatesTest : public testing::Test { -protected: - PowerscaleCoordinatesTest() { - } - - ~PowerscaleCoordinatesTest() { - } - - void reset() { - } - - openspace::Scene* scenegraph; -}; - - -TEST_F(PowerscaleCoordinatesTest, psc) { - - openspace::psc reference(2.f, 1.f, 1.1f, 1.f); - - openspace::psc first(1.f, 0.f, 1.f, 0.f); - openspace::psc second(1.9f, 1.f, 1.f, 1.f); - - EXPECT_EQ(reference, first + second); - EXPECT_TRUE(reference == (first + second)); - - openspace::psc third = first; - first[0] = 0.0; - - EXPECT_TRUE(third != first); - - -} - - - From e3afd82c4700536a2221fc76f64fdc873c93e964 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 28 Dec 2019 00:25:17 +0100 Subject: [PATCH 100/214] Move the mapping target->frame from SpiceManager to SpacecraftInstrumentModule (#closes 21) --- include/openspace/util/spicemanager.h | 52 ------------------- .../rendering/renderablefov.cpp | 15 ++++-- .../rendering/renderableplaneprojection.cpp | 5 +- .../spacecraftinstrumentsmodule.cpp | 27 ++++++++++ .../spacecraftinstrumentsmodule.h | 6 +++ src/util/spicemanager.cpp | 45 ---------------- 6 files changed, 49 insertions(+), 101 deletions(-) diff --git a/include/openspace/util/spicemanager.h b/include/openspace/util/spicemanager.h index 8aab7b6094..634a836571 100644 --- a/include/openspace/util/spicemanager.h +++ b/include/openspace/util/spicemanager.h @@ -652,36 +652,6 @@ public: FieldOfViewMethod method, AberrationCorrection aberrationCorrection, double& ephemerisTime) const; - /** - * Determine whether a specific \p target is in the field-of-view of a specified - * \p instrument or an \p observer at a given time. The reference frame used is - * derived from the \p target by converting it into an \c IAU inertial reference - * frame. - * - * \param target The name or NAIF ID code string of the target - * \param observer The name or NAIF ID code string of the observer - * \param instrument The name or NAIF ID code string of the instrument - * \param method The type of shape model used for the target - * \param aberrationCorrection The aberration correction method - * \param ephemerisTime Time of the observation (seconds past J2000) - * \return \c true if the target is visible, \c false otherwise - * - * \throw SpiceException If the \p target or \p observer do not name valid - * NAIF objects, the \p target or \p observer name the same NAIF object, the - * \p instrument does not name a valid NAIF object, or insufficient kernel - * information has been loaded. - * \pre \p target must not be empty. - * \pre \p observer must not be empty. - * \pre \p target and \p observer must not be different strings - * \pre \p referenceFrame must not be empty. - * \pre \p instrument must not be empty. - * - * \sa http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/fovtrg_c.html - */ - bool isTargetInFieldOfView(const std::string& target, const std::string& observer, - const std::string& instrument, FieldOfViewMethod method, - AberrationCorrection aberrationCorrection, double& ephemerisTime) const; - /// Struct that is used as the return value from the #targetState method struct TargetStateResult { /// The target position @@ -902,26 +872,6 @@ public: AberrationCorrection aberrationCorrection, double ephemerisTime, int numberOfTerminatorPoints); - /** - * This function adds a frame to a body. - * - * \param body - the name of the body - * \param frame - the name of the frame - * \return false if the arguments are empty - * - * \todo I think this function should die ---abock - */ - bool addFrame(std::string body, std::string frame); - - /** - * This function returns the frame of a body if defined, otherwise it returns - * IAU_ + body (most frames are known by the International Astronomical Union) - * \param body - the name of the body - * \return the frame of the body - * \todo I think this function should die ---abock - */ - std::string frameFromBody(const std::string& body) const; - /** * Sets the SpiceManager's exception handling. If UseException::No is passed to this * function, all subsequent calls will not throw an error, but fail silently instead. @@ -1048,8 +998,6 @@ private: std::map>> _spkIntervals; std::map> _ckCoverageTimes; std::map> _spkCoverageTimes; - // Vector of pairs: Body, Frame - std::vector> _frameByBody; /// Stores whether the SpiceManager throws exceptions (Yes) or fails silently (No) UseException _useExceptions = UseException::Yes; diff --git a/modules/spacecraftinstruments/rendering/renderablefov.cpp b/modules/spacecraftinstruments/rendering/renderablefov.cpp index ab4e0696e9..d4396b270e 100644 --- a/modules/spacecraftinstruments/rendering/renderablefov.cpp +++ b/modules/spacecraftinstruments/rendering/renderablefov.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -151,7 +152,6 @@ namespace { return 0.5 * bisect(p1, half, testFunction, half); } } - } // namespace namespace openspace { @@ -294,7 +294,10 @@ RenderableFov::RenderableFov(const ghoul::Dictionary& dictionary) if (dictionary.hasKey(KeyFrameConversions)) { ghoul::Dictionary fc = dictionary.value(KeyFrameConversions); for (const std::string& key : fc.keys()) { - openspace::SpiceManager::ref().addFrame(key, fc.value(key)); + global::moduleEngine.module()->addFrame( + key, + fc.value(key) + ); } } @@ -524,7 +527,12 @@ void RenderableFov::computeIntercepts(const UpdateData& data, const std::string& { const bool convert = (ref.find("IAU_") == std::string::npos); if (convert) { - return { SpiceManager::ref().frameFromBody(target), true }; + return { + global::moduleEngine.module()->frameFromBody( + target + ), + true + }; } else { return { ref, false }; @@ -917,6 +925,7 @@ std::pair RenderableFov::determineTarget(double time) { bool inFOV = SpiceManager::ref().isTargetInFieldOfView( pt, _instrument.spacecraft, + global::moduleEngine.module()->frameFromBody(pt), _instrument.name, SpiceManager::FieldOfViewMethod::Ellipsoid, _instrument.aberrationCorrection, diff --git a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp index 85eed498c2..64b7864e70 100644 --- a/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderableplaneprojection.cpp @@ -24,8 +24,10 @@ #include +#include #include #include +#include #include #include #include @@ -309,7 +311,8 @@ void RenderablePlaneProjection::setTarget(std::string body) { return; } - _target.frame = SpiceManager::ref().frameFromBody(body); + _target.frame = + global::moduleEngine.module()->frameFromBody(body); _target.body = std::move(body); } diff --git a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp index 3e2bf6847a..460418b055 100644 --- a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp +++ b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.cpp @@ -94,4 +94,31 @@ SpacecraftInstrumentsModule::documentations() const }; } +bool SpacecraftInstrumentsModule::addFrame(std::string body, std::string frame) { + if (body.empty() || frame.empty()) { + return false; + } + else { + _frameByBody.emplace_back(body, frame); + return true; + } +} + +std::string SpacecraftInstrumentsModule::frameFromBody(const std::string& body) { + for (const std::pair& pair : _frameByBody) { + if (pair.first == body) { + return pair.second; + } + } + + constexpr const char* unionPrefix = "IAU_"; + + if (body.find(unionPrefix) == std::string::npos) { + return unionPrefix + body; + } + else { + return body; + } +} + } // namespace openspace diff --git a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h index d05fefe8c5..fc37bd53bb 100644 --- a/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h +++ b/modules/spacecraftinstruments/spacecraftinstrumentsmodule.h @@ -41,10 +41,16 @@ public: static ghoul::opengl::ProgramObjectManager ProgramObjectManager; + bool addFrame(std::string body, std::string frame); + std::string frameFromBody(const std::string& body); + protected: void internalInitialize(const ghoul::Dictionary&) override; void internalDeinitialize() override; void internalDeinitializeGL() override; + +private: + std::vector> _frameByBody; }; } // namespace openspace diff --git a/src/util/spicemanager.cpp b/src/util/spicemanager.cpp index 9aa2e51803..bd65b59db5 100644 --- a/src/util/spicemanager.cpp +++ b/src/util/spicemanager.cpp @@ -687,24 +687,6 @@ bool SpiceManager::isTargetInFieldOfView(const std::string& target, return visible == SPICETRUE; } -bool SpiceManager::isTargetInFieldOfView(const std::string& target, - const std::string& observer, - const std::string& instrument, - FieldOfViewMethod method, - AberrationCorrection aberrationCorrection, - double& ephemerisTime) const -{ - return isTargetInFieldOfView( - target, - observer, - frameFromBody(target), - instrument, - method, - aberrationCorrection, - ephemerisTime - ); -} - SpiceManager::TargetStateResult SpiceManager::targetState(const std::string& target, const std::string& observer, const std::string& referenceFrame, @@ -913,33 +895,6 @@ SpiceManager::TerminatorEllipseResult SpiceManager::terminatorEllipse( return res; } -bool SpiceManager::addFrame(std::string body, std::string frame) { - if (body.empty() || frame.empty()) { - return false; - } - else { - _frameByBody.emplace_back(body, frame); - return true; - } -} - -std::string SpiceManager::frameFromBody(const std::string& body) const { - for (const std::pair& pair : _frameByBody) { - if (pair.first == body) { - return pair.second; - } - } - - constexpr const char* unionPrefix = "IAU_"; - - if (body.find(unionPrefix) == std::string::npos) { - return unionPrefix + body; - } - else { - return body; - } -} - void SpiceManager::findCkCoverage(const std::string& path) { ghoul_assert(!path.empty(), "Empty file path"); ghoul_assert(FileSys.fileExists(path), fmt::format("File '{}' does not exist", path)); From 3ef1b8d51109af33872b4ebe4565440af80457f7 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 3 Jan 2020 12:31:20 -0700 Subject: [PATCH 101/214] Fixes to allow using temp directory for profile-to-asset conversion --- scripts/convertProfileToScene.lua | 7 +++---- src/engine/configuration.cpp | 2 +- src/engine/openspaceengine.cpp | 26 ++++++++++++++++---------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index e27dec9ad5..1321dd52a5 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -308,7 +308,7 @@ function generateAsset(T, fileOut) end --Asset section - AssetStr = AssetStr.."asset.require('./base');\n" + AssetStr = AssetStr.."asset.require('base');\n" AssetStr = AssetStr.."local assetHelper = asset.require('util/asset_helper')\n" AssetStr = AssetStr.."local propertyHelper = asset.require('util/property_helper')\n" AssetStr = AssetStr.."local sceneHelper = asset.require('util/scene_helper')\n" @@ -467,8 +467,7 @@ parsingSections = { profileFilename = openspace.profile.getFilename() profilePath = openspace.profile.getPath() -profileIn = profilePath.."\\"..profileFilename -assetOut = profilePath.."\\"..profileFilename:match("^.+%.").."scene" +assetOut = profilePath..".scene" -local resultTable = parseProfile(profileIn) +local resultTable = parseProfile(profilePath) generateAsset(resultTable, assetOut) diff --git a/src/engine/configuration.cpp b/src/engine/configuration.cpp index cbb6080af3..6c2b2fe043 100644 --- a/src/engine/configuration.cpp +++ b/src/engine/configuration.cpp @@ -362,7 +362,7 @@ Configuration loadConfigurationFromFile(const std::string& filename) { // created with that name, and also because the profile name will override // an asset name if both are provided. if (!result.profile.empty()) { - result.asset = result.profile; + result.asset = "../../temp/" + result.profile; } return result; diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index e393807bc2..4e858562ed 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -301,18 +301,24 @@ void OpenSpaceEngine::initialize() { global::configuration.profile)); ghoul::lua::LuaState lState; - // Get path where .scene files reside. Need to add extra escape slashes to - // accomodate lua parser. + // Generate path to temp dir where output .scene file will reside. + // Needs to handle either windows (which seems to require double back-slashes) + // or unix path slashes. std::string outputScenePath = absPath("${TEMPORARY}"); - std::string search = "\\"; - std::string replace = "\\\\"; - for (std::string::size_type i = outputScenePath.find(search); - i != std::string::npos; - i = outputScenePath.find(search, i)) - { - outputScenePath.replace(i, search.length(), replace); - i += replace.length(); + const std::string search = "\\"; + const std::string replace = "\\\\"; + if (outputScenePath.find(search) != std::string::npos) { + size_t start_pos = 0; + while((start_pos = outputScenePath.find(search, start_pos)) != std::string::npos) { + outputScenePath.replace(start_pos, search.length(), replace); + start_pos += replace.length(); + } + outputScenePath.append(replace); } + else { + outputScenePath.append("/"); + } + outputScenePath.append(global::configuration.profile); std::string setProfileFilenameInLuaState = fmt::format(R"( openspace = {{}} From 425ed3fef663a1a7fe4c1639bb8ced7905152ce2 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 3 Jan 2020 14:11:57 -0700 Subject: [PATCH 102/214] Added handling a telemetry file read exception --- modules/space/rendering/renderablesmallbody.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index ef939a6ab3..36a54de788 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -320,14 +320,20 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { } catch (std::invalid_argument&) { LERROR(fmt::format( - "invalid_argument exception on line {} of {}", - csvLine + 1, filename + "invalid_argument exception on line {}/{} of {}", + csvLine + 1, numberOfLines, filename )); } catch (std::out_of_range&) { LERROR(fmt::format( - "out_of_range exception on line {} of {}", - csvLine + 1, filename + "out_of_range exception on line {}/{} of {}", + csvLine + 1, numberOfLines, filename + )); + } + catch (std::ios_base::failure&) { + LERROR(fmt::format( + "ios_base::failure exception on line {}/{} of {}", + csvLine + 1, numberOfLines, filename )); } From 684ba237ec1e98323a587c638d3c23064621c558 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 6 Jan 2020 09:17:11 -0500 Subject: [PATCH 103/214] Fixed Sun's shadow below rings. --- modules/globebrowsing/shaders/rings_fs.glsl | 1 - modules/globebrowsing/src/renderableglobe.cpp | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index fb198a952a..4eb8ce25b6 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -34,7 +34,6 @@ uniform sampler1D ringTexture; uniform vec2 textureOffset; uniform float transparency; -uniform bool hasSunPosition; uniform vec3 sunPosition; uniform float _nightFactor; uniform int nShadowSamples; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 89cc1035a1..9584a5816a 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -910,6 +910,15 @@ void RenderableGlobe::update(const UpdateData& data) { _layerManager.reset(); _debugProperties.resetTileProviders = false; } + + if (_hasRings) { + _ringsComponent.update(data); + } + + if (_hasShadows) { + _shadowComponent.update(data); + } + #ifdef OPENSPACE_MODULE_GLOBEBROWSING_INSTRUMENTATION _nUploadedTiles = _layerManager.update(); #else From 48a65f8b5f5b7b926c54b197aa4a1f5194a9125a Mon Sep 17 00:00:00 2001 From: GPayne Date: Mon, 6 Jan 2020 15:35:12 -0700 Subject: [PATCH 104/214] Fixed csv telemetry file parsing and copied line fade changes from satellites --- .../scene/solarsystem/sssb/sssb_shared.asset | 10 +- .../space/rendering/renderablesmallbody.cpp | 128 +++++++++++++----- modules/space/rendering/renderablesmallbody.h | 2 - modules/space/shaders/debrisViz_fs.glsl | 17 ++- 4 files changed, 115 insertions(+), 42 deletions(-) diff --git a/data/assets/scene/solarsystem/sssb/sssb_shared.asset b/data/assets/scene/solarsystem/sssb/sssb_shared.asset index 62c127a54b..ae54c5eba1 100644 --- a/data/assets/scene/solarsystem/sssb/sssb_shared.asset +++ b/data/assets/scene/solarsystem/sssb/sssb_shared.asset @@ -22,10 +22,8 @@ function downloadSssbDatabaseFile(sceneAsset, url, name) end local registerSssbGroupObjects = function(containingAsset, filename, sssbFolder, shouldAddDuplicates) - --local filename = group.Url:match("([^/]+)$") local filenameSansExt = filename:gsub(filename:match("(%.%w+)$"), "") - --local path = sssbFolder .. "/" .. filename - local trailColor = { 0.75, 0.75, 0.35 } + local trailColor = { 0.75, 0.1, 0.1 } function numLinesInFile(filename) local ctr = 0 @@ -40,9 +38,9 @@ local registerSssbGroupObjects = function(containingAsset, filename, sssbFolder, Renderable = { Type = "RenderableSmallBody", Path = file, - Segments = 160, - Color = color, - Fade = 0.5 + Segments = 200, + Color = trailColor, + Fade = 0.5, }, GUI = { Path = "/Solar System/sssb" diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 36a54de788..0a45b65360 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -224,7 +224,6 @@ RenderableSmallBody::RenderableSmallBody(const ghoul::Dictionary& dictionary) : Renderable(dictionary) , _path(PathInfo) , _nSegments(SegmentsInfo) - , _lineFade(FadeInfo) { documentation::testSpecificationAndThrow( @@ -235,16 +234,25 @@ RenderableSmallBody::RenderableSmallBody(const ghoul::Dictionary& dictionary) _path = dictionary.value(PathInfo.identifier); _nSegments = static_cast(dictionary.value(SegmentsInfo.identifier)); - _lineFade = static_cast(dictionary.value(FadeInfo.identifier)); if (dictionary.hasKeyAndValue(LineColorInfo.identifier)) { _appearance.lineColor = dictionary.value(LineColorInfo.identifier); } + if (dictionary.hasKeyAndValue("FadeInfo")) { + _appearance.lineFade = static_cast( + dictionary.value("FadeInfo") + ); + } + else { + _appearance.lineFade = 20; + } addPropertySubOwner(_appearance); addProperty(_path); addProperty(_nSegments); - addProperty(_lineFade); + addProperty(_opacity); + + setRenderBin(Renderable::RenderBin::Overlay); } @@ -265,75 +273,129 @@ void RenderableSmallBody::readJplSbDb(const std::string& filename) { std::string line; std::string name; - std::string ignore; - std::streamoff csvLine; + std::string field; + std::streamoff csvLine = -1; + int fieldCount = 0; + const std::string expectedHeaderLine = + "full_name,neo,pha,diameter,epoch_cal,e,a,i,om,w,ma,per"; try { std::getline(file, line); // get rid of first line (header) + numberOfLines -= 1; + if (line.compare(expectedHeaderLine) != 0) { + LERROR(fmt::format( + "File {} does not have the appropriate JPL SBDB header at line 1.", + filename + )); + file.close(); + return; + } + for (csvLine = 0; csvLine < numberOfLines; csvLine++) { + fieldCount = 0; KeplerParameters keplerElements; // Object designator string std::getline(file, name, ','); + fieldCount++; // (Ignore object status for NEO, PHA, diameter) - std::getline(file, ignore, ','); - std::getline(file, ignore, ','); - std::getline(file, ignore, ','); + std::getline(file, field, ','); + std::getline(file, field, ','); + std::getline(file, field, ','); + fieldCount += 3; // Epoch - std::getline(file, ignore, ','); - keplerElements.epoch = epochFromYMDdSubstring(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read epoch from line" + + std::to_string(csvLine + 1)); + } + keplerElements.epoch = epochFromYMDdSubstring(field); + fieldCount++; // Eccentricity (unit-less) - std::getline(file, ignore, ','); - keplerElements.eccentricity = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read eccentricity from line" + + std::to_string(csvLine + 1)); + } + keplerElements.eccentricity = std::stod(field); + fieldCount++; // Semi-major axis (astronomical units - au) - std::getline(file, ignore, ','); - keplerElements.semiMajorAxis = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read semi-major axis from line" + + std::to_string(csvLine + 1)); + } + keplerElements.semiMajorAxis = std::stod(field); keplerElements.semiMajorAxis *= convertAuToKm; + fieldCount++; // Inclination (degrees) - std::getline(file, ignore, ','); - keplerElements.inclination = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read inclination from line" + + std::to_string(csvLine + 1)); + } + keplerElements.inclination = std::stod(field); + fieldCount++; // Longitude of ascending node (degrees) - std::getline(file, ignore, ','); - keplerElements.ascendingNode = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read ascending node from line" + + std::to_string(csvLine + 1)); + } + keplerElements.ascendingNode = std::stod(field); + fieldCount++; // Argument of Periapsis (degrees) - std::getline(file, ignore, ','); - keplerElements.argumentOfPeriapsis = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read arg of periapsis from line" + + std::to_string(csvLine + 1)); + } + keplerElements.argumentOfPeriapsis = std::stod(field); + fieldCount++; // Mean Anomaly (degrees) - std::getline(file, ignore, ','); - keplerElements.meanAnomaly = std::stod(ignore); + if (!std::getline(file, field, ',')) { + throw std::invalid_argument("Unable to read mean anomaly from line" + + std::to_string(csvLine + 1)); + } + keplerElements.meanAnomaly = std::stod(field); + fieldCount++; // Period (days) - std::getline(file, ignore); - keplerElements.period = std::stod(ignore); + if (!std::getline(file, field)) { + throw std::invalid_argument("Unable to read period from line" + + std::to_string(csvLine + 1)); + } + keplerElements.period = std::stod(field); keplerElements.period *= convertDaysToSecs; + fieldCount++; _sbData.push_back(keplerElements); _sbNames.push_back(name); } } catch (std::invalid_argument&) { + const char* errMsg = "Unable to convert field {} to double value "\ + "(invalid_argument exception) at line {}/{} of {}"; LERROR(fmt::format( - "invalid_argument exception on line {}/{} of {}", - csvLine + 1, numberOfLines, filename + errMsg, + fieldCount, csvLine + 1, numberOfLines, filename )); } catch (std::out_of_range&) { + const char* errMsg = "Unable to convert field {} to double value "\ + "(out_of_range exception) at line {}/{} of {}"; LERROR(fmt::format( - "out_of_range exception on line {}/{} of {}", - csvLine + 1, numberOfLines, filename + errMsg, + fieldCount, csvLine + 1, numberOfLines, filename )); } catch (std::ios_base::failure&) { + const char* errMsg = "File read exception (ios_base::failure) while trying "\ + "to read field {} at line {}/{} of {}"; LERROR(fmt::format( - "ios_base::failure exception on line {}/{} of {}", - csvLine + 1, numberOfLines, filename + errMsg, + fieldCount, csvLine + 1, numberOfLines, filename )); } @@ -401,10 +463,12 @@ void RenderableSmallBody::render(const RenderData& data, RendererTasks&) { _uniformCache.modelView, data.camera.combinedViewMatrix() * modelTransform ); + // Because we want the property to work similar to the planet trails + float fade = static_cast(pow(_appearance.lineFade.maxValue() - _appearance.lineFade, 2.0)); _programObject->setUniform(_uniformCache.projection, data.camera.projectionMatrix()); _programObject->setUniform(_uniformCache.color, _appearance.lineColor); - _programObject->setUniform(_uniformCache.lineFade, _appearance.lineFade); + _programObject->setUniform(_uniformCache.lineFade, fade); glLineWidth(_appearance.lineWidth); @@ -483,7 +547,7 @@ void RenderableSmallBody::updateBuffers() { ); glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)0); // stride : 4*sizeof(GL_FLOAT) + 2*sizeof(GL_DOUBLE) + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(TrailVBOLayout), nullptr); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(TrailVBOLayout), (GLvoid*)(4*sizeof(GL_FLOAT)) ); diff --git a/modules/space/rendering/renderablesmallbody.h b/modules/space/rendering/renderablesmallbody.h index 4f0ca15e81..1d73fe7456 100644 --- a/modules/space/rendering/renderablesmallbody.h +++ b/modules/space/rendering/renderablesmallbody.h @@ -115,8 +115,6 @@ private: properties::StringProperty _path; properties::UIntProperty _nSegments; - properties::DoubleProperty _lineFade; - RenderableTrail::Appearance _appearance; glm::vec3 _position; diff --git a/modules/space/shaders/debrisViz_fs.glsl b/modules/space/shaders/debrisViz_fs.glsl index ada17beb95..d1d28f9804 100644 --- a/modules/space/shaders/debrisViz_fs.glsl +++ b/modules/space/shaders/debrisViz_fs.glsl @@ -63,10 +63,23 @@ Fragment getFragment() { vertexDistance_f += 1.0; } - float invert = 1.0 - vertexDistance_f; - float fade = clamp(invert * lineFade, 0.0, 1.0); + //float invert = 1.0 - vertexDistance_f; + //float fade = clamp(invert * lineFade, 0.0, 1.0); + float invert = pow((1.0 - vertexDistance_f), lineFade); + float fade = clamp(invert, 0.0, 1.0); + + // Currently even fully transparent lines can occlude other lines, thus we discard + // these fragments since debris and satellites are rendered so close to each other + if (fade < 0.05) { + discard; + } Fragment frag; + + // Use additive blending for some values to make the discarding less abrupt + if (fade < 0.15) { + frag.blend = BLEND_MODE_ADDITIVE; + } frag.color = vec4(color, fade * opacity); frag.depth = vs_position_w; frag.gPosition = viewSpacePosition; From fb2ae7f18aa237dd775c801878e826d5bed85c90 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Wed, 8 Jan 2020 16:48:57 +0100 Subject: [PATCH 105/214] Setup vislab module --- modules/vislab/CMakeLists.txt | 41 +++++++++++++++ .../rendering/renderabledistancelabel.cpp | 34 ++++++++++++ .../rendering/renderabledistancelabel.h | 43 +++++++++++++++ modules/vislab/vislabmodule.cpp | 40 ++++++++++++++ modules/vislab/vislabmodule.h | 52 +++++++++++++++++++ 5 files changed, 210 insertions(+) create mode 100644 modules/vislab/CMakeLists.txt create mode 100644 modules/vislab/rendering/renderabledistancelabel.cpp create mode 100644 modules/vislab/rendering/renderabledistancelabel.h create mode 100644 modules/vislab/vislabmodule.cpp create mode 100644 modules/vislab/vislabmodule.h diff --git a/modules/vislab/CMakeLists.txt b/modules/vislab/CMakeLists.txt new file mode 100644 index 0000000000..6b77ef5098 --- /dev/null +++ b/modules/vislab/CMakeLists.txt @@ -0,0 +1,41 @@ +########################################################################################## +# # +# OpenSpace # +# # +# Copyright (c) 2014-2020 # +# # +# Permission is hereby granted, free of charge, to any person obtaining a copy of this # +# software and associated documentation files (the "Software"), to deal in the Software # +# without restriction, including without limitation the rights to use, copy, modify, # +# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # +# permit persons to whom the Software is furnished to do so, subject to the following # +# conditions: # +# # +# The above copyright notice and this permission notice shall be included in all copies # +# or substantial portions of the Software. # +# # +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # +# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # +# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF # +# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE # +# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +########################################################################################## + +include(${OPENSPACE_CMAKE_EXT_DIR}/module_definition.cmake) + +set(HEADER_FILES +${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabledistancelabel.h +) +source_group("Header Files" FILES ${HEADER_FILES}) + +set(SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/rendering/renderabledistancelabel.cpp +) +source_group("Source Files" FILES ${SOURCE_FILES}) + +create_new_module( + "VisLab" + vislab_module + ${HEADER_FILES} ${SOURCE_FILES} +) \ No newline at end of file diff --git a/modules/vislab/rendering/renderabledistancelabel.cpp b/modules/vislab/rendering/renderabledistancelabel.cpp new file mode 100644 index 0000000000..4e8102e84b --- /dev/null +++ b/modules/vislab/rendering/renderabledistancelabel.cpp @@ -0,0 +1,34 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { + +//RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictionary) +//{ +//} + +} // namespace openspace + diff --git a/modules/vislab/rendering/renderabledistancelabel.h b/modules/vislab/rendering/renderabledistancelabel.h new file mode 100644 index 0000000000..8b38cc20ef --- /dev/null +++ b/modules/vislab/rendering/renderabledistancelabel.h @@ -0,0 +1,43 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + + +#ifndef __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ +#define __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ + +namespace openspace { + + +class RenderableDistanceLabel { +public: + // RenderableDistanceLabel(const ghoul::Dictionary& dictionary); + +private: +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ + + diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp new file mode 100644 index 0000000000..6cae50809c --- /dev/null +++ b/modules/vislab/vislabmodule.cpp @@ -0,0 +1,40 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +namespace openspace { +constexpr const char* _loggerCat = "VisLab Module"; + +VisLabModule::VisLabModule() : OpenSpaceModule(Name) { +} + +void VisLabModule::internalInitialize(const ghoul::Dictionary&) { + //auto renderableFactory = FactoryManager::ref().factory(); + //ghoul_assert(renderableFactory, "No renderable factory existed"); + + //renderableFactory->registerClass("RenderableDistanceLabel"); +} + +} // namespace openspace diff --git a/modules/vislab/vislabmodule.h b/modules/vislab/vislabmodule.h new file mode 100644 index 0000000000..045932d099 --- /dev/null +++ b/modules/vislab/vislabmodule.h @@ -0,0 +1,52 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_VISLAB___VISLABMODULE___H__ +#define __OPENSPACE_MODULE_VISLAB___VISLABMODULE___H__ + + +#include +#include +#include +#include +#include + +#include + +namespace openspace { + +class VisLabModule : public OpenSpaceModule { +public: + constexpr static const char* Name = "VisLab"; + + VisLabModule(); + +private: + void internalInitialize(const ghoul::Dictionary&) override; + +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_VISLAB___VISLABMODULE___H__ From 4ffc5595d961917eae6eaeae8379ee52f90a8c67 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Thu, 9 Jan 2020 09:59:38 +0100 Subject: [PATCH 106/214] WIP inheriting from renderablelabels --- modules/base/rendering/renderablelabels.cpp | 50 +++++++++---------- modules/base/rendering/renderablelabels.h | 1 - .../rendering/renderabledistancelabel.cpp | 49 +++++++++++++++++- .../rendering/renderabledistancelabel.h | 11 +++- modules/vislab/vislabmodule.cpp | 6 +-- 5 files changed, 84 insertions(+), 33 deletions(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index d5a51afea1..ece6cfe978 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -701,31 +701,31 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { //} } -void RenderableLabels::update(const UpdateData& data) { - - if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { - - // Calculate distance - SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); - RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); - double myDistance = nodeline->getDistance(); - - // format string - float scale = getUnit(Kilometer); - std::string distanceText = std::to_string(std::round(myDistance / scale)); - int pos = distanceText.find("."); - std::string subStr = distanceText.substr(pos); - distanceText.erase(pos, subStr.size()); - std::string finalText = distanceText + " " + KilometerUnit; - setLabelText(finalText); - - // Update placement of label with transformation matrix - glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); - glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); - glm::dvec3 goalPos = start + (end - start) / 2.0; - _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); - } -} +//void RenderableLabels::update(const UpdateData& data) { +// +// if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { +// +// // Calculate distance +// SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); +// RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); +// double myDistance = nodeline->getDistance(); +// +// // format string +// float scale = getUnit(Kilometer); +// std::string distanceText = std::to_string(std::round(myDistance / scale)); +// int pos = distanceText.find("."); +// std::string subStr = distanceText.substr(pos); +// distanceText.erase(pos, subStr.size()); +// std::string finalText = distanceText + " " + KilometerUnit; +// setLabelText(finalText); +// +// // Update placement of label with transformation matrix +// glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); +// glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); +// glm::dvec3 goalPos = start + (end - start) / 2.0; +// _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); +// } +//} void RenderableLabels::setLabelText(const std::string & newText) { _labelText = newText; diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 7b97b80a98..03c7ccb0e6 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -64,7 +64,6 @@ public: bool isReady() const override; void render(const RenderData& data, RendererTasks& rendererTask) override; - void update(const UpdateData& data) override; static documentation::Documentation Documentation(); diff --git a/modules/vislab/rendering/renderabledistancelabel.cpp b/modules/vislab/rendering/renderabledistancelabel.cpp index 4e8102e84b..41244f8708 100644 --- a/modules/vislab/rendering/renderabledistancelabel.cpp +++ b/modules/vislab/rendering/renderabledistancelabel.cpp @@ -24,10 +24,55 @@ #include +#include +//#include + namespace openspace { -//RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictionary) -//{ +documentation::Documentation RenderableDistanceLabel::Documentation() { + using namespace documentation; + return { + "Renderable Distance Label", + "vislab_renderable_distance_label", + { + } + }; +} + +RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictionary) + : RenderableLabels(dictionary) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "RenderableDistanceLabel" + ); +} + +//void RenderableDistanceLabel::update(const UpdateData& data) { +// +// if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { +// +// // Calculate distance +// SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); +// RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); +// double myDistance = nodeline->getDistance(); +// +// // format string +// float scale = getUnit(Kilometer); +// std::string distanceText = std::to_string(std::round(myDistance / scale)); +// int pos = distanceText.find("."); +// std::string subStr = distanceText.substr(pos); +// distanceText.erase(pos, subStr.size()); +// std::string finalText = distanceText + " " + KilometerUnit; +// setLabelText(finalText); +// +// // Update placement of label with transformation matrix +// glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); +// glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); +// glm::dvec3 goalPos = start + (end - start) / 2.0; +// _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); +// } //} } // namespace openspace diff --git a/modules/vislab/rendering/renderabledistancelabel.h b/modules/vislab/rendering/renderabledistancelabel.h index 8b38cc20ef..7cb9e4fabb 100644 --- a/modules/vislab/rendering/renderabledistancelabel.h +++ b/modules/vislab/rendering/renderabledistancelabel.h @@ -26,12 +26,19 @@ #ifndef __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ #define __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ +#include + + namespace openspace { +namespace documentation { struct Documentation; } -class RenderableDistanceLabel { +class RenderableDistanceLabel : public RenderableLabels { public: - // RenderableDistanceLabel(const ghoul::Dictionary& dictionary); + RenderableDistanceLabel(const ghoul::Dictionary& dictionary); + + // void update(const UpdateData& data) override; + static documentation::Documentation Documentation(); private: }; diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp index 6cae50809c..fcb8a19d2b 100644 --- a/modules/vislab/vislabmodule.cpp +++ b/modules/vislab/vislabmodule.cpp @@ -31,10 +31,10 @@ VisLabModule::VisLabModule() : OpenSpaceModule(Name) { } void VisLabModule::internalInitialize(const ghoul::Dictionary&) { - //auto renderableFactory = FactoryManager::ref().factory(); - //ghoul_assert(renderableFactory, "No renderable factory existed"); + auto renderableFactory = FactoryManager::ref().factory(); + ghoul_assert(renderableFactory, "No renderable factory existed"); - //renderableFactory->registerClass("RenderableDistanceLabel"); + renderableFactory->registerClass("RenderableDistanceLabel"); } } // namespace openspace From 07cc8d4a4f8ad2664e30b28b9ec4cf55b67e1603 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Thu, 9 Jan 2020 12:01:00 +0100 Subject: [PATCH 107/214] Working distance label --- modules/base/rendering/renderablelabels.cpp | 42 ---------- modules/base/rendering/renderablelabels.h | 15 ++-- .../rendering/renderabledistancelabel.cpp | 80 +++++++++++++------ .../rendering/renderabledistancelabel.h | 5 +- 4 files changed, 64 insertions(+), 78 deletions(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index ece6cfe978..d5f84a2427 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -46,11 +46,6 @@ #include #include -#include -#include -#include -#include - namespace { constexpr const char* _loggerCat = "base::RenderableLabels"; @@ -181,12 +176,6 @@ namespace { "Fade-In/-Out ending speed." }; - constexpr openspace::properties::Property::PropertyInfo NodeLineInfo = { - "NodeLine", - "Node Line", - "Optional property to track a nodeline. When tracking the label text will be updating the distance " - "from the nodeline start and end. " - }; } // namespace namespace openspace { @@ -327,7 +316,6 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) , _pixelSizeControl(PixelSizeControlInfo, false) , _enableFadingEffect(EnableFadingEffectInfo, false) , _labelText(LabelTextInfo) - , _nodeLine(NodeLineInfo) , _fadeStartDistance(FadeStartDistInfo, 1.f, 0.f, 100.f) , _fadeEndDistance(FadeEndDistInfo, 1.f, 0.f, 100.f) , _fadeStartSpeed(FadeStartSpeedInfo, 1.f, 1.f, 100.f) @@ -460,11 +448,6 @@ RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary) _fadeStartDistance = dictionary.value(FadeStartDistInfo.identifier); } - if (dictionary.hasKey(NodeLineInfo.identifier)) { - _nodeLine = dictionary.value(NodeLineInfo.identifier); - addProperty(_nodeLine); - } - addProperty(_fadeStartDistance); _fadeStartUnitOption.addOption(Meter, MeterUnit); @@ -701,31 +684,6 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { //} } -//void RenderableLabels::update(const UpdateData& data) { -// -// if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { -// -// // Calculate distance -// SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); -// RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); -// double myDistance = nodeline->getDistance(); -// -// // format string -// float scale = getUnit(Kilometer); -// std::string distanceText = std::to_string(std::round(myDistance / scale)); -// int pos = distanceText.find("."); -// std::string subStr = distanceText.substr(pos); -// distanceText.erase(pos, subStr.size()); -// std::string finalText = distanceText + " " + KilometerUnit; -// setLabelText(finalText); -// -// // Update placement of label with transformation matrix -// glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); -// glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); -// glm::dvec3 goalPos = start + (end - start) / 2.0; -// _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); -// } -//} void RenderableLabels::setLabelText(const std::string & newText) { _labelText = newText; diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 03c7ccb0e6..4546ad9211 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -72,7 +72,12 @@ public: protected: properties::OptionProperty _blendMode; -private: + float getUnit(int unit) const; + + // Data may require some type of transformation prior the spice transformation being + // applied. + glm::dmat4 _transformationMatrix = glm::dmat4(1.0); + enum Unit { Meter = 0, Kilometer, @@ -88,6 +93,7 @@ private: GigalightYears }; +private: void renderLabels(const RenderData& data, const glm::dmat4& modelViewProjectionMatrix, const glm::dvec3& orthoRight, const glm::dvec3& orthoUp, float fadeInVariable); @@ -96,8 +102,6 @@ private: float linearSmoothStepFunc(float x, float startX, float endX, float sUnit, float eUnit) const; - float getUnit(int unit) const; - properties::Vec4Property _labelColor; properties::FloatProperty _labelSize; properties::FloatProperty _fontSize; @@ -106,7 +110,6 @@ private: properties::BoolProperty _pixelSizeControl; properties::BoolProperty _enableFadingEffect; properties::StringProperty _labelText; - properties::StringProperty _nodeLine; properties::FloatProperty _fadeStartDistance; properties::FloatProperty _fadeEndDistance; properties::FloatProperty _fadeStartSpeed; @@ -123,10 +126,6 @@ private: std::string _labelFile; std::string _colorOptionString; std::string _datavarSizeOptionString; - - // Data may require some type of transformation prior the spice transformation being - // applied. - glm::dmat4 _transformationMatrix = glm::dmat4(1.0); }; } // namespace openspace diff --git a/modules/vislab/rendering/renderabledistancelabel.cpp b/modules/vislab/rendering/renderabledistancelabel.cpp index 41244f8708..03147ac090 100644 --- a/modules/vislab/rendering/renderabledistancelabel.cpp +++ b/modules/vislab/rendering/renderabledistancelabel.cpp @@ -24,8 +24,24 @@ #include +#include #include -//#include +#include +#include +#include +#include +#include + +namespace { + constexpr const char* _loggerCat = "RenderableDistanceLabel"; + + constexpr openspace::properties::Property::PropertyInfo NodeLineInfo = { + "NodeLine", + "Node Line", + "Property to track a nodeline. When tracking the label text will be updating the distance " + "from the nodeline start and end. " + }; +} namespace openspace { @@ -35,45 +51,57 @@ documentation::Documentation RenderableDistanceLabel::Documentation() { "Renderable Distance Label", "vislab_renderable_distance_label", { + { + NodeLineInfo.identifier, + new StringVerifier, + Optional::No, + NodeLineInfo.description + }, } }; } RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictionary) : RenderableLabels(dictionary) + , _nodeLine(NodeLineInfo) { documentation::testSpecificationAndThrow( Documentation(), dictionary, "RenderableDistanceLabel" ); + + if (dictionary.hasKey(NodeLineInfo.identifier)) { + _nodeLine = dictionary.value(NodeLineInfo.identifier); + addProperty(_nodeLine); + } } -//void RenderableDistanceLabel::update(const UpdateData& data) { -// -// if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { -// -// // Calculate distance -// SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); -// RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); -// double myDistance = nodeline->getDistance(); -// -// // format string -// float scale = getUnit(Kilometer); -// std::string distanceText = std::to_string(std::round(myDistance / scale)); -// int pos = distanceText.find("."); -// std::string subStr = distanceText.substr(pos); -// distanceText.erase(pos, subStr.size()); -// std::string finalText = distanceText + " " + KilometerUnit; -// setLabelText(finalText); -// -// // Update placement of label with transformation matrix -// glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); -// glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); -// glm::dvec3 goalPos = start + (end - start) / 2.0; -// _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); -// } -//} +void RenderableDistanceLabel::update(const UpdateData& data) { + + if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { + + // Calculate distance + SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); + RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); + double myDistance = nodeline->getDistance(); + + // format string + float scale = getUnit(Kilometer); + std::string distanceText = std::to_string(std::round(myDistance / scale)); + int pos = distanceText.find("."); + std::string subStr = distanceText.substr(pos); + distanceText.erase(pos, subStr.size()); + std::string finalText = distanceText + " Km"; + setLabelText(finalText); + + // Update placement of label with transformation matrix + glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); + glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); + glm::dvec3 goalPos = start + (end - start) / 2.0; + _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); + } +} } // namespace openspace diff --git a/modules/vislab/rendering/renderabledistancelabel.h b/modules/vislab/rendering/renderabledistancelabel.h index 7cb9e4fabb..65a34a6525 100644 --- a/modules/vislab/rendering/renderabledistancelabel.h +++ b/modules/vislab/rendering/renderabledistancelabel.h @@ -28,7 +28,6 @@ #include - namespace openspace { namespace documentation { struct Documentation; } @@ -37,9 +36,11 @@ class RenderableDistanceLabel : public RenderableLabels { public: RenderableDistanceLabel(const ghoul::Dictionary& dictionary); - // void update(const UpdateData& data) override; + void update(const UpdateData& data) override; static documentation::Documentation Documentation(); + properties::StringProperty _nodeLine; + private: }; From b99bcf9490dc5793256559de8c04c05b734a89e4 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Fri, 10 Jan 2020 00:22:49 +0100 Subject: [PATCH 108/214] Adding validation check for _start and _end --- modules/base/rendering/renderablenodeline.cpp | 33 +++++++++++++++++-- modules/base/rendering/renderablenodeline.h | 13 +++----- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/modules/base/rendering/renderablenodeline.cpp b/modules/base/rendering/renderablenodeline.cpp index 36fbbe5a50..8d809df5f4 100644 --- a/modules/base/rendering/renderablenodeline.cpp +++ b/modules/base/rendering/renderablenodeline.cpp @@ -34,22 +34,26 @@ #include #include #include +#include #include namespace { + constexpr const char* _loggerCat = "RenderableNodeLine"; constexpr const char* ProgramName = "NodeLineProgram"; constexpr const char* Root = "Root"; constexpr openspace::properties::Property::PropertyInfo StartNodeInfo = { "StartNode", "Start Node", - "The identifier of the node the line starts from. Defaults to 'Root' if not specified. " + "The identifier of the node the line starts from. " + "Defaults to 'Root' if not specified. " }; constexpr openspace::properties::Property::PropertyInfo EndNodeInfo = { "EndNode", "End Node", - "The identifier of the node the line ends at. Defaults to 'Root' if not specified. " + "The identifier of the node the line ends at. " + "Defaults to 'Root' if not specified. " }; constexpr openspace::properties::Property::PropertyInfo LineColorInfo = { @@ -129,6 +133,9 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) _lineWidth = static_cast(dictionary.value(LineWidthInfo.identifier)); } + _start.onChange([&]() { validateNodes(); }); + _end.onChange([&]() { validateNodes(); }); + addProperty(_start); addProperty(_end); addProperty(_lineColor); @@ -141,6 +148,16 @@ double RenderableNodeLine::getDistance() return glm::distance(_startPos, _endPos); } +const std::string RenderableNodeLine::getStart() +{ + return _start.value(); +} + +const std::string RenderableNodeLine::getEnd() +{ + return _end.value(); +} + void RenderableNodeLine::initializeGL() { _program = BaseModule::ProgramObjectManager.request( ProgramName, @@ -294,6 +311,18 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { } } +void RenderableNodeLine::validateNodes() +{ + if (!global::renderEngine.scene()->sceneGraphNode(_start)) { + LERROR(fmt::format("There is no scenegraph node with id {}, defaults to 'Root'", _start)); + _start = Root; + } + if (!global::renderEngine.scene()->sceneGraphNode(_end)) { + LERROR(fmt::format("There is no scenegraph node with id {}, defaults to 'Root'", _end)); + _end = Root; + } +} + /* Returns a position that is relative to the current anchor node. This is a method to handle precision diff --git a/modules/base/rendering/renderablenodeline.h b/modules/base/rendering/renderablenodeline.h index 2792f986d5..53cd54a860 100644 --- a/modules/base/rendering/renderablenodeline.h +++ b/modules/base/rendering/renderablenodeline.h @@ -27,7 +27,6 @@ #include -#include #include #include #include @@ -52,16 +51,11 @@ public: static documentation::Documentation Documentation(); - // Identifier of the optional distance label - std::string _distanceLabelId; - //SceneGraphNode* distanceLabelNode = nullptr; - //RenderableLabels* distanceLabel; - // Get the distance between the start and end node double getDistance(); - properties::StringProperty _start; - properties::StringProperty _end; + const std::string getStart(); + const std::string getEnd(); private: void initializeGL() override; @@ -70,6 +64,7 @@ private: bool isReady() const override; void updateVertexData(); void render(const RenderData& data, RendererTasks& rendererTask) override; + void validateNodes(); void unbindGL(); void bindGL(); @@ -87,6 +82,8 @@ private: glm::dvec3 _startPos; glm::dvec3 _endPos; + properties::StringProperty _start; + properties::StringProperty _end; properties::Vec3Property _lineColor; properties::FloatProperty _lineWidth; }; From 311be5ac6abda566eb47a73b7eac4ea95e9f5e61 Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Fri, 10 Jan 2020 00:25:37 +0100 Subject: [PATCH 109/214] Adding nullptr check, error throwing to log, cleanup --- modules/vislab/CMakeLists.txt | 2 +- .../rendering/renderabledistancelabel.cpp | 28 +++++++++++++------ .../rendering/renderabledistancelabel.h | 7 ++--- modules/vislab/vislabmodule.cpp | 1 - 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/modules/vislab/CMakeLists.txt b/modules/vislab/CMakeLists.txt index 6b77ef5098..1e75a257b2 100644 --- a/modules/vislab/CMakeLists.txt +++ b/modules/vislab/CMakeLists.txt @@ -38,4 +38,4 @@ create_new_module( "VisLab" vislab_module ${HEADER_FILES} ${SOURCE_FILES} -) \ No newline at end of file +) diff --git a/modules/vislab/rendering/renderabledistancelabel.cpp b/modules/vislab/rendering/renderabledistancelabel.cpp index 03147ac090..3ff5082758 100644 --- a/modules/vislab/rendering/renderabledistancelabel.cpp +++ b/modules/vislab/rendering/renderabledistancelabel.cpp @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -63,7 +64,7 @@ documentation::Documentation RenderableDistanceLabel::Documentation() { RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictionary) : RenderableLabels(dictionary) - , _nodeLine(NodeLineInfo) + , _nodelineId(NodeLineInfo) { documentation::testSpecificationAndThrow( Documentation(), @@ -72,21 +73,28 @@ RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictio ); if (dictionary.hasKey(NodeLineInfo.identifier)) { - _nodeLine = dictionary.value(NodeLineInfo.identifier); - addProperty(_nodeLine); + _nodelineId = dictionary.value(NodeLineInfo.identifier); + addProperty(_nodelineId); } } void RenderableDistanceLabel::update(const UpdateData& data) { - if (global::renderEngine.scene()->sceneGraphNode(_nodeLine)) { + SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodelineId); + + if (nodelineNode && !_errorThrown) { // Calculate distance - SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodeLine); RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); + if (!nodeline) { + LERROR("Expected renderable to be of type 'RenderableNodeLine'"); + _errorThrown = true; + return; + } + double myDistance = nodeline->getDistance(); - // format string + // Format string float scale = getUnit(Kilometer); std::string distanceText = std::to_string(std::round(myDistance / scale)); int pos = distanceText.find("."); @@ -96,11 +104,15 @@ void RenderableDistanceLabel::update(const UpdateData& data) { setLabelText(finalText); // Update placement of label with transformation matrix - glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->_start)->worldPosition(); - glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->_end)->worldPosition(); + glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->getStart())->worldPosition(); + glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->getEnd())->worldPosition(); glm::dvec3 goalPos = start + (end - start) / 2.0; _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); } + else if (!_errorThrown) { + LERROR(fmt::format("There is no scenegraph node with id {}", _nodelineId)); + _errorThrown = true; + } } } // namespace openspace diff --git a/modules/vislab/rendering/renderabledistancelabel.h b/modules/vislab/rendering/renderabledistancelabel.h index 65a34a6525..d6eee298f4 100644 --- a/modules/vislab/rendering/renderabledistancelabel.h +++ b/modules/vislab/rendering/renderabledistancelabel.h @@ -39,13 +39,10 @@ public: void update(const UpdateData& data) override; static documentation::Documentation Documentation(); - properties::StringProperty _nodeLine; - -private: + properties::StringProperty _nodelineId; + bool _errorThrown = false; }; } // namespace openspace #endif // __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ - - diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp index fcb8a19d2b..5c35c536bb 100644 --- a/modules/vislab/vislabmodule.cpp +++ b/modules/vislab/vislabmodule.cpp @@ -25,7 +25,6 @@ #include namespace openspace { -constexpr const char* _loggerCat = "VisLab Module"; VisLabModule::VisLabModule() : OpenSpaceModule(Name) { } From 18f012dd625e42b0a3b39a3edd654bb5cec05f8c Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Fri, 10 Jan 2020 00:33:55 +0100 Subject: [PATCH 110/214] Moving includes to cpp, removing unused logmanager --- modules/vislab/vislabmodule.cpp | 5 +++++ modules/vislab/vislabmodule.h | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp index 5c35c536bb..ac49e60b77 100644 --- a/modules/vislab/vislabmodule.cpp +++ b/modules/vislab/vislabmodule.cpp @@ -24,6 +24,11 @@ #include +#include +#include +#include +#include + namespace openspace { VisLabModule::VisLabModule() : OpenSpaceModule(Name) { diff --git a/modules/vislab/vislabmodule.h b/modules/vislab/vislabmodule.h index 045932d099..7e43152cac 100644 --- a/modules/vislab/vislabmodule.h +++ b/modules/vislab/vislabmodule.h @@ -27,12 +27,6 @@ #include -#include -#include -#include -#include - -#include namespace openspace { From d125694062c5d68b9bbf0050961b187f85057513 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 10 Jan 2020 16:16:42 +0100 Subject: [PATCH 111/214] Reset SGCT to a commit that exists --- apps/OpenSpace/ext/sgct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/OpenSpace/ext/sgct b/apps/OpenSpace/ext/sgct index 9f62068efb..25c8d30bde 160000 --- a/apps/OpenSpace/ext/sgct +++ b/apps/OpenSpace/ext/sgct @@ -1 +1 @@ -Subproject commit 9f62068efb344d37f1c1e2bf0303f838ef7da9f3 +Subproject commit 25c8d30bde216066840d197e4443def196c70e17 From 1ac68f8236dc25f9aaebab7e5b8f082eac8c7331 Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 10 Jan 2020 15:22:26 -0700 Subject: [PATCH 112/214] Fixed profile parser so it gets the profile input file first --- include/openspace/engine/openspaceengine.h | 1 + scripts/convertProfileToScene.lua | 9 +++-- src/engine/openspaceengine.cpp | 47 +++++++++++++--------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index fb0ad85061..7d7114da0a 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -106,6 +106,7 @@ private: void runGlobalCustomizationScripts(); void configureLogging(); + std::string generateFilePath(std::string openspaceRelativePath); std::unique_ptr _scene; std::unique_ptr _assetManager; diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua index 1321dd52a5..bc1d34de86 100644 --- a/scripts/convertProfileToScene.lua +++ b/scripts/convertProfileToScene.lua @@ -464,10 +464,11 @@ parsingSections = { {section = "MarkNodes", func = parseMarkNodes} } -profileFilename = openspace.profile.getFilename() -profilePath = openspace.profile.getPath() +profilePathIn = openspace.profile.getProfileInputPath() +scenePathOut = openspace.profile.getSceneOutputPath() -assetOut = profilePath..".scene" +profileIn = profilePathIn..".profile" +assetOut = scenePathOut..".scene" -local resultTable = parseProfile(profilePath) +local resultTable = parseProfile(profileIn) generateAsset(resultTable, assetOut) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 4e858562ed..43578a1f58 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -301,24 +301,8 @@ void OpenSpaceEngine::initialize() { global::configuration.profile)); ghoul::lua::LuaState lState; - // Generate path to temp dir where output .scene file will reside. - // Needs to handle either windows (which seems to require double back-slashes) - // or unix path slashes. - std::string outputScenePath = absPath("${TEMPORARY}"); - const std::string search = "\\"; - const std::string replace = "\\\\"; - if (outputScenePath.find(search) != std::string::npos) { - size_t start_pos = 0; - while((start_pos = outputScenePath.find(search, start_pos)) != std::string::npos) { - outputScenePath.replace(start_pos, search.length(), replace); - start_pos += replace.length(); - } - outputScenePath.append(replace); - } - else { - outputScenePath.append("/"); - } - outputScenePath.append(global::configuration.profile); + std::string inputProfilePath = generateFilePath("${BASE}/data/assets"); + std::string outputScenePath = generateFilePath("${TEMPORARY}"); std::string setProfileFilenameInLuaState = fmt::format(R"( openspace = {{}} @@ -326,11 +310,14 @@ void OpenSpaceEngine::initialize() { function openspace.profile.getFilename() return "{}.profile" end - function openspace.profile.getPath() + function openspace.profile.getProfileInputPath() + return "{}" + end + function openspace.profile.getSceneOutputPath() return "{}" end )", - global::configuration.profile, outputScenePath + global::configuration.profile, inputProfilePath, outputScenePath ); ghoul::lua::runScript(lState, setProfileFilenameInLuaState); @@ -385,6 +372,26 @@ void OpenSpaceEngine::initialize() { LTRACE("OpenSpaceEngine::initialize(end)"); } +std::string OpenSpaceEngine::generateFilePath(std::string openspaceRelativePath) { + std::string path = absPath(openspaceRelativePath); + // Needs to handle either windows (which seems to require double back-slashes) + // or unix path slashes. + const std::string search = "\\"; + const std::string replace = "\\\\"; + if (path.find(search) != std::string::npos) { + size_t start_pos = 0; + while ((start_pos = path.find(search, start_pos)) != std::string::npos) { + path.replace(start_pos, search.length(), replace); + start_pos += replace.length(); + } + path.append(replace); + } + else { + path.append("/"); + } + return path.append(global::configuration.profile); +} + void OpenSpaceEngine::initializeGL() { LTRACE("OpenSpaceEngine::initializeGL(begin)"); From 76240c3eddb5b0345a4ab33a2769d4e1904f53dd Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 11 Jan 2020 21:07:38 +0100 Subject: [PATCH 113/214] Coding style updates --- data/assets/default.scene | 2 +- .../globebrowsing/shaders/renderer_fs.glsl | 6 +- modules/globebrowsing/shaders/rings_fs.glsl | 7 +- .../globebrowsing/shaders/rings_geom_fs.glsl | 3 +- modules/globebrowsing/shaders/rings_vs.glsl | 6 +- modules/globebrowsing/src/renderableglobe.cpp | 4 +- modules/globebrowsing/src/ringscomponent.h | 126 +++++++------- modules/globebrowsing/src/shadowcomponent.cpp | 162 ++++++------------ modules/globebrowsing/src/shadowcomponent.h | 13 +- 9 files changed, 131 insertions(+), 198 deletions(-) diff --git a/data/assets/default.scene b/data/assets/default.scene index ab9d0de977..c6d3e2523c 100644 --- a/data/assets/default.scene +++ b/data/assets/default.scene @@ -9,7 +9,7 @@ asset.onInitialize(function () openspace.globebrowsing.goToGeo("Earth", 58.5877, 16.1924, 20000000) - openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun"}) + openspace.markInterestingNodes({ "Earth", "Mars", "Moon", "Sun" }) end) asset.onDeinitialize(function () diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index 082f8630aa..e7633d405e 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -267,12 +267,12 @@ Fragment getFragment() { #if SHADOW_MAPPING_ENABLED float shadow = 1.0; - if ( shadowCoords.w > 1 ) { + if (shadowCoords.w > 1) { vec4 normalizedShadowCoords = shadowCoords; normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w); normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - + float sum = 0; for (int i = 0; i < nShadowSamples; ++i) { sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); @@ -285,7 +285,7 @@ Fragment getFragment() { sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); } sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.f * nShadowSamples + 1.f); + shadow = sum / (8.0 * nShadowSamples + 1.f); } frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow; #endif diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 4eb8ce25b6..12ba8b4e74 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -50,8 +50,9 @@ Fragment getFragment() { float radius = length(st); // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) + if (radius > 1.0) { discard; + } // Remapping the texture coordinates // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] @@ -61,7 +62,7 @@ Fragment getFragment() { if (texCoord < 0.f || texCoord > 1.f) { discard; } - + vec4 diffuse = texture(ringTexture, texCoord); float colorValue = length(diffuse.rgb); // times 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want @@ -90,7 +91,7 @@ Fragment getFragment() { sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); } sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.f * nShadowSamples + 1.f); + shadow = sum / (8.0 * nShadowSamples + 1.f); } // The normal for the one plane depends on whether we are dealing diff --git a/modules/globebrowsing/shaders/rings_geom_fs.glsl b/modules/globebrowsing/shaders/rings_geom_fs.glsl index 211d17d596..d7ec721368 100644 --- a/modules/globebrowsing/shaders/rings_geom_fs.glsl +++ b/modules/globebrowsing/shaders/rings_geom_fs.glsl @@ -39,8 +39,9 @@ Fragment getFragment() { float radius = length(st); // We only want to consider ring-like objects so we need to discard everything else - if (radius > 1.0) + if (radius > 1.0) { discard; + } // Remapping the texture coordinates // Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y] diff --git a/modules/globebrowsing/shaders/rings_vs.glsl b/modules/globebrowsing/shaders/rings_vs.glsl index dfe33ed905..83c4d4510e 100644 --- a/modules/globebrowsing/shaders/rings_vs.glsl +++ b/modules/globebrowsing/shaders/rings_vs.glsl @@ -41,17 +41,13 @@ uniform dmat4 modelViewProjectionMatrix; // where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1] uniform dmat4 shadowMatrix; - void main() { vs_st = in_st; - dvec4 positionClipSpace = modelViewProjectionMatrix * - dvec4(in_position, 0.0, 1.0); + dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0); vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace)); shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0)); - vs_screenSpaceDepth = positionClipSpaceZNorm.w; - gl_Position = positionClipSpaceZNorm; } diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 9584a5816a..ff436a2f9e 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -1350,7 +1350,9 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& } void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& data, - const ShadowComponent::ShadowMapData& shadowData, const bool renderGeomOnly) { + const ShadowComponent::ShadowMapData& shadowData, + bool renderGeomOnly) +{ //PerfMeasure("locally"); const TileIndex& tileIndex = chunk.tileIndex; ghoul::opengl::ProgramObject& program = *_localRenderer.program; diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index f2e277b3a4..b42313e692 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -38,80 +38,74 @@ #include #include -namespace ghoul { - class Dictionary; -} - +namespace ghoul { class Dictionary; } namespace ghoul::filesystem { class File; } - -namespace ghoul::opengl { - class ProgramObject; -} // namespace ghoul::opengl +namespace ghoul::opengl { class ProgramObject; } namespace openspace { struct RenderData; struct UpdateData; - namespace documentation { struct Documentation; } +namespace documentation { struct Documentation; } - class RingsComponent : public properties::PropertyOwner { - public: - enum RenderPass { - GeometryOnly, - GeometryAndShading - }; - public: - RingsComponent(const ghoul::Dictionary& dictionary); - - void initialize(); - void initializeGL(); - void deinitializeGL(); - - bool isReady() const; - - void draw( - const RenderData& data, - const RingsComponent::RenderPass renderPass, - const ShadowComponent::ShadowMapData& shadowData = {} - ); - void update(const UpdateData& data); - - static documentation::Documentation Documentation(); - - bool isEnabled() const; - - private: - void loadTexture(); - void createPlane(); - - properties::StringProperty _texturePath; - properties::FloatProperty _size; - properties::Vec2Property _offset; - properties::FloatProperty _nightFactor; - properties::FloatProperty _transparency; - properties::BoolProperty _enabled; - properties::FloatProperty _zFightingPercentage; - properties::IntProperty _nShadowSamples; - - std::unique_ptr _shader; - std::unique_ptr _geometryOnlyShader; - UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, - sunPosition, ringTexture, shadowMatrix, shadowMapTexture, - nShadowSamples, zFightingPercentage - ) _uniformCache; - UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture) - _geomUniformCache; - std::unique_ptr _texture; - std::unique_ptr _textureFile; - - ghoul::Dictionary _ringsDictionary; - bool _textureIsDirty = false; - GLuint _quad = 0; - GLuint _vertexPositionBuffer = 0; - bool _planeIsDirty = false; - - glm::vec3 _sunPosition; +class RingsComponent : public properties::PropertyOwner { +public: + enum RenderPass { + GeometryOnly, + GeometryAndShading }; + + RingsComponent(const ghoul::Dictionary& dictionary); + + void initialize(); + void initializeGL(); + void deinitializeGL(); + + bool isReady() const; + + void draw( + const RenderData& data, + const RingsComponent::RenderPass renderPass, + const ShadowComponent::ShadowMapData& shadowData = {} + ); + void update(const UpdateData& data); + + static documentation::Documentation Documentation(); + + bool isEnabled() const; + +private: + void loadTexture(); + void createPlane(); + + properties::StringProperty _texturePath; + properties::FloatProperty _size; + properties::Vec2Property _offset; + properties::FloatProperty _nightFactor; + properties::FloatProperty _transparency; + properties::BoolProperty _enabled; + properties::FloatProperty _zFightingPercentage; + properties::IntProperty _nShadowSamples; + + std::unique_ptr _shader; + std::unique_ptr _geometryOnlyShader; + UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, + sunPosition, ringTexture, shadowMatrix, shadowMapTexture, nShadowSamples, + zFightingPercentage + ) _uniformCache; + UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture) + _geomUniformCache; + std::unique_ptr _texture; + std::unique_ptr _textureFile; + + ghoul::Dictionary _ringsDictionary; + bool _textureIsDirty = false; + GLuint _quad = 0; + GLuint _vertexPositionBuffer = 0; + bool _planeIsDirty = false; + + glm::vec3 _sunPosition; +}; } // namespace openspace diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 2d16428728..2a2e5a9c7b 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -75,6 +75,8 @@ namespace { "The depth map size in pixels. You must entry the width and height values." }; + constexpr const GLfloat ShadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; + void checkFrameBufferState(const std::string& codePosition) { if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { LERROR("Framework not built. " + codePosition); @@ -232,7 +234,6 @@ void ShadowComponent::deinitializeGL() { glDeleteTextures(1, &_shadowDepthTexture); glDeleteTextures(1, &_positionInLightSpaceTexture); glDeleteFramebuffers(1, &_shadowFBO); - checkGLError("ShadowComponent::deinitializeGL() -- Deleted Textures and Framebuffer"); } RenderData ShadowComponent::begin(const RenderData& data) { @@ -245,15 +246,15 @@ RenderData ShadowComponent::begin(const RenderData& data) { glm::dvec3 lightDirection = glm::normalize(diffVector); // Percentage of the original light source distance (to avoid artifacts) - /*double multiplier = originalLightDistance * - (static_cast(_distanceFraction)/1.0E5);*/ + //double multiplier = originalLightDistance * + // (static_cast(_distanceFraction)/1.0E5); double multiplier = originalLightDistance * (static_cast(_distanceFraction) / 1E17); // New light source position - /*glm::dvec3 lightPosition = data.modelTransform.translation + - (lightDirection * multiplier);*/ + //glm::dvec3 lightPosition = data.modelTransform.translation + + // (lightDirection * multiplier); glm::dvec3 lightPosition = data.modelTransform.translation + (diffVector * multiplier); @@ -338,14 +339,14 @@ RenderData ShadowComponent::begin(const RenderData& data) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - /*glEnable(GL_CULL_FACE); - checkGLError("begin() -- enabled cull face"); - glCullFace(GL_FRONT); - checkGLError("begin() -- set cullface to front");*/ - /*glEnable(GL_POLYGON_OFFSET_FILL); - checkGLError("begin() -- enabled polygon offset fill"); - glPolygonOffset(2.5f, 10.0f); - checkGLError("begin() -- set values for polygon offset");*/ + //glEnable(GL_CULL_FACE); + //checkGLError("begin() -- enabled cull face"); + //glCullFace(GL_FRONT); + //checkGLError("begin() -- set cullface to front"); + //glEnable(GL_POLYGON_OFFSET_FILL); + //checkGLError("begin() -- enabled polygon offset fill"); + //glPolygonOffset(2.5f, 10.0f); + //checkGLError("begin() -- set values for polygon offset"); RenderData lightRenderData{ *_lightCamera, @@ -437,12 +438,13 @@ void ShadowComponent::end() { } } -void ShadowComponent::update(const UpdateData& /*data*/) { +void ShadowComponent::update(const UpdateData&) { _sunPosition = global::renderEngine.scene()->sceneGraphNode("Sun")->worldPosition(); glm::ivec2 renderingResolution = global::renderEngine.renderingResolution(); if (_dynamicDepthTextureRes && ((_shadowDepthTextureWidth != renderingResolution.x) || - (_shadowDepthTextureHeight != renderingResolution.y))) { + (_shadowDepthTextureHeight != renderingResolution.y))) + { _shadowDepthTextureWidth = renderingResolution.x * 2; _shadowDepthTextureHeight = renderingResolution.y * 2; updateDepthTexture(); @@ -453,8 +455,6 @@ void ShadowComponent::createDepthTexture() { glGenTextures(1, &_shadowDepthTexture); updateDepthTexture(); - checkGLError("createDepthTexture() -- Depth texture created"); - _shadowData.shadowDepthTexture = _shadowDepthTexture; //_shadowData.positionInLightSpaceTexture = _positionInLightSpaceTexture; } @@ -472,14 +472,13 @@ void ShadowComponent::createShadowFBO() { 0 ); - /*glFramebufferTexture( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - _positionInLightSpaceTexture, - 0 - );*/ + //glFramebufferTexture( + // GL_FRAMEBUFFER, + // GL_COLOR_ATTACHMENT0, + // _positionInLightSpaceTexture, + // 0 + //); - checkGLError("createShadowFBO() -- Created Shadow Framebuffer"); //GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE }; GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE }; glDrawBuffers(3, drawBuffers); @@ -492,15 +491,15 @@ void ShadowComponent::createShadowFBO() { void ShadowComponent::updateDepthTexture() { glBindTexture(GL_TEXTURE_2D, _shadowDepthTexture); - /* - glTexStorage2D( - GL_TEXTURE_2D, - 1, - GL_DEPTH_COMPONENT32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight - ); - */ + + //glTexStorage2D( + // GL_TEXTURE_2D, + // 1, + // GL_DEPTH_COMPONENT32F, + // _shadowDepthTextureWidth, + // _shadowDepthTextureHeight + //); + glTexImage2D( GL_TEXTURE_2D, 0, @@ -521,30 +520,30 @@ void ShadowComponent::updateDepthTexture() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - /*glGenTextures(1, &_positionInLightSpaceTexture); - glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGB32F, - _shadowDepthTextureWidth, - _shadowDepthTextureHeight, - 0, - GL_RGBA, - GL_FLOAT, - nullptr - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ + //glGenTextures(1, &_positionInLightSpaceTexture); + //glBindTexture(GL_TEXTURE_2D, _positionInLightSpaceTexture); + //glTexImage2D( + // GL_TEXTURE_2D, + // 0, + // GL_RGB32F, + // _shadowDepthTextureWidth, + // _shadowDepthTextureHeight, + // 0, + // GL_RGBA, + // GL_FLOAT, + // nullptr + //); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); } void ShadowComponent::saveDepthBuffer() { int size = _shadowDepthTextureWidth * _shadowDepthTextureHeight; - GLubyte* buffer = new GLubyte[size]; + std::vector buffer(size); glReadPixels( 0, @@ -553,10 +552,9 @@ void ShadowComponent::saveDepthBuffer() { _shadowDepthTextureHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, - buffer + buffer.data() ); - checkGLError("readDepthBuffer To buffer"); std::fstream ppmFile; ppmFile.open("depthBufferShadowMapping.ppm", std::fstream::out); @@ -582,9 +580,9 @@ void ShadowComponent::saveDepthBuffer() { std::cout << "Texture saved to file depthBufferShadowMapping.ppm\n\n"; } - delete[] buffer; + buffer.clear(); - GLfloat* bBuffer = new GLfloat[size * 4]; + std::vector bBuffer(size * 4); glReadBuffer(GL_COLOR_ATTACHMENT3); glReadPixels( @@ -594,10 +592,9 @@ void ShadowComponent::saveDepthBuffer() { _shadowDepthTextureHeight, GL_RGBA, GL_FLOAT, - bBuffer + bBuffer.data() ); - checkGLError("readPositionBuffer To buffer"); ppmFile.clear(); ppmFile.open("positionBufferShadowMapping.ppm", std::fstream::out); @@ -636,56 +633,7 @@ void ShadowComponent::saveDepthBuffer() { ppmFile.close(); - std::cout << "Texture saved to file positionBufferShadowMapping.ppm\n\n"; - } - - delete[] bBuffer; -} - -void ShadowComponent::checkGLError(const std::string & where) const { - const GLenum error = glGetError(); - switch (error) { - case GL_NO_ERROR: - break; - case GL_INVALID_ENUM: - LERRORC( - "OpenGL Invalid State", - fmt::format("Function {}: GL_INVALID_ENUM", where) - ); - break; - case GL_INVALID_VALUE: - LERRORC( - "OpenGL Invalid State", - fmt::format("Function {}: GL_INVALID_VALUE", where) - ); - break; - case GL_INVALID_OPERATION: - LERRORC( - "OpenGL Invalid State", - fmt::format( - "Function {}: GL_INVALID_OPERATION", where - )); - break; - case GL_INVALID_FRAMEBUFFER_OPERATION: - LERRORC( - "OpenGL Invalid State", - fmt::format( - "Function {}: GL_INVALID_FRAMEBUFFER_OPERATION", - where - ) - ); - break; - case GL_OUT_OF_MEMORY: - LERRORC( - "OpenGL Invalid State", - fmt::format("Function {}: GL_OUT_OF_MEMORY", where) - ); - break; - default: - LERRORC( - "OpenGL Invalid State", - fmt::format("Unknown error code: {0:x}", static_cast(error)) - ); + LINFO("Texture saved to file positionBufferShadowMapping.ppm"); } } diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index d1505a3e31..6be4766419 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -41,15 +41,9 @@ #include #include -namespace ghoul { - class Dictionary; -} - +namespace ghoul { class Dictionary; } namespace ghoul::filesystem { class File; } - -namespace ghoul::opengl { - class ProgramObject; -} // namespace ghoul::opengl +namespace ghoul::opengl { class ProgramObject; } namespace openspace { struct RenderData; @@ -57,8 +51,6 @@ namespace openspace { namespace documentation { struct Documentation; } -static const GLfloat ShadowBorder[] = { 1.f, 1.f, 1.f, 1.f }; - class ShadowComponent : public properties::PropertyOwner { public: struct ShadowMapData { @@ -94,7 +86,6 @@ private: // Debug void saveDepthBuffer(); - void checkGLError(const std::string & where) const; ShadowMapData _shadowData; From 4e75b161db2788b503a5f2a04336c510003b8d60 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Mon, 13 Jan 2020 08:27:13 +0100 Subject: [PATCH 114/214] Feature/internal touchhandling (#1038) * Removal of dead code and compiler warnings * Added basic internal touch This commit only adds the description-shell of the touch implementation * Added callbacks and first WIP of internal touch Makes use of the TouchInput/TouchInputs class in the TouchModule. Internally we cache the TouchInputs as an input deque and utilizes it for motion-vectors. This commit has bugs and issues, which will be worked upon. * Happy new year! Bumped year on branch-local files * Improvements to internal touch Almost reached feature-parity with tuio-handled touch events - Added most of the touch-logic to touchinteraction - Added helper functions to new TouchInput/TouchInputs classes * Naming changes to touch interface * Translate TUIO to TouchInput This commit translates TUIO messages to an internal TouchInput structure while still trying to keep feature parity. Removed TUIO-dependencies from many files. Changed behavior on tuioear to lock-swap its content. * Minor cleanup and fixes - Should fix touch roll - Simplified some functions * Build fix * Use internal touch in webgui - Added consume-logic to touch callbacks - Constrained touch-input to either webgui or 3D application as mouse is - This fixes some flaws with previous implementation, such as ghost inputs - Initialize touchmodule through init-functions rather than constructor * Cleanup of comments * Simplified touch classes Added timestamp through constructor meaning no more sprinkled timestamps Renamed TouchInputs to TouchInputHolder for clarity Added helper functions to the Holder to see if it holds an input Remade addInput as tryAddInput which return true on successful insertion + other cleanup * Code style cleanup and tweaks Removed avoidable zero-comparison for code clarity Cleanup of code style * Added comments to DirectInputSolver Clarifying the use of the DirectInputSolver. * Changes for coding style Change SGCT version to make it checkout-able * Clarify magic bitmask * const -> constexpr const for magic bitmasks Co-authored-by: Alexander Bock --- include/openspace/engine/globalscallbacks.h | 12 +- include/openspace/engine/openspaceengine.h | 6 +- include/openspace/util/camera.h | 1 - include/openspace/util/touch.h | 88 ++++ modules/touch/include/directinputsolver.h | 22 +- modules/touch/include/touchinteraction.h | 66 +-- modules/touch/include/touchmarker.h | 11 +- modules/touch/include/tuioear.h | 92 ++-- modules/touch/src/directinputsolver.cpp | 59 +-- modules/touch/src/touchinteraction.cpp | 557 ++++++++------------ modules/touch/src/touchmarker.cpp | 23 +- modules/touch/src/tuioear.cpp | 137 ++--- modules/touch/src/win32_touch.cpp | 240 ++++++--- modules/touch/touchmodule.cpp | 225 ++++---- modules/touch/touchmodule.h | 67 ++- modules/webbrowser/include/eventhandler.h | 8 +- modules/webbrowser/src/eventhandler.cpp | 158 ++++-- src/CMakeLists.txt | 2 + src/engine/globalscallbacks.cpp | 15 + src/engine/openspaceengine.cpp | 28 + src/rendering/framebufferrenderer.cpp | 9 - src/rendering/renderengine.cpp | 2 +- src/util/touch.cpp | 185 +++++++ 23 files changed, 1191 insertions(+), 822 deletions(-) create mode 100644 include/openspace/util/touch.h create mode 100644 src/util/touch.cpp diff --git a/include/openspace/engine/globalscallbacks.h b/include/openspace/engine/globalscallbacks.h index 856cc79f4f..08452a2af1 100644 --- a/include/openspace/engine/globalscallbacks.h +++ b/include/openspace/engine/globalscallbacks.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -53,6 +54,10 @@ std::vector>& gMouseB std::vector>& gMousePosition(); std::vector>& gMouseScrollWheel(); +std::vector>& gTouchDetected(); +std::vector>& gTouchUpdated(); +std::vector>& gTouchExit(); + } // namespace detail namespace callback { @@ -76,7 +81,12 @@ static std::vector>& mousePosition = detail::gMousePosition(); static std::vector>& mouseScrollWheel = detail::gMouseScrollWheel(); - +static std::vector>& touchDetected = + detail::gTouchDetected(); +static std::vector>& touchUpdated = + detail::gTouchUpdated(); +static std::vector>& touchExit = + detail::gTouchExit(); /** * If the framerate becomes slow, Chromium Embedded Framework (used in Web Browser Module) diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index fb0ad85061..e4e006ba41 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,9 @@ public: void mouseButtonCallback(MouseButton button, MouseAction action, KeyModifier mods); void mousePositionCallback(double x, double y); void mouseScrollWheelCallback(double posX, double posY); - void externalControlCallback(const char* receivedChars, int size, int clientId); + void touchDetectionCallback(TouchInput input); + void touchUpdateCallback(TouchInput input); + void touchExitCallback(TouchInput input); std::vector encode(); void decode(std::vector data); @@ -105,7 +108,6 @@ private: void loadFonts(); void runGlobalCustomizationScripts(); - void configureLogging(); std::unique_ptr _scene; std::unique_ptr _assetManager; diff --git a/include/openspace/util/camera.h b/include/openspace/util/camera.h index 8335329b31..f71564dd82 100644 --- a/include/openspace/util/camera.h +++ b/include/openspace/util/camera.h @@ -99,7 +99,6 @@ public: // Right now this function returns the actual combined matrix which makes some // of the old calls to the function wrong.. const glm::dmat4& combinedViewMatrix() const; - const glm::dmat4& combinedViewMatrixNoScale() const; void invalidateCache(); diff --git a/include/openspace/util/touch.h b/include/openspace/util/touch.h new file mode 100644 index 0000000000..5871094fb6 --- /dev/null +++ b/include/openspace/util/touch.h @@ -0,0 +1,88 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___TOUCH___H__ +#define __OPENSPACE_CORE___TOUCH___H__ + +#include + +#include +#include + +namespace openspace { + +struct TouchInput { + TouchInput(size_t touchDeviceId, size_t fingerId, float x, float y, double timestamp); + glm::vec2 screenCoordinates(glm::vec2 resolution) const; + glm::vec2 currentWindowCoordinates() const; + bool isMoving() const; + float distanceToPos(float otherX, float otherY) const; + float angleToPos(float otherX, float otherY) const; + + size_t touchDeviceId; + size_t fingerId; + float x; + float y; + float dx = 0.f; // movement in x direction since last touch input + float dy = 0.f; // movement in y direction since last touch input + double timestamp; // timestamp in seconds from global touch initialization +}; + +class TouchInputHolder { +public: + TouchInputHolder(TouchInput input); + + // tryAddInput: + // Succeeds upon a different input than last. + // Fails upon a too similar input as last. + bool tryAddInput(TouchInput input); + void clearInputs(); + + bool holdsInput(const TouchInput &input) const; + + size_t touchDeviceId() const; + size_t fingerId() const; + + float speedX() const; + float speedY() const; + + bool isMoving() const; + float gestureDistance() const; + double gestureTime() const; + + size_t numInputs() const; + const TouchInput& latestInput() const; + const std::deque& peekInputs() const; + +private: + //A deque of recorded inputs. Adding newer points to the front of the queue + std::deque _inputs; + + size_t _touchDeviceId; + size_t _fingerId; +}; + +} // namespace openspace + +#endif // __OPENSPACE_CORE___TOUCH___H__ diff --git a/modules/touch/include/directinputsolver.h b/modules/touch/include/directinputsolver.h index 50f5cbeceb..bc866ba2dd 100644 --- a/modules/touch/include/directinputsolver.h +++ b/modules/touch/include/directinputsolver.h @@ -25,8 +25,8 @@ #ifndef __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ #define __OPENSPACE_MODULE_TOUCH___DIRECTINPUT_SOLVER___H__ +#include #include -#include #include @@ -35,23 +35,35 @@ namespace openspace { class Camera; class SceneGraphNode; +/** + * The DirectInputSolver is used to minimize the L2 error of touch input + * to 3D camera position. It uses the levmarq algorithm in order to do this. + * */ class DirectInputSolver { public: // Stores the selected node, the cursor ID as well as the surface coordinates the // cursor touched struct SelectedBody { - long id; + size_t id; SceneGraphNode* node; glm::dvec3 coordinates; }; DirectInputSolver(); - bool solve(const std::vector& list, + + /** + * Returns true if the error could be minimized within certain bounds. + * If the error is found to be outside the bounds after a certain amount of + * iterations, this function fails. + * */ + bool solve(const std::vector& list, const std::vector& selectedBodies, std::vector* calculatedValues, const Camera& camera); - int getNDof() const; - const LMstat& getLevMarqStat(); + int nDof() const; + + const LMstat& levMarqStat(); + void setLevMarqVerbosity(bool verbose); private: diff --git a/modules/touch/include/touchinteraction.h b/modules/touch/include/touchinteraction.h index 7158973b70..a0f025d90b 100644 --- a/modules/touch/include/touchinteraction.h +++ b/modules/touch/include/touchinteraction.h @@ -28,8 +28,6 @@ #include #include -#include - #include #include #include @@ -37,7 +35,7 @@ #include #include #include - +#include #include //#define TOUCH_DEBUG_PROPERTIES @@ -66,8 +64,6 @@ private: class TouchInteraction : public properties::PropertyOwner { public: - using Point = std::pair; - TouchInteraction(); // for interpretInteraction() @@ -95,15 +91,13 @@ public: * 8 Evaluate if directControl should be called next frame- true if all contact points * select the same node and said node is larger than _nodeRadiusThreshold */ - void updateStateFromInput(const std::vector& list, - std::vector& lastProcessed); + + void updateStateFromInput(const std::vector& list, + std::vector& lastProcessed); // Calculates the new camera state with velocities and time since last frame void step(double dt); - // Used to save LMA data for one frame if the user chose to - void unitTest(); - // Called each frame we have no new input, used to reset data void resetAfterInput(); @@ -120,37 +114,32 @@ public: void setCamera(Camera* camera); private: - /* Returns true if the clicked position contains WebGui content and the event will - * be parsed to the webbrowser - */ - bool webContent(const std::vector& list); - /* Returns true if we have the GUI window open. If so, emulates the incoming touch * input to a mouse such that we can interact with the GUI */ - bool guiMode(const std::vector& list); + bool isGuiMode(glm::dvec2 screenPosition, size_t numFingers); /* Function that calculates the new camera state such that it minimizes the L2 error * in screenspace * between contact points and surface coordinates projected to clip space using LMA */ - void directControl(const std::vector& list); + void directControl(const std::vector& list); /* Traces each contact point into the scene as a ray * if the ray hits a node, save the id, node and surface coordinates the cursor hit * in the list _selected */ - void findSelectedNode(const std::vector& list); + void findSelectedNode(const std::vector& list); /* Returns an int (ROT = 0, PINCH, PAN, ROLL, PICK) for what interaction to be used, * depending on what input was gotten */ - int interpretInteraction(const std::vector& list, - const std::vector& lastProcessed); + int interpretInteraction(const std::vector& list, + const std::vector& lastProcessed); // Compute new velocity according to the interpreted action - void computeVelocities(const std::vector& list, - const std::vector& lastProcessed); + void computeVelocities(const std::vector& list, + const std::vector& lastProcessed); //Compute velocity based on double-tap for zooming double computeTapZoomDistance(double zoomGain); @@ -158,11 +147,6 @@ private: //Compute coefficient for velocity decay to be applied in decceleration double computeConstTimeDecayCoefficient(double velocity); - //Compute coefficient of decay based on current frametime; if frametime has been - // longer than usual then multiple decay steps may be applied to keep the decay - // relative to user time - double computeDecayCoeffFromFrametime(double coeff, int times); - /* Decelerate the velocities. Function is called in step() but is dereferenced from * frame time to assure same behaviour on all systems */ @@ -224,25 +208,25 @@ private: VelocityStates _lastVel; VelocityStates _sensitivity; - double _projectionScaleFactor; - double _currentRadius; - double _slerpdT; - double _timeSlack; - int _numOfTests; - TUIO::TuioTime _time; - bool _directTouchMode; - bool _wasPrevModeDirectTouch; - bool _tap; - bool _doubleTap; - bool _zoomOutTap; - bool _lmSuccess; - bool _guiON; + double _projectionScaleFactor = 1.000004; + double _currentRadius = 1.0; + double _slerpdT = 10001.0; + double _timeSlack = 0.0; + int _numOfTests = 0; + std::chrono::milliseconds _time; + bool _directTouchMode = false; + bool _wasPrevModeDirectTouch = false; + bool _tap = false; + bool _doubleTap = false; + bool _zoomOutTap = false; + bool _lmSuccess = true; + bool _guiON = false; std::vector _selected; SceneGraphNode* _pickingSelected = nullptr; DirectInputSolver _solver; glm::dquat _toSlerp; - glm::dvec3 _centroid; + glm::vec2 _centroid = glm::vec2(0.f); FrameTimeAverage _frameTimeAvg; diff --git a/modules/touch/include/touchmarker.h b/modules/touch/include/touchmarker.h index ab2488b830..c11ea7f65d 100644 --- a/modules/touch/include/touchmarker.h +++ b/modules/touch/include/touchmarker.h @@ -25,9 +25,6 @@ #ifndef __OPENSPACE_MODULE_TOUCH___TOUCH_MARKER___H__ #define __OPENSPACE_MODULE_TOUCH___TOUCH_MARKER___H__ -#include - -#include #include #include #include @@ -35,10 +32,10 @@ #include #include #include - +#include #include +#include #include - #include #include @@ -54,10 +51,10 @@ public: void initialize(); void deinitialize(); - void render(const std::vector& list); + void render(const std::vector& list); private: - void createVertexList(const std::vector& list); + void createVertexList(const std::vector& list); properties::BoolProperty _visible; properties::FloatProperty _radiusSize; diff --git a/modules/touch/include/tuioear.h b/modules/touch/include/tuioear.h index a05296ba89..25c98edbf8 100644 --- a/modules/touch/include/tuioear.h +++ b/modules/touch/include/tuioear.h @@ -38,8 +38,6 @@ #include #include -#include -#include #if (defined(__GNUC__) && !defined(__clang__)) #pragma GCC diagnostic pop @@ -48,72 +46,52 @@ #pragma clang diagnostic pop #endif // __clang__ +#include #include - +#include #include -#include #include #include -#include +#include +namespace openspace { class TuioEar : public TUIO::TuioListener { - public: - TuioEar(); - ~TuioEar() { - _tuioClient.disconnect(); - } +public: + TuioEar(); + ~TuioEar(); - /** - * Callback functions, listens to the TUIO server + /** + * Callback functions, listens to the TUIO server + */ + void addTuioObject(TUIO::TuioObject *tobj); + void updateTuioObject(TUIO::TuioObject *tobj); + void removeTuioObject(TUIO::TuioObject *tobj); + + void addTuioCursor(TUIO::TuioCursor *tcur); + void updateTuioCursor(TUIO::TuioCursor *tcur); + void removeTuioCursor(TUIO::TuioCursor *tcur); + + void addTuioBlob(TUIO::TuioBlob *tblb); + void updateTuioBlob(TUIO::TuioBlob *tblb); + void removeTuioBlob(TUIO::TuioBlob *tblb); + + void refresh(TUIO::TuioTime frameTime); + + /** + * Lock-swap the containers of this listener */ - void addTuioObject(TUIO::TuioObject *tobj); - void updateTuioObject(TUIO::TuioObject *tobj); - void removeTuioObject(TUIO::TuioObject *tobj); + std::vector takeInput(); + std::vector takeRemovals(); - void addTuioCursor(TUIO::TuioCursor *tcur); - void updateTuioCursor(TUIO::TuioCursor *tcur); - void removeTuioCursor(TUIO::TuioCursor *tcur); +private: + TUIO::TuioClient _tuioClient; - void addTuioBlob(TUIO::TuioBlob *tblb); - void updateTuioBlob(TUIO::TuioBlob *tblb); - void removeTuioBlob(TUIO::TuioBlob *tblb); - - void refresh(TUIO::TuioTime frameTime); - - /** - * Returns a list of all touch history that happened since the last frame - */ - std::vector getInput(); - - /** - * Returns true if a tap occured since the last frame - */ - bool tap(); - - /** - * Returns tap's cursor coordinates and time information - */ - TUIO::TuioCursor getTap(); - - /** - * Clears the input list, function called after getInput() each frame - */ - void clearInput(); - - private: - bool _tap = false; - TUIO::TuioCursor _tapCo = TUIO::TuioCursor(-1, -1, -1.0f, -1.0f); - std::mutex _mx; - - TUIO::TuioClient _tuioClient; - - std::vector _list; - - /** - * A list that tracks all of the cursor ID's that got removed since last frame - */ - std::vector _removeList; + std::vector _inputList; + std::vector _removalList; + std::mutex _mx; }; +} // namespace openspace + #endif // __OPENSPACE_MODULE_TOUCH___TUIO_EAR___H__ diff --git a/modules/touch/src/directinputsolver.cpp b/modules/touch/src/directinputsolver.cpp index 6ceed7dac4..46701af1da 100644 --- a/modules/touch/src/directinputsolver.cpp +++ b/modules/touch/src/directinputsolver.cpp @@ -37,7 +37,7 @@ namespace { openspace::SceneGraphNode* node; LMstat stats; }; -} +} // namespace namespace openspace { @@ -45,7 +45,8 @@ DirectInputSolver::DirectInputSolver() { levmarq_init(&_lmstat); } -// project back a 3D point in model view to clip space [-1,1] coordinates on the view plane +// project back a 3D point in model view to clip space [-1,1] coordinates on the view +// plane glm::dvec2 castToNDC(const glm::dvec3& vec, Camera& camera, SceneGraphNode* node) { glm::dvec3 posInCamSpace = glm::inverse(camera.rotationQuaternion()) * (node->worldRotationMatrix() * vec + @@ -82,20 +83,24 @@ double distToMinimize(double* par, int x, void* fdata, LMstat* lmstat) { dvec3(0, 0, 0), directionToCenter, // To avoid problem with lookup in up direction - normalize(camDirection + lookUp)); + normalize(camDirection + lookUp) + ); dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); dquat localCamRot = inverse(globalCamRot) * ptr->camera->rotationQuaternion(); - { // Roll + { + // Roll dquat rollRot = angleAxis(q[3], dvec3(0.0, 0.0, 1.0)); localCamRot = localCamRot * rollRot; } - { // Panning (local rotation) + { + // Panning (local rotation) dvec3 eulerAngles(q[5], q[4], 0); dquat panRot = dquat(eulerAngles); localCamRot = localCamRot * panRot; } - { // Orbit (global rotation) + { + // Orbit (global rotation) dvec3 eulerAngles(q[1], q[0], 0); dquat rotationDiffCamSpace = dquat(eulerAngles); @@ -169,15 +174,17 @@ void gradient(double* g, double* par, int x, void* fdata, LMstat* lmstat) { } // calculate f1 with good h for finite difference - dPar.at(i) += h; + dPar[i] += h; f1 = distToMinimize(dPar.data(), x, fdata, lmstat); - dPar.at(i) = par[i]; + dPar[i] = par[i]; break; } - else if ((f1 - f0) != 0 && lastG != 0) { // h too big + else if ((f1 - f0) != 0 && lastG != 0) { + // h too big h /= scale; } - else if ((f1 - f0) == 0) { // h too small + else if ((f1 - f0) == 0) { + // h too small h *= scale; } lastG = f1 - f0; @@ -201,9 +208,9 @@ void gradient(double* g, double* par, int x, void* fdata, LMstat* lmstat) { } } -bool DirectInputSolver::solve(const std::vector& list, +bool DirectInputSolver::solve(const std::vector& list, const std::vector& selectedBodies, - std::vector* parameters, const Camera& camera) + std::vector* parameters, const Camera& camera) { int nFingers = std::min(static_cast(list.size()), 3); _nDof = std::min(nFingers * 2, 6); @@ -216,29 +223,9 @@ bool DirectInputSolver::solve(const std::vector& list, const SelectedBody& sb = selectedBodies.at(i); selectedPoints.push_back(sb.coordinates); screenPoints.emplace_back( - 2 * (list[i].getX() - 0.5), - -2 * (list[i].getY() - 0.5) + 2.0 * (list[i].latestInput().x - 0.5), + -2.0 * (list[i].latestInput().y - 0.5) ); - - // This might be needed when we're directing the touchtable from another screen? - // std::vector::const_iterator c = std::find_if( - // list.begin(), - // list.end(), - // [&sb](const TuioCursor& c) { return c.getSessionID() == sb.id; } - // ); - // if (c != list.end()) { - // // normalized -1 to 1 coordinates on screen - // screenPoints.emplace_back(2 * (c->getX() - 0.5), -2 * (c->getY() - 0.5)); - // } - // else { - // global::moduleEngine.module()->touchInput = { - // true, - // glm::dvec2(0.0, 0.0), - // 1 - // }; - // resetAfterInput(); - // return; - // } } FunctionData fData = { @@ -265,11 +252,11 @@ bool DirectInputSolver::solve(const std::vector& list, return result; } -int DirectInputSolver::getNDof() const { +int DirectInputSolver::nDof() const { return _nDof; } -const LMstat& DirectInputSolver::getLevMarqStat() { +const LMstat& DirectInputSolver::levMarqStat() { return _lmstat; } diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index eab3fa0185..36d30b6154 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -24,39 +24,35 @@ #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - #ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED #include #include #endif -#ifdef OPENSPACE_MODULE_WEBBROWSER_ENABLED -#include -#endif - -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include #include +#include #ifdef WIN32 #pragma warning (push) @@ -69,10 +65,6 @@ #pragma warning (pop) #endif // WIN32 -#include -#include -#include - namespace { constexpr const char* _loggerCat = "TouchInteraction"; @@ -246,9 +238,19 @@ namespace { "Its purpose is to limit zooming in on a node. If this value is not set it " "defaults to the surface of the current anchor. " }; -} // namespace -using namespace TUIO; + // Compute coefficient of decay based on current frametime; if frametime has been + // longer than usual then multiple decay steps may be applied to keep the decay + // relative to user time + double computeDecayCoeffFromFrametime(double coeff, int times) { + if (coeff > 0.00001) { + return std::pow(coeff, times); + } + else { + return 0.0; + } + } +} // namespace namespace openspace { @@ -310,22 +312,6 @@ TouchInteraction::TouchInteraction() , _constTimeDecay_secs(ConstantTimeDecaySecsInfo, 1.75f, 0.1f, 4.0f) // calculated with two vectors with known diff in length, then // projDiffLength/diffLength. - , _projectionScaleFactor(1.000004) - , _currentRadius(1.0) - , _slerpdT(1000) - , _timeSlack(0.0) - , _numOfTests(0) - , _directTouchMode(false) - , _wasPrevModeDirectTouch(false) - , _tap(false) - , _doubleTap(false) - , _zoomOutTap(false) - , _lmSuccess(true) - , _guiON(false) -#ifdef TOUCH_DEBUG_PROPERTIES - , _debugProperties() -#endif - , _centroid(glm::dvec3(0.0)) { addProperty(_touchActive); addProperty(_unitTest); @@ -370,41 +356,42 @@ TouchInteraction::TouchInteraction() )); } }); - - _time.initSession(); + _time = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch() + ); } -// Called each frame if there is any input -void TouchInteraction::updateStateFromInput(const std::vector& list, - std::vector& lastProcessed) + +void TouchInteraction::updateStateFromInput(const std::vector& list, + std::vector& lastProcessed) { #ifdef TOUCH_DEBUG_PROPERTIES _debugProperties.nFingers = list.size(); #endif - if (_tap) { // check for doubletap - if (_time.getSessionTime().getTotalMilliseconds() < _maxTapTime) { + if (_tap) { + // check for doubletap + using namespace std::chrono; + milliseconds timestamp = duration_cast( + high_resolution_clock::now().time_since_epoch() + ); + if ((timestamp - _time).count() < _maxTapTime) { _doubleTap = true; _tap = false; } - _time.initSession(); + _time = timestamp; } + // Code for lower-right corner double-tap to zoom-out + const glm::vec2 res = global::windowDelegate.currentWindowSize(); + const glm::vec2 pos = list[0].latestInput().screenCoordinates(res); - bool hasWebContent = webContent(list); - - //Code for lower-right corner double-tap to zoom-out - glm::ivec2 res = global::windowDelegate.currentWindowSize(); - glm::dvec2 pos = glm::vec2( - list.at(0).getScreenX(res.x), - list.at(0).getScreenY(res.y) - ); const float bottomCornerSizeForZoomTap_fraction = 0.08f; - int zoomTapThresholdX = static_cast( - res.x * (1.0f - bottomCornerSizeForZoomTap_fraction) + const int zoomTapThresholdX = static_cast( + res.x * (1.f - bottomCornerSizeForZoomTap_fraction) ); - int zoomTapThresholdY = static_cast( - res.y * (1.0f - bottomCornerSizeForZoomTap_fraction) + const int zoomTapThresholdY = static_cast( + res.y * (1.f - bottomCornerSizeForZoomTap_fraction) ); - bool isTapInLowerRightCorner = + const bool isTapInLowerRightCorner = (std::abs(pos.x) > zoomTapThresholdX && std::abs(pos.y) > zoomTapThresholdY); if (_doubleTap && isTapInLowerRightCorner) { @@ -413,22 +400,18 @@ void TouchInteraction::updateStateFromInput(const std::vector& list, _doubleTap = false; } - if (!guiMode(list) && !hasWebContent) { - bool isThisFrameTransitionBetweenTouchModes - = (_wasPrevModeDirectTouch != _directTouchMode); - if (isThisFrameTransitionBetweenTouchModes) { + size_t numFingers = list.size(); + if (!isGuiMode(pos, numFingers)) { + bool isTransitionBetweenModes = (_wasPrevModeDirectTouch != _directTouchMode); + if (isTransitionBetweenModes) { _vel.orbit = glm::dvec2(0.0, 0.0); _vel.zoom = 0.0; _vel.roll = 0.0; _vel.pan = glm::dvec2(0.0, 0.0); resetAfterInput(); - /*if( _directTouchMode ) - LINFO("Touch -> Direct-touch"); - else - LINFO("Direct-touch -> Touch");*/ } - if (_directTouchMode && _selected.size() > 0 && list.size() == _selected.size()) { + if (_directTouchMode && _selected.size() > 0 && numFingers == _selected.size()) { #ifdef TOUCH_DEBUG_PROPERTIES _debugProperties.interactionMode = "Direct"; #endif @@ -448,41 +431,21 @@ void TouchInteraction::updateStateFromInput(const std::vector& list, _wasPrevModeDirectTouch = _directTouchMode; // evaluates if current frame is in directTouchMode (will be used next frame) _directTouchMode = - (_currentRadius > _nodeRadiusThreshold && _selected.size() == list.size()); + (_currentRadius > _nodeRadiusThreshold && _selected.size() == numFingers); } } -bool TouchInteraction::webContent(const std::vector& list) { -#ifdef OPENSPACE_MODULE_WEBBROWSER_ENABLED - glm::ivec2 res = global::windowDelegate.currentWindowSize(); - glm::dvec2 pos = glm::vec2( - list.at(0).getScreenX(res.x), - list.at(0).getScreenY(res.y) - ); - - WebBrowserModule& module = *(global::moduleEngine.module()); - return module.eventHandler().hasContentCallback(pos.x, pos.y); -#else - return false; -#endif -} - -// Activates/Deactivates gui input mode (if active it voids all other interactions) -bool TouchInteraction::guiMode(const std::vector& list) { +bool TouchInteraction::isGuiMode(glm::dvec2 screenPosition, size_t numFingers) { if (_ignoreGui) { return false; } - glm::ivec2 res = global::windowDelegate.currentWindowSize(); - glm::dvec2 pos = glm::vec2( - list.at(0).getScreenX(res.x), - list.at(0).getScreenY(res.y) - ); ImGUIModule& module = *(global::moduleEngine.module()); _guiON = module.gui.isEnabled(); - if (_tap && list.size() == 1 && - std::abs(pos.x) < _guiButton.value().x && std::abs(pos.y) < _guiButton.value().y) + if (_tap && numFingers == 1 && + std::abs(screenPosition.x) < _guiButton.value().x && + std::abs(screenPosition.y) < _guiButton.value().y) { // pressed invisible button _guiON = !_guiON; @@ -491,19 +454,19 @@ bool TouchInteraction::guiMode(const std::vector& list) { LINFO(fmt::format( "GUI mode is {}. Inside box by: ({}%, {}%)", _guiON ? "activated" : "deactivated", - static_cast(100 * (pos.x / _guiButton.value().x)), - static_cast(100 * (pos.y / _guiButton.value().y)) + static_cast(100 * (screenPosition.x / _guiButton.value().x)), + static_cast(100 * (screenPosition.y / _guiButton.value().y)) )); } else if (_guiON) { - module.touchInput = { _guiON, pos, 1 }; // emulate touch input as a mouse + // emulate touch input as a mouse + module.touchInput = { _guiON, screenPosition, 1 }; } return _guiON; } -// Sets _vel to update _camera according to direct-manipulation (L2 error) -void TouchInteraction::directControl(const std::vector& list) { +void TouchInteraction::directControl(const std::vector& list) { // Reset old velocities upon new interaction _vel.orbit = glm::dvec2(0.0, 0.0); _vel.zoom = 0.0; @@ -515,10 +478,10 @@ void TouchInteraction::directControl(const std::vector& list) { // finds best transform values for the new camera state and stores them in par std::vector par(6, 0.0); - par.at(0) = _lastVel.orbit.x; // use _lastVel for orbit - par.at(1) = _lastVel.orbit.y; + par[0] = _lastVel.orbit.x; // use _lastVel for orbit + par[1] = _lastVel.orbit.y; _lmSuccess = _solver.solve(list, _selected, &par, *_camera); - int nDof = _solver.getNDof(); + int nDof = _solver.nDof(); if (_lmSuccess && !_unitTest) { // if good values were found set new camera state @@ -543,19 +506,17 @@ void TouchInteraction::directControl(const std::vector& list) { else { // prevents touch to infinitely be active (due to windows bridge case where event // doesnt get consumed sometimes when LMA fails to converge) - global::moduleEngine.module()->touchInput = { - true, - glm::dvec2(0.0, 0.0), - 1 - }; + Touch touch; + touch.active = true; + touch.pos = glm::dvec2(0.0, 0.0); + touch.action = 1; + global::moduleEngine.module()->touchInput = touch; resetAfterInput(); } } -// Traces the touch input into the scene and finds the surface coordinates of touched -// planets (if occuring) -void TouchInteraction::findSelectedNode(const std::vector& list) { - //trim list to only contain visible nodes that make sense +void TouchInteraction::findSelectedNode(const std::vector& list) { + // trim list to only contain visible nodes that make sense std::string selectables[30] = { "Sun", "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "Moon", "Titan", "Rhea", "Mimas", "Iapetus", "Enceladus", @@ -574,30 +535,31 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { glm::dquat camToWorldSpace = _camera->rotationQuaternion(); glm::dvec3 camPos = _camera->positionVec3(); std::vector newSelected; - - //node & distance - std::tuple currentlyPicked = { + + // node & distance + std::pair currentlyPicked = { nullptr, std::numeric_limits::max() }; - - for (const TuioCursor& c : list) { - double xCo = 2 * (c.getX() - 0.5); - double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen + + for (const TouchInputHolder& inputHolder : list) { + // normalized -1 to 1 coordinates on screen + double xCo = 2 * (inputHolder.latestInput().x - 0.5); + double yCo = -2 * (inputHolder.latestInput().y - 0.5); glm::dvec3 cursorInWorldSpace = camToWorldSpace * glm::dvec3(glm::inverse(_camera->projectionMatrix()) * glm::dvec4(xCo, yCo, -1.0, 1.0)); glm::dvec3 raytrace = glm::normalize(cursorInWorldSpace); - long id = c.getSessionID(); + size_t id = inputHolder.fingerId(); for (SceneGraphNode* node : selectableNodes) { double boundingSphereSquared = static_cast(node->boundingSphere()) * static_cast(node->boundingSphere()); glm::dvec3 camToSelectable = node->worldPosition() - camPos; double intersectionDist = 0.0; - bool intersected = glm::intersectRaySphere( + const bool intersected = glm::intersectRaySphere( camPos, raytrace, node->worldPosition(), @@ -616,7 +578,7 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { [id](const DirectInputSolver::SelectedBody& s) { return s.id == id; } ); if (oldNode != newSelected.end()) { - double oldNodeDist = glm::length( + const double oldNodeDist = glm::length( oldNode->node->worldPosition() - camPos ); if (glm::length(camToSelectable) < oldNodeDist) { @@ -637,11 +599,12 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { glm::vec4(node->worldPosition(), 1.0); glm::dvec2 ndc = clip / clip.w; - // If the object is not in the screen, we dont want to consider it at all - if (ndc.x >= -1.0 && ndc.x <= 1.0 && ndc.y >= -1.0 && ndc.y <= 1.0) { + const bool isVisibleX = (ndc.x >= -1.0 && ndc.x <= 1.0); + const bool isVisibleY = (ndc.y >= -1.0 && ndc.y <= 1.0); + if (isVisibleX && isVisibleY) { glm::dvec2 cursor = { xCo, yCo }; - double ndcDist = glm::length(ndc - cursor); + const double ndcDist = glm::length(ndc - cursor); // We either want to select the object if it's bounding sphere as been // touched (checked by the first part of this loop above) or if the touch // point is within a minimum distance of the center @@ -668,12 +631,9 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { "Picking candidate based on proximity" ); #endif //#ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES - double dist = length(camToSelectable); - if (dist < std::get<1>(currentlyPicked)) { - currentlyPicked = { - node, - dist - }; + const double dist = length(camToSelectable); + if (dist < currentlyPicked.second) { + currentlyPicked = std::make_pair(node, dist); } } } @@ -681,7 +641,7 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { } // If an item has been picked, it's in the first position of the vector now - if (SceneGraphNode* node = std::get<0>(currentlyPicked)) { + if (SceneGraphNode* node = currentlyPicked.first) { _pickingSelected = node; #ifdef TOUCH_DEBUG_NODE_PICK_MESSAGES LINFOC("Picking", "Picked node: " + _pickingSelected->identifier()); @@ -691,65 +651,60 @@ void TouchInteraction::findSelectedNode(const std::vector& list) { _selected = std::move(newSelected); } -// Interprets the input gesture to a specific interaction -int TouchInteraction::interpretInteraction(const std::vector& list, - const std::vector& lastProcessed) +int TouchInteraction::interpretInteraction(const std::vector& list, + const std::vector& lastProcessed) { - glm::dvec3 lastCentroid = _centroid; - _centroid.x = std::accumulate( - list.begin(), - list.end(), - 0.0, - [](double x, const TuioCursor& c) { return x + c.getX(); } - ) / list.size(); - _centroid.y = std::accumulate( - list.begin(), - list.end(), - 0.0, - [](double y, const TuioCursor& c) { return y + c.getY(); } - ) / list.size(); + glm::fvec2 lastCentroid = _centroid; + _centroid = { 0.f, 0.f }; + for (const TouchInputHolder& inputHolder : list) { + _centroid += glm::vec2( + inputHolder.latestInput().x, + inputHolder.latestInput().y + ); + } + _centroid /= static_cast(list.size()); // see if the distance between fingers changed - used in pan interpretation double dist = 0; double lastDist = 0; - TuioCursor cursor = list.at(0); - for (const TuioCursor& c : list) { + TouchInput distInput = list[0].latestInput(); + for (const TouchInputHolder& inputHolder : list) { + const TouchInput& latestInput = inputHolder.latestInput(); dist += glm::length( - glm::dvec2(c.getX(), c.getY()) - glm::dvec2(cursor.getX(), cursor.getY()) + glm::dvec2(latestInput.x, latestInput.y) - + glm::dvec2(distInput.x, distInput.y) ); - cursor = c; + distInput = latestInput; } - TuioPoint point = lastProcessed.at(0).second; - for (const Point& p : lastProcessed) { - lastDist += glm::length(glm::dvec2(p.second.getX(), p.second.getY()) - - glm::dvec2(point.getX(), point.getY())); - point = p.second; + distInput = lastProcessed[0]; + for (const TouchInput& p : lastProcessed) { + lastDist += glm::length(glm::dvec2(p.x, p.y) - + glm::dvec2(distInput.x, distInput.y)); + distInput = p; } // find the slowest moving finger - used in roll interpretation double minDiff = 1000; - long id = 0; - for (const TuioCursor& c : list) { - auto it = std::find_if( - lastProcessed.begin(), - lastProcessed.end(), - [&c](const Point& p) { - return p.first == c.getSessionID(); + for (const TouchInputHolder& inputHolder : list) { + const auto it = std::find_if( + lastProcessed.cbegin(), + lastProcessed.cend(), + [&inputHolder](const TouchInput& input) { + return inputHolder.holdsInput(input); }); - if (it == lastProcessed.end()) { + if (it == lastProcessed.cend()) { continue; } + const TouchInput& latestInput = inputHolder.latestInput(); + const TouchInput& prevInput = *it; - TuioPoint itPoint = it->second; - double diff = c.getX() - itPoint.getX() + c.getY() - itPoint.getY(); + double diff = latestInput.x - prevInput.x + latestInput.y - prevInput.y; - if (!c.isMoving()) { - diff = minDiff = 0.0; - id = c.getSessionID(); + if (!inputHolder.isMoving()) { + minDiff = 0.0; } else if (std::abs(diff) < std::abs(minDiff)) { minDiff = diff; - id = c.getSessionID(); } } // find if all fingers angles are high - used in roll interpretation @@ -757,26 +712,22 @@ int TouchInteraction::interpretInteraction(const std::vector& list, list.begin(), list.end(), 0.0, - [&](double diff, const TuioCursor& c) { - TuioPoint point = std::find_if( + [&](double diff, const TouchInputHolder& inputHolder) { + const TouchInput& lastPoint = *std::find_if( lastProcessed.begin(), lastProcessed.end(), - [&c](const Point& p) { return p.first == c.getSessionID(); } - )->second; + [&inputHolder](const TouchInput& input) { + return inputHolder.holdsInput(input); + }); double res = 0.0; - float lastAngle = point.getAngle( - static_cast(_centroid.x), - static_cast(_centroid.y) - ); - float currentAngle = c.getAngle( - static_cast(_centroid.x), - static_cast(_centroid.y) - ); - if (lastAngle > currentAngle + 1.5 * M_PI) { - res = currentAngle + (2 * M_PI - lastAngle); + + float lastAngle = lastPoint.angleToPos(_centroid.x, _centroid.y); + float currentAngle = inputHolder.latestInput().angleToPos(_centroid.x, _centroid.y); + if (lastAngle > currentAngle + 1.5 * glm::pi()) { + res = currentAngle + (2.0 * glm::pi() - lastAngle); } - else if (currentAngle > lastAngle + 1.5 * M_PI) { - res = (2 * M_PI - currentAngle) + lastAngle; + else if (currentAngle > lastAngle + 1.5 * glm::pi()) { + res = (2.0 * glm::pi() - currentAngle) + lastAngle; } else { res = currentAngle - lastAngle; @@ -810,9 +761,7 @@ int TouchInteraction::interpretInteraction(const std::vector& list, return ROT; } else { - float avgDistance = static_cast( - std::abs(dist - lastDist) / list.at(0).getMotionSpeed() - ); + float avgDistance = static_cast(std::abs(dist - lastDist)); // if average distance between 3 fingers are constant we have panning if (_panEnabled && (avgDistance < _interpretPan && list.size() == 3)) { return PAN; @@ -833,11 +782,9 @@ int TouchInteraction::interpretInteraction(const std::vector& list, } } -// Calculate how much interpreted interaction (_vel) should change the camera state -void TouchInteraction::computeVelocities(const std::vector& list, - const std::vector& lastProcessed) +void TouchInteraction::computeVelocities(const std::vector& list, + const std::vector& lastProcessed) { - const TuioCursor& cursor = list.at(0); const int action = interpretInteraction(list, lastProcessed); const SceneGraphNode* anchor = global::navigationHandler.orbitalNavigator().anchorNode(); @@ -868,14 +815,16 @@ void TouchInteraction::computeVelocities(const std::vector& list, } #endif + const TouchInputHolder& inputHolder = list.at(0); switch (action) { case ROT: { // add rotation velocity - _vel.orbit += glm::dvec2(cursor.getXSpeed() * - _sensitivity.orbit.x, cursor.getYSpeed() * + _vel.orbit += glm::dvec2(inputHolder.speedX() * + _sensitivity.orbit.x, inputHolder.speedY() * _sensitivity.orbit.y); - double orbitVelocityAvg = glm::distance(_vel.orbit.x, _vel.orbit.y); - _constTimeDecayCoeff.orbit - = computeConstTimeDecayCoefficient(orbitVelocityAvg); + const double orbitVelocityAvg = glm::distance(_vel.orbit.x, _vel.orbit.y); + _constTimeDecayCoeff.orbit = computeConstTimeDecayCoefficient( + orbitVelocityAvg + ); break; } case PINCH: { @@ -885,22 +834,18 @@ void TouchInteraction::computeVelocities(const std::vector& list, list.begin(), list.end(), 0.0, - [&](double d, const TuioCursor& c) { - return d + c.getDistance( - static_cast(_centroid.x), - static_cast(_centroid.y) - ); + [&](double d, const TouchInputHolder& c) { + const glm::vec2 currPos = { c.latestInput().x, c.latestInput().y }; + return d + glm::distance(currPos, _centroid); } ) / list.size(); double lastDistance = std::accumulate( lastProcessed.begin(), lastProcessed.end(), - 0.0f, - [&](float d, const Point& p) { - return d + p.second.getDistance( - static_cast(_centroid.x), - static_cast(_centroid.y) - ); + 0.f, + [&](float d, const TouchInput& p) { + const glm::vec2 lastPos = { p.x, p.y }; + return d + glm::distance(lastPos, _centroid); } ) / lastProcessed.size(); @@ -908,7 +853,7 @@ void TouchInteraction::computeVelocities(const std::vector& list, glm::dvec3 centerPos = anchor->worldPosition(); glm::dvec3 currDistanceToFocusNode = camPos - centerPos; - double distanceFromFocusSurface = + const double distanceFromFocusSurface = length(currDistanceToFocusNode) - anchor->boundingSphere(); double zoomFactor = (distance - lastDistance); #ifdef TOUCH_DEBUG_PROPERTIES @@ -918,11 +863,11 @@ void TouchInteraction::computeVelocities(const std::vector& list, _constTimeDecayCoeff.zoom = computeConstTimeDecayCoefficient(_vel.zoom); if (distanceFromFocusSurface > 0.1) { - double ratioOfDistanceToNodeVsSurface = + const double ratioOfDistanceToNodeVsSurface = length(currDistanceToFocusNode) / distanceFromFocusSurface; if (ratioOfDistanceToNodeVsSurface > _zoomSensitivityDistanceThreshold) { zoomFactor *= pow( - std::abs(distanceFromFocusSurface), + std::abs(distanceFromFocusSurface), static_cast(_zoomSensitivityExponential) ); } @@ -940,27 +885,26 @@ void TouchInteraction::computeVelocities(const std::vector& list, list.begin(), list.end(), 0.0, - [&](double diff, const TuioCursor& c) { - TuioPoint point = std::find_if( + [&](double diff, const TouchInputHolder& inputHolder) { + TouchInput point = *std::find_if( lastProcessed.begin(), lastProcessed.end(), - [&c](const Point& p) { return p.first == c.getSessionID(); } - )->second; - double res = diff; - double lastAngle = point.getAngle( - static_cast(_centroid.x), - static_cast(_centroid.y) + [&inputHolder](const TouchInput& input) { + return inputHolder.holdsInput(input); + } ); - double currentAngle = c.getAngle( - static_cast(_centroid.x), - static_cast(_centroid.y) + double res = diff; + float lastAngle = point.angleToPos(_centroid.x, _centroid.y); + float currentAngle = inputHolder.latestInput().angleToPos( + _centroid.x, + _centroid.y ); // if's used to set angles 359 + 1 = 0 and 0 - 1 = 359 - if (lastAngle > currentAngle + 1.5 * M_PI) { - res += currentAngle + (2 * M_PI - lastAngle); + if (lastAngle > currentAngle + 1.5 * glm::pi()) { + res += currentAngle + (2 * glm::pi() - lastAngle); } - else if (currentAngle > lastAngle + 1.5 * M_PI) { - res += (2 * M_PI - currentAngle) + lastAngle; + else if (currentAngle > lastAngle + 1.5 * glm::pi()) { + res += (2 * glm::pi() - currentAngle) + lastAngle; } else { res += currentAngle - lastAngle; @@ -968,15 +912,14 @@ void TouchInteraction::computeVelocities(const std::vector& list, return res; } ) / list.size(); - _vel.roll += -rollFactor * _sensitivity.roll; _constTimeDecayCoeff.roll = computeConstTimeDecayCoefficient(_vel.roll); break; } case PAN: { // add local rotation velocity - _vel.pan += glm::dvec2(cursor.getXSpeed() * - _sensitivity.pan.x, cursor.getYSpeed() * _sensitivity.pan.y); + _vel.pan += glm::dvec2(inputHolder.speedX() * + _sensitivity.pan.x, inputHolder.speedY() * _sensitivity.pan.y); double panVelocityAvg = glm::distance(_vel.pan.x, _vel.pan.y); _constTimeDecayCoeff.pan = computeConstTimeDecayCoefficient(panVelocityAvg); break; @@ -1015,8 +958,8 @@ void TouchInteraction::computeVelocities(const std::vector& list, } double TouchInteraction::computeConstTimeDecayCoefficient(double velocity) { - const double postDecayVelocityTarget = 1e-6; - double stepsToDecay = _constTimeDecay_secs / _frameTimeAvg.averageFrameTime(); + constexpr const double postDecayVelocityTarget = 1e-6; + const double stepsToDecay = _constTimeDecay_secs / _frameTimeAvg.averageFrameTime(); if (stepsToDecay > 0.0 && std::abs(velocity) > postDecayVelocityTarget) { return std::pow(postDecayVelocityTarget / std::abs(velocity), 1.0 / stepsToDecay); @@ -1061,17 +1004,17 @@ void TouchInteraction::step(double dt) { if (anchor && _camera) { // Create variables from current state dvec3 camPos = _camera->positionVec3(); - dvec3 centerPos = anchor->worldPosition(); + const dvec3 centerPos = anchor->worldPosition(); dvec3 directionToCenter = normalize(centerPos - camPos); - dvec3 centerToCamera = camPos - centerPos; - dvec3 lookUp = _camera->lookUpVectorWorldSpace(); - dvec3 camDirection = _camera->viewDirectionWorldSpace(); + const dvec3 centerToCamera = camPos - centerPos; + const dvec3 lookUp = _camera->lookUpVectorWorldSpace(); + const dvec3 camDirection = _camera->viewDirectionWorldSpace(); // Make a representation of the rotation quaternion with local and global // rotations // To avoid problem with lookup in up direction - dmat4 lookAtMat = lookAt( + const dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, normalize(camDirection + lookUp) @@ -1079,60 +1022,61 @@ void TouchInteraction::step(double dt) { dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); dquat localCamRot = inverse(globalCamRot) * _camera->rotationQuaternion(); - double boundingSphere = anchor->boundingSphere(); - double distance = std::max(length(centerToCamera) - boundingSphere, 0.0); - _currentRadius = boundingSphere / - std::max(distance * _projectionScaleFactor, 1.0); + const double boundingSphere = anchor->boundingSphere(); + const double distance = std::max(length(centerToCamera) - boundingSphere, 0.0); + _currentRadius = boundingSphere / + std::max(distance * _projectionScaleFactor, 1.0); { // Roll - dquat camRollRot = angleAxis(_vel.roll * dt, dvec3(0.0, 0.0, 1.0)); + const dquat camRollRot = angleAxis(_vel.roll * dt, dvec3(0.0, 0.0, 1.0)); localCamRot = localCamRot * camRollRot; } { // Panning (local rotation) - dvec3 eulerAngles(_vel.pan.y * dt, _vel.pan.x * dt, 0); - dquat rotationDiff = dquat(eulerAngles); + const dvec3 eulerAngles(_vel.pan.y * dt, _vel.pan.x * dt, 0); + const dquat rotationDiff = dquat(eulerAngles); localCamRot = localCamRot * rotationDiff; // if we have chosen a new focus node if (_slerpdT < _slerpTime) { - _slerpdT += 0.1*dt; + _slerpdT += 0.1 * dt; localCamRot = slerp(localCamRot, _toSlerp, _slerpdT / _slerpTime); } } { // Orbit (global rotation) - dvec3 eulerAngles(_vel.orbit.y*dt, _vel.orbit.x*dt, 0); - dquat rotationDiffCamSpace = dquat(eulerAngles); + const dvec3 eulerAngles(_vel.orbit.y*dt, _vel.orbit.x*dt, 0); + const dquat rotationDiffCamSpace = dquat(eulerAngles); - dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * - inverse(globalCamRot); - dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - - centerToCamera; + const dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * + inverse(globalCamRot); + const dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - + centerToCamera; camPos += rotationDiffVec3; - dvec3 centerToCam = camPos - centerPos; + const dvec3 centerToCam = camPos - centerPos; directionToCenter = normalize(-centerToCam); - dvec3 lookUpWhenFacingCenter = globalCamRot * + const dvec3 lookUpWhenFacingCenter = globalCamRot * dvec3(_camera->lookUpVectorCameraSpace()); - dmat4 lookAtMatrix = lookAt( + const dmat4 lookAtMatrix = lookAt( dvec3(0, 0, 0), directionToCenter, lookUpWhenFacingCenter); globalCamRot = normalize(quat_cast(inverse(lookAtMatrix))); } - { // Zooming + { + // Zooming // This is a rough estimate of the node surface - double zoomInBounds = boundingSphere * _zoomBoundarySphereMultiplier; + const double zoomInBounds = boundingSphere * _zoomBoundarySphereMultiplier; // If nobody has set another zoom in limit, use the default zoom in bounds if (_zoomInLimit.value() < 0) { _zoomInLimit.setValue(zoomInBounds); } else if (_zoomInLimit.value() < zoomInBounds) { - // If zoom in limit is less than the estimated node radius we need to + // If zoom in limit is less than the estimated node radius we need to // make sure we do not get too close to possible height maps SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle( camPos @@ -1142,7 +1086,7 @@ void TouchInteraction::step(double dt) { posHandle.referenceSurfaceOutDirection * posHandle.heightToSurface; glm::dvec3 centerToActualSurface = glm::dmat3(anchor->modelTransform()) * centerToActualSurfaceModelSpace; - double nodeRadius = length(centerToActualSurface); + const double nodeRadius = length(centerToActualSurface); // Because of heightmaps we should make sure we do not go through the surface if (_zoomInLimit.value() < nodeRadius) { @@ -1151,28 +1095,28 @@ void TouchInteraction::step(double dt) { "center to surface, setting it to {}", _loggerCat, zoomInBounds)); #endif _zoomInLimit.setValue(zoomInBounds); - } + } } - + // Make sure zoom in limit is not larger than zoom out limit if (_zoomInLimit.value() > _zoomOutLimit.value()) { LWARNING(fmt::format( - "{}: Zoom In Limit should be smaller than Zoom Out Limit", + "{}: Zoom In Limit should be smaller than Zoom Out Limit", _loggerCat, _zoomOutLimit.value() )); } //Apply the velocity to update camera position glm::dvec3 zoomDistanceIncrement = directionToCenter * _vel.zoom * dt; - double newPosDistance = length(centerToCamera + zoomDistanceIncrement); - double currentPosDistance = length(centerToCamera); + const double newPosDistance = length(centerToCamera + zoomDistanceIncrement); + const double currentPosDistance = length(centerToCamera); // Possible with other navigations performed outside touch interaction - bool currentPosViolatingZoomOutLimit = + const bool currentPosViolatingZoomOutLimit = (currentPosDistance >= _zoomOutLimit.value()); - bool willNewPositionViolateZoomOutLimit = + const bool willNewPositionViolateZoomOutLimit = (newPosDistance >= _zoomOutLimit.value()); - bool willNewPositionViolateZoomInLimit = + const bool willNewPositionViolateZoomInLimit = (newPosDistance < _zoomInLimit.value()); if (!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){ @@ -1185,8 +1129,7 @@ void TouchInteraction::step(double dt) { _loggerCat, _zoomOutLimit.value()); #endif // Only allow zooming in if you are outside the zoom out limit - if (newPosDistance < currentPosDistance) - { + if (newPosDistance < currentPosDistance) { camPos += zoomDistanceIncrement; } } @@ -1224,46 +1167,6 @@ void TouchInteraction::step(double dt) { } } -void TouchInteraction::unitTest() { - if (_unitTest) { - _solver.setLevMarqVerbosity(true); - - // set _selected pos and new pos (on screen) - std::vector lastFrame = { - { TuioCursor(0, 10, 0.45f, 0.4f) }, // session id, cursor id, x, y - { TuioCursor(1, 11, 0.55f, 0.6f) } - }; - std::vector currFrame = { - { TuioCursor(0, 10, 0.2f, 0.6f) }, // (-0.6,-0.2) - { TuioCursor(1, 11, 0.8f, 0.4f) } // (0.6, 0.2) - }; - - // call update - findSelectedNode(lastFrame); - directControl(currFrame); - - // save lmstats.data into a file and clear it - char buffer[32]; - snprintf(buffer, sizeof(char) * 32, "lmdata%i.csv", _numOfTests); - _numOfTests++; - std::ofstream file(buffer); - file << _solver.getLevMarqStat().data; - - // clear everything - _selected.clear(); - _pickingSelected = nullptr; - _vel.orbit = glm::dvec2(0.0, 0.0); - _vel.zoom = 0.0; - _vel.roll = 0.0; - _vel.pan = glm::dvec2(0.0, 0.0); - _lastVel = _vel; - _unitTest = false; - - _solver.setLevMarqVerbosity(false); - // could be the camera copy in func - } -} - // Decelerate velocities, called a set number of times per second to dereference it from // frame time // Example: @@ -1289,15 +1192,6 @@ void TouchInteraction::decelerate(double dt) { _vel.zoom *= computeDecayCoeffFromFrametime(_constTimeDecayCoeff.zoom, times); } -double TouchInteraction::computeDecayCoeffFromFrametime(double coeff, int times) { - if (coeff > 0.00001) { - return std::pow(coeff, times); - } - else { - return 0.0; - } -} - // Called if all fingers are off the screen void TouchInteraction::resetAfterInput() { #ifdef TOUCH_DEBUG_PROPERTIES @@ -1403,12 +1297,13 @@ void FrameTimeAverage::updateWithNewFrame(double sample) { } double FrameTimeAverage::averageFrameTime() const { - double ft; - if (_nSamples == 0) - ft = 1.0 / 60.0; //Just guess at 60fps if no data is available yet - else - ft = std::accumulate(_samples, _samples + _nSamples, 0.0) / (double)(_nSamples); - return ft; + if (_nSamples == 0) { + // Just guess at 60fps if no data is available yet + return 1.0 / 60.0; + } + else { + return std::accumulate(_samples, _samples + _nSamples, 0.0) / (double)(_nSamples); + } } #ifdef TOUCH_DEBUG_PROPERTIES diff --git a/modules/touch/src/touchmarker.cpp b/modules/touch/src/touchmarker.cpp index 07d15aec9a..7757286dab 100644 --- a/modules/touch/src/touchmarker.cpp +++ b/modules/touch/src/touchmarker.cpp @@ -27,9 +27,8 @@ #include #include #include -#include - #include +#include namespace { constexpr const std::array UniformNames = { @@ -63,6 +62,7 @@ namespace { constexpr openspace::properties::Property::PropertyInfo ColorInfo = { "MarkerColor", "Marker color", "" // @TODO Missing documentation }; + } // namespace namespace openspace { @@ -73,13 +73,7 @@ TouchMarker::TouchMarker() , _radiusSize(RadiusInfo, 30.f, 0.f, 100.f) , _transparency(TransparencyInfo, 0.8f, 0.f, 1.f) , _thickness(ThicknessInfo, 2.f, 0.f, 4.f ) - , _color( - ColorInfo, - glm::vec3(204.f / 255.f, 51.f / 255.f, 51.f / 255.f), - glm::vec3(0.f), - glm::vec3(1.f) - ) - , _shader(nullptr) + , _color(ColorInfo, glm::vec3(0.96f, 0.2f, 0.2f), glm::vec3(0.f), glm::vec3(1.f)) { addProperty(_visible); addProperty(_radiusSize); @@ -117,7 +111,7 @@ void TouchMarker::deinitialize() { } } -void TouchMarker::render(const std::vector& list) { +void TouchMarker::render(const std::vector& list) { if (_visible && !list.empty()) { createVertexList(list); _shader->activate(); @@ -131,7 +125,6 @@ void TouchMarker::render(const std::vector& list) { glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_PROGRAM_POINT_SIZE); // Enable gl_PointSize in vertex shader - // glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // When included this line makes the webgui disappear at touch interaction glBindVertexArray(_quad); glDrawArrays(GL_POINTS, 0, static_cast(_vertexData.size() / 2)); @@ -139,13 +132,13 @@ void TouchMarker::render(const std::vector& list) { } } -void TouchMarker::createVertexList(const std::vector& list) { +void TouchMarker::createVertexList(const std::vector& list) { _vertexData.resize(list.size() * 2); int i = 0; - for (const TUIO::TuioCursor& c : list) { - _vertexData[i] = 2 * (c.getX() - 0.5f); - _vertexData[i + 1] = -2 * (c.getY() - 0.5f); + for (const openspace::TouchInputHolder& inputHolder : list) { + _vertexData[i] = 2 * (inputHolder.latestInput().x - 0.5f); + _vertexData[i + 1] = -2 * (inputHolder.latestInput().y - 0.5f); i += 2; } diff --git a/modules/touch/src/tuioear.cpp b/modules/touch/src/tuioear.cpp index 4a9969f241..885f069969 100644 --- a/modules/touch/src/tuioear.cpp +++ b/modules/touch/src/tuioear.cpp @@ -29,11 +29,12 @@ #include #include #include - #include using namespace TUIO; +namespace openspace { + void TuioEar::addTuioObject(TuioObject*) { } void TuioEar::updateTuioObject(TuioObject*) { } @@ -42,67 +43,41 @@ void TuioEar::removeTuioObject(TuioObject*) { } void TuioEar::addTuioCursor(TuioCursor* tcur) { _mx.lock(); - _tap = false; - // find same id in _list if it exists in _removeList (new input with same ID as a - // previously stored) - long i = tcur->getSessionID(); - std::vector::iterator foundID = std::find_if( - _removeList.begin(), - _removeList.end(), - [&i](long id) { return id == i; }); - - // if found, remove id from _removeList and update, otherwise add new id to list - if (foundID != _removeList.end()) { - std::find_if( - _list.begin(), - _list.end(), - [&i](const TuioCursor& cursor) { - return cursor.getSessionID() == i; - } - )->update(tcur); - _removeList.erase(foundID); - } - else { - _list.emplace_back(*tcur); - } + TouchInput input( + static_cast(tcur->getTuioSourceID()), + static_cast(tcur->getCursorID()), + tcur->getX(), + tcur->getY(), + static_cast(tcur->getTuioTime().getTotalMilliseconds()) / 1000.0 + ); + _inputList.emplace_back(input); _mx.unlock(); } void TuioEar::updateTuioCursor(TuioCursor* tcur) { _mx.lock(); - _tap = false; - long i = tcur->getSessionID(); - std::find_if( - _list.begin(), - _list.end(), - [&i](const TuioCursor& cursor) { - return cursor.getSessionID() == i; - } - )->update(tcur); + TouchInput input( + static_cast(tcur->getTuioSourceID()), + static_cast(tcur->getCursorID()), + tcur->getX(), + tcur->getY(), + static_cast(tcur->getTuioTime().getTotalMilliseconds()) / 1000.0 + ); + _inputList.emplace_back(input); _mx.unlock(); } // save id to be removed and remove it in clearInput void TuioEar::removeTuioCursor(TuioCursor* tcur) { _mx.lock(); - _removeList.push_back(tcur->getSessionID()); - - // Check if the cursor ID could be considered a tap - glm::dvec2 currPos = glm::dvec2(tcur->getX(), tcur->getY()); - double dist = 0; - for (const TuioPoint& p : tcur->getPath()) { - dist += glm::length(glm::dvec2(p.getX(), p.getY()) - currPos); - } - dist /= tcur->getPath().size(); - - double heldTime = - tcur->getPath().back().getTuioTime().getTotalMilliseconds() - - tcur->getPath().front().getTuioTime().getTotalMilliseconds(); - - if (heldTime < 180 && dist < 0.0004 && _list.size() == 1 && _removeList.size() == 1) { - _tapCo = TuioCursor(*tcur); - _tap = true; - } + TouchInput input( + static_cast(tcur->getTuioSourceID()), + static_cast(tcur->getCursorID()), + tcur->getX(), + tcur->getY(), + static_cast(tcur->getTuioTime().getTotalMilliseconds()) / 1000.0 + ); + _removalList.emplace_back(input); _mx.unlock(); } @@ -114,48 +89,22 @@ void TuioEar::removeTuioBlob(TuioBlob*) { } void TuioEar::refresh(TuioTime) { } // about every 15ms -std::vector TuioEar::getInput() { - std::lock_guard lock(_mx); - return _list; -} - -bool TuioEar::tap() { - std::lock_guard lock(_mx); - if (_tap) { - _tap = false; - return !_tap; +std::vector TuioEar::takeInput() { + std::vector outputList; + { + std::lock_guard lock(_mx); + outputList.swap(_inputList); } - else { - return _tap; + return outputList; +} + +std::vector TuioEar::takeRemovals() { + std::vector outputList; + { + std::lock_guard lock(_mx); + outputList.swap(_removalList); } -} - -TuioCursor TuioEar::getTap() { - std::lock_guard lock(_mx); - return _tapCo; -} - -// Removes all cursor ID from list that exists in _removeList -void TuioEar::clearInput() { - _mx.lock(); - _list.erase( - std::remove_if( - _list.begin(), - _list.end(), - [this](const TuioCursor& cursor) { - return std::find_if( - _removeList.begin(), - _removeList.end(), - [&cursor](long id) { - return cursor.getSessionID() == id; - } - ) != _removeList.end(); - } - ), - _list.end() - ); - _removeList.clear(); - _mx.unlock(); + return outputList; } // Standard UDP IP connection to port 3333 @@ -165,3 +114,9 @@ TuioEar::TuioEar() _tuioClient.addTuioListener(this); _tuioClient.connect(); } + +TuioEar::~TuioEar() { + _tuioClient.disconnect(); +} + +} // namespace openspace diff --git a/modules/touch/src/win32_touch.cpp b/modules/touch/src/win32_touch.cpp index 03ded0a114..5c1db8381d 100644 --- a/modules/touch/src/win32_touch.cpp +++ b/modules/touch/src/win32_touch.cpp @@ -26,84 +26,133 @@ #include +#include #include #include #include #include +#include +#include #include #include +// #define ENABLE_TUIOMESSAGES +#define ENABLE_DIRECTMSG + namespace { constexpr const char* _loggerCat = "win32_touch"; - HHOOK gTouchHook{ nullptr }; - bool gStarted{ false }; - TUIO::TuioServer* gTuioServer{ nullptr }; + HHOOK gTouchHook = nullptr; + std::thread* gMouseHookThread; + HHOOK gMouseHook = nullptr; + bool gStarted = false; + std::chrono::microseconds gStartTime = std::chrono::microseconds(0); + std::unordered_map< + UINT32, + std::unique_ptr + > gTouchInputsMap; +#ifdef ENABLE_TUIOMESSAGES + TUIO::TuioServer* gTuioServer = nullptr; std::unordered_map gCursorMap; +#endif } // namespace namespace openspace { +LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam); -// This hook will only work for Win7+ Digitizers. +// This hook will only work for Win8+ Digitizers. // - Once GLFW has native touch support, we can remove this windows-specific code LRESULT CALLBACK HookCallback(int nCode, WPARAM wParam, LPARAM lParam) { - if (nCode < 0) { + if (nCode != HC_ACTION) { return CallNextHookEx(0, nCode, wParam, lParam); } - if (nCode == HC_ACTION) { - LPMSG pStruct = reinterpret_cast(lParam); - const UINT message = pStruct->message; - switch (message) { - case WM_POINTERDOWN: - case WM_POINTERUPDATE: - case WM_POINTERUP: - { - POINTER_INFO pointerInfo = {}; - if (GetPointerInfo(GET_POINTERID_WPARAM(pStruct->wParam), &pointerInfo)) { - RECT rect; - GetClientRect(pStruct->hwnd, reinterpret_cast(&rect)); - POINT p = pointerInfo.ptPixelLocation; - // native touch to screen conversion - ScreenToClient(pStruct->hwnd, reinterpret_cast(&p)); - - float xPos = static_cast(p.x) / - static_cast(rect.right - rect.left); - float yPos = static_cast(p.y) / - static_cast(rect.bottom - rect.top); - if (pointerInfo.pointerFlags & POINTER_FLAG_DOWN) { - // Handle new touchpoint - gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); - gCursorMap[pointerInfo.pointerId] = gTuioServer->addTuioCursor( - xPos, - yPos - ); - gTuioServer->commitFrame(); - } - else if (pointerInfo.pointerFlags & POINTER_FLAG_UPDATE) { - // Handle update of touchpoint - TUIO::TuioTime frameTime = TUIO::TuioTime::getSessionTime(); - if (gCursorMap[pointerInfo.pointerId]->getTuioTime() == frameTime) - { - break; - } - gTuioServer->initFrame(frameTime); - gTuioServer->updateTuioCursor( - gCursorMap[pointerInfo.pointerId], - xPos, - yPos - ); - gTuioServer->commitFrame(); - } - else if (pointerInfo.pointerFlags & POINTER_FLAG_UP) { - // Handle removed touchpoint - gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); - gTuioServer->removeTuioCursor(gCursorMap[pointerInfo.pointerId]); - gTuioServer->commitFrame(); - gCursorMap.erase(pointerInfo.pointerId); - } - } + LPMSG pStruct = reinterpret_cast(lParam); + const UINT message = pStruct->message; + switch (message) { + case WM_POINTERDOWN: + case WM_POINTERUPDATE: + case WM_POINTERUP: + { + POINTER_INFO info = {}; + BOOL hasInfo = GetPointerInfo(GET_POINTERID_WPARAM(pStruct->wParam), &info); + if (!hasInfo) { break; } + + using namespace std::chrono; + const microseconds timestamp = duration_cast( + high_resolution_clock::now().time_since_epoch() + ) - gStartTime; + RECT rect; + GetClientRect(pStruct->hwnd, reinterpret_cast(&rect)); + + POINT p = info.ptPixelLocation; + // native touch to screen conversion + ScreenToClient(pStruct->hwnd, reinterpret_cast(&p)); + + float xPos = static_cast(p.x) / + static_cast(rect.right - rect.left); + float yPos = static_cast(p.y) / + static_cast(rect.bottom - rect.top); + + TouchInput touchInput( + reinterpret_cast(info.sourceDevice), + static_cast(info.pointerId), + xPos, + yPos, + static_cast(timestamp.count())/1'000'000.0 + ); + + if (info.pointerFlags & POINTER_FLAG_DOWN) { +#ifdef ENABLE_DIRECTMSG + std::unique_ptr points = + std::make_unique(touchInput); + gTouchInputsMap.emplace(info.pointerId, std::move(points)); + global::openSpaceEngine.touchDetectionCallback(touchInput); +#endif +#ifdef ENABLE_TUIOMESSAGES + // Handle new touchpoint + gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); + gCursorMap[info.pointerId] = gTuioServer->addTuioCursor( + xPos, + yPos + ); + gTuioServer->commitFrame(); +#endif + } + else if (info.pointerFlags & POINTER_FLAG_UPDATE) { + // Handle update of touchpoint +#ifdef ENABLE_DIRECTMSG + TouchInputHolder* points = gTouchInputsMap[info.pointerId].get(); + + if (points->tryAddInput(touchInput)) { + global::openSpaceEngine.touchUpdateCallback(points->latestInput()); + } +#endif +#ifdef ENABLE_TUIOMESSAGES + TUIO::TuioTime frameTime = TUIO::TuioTime::getSessionTime(); + if (gCursorMap[info.pointerId]->getTuioTime() == frameTime) { + break; + } + gTuioServer->initFrame(frameTime); + gTuioServer->updateTuioCursor(gCursorMap[info.pointerId], xPos, yPos); + gTuioServer->commitFrame(); +#endif + } + else if (info.pointerFlags & POINTER_FLAG_UP) { +#ifdef ENABLE_DIRECTMSG + gTouchInputsMap.erase(info.pointerId); + global::openSpaceEngine.touchExitCallback(touchInput); +#endif +#ifdef ENABLE_TUIOMESSAGES + // Handle removed touchpoint + gTuioServer->initFrame(TUIO::TuioTime::getSessionTime()); + gTuioServer->removeTuioCursor(gCursorMap[info.pointerId]); + gTuioServer->commitFrame(); + gCursorMap.erase(info.pointerId); +#endif + } + break; } } @@ -119,9 +168,18 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow) return; } + // HACK: This hack is required as long as our GLFW version is based on the touch + // branch. There is no convenient way to set a GLFWBool (uint32_t) which sets the + // state of touch-to-mouseinput interpretation. It happens to be 116 bytes into an + // internal glfw struct... + uint32_t* HACKY_PTR = (uint32_t *)GetPropW(hWnd, L"GLFW"); + HACKY_PTR += 116/sizeof(uint32_t); + *HACKY_PTR = 1; + + // Test for touch: int value = GetSystemMetrics(SM_DIGITIZER); - if ((value & NID_READY) == 0) { + if ((value & NID_READY) == 0) { // Don't bother setting up touch hooks? return; } @@ -130,12 +188,12 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow) // Digitizer is multitouch LINFO("Found Multitouch input digitizer!"); } - if (value & NID_INTEGRATED_TOUCH) { + if (value & NID_INTEGRATED_TOUCH) { // Integrated touch } // This should be needed, but we seem to receive messages even without it, - // probably a Win7+ behaviour + // this ought to be part to the older (< win8) windows touch-api. // Also - RegisterTouchWindow enables Windows gestures, which we don't want // since they produce visual feedback for "press-and-tap" etc. // RegisterTouchWindow(hWnd, TWF_FINETOUCH | TWF_WANTPALM); @@ -143,7 +201,7 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow) // TODO: Would be nice to find out if the gesture "press-and-tap" can be disabled // basically we don't really care for windows gestures for now... // this disables press and hold (right-click) gesture - const DWORD dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD; + const UINT_PTR dwHwndTabletProperty = TABLET_DISABLE_PRESSANDHOLD; ATOM atom = ::GlobalAddAtom(MICROSOFT_TABLETPENSERVICE_PROPERTY); ::SetProp( @@ -155,28 +213,88 @@ Win32TouchHook::Win32TouchHook(void* nativeWindow) if (!gStarted) { gStarted = true; + gStartTime = std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch() + ); +#ifdef ENABLE_TUIOMESSAGES gTuioServer = new TUIO::TuioServer("localhost", 3333); TUIO::TuioTime::initSession(); +#endif gTouchHook = SetWindowsHookExW( WH_GETMESSAGE, HookCallback, GetModuleHandleW(NULL), GetCurrentThreadId() ); + + // In theory, if our UI is pumped from a different thread, we can + // handle Low-level mouse events in that thread as well. + // this might help reduce mouse lag while running OpenSpace? + // gMouseHookThread = new std::thread([](){ + // gMouseHook = SetWindowsHookExW( + // WH_MOUSE_LL, + // LowLevelMouseProc, + // GetModuleHandleW(NULL), + // 0 //<- Global thread id (low-level mouse is global only) + // ); + // if(!gMouseHook){ + // LINFO("Could not setup mousehook!"); + // } + + // MSG msg; + // while (GetMessage(&msg, NULL, 0, 0)) + // { + // DispatchMessage(&msg); + // } + // }); + if (!gTouchHook) { LINFO(fmt::format("Failed to setup WindowsHook for touch input redirection")); +#ifdef ENABLE_TUIOMESSAGES delete gTuioServer; +#endif gStarted = false; } } } + Win32TouchHook::~Win32TouchHook() { if (gStarted) { UnhookWindowsHookEx(gTouchHook); + UnhookWindowsHookEx(gMouseHook); +#ifdef ENABLE_TUIOMESSAGES delete gTuioServer; +#endif } } +// Low-level mouse hook is "needed" if we want to stop mousecursor from moving +// when we get a touch-input on our window A negative effect is that this +// function is for global threads, meaning our application will cause Windows to +// stall the mouse cursor when this function can't be scheduled. This is not yet +// fail-proof...might be a race-condition on message pumping? +// - Seems to move the cursor when we get two fingers as input.. +// - If we ourselves would pump windows for events, we can handle this in the +// pump-loop +LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { + constexpr const LONG_PTR SIGNATURE_MASK = 0xFFFFFF00; + constexpr const LONG_PTR MOUSEEVENTF_FROMTOUCH = 0xFF515700; + if (nCode < 0) { + // do not process message + return CallNextHookEx(0, nCode, wParam, lParam); + } + LPMSLLHOOKSTRUCT msg = reinterpret_cast(lParam); + // block injected events (in most cases generated by touches) + bool isFromTouch = (msg->dwExtraInfo || SIGNATURE_MASK) == MOUSEEVENTF_FROMTOUCH; + if (msg->flags & LLMHF_INJECTED || isFromTouch) { + return 1; + } + + // forward event + return CallNextHookEx(0, nCode, wParam, lParam); +} + } // namespace openspace + #endif // WIN32 diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index f968095a44..a436f1107a 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -23,95 +23,94 @@ ****************************************************************************************/ #include -#include -#include +#include +#include #include #include #include #include -#include #include +#include #include #include #include #include #include #include -#include - -#ifdef OPENSPACE_MODULE_WEBBROWSER_ENABLED -#include -#endif using namespace TUIO; +namespace { + constexpr const double ONE_MS = 0.001; +} // namespace + namespace openspace { bool TouchModule::processNewInput() { // Get new input from listener + std::vector earInputs = _ear->takeInput(); + std::vector earRemovals = _ear->takeRemovals(); + + for(const TouchInput& input : earInputs) { + updateOrAddTouchInput(input); + } + for(const TouchInput& removal : earRemovals) { + removeTouchInput(removal); + } - _listOfContactPoints = _ear.getInput(); - _ear.clearInput(); // Set touch property to active (to void mouse input, mainly for mtdev bridges) - _touch.touchActive(!_listOfContactPoints.empty()); + _touch.touchActive(!_touchPoints.empty()); - if (!_listOfContactPoints.empty()) { + if (!_touchPoints.empty()) { global::interactionMonitor.markInteraction(); } // Erase old input id's that no longer exists - _lastProcessed.erase( + _lastTouchInputs.erase( std::remove_if( - _lastProcessed.begin(), - _lastProcessed.end(), - [this](const Point& point) { - return std::find_if( - _listOfContactPoints.begin(), - _listOfContactPoints.end(), - [&point](const TuioCursor& c) { - return point.first == c.getSessionID(); - } - ) == _listOfContactPoints.end(); }), - _lastProcessed.end()); + _lastTouchInputs.begin(), + _lastTouchInputs.end(), + [this](const TouchInput& input) { + return !std::any_of( + _touchPoints.cbegin(), + _touchPoints.cend(), + [&input](const TouchInputHolder& holder) { + return holder.holdsInput(input); + } + ); + } + ), + _lastTouchInputs.end() + ); - // if tap occured, we have new input - if (_listOfContactPoints.empty() && _lastProcessed.empty() && _ear.tap()) { - TuioCursor c = _ear.getTap(); - _listOfContactPoints.push_back(c); - _lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); + if (_tap) { _touch.tap(); + _tap = false; return true; } - // Check if we need to parse touchevent to the webgui - processNewWebInput(_listOfContactPoints); - // Return true if we got new input - if (_listOfContactPoints.size() == _lastProcessed.size() && - !_listOfContactPoints.empty()) + if (_touchPoints.size() == _lastTouchInputs.size() && + !_touchPoints.empty()) { bool newInput = true; // go through list and check if the last registrered time is newer than the one in // lastProcessed (last frame) std::for_each( - _lastProcessed.begin(), - _lastProcessed.end(), - [this, &newInput](Point& p) { - std::vector::iterator cursor = std::find_if( - _listOfContactPoints.begin(), - _listOfContactPoints.end(), - [&p](const TuioCursor& c) { return c.getSessionID() == p.first; } + _lastTouchInputs.begin(), + _lastTouchInputs.end(), + [this, &newInput](TouchInput& input) { + std::vector::iterator holder = std::find_if( + _touchPoints.begin(), + _touchPoints.end(), + [&input](const TouchInputHolder& inputHolder) { + return inputHolder.holdsInput(input); + } ); - double now = cursor->getPath().back().getTuioTime().getTotalMilliseconds(); - if (!cursor->isMoving()) { - // if current cursor isn't moving, we want to interpret that as new input - // for interaction purposes + if (!holder->isMoving()) { newInput = true; } - else if (p.second.getTuioTime().getTotalMilliseconds() == now) { - newInput = false; - } }); return newInput; } @@ -120,31 +119,51 @@ bool TouchModule::processNewInput() { } } -void TouchModule::processNewWebInput(const std::vector& listOfContactPoints) { - bool isWebPositionCallbackZero = - (_webPositionCallback.x == 0 && _webPositionCallback.y == 0); - bool isSingleContactPoint = (listOfContactPoints.size() == 1); - if (isSingleContactPoint && isWebPositionCallbackZero) { - glm::ivec2 res = global::windowDelegate.currentWindowSize(); - glm::dvec2 pos = glm::vec2( - listOfContactPoints.at(0).getScreenX(res.x), - listOfContactPoints.at(0).getScreenY(res.y) - ); - -#ifdef OPENSPACE_MODULE_WEBBROWSER_ENABLED - WebBrowserModule& module = *(global::moduleEngine.module()); - if (module.eventHandler().hasContentCallback(pos.x, pos.y)) { - _webPositionCallback = glm::vec2(pos.x, pos.y); - module.eventHandler().touchPressCallback(pos.x, pos.y); +void TouchModule::clearInputs() { + for (const TouchInput& input : _deferredRemovals) { + for (TouchInputHolder& inputHolder : _touchPoints) { + if (inputHolder.holdsInput(input)) { + inputHolder = std::move(_touchPoints.back()); + _touchPoints.pop_back(); + break; + } } } - // Send mouse release if not same point input - else if (!isSingleContactPoint && !isWebPositionCallbackZero) { - WebBrowserModule& module = *(global::moduleEngine.module()); - module.eventHandler().touchReleaseCallback(_webPositionCallback.x, - _webPositionCallback.y); - _webPositionCallback = glm::vec2(0, 0); -#endif + _deferredRemovals.clear(); +} + +void TouchModule::addTouchInput(TouchInput input) { + _touchPoints.emplace_back(input); +} + +void TouchModule::updateOrAddTouchInput(TouchInput input) { + for (TouchInputHolder& inputHolder : _touchPoints) { + if (inputHolder.holdsInput(input)){ + inputHolder.tryAddInput(input); + return; + } + } + _touchPoints.emplace_back(input); +} + +void TouchModule::removeTouchInput(TouchInput input) { + _deferredRemovals.emplace_back(input); + //Check for "tap" gesture: + for (TouchInputHolder& inputHolder : _touchPoints) { + if (inputHolder.holdsInput(input)) { + inputHolder.tryAddInput(input); + const double totalTime = inputHolder.gestureTime(); + const float totalDistance = inputHolder.gestureDistance(); + //Magic values taken from tuioear.cpp: + const bool isWithinTapTime = totalTime < 0.18; + const bool wasStationary = totalDistance < 0.0004f; + if (isWithinTapTime && wasStationary && _touchPoints.size() == 1 && + _deferredRemovals.size() == 1) + { + _tap = true; + } + return; + } } } @@ -153,17 +172,25 @@ TouchModule::TouchModule() { addPropertySubOwner(_touch); addPropertySubOwner(_markers); +} + +TouchModule::~TouchModule() { + // intentionally left empty +} + +void TouchModule::internalInitialize(const ghoul::Dictionary& /*dictionary*/){ + _ear.reset(new TuioEar()); global::callback::initializeGL.push_back([&]() { LDEBUGC("TouchModule", "Initializing TouchMarker OpenGL"); _markers.initialize(); #ifdef WIN32 - // We currently only support one window of touch input internally - // so here we grab the first window-handle and use it. - void* nativeWindowHandle = global::windowDelegate.getNativeWindowHandle(0); - if (nativeWindowHandle) { - _win32TouchHook.reset(new Win32TouchHook(nativeWindowHandle)); - } + // We currently only support one window of touch input internally + // so here we grab the first window-handle and use it. + void* nativeWindowHandle = global::windowDelegate.getNativeWindowHandle(0); + if (nativeWindowHandle) { + _win32TouchHook = std::make_unique(nativeWindowHandle); + } #endif }); @@ -172,35 +199,51 @@ TouchModule::TouchModule() _markers.deinitialize(); }); + // These are handled in UI thread, which (as of 20th dec 2019) is in main/rendering + // thread so we don't need a mutex here + global::callback::touchDetected.push_back( + [this](TouchInput i) { + addTouchInput(i); + return true; + } + ); + + global::callback::touchUpdated.push_back( + [this](TouchInput i) { + updateOrAddTouchInput(i); + return true; + } + ); + + global::callback::touchExit.push_back( + std::bind(&TouchModule::removeTouchInput, this, std::placeholders::_1) + ); + + global::callback::preSync.push_back([&]() { _touch.setCamera(global::navigationHandler.camera()); _touch.setFocusNode(global::navigationHandler.orbitalNavigator().anchorNode()); if (processNewInput() && global::windowDelegate.isMaster()) { - _touch.updateStateFromInput(_listOfContactPoints, _lastProcessed); + _touch.updateStateFromInput(_touchPoints, _lastTouchInputs); } - else if (_listOfContactPoints.empty()) { + else if (_touchPoints.empty()) { _touch.resetAfterInput(); } // update lastProcessed - _lastProcessed.clear(); - for (const TuioCursor& c : _listOfContactPoints) { - _lastProcessed.emplace_back(c.getSessionID(), c.getPath().back()); + _lastTouchInputs.clear(); + for (const TouchInputHolder& points : _touchPoints) { + _lastTouchInputs.emplace_back(points.latestInput()); } - // used to save data from solver, only calculated for one frame when user chooses - // in GUI - _touch.unitTest(); // calculate the new camera state for this frame _touch.step(global::windowDelegate.deltaTime()); + clearInputs(); }); - global::callback::render.push_back([&]() { _markers.render(_listOfContactPoints); }); - -} - -TouchModule::~TouchModule() { - //intentionally left empty + global::callback::render.push_back([&]() { + _markers.render(_touchPoints); + }); } } // namespace openspace diff --git a/modules/touch/touchmodule.h b/modules/touch/touchmodule.h index 5300967a36..f32b28d854 100644 --- a/modules/touch/touchmodule.h +++ b/modules/touch/touchmodule.h @@ -25,43 +25,52 @@ #ifndef __OPENSPACE_MODULE_TOUCH___TOUCHMODULE___H__ #define __OPENSPACE_MODULE_TOUCH___TOUCHMODULE___H__ -#include #include #include - +#include +#include +#include namespace openspace { - #ifdef WIN32 - class Win32TouchHook; - #endif //WIN32 - class TouchModule : public OpenSpaceModule { - using Point = std::pair; - public: - TouchModule(); - ~TouchModule(); + class TuioEar; - private: - /** - * Returns true if new touch input occured since the last frame - */ - bool processNewInput(); - /** - * Checks if touchevent should be parsed to the webgui - */ - void processNewWebInput(const std::vector& listOfContactPoints); - - TuioEar _ear; - TouchInteraction _touch; - TouchMarker _markers; - std::vector _listOfContactPoints; - // contains an id and the TuioPoint that was processed last frame - std::vector _lastProcessed; - glm::ivec2 _webPositionCallback = glm::ivec2(0,0); #ifdef WIN32 - std::unique_ptr _win32TouchHook; +class Win32TouchHook; #endif //WIN32 - }; + +class TouchModule : public OpenSpaceModule { +public: + TouchModule(); + ~TouchModule(); + +protected: + void internalInitialize(const ghoul::Dictionary& dictionary) override; + +private: + /// Returns true if new touch input occured since the last frame + bool processNewInput(); + + void clearInputs(); + + void addTouchInput(TouchInput input); + void updateOrAddTouchInput(TouchInput input); + void removeTouchInput(TouchInput input); + + std::unique_ptr _ear; + TouchInteraction _touch; + TouchMarker _markers; + std::vector _touchPoints; + std::vector _deferredRemovals; + std::vector _lastTouchInputs; + + // contains an id and the Point that was processed last frame + glm::ivec2 _webPositionCallback = glm::ivec2(0,0); +#ifdef WIN32 + std::unique_ptr _win32TouchHook; +#endif //WIN32 + bool _tap = false; +}; } // namespace openspace diff --git a/modules/webbrowser/include/eventhandler.h b/modules/webbrowser/include/eventhandler.h index 3ef6bdce06..22cc3bbe7d 100644 --- a/modules/webbrowser/include/eventhandler.h +++ b/modules/webbrowser/include/eventhandler.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -60,10 +61,6 @@ public: void setBrowserInstance(BrowserInstance* browserInstance); void resetBrowserInstance(); - void touchPressCallback(const double x, const double y); - void touchReleaseCallback(const double x, const double y); - bool hasContentCallback(const double, const double); - private: bool mouseButtonCallback(MouseButton button, MouseAction action, KeyModifier mods); bool mousePositionCallback(double x, double y); @@ -107,6 +104,9 @@ private: MouseButtonState _leftButton; MouseButtonState _rightButton; + //This vector assumes first element to be the active one: + std::vector _validTouchStates; + /** * determines if a click should be sent as a double click or not * @return diff --git a/modules/webbrowser/src/eventhandler.cpp b/modules/webbrowser/src/eventhandler.cpp index c805e22722..ef68227e2f 100644 --- a/modules/webbrowser/src/eventhandler.cpp +++ b/modules/webbrowser/src/eventhandler.cpp @@ -29,7 +29,6 @@ #include #include #include - #include #include @@ -37,12 +36,12 @@ namespace { constexpr const char* _loggerCat = "WebBrowser:EventHandler"; /** - * Map from GLFW key codes to windows key codes, supported by JS and CEF. - * See http://keycode.info/ for lookup - * - * \param key - * \return the key code, if mapped or the GLFW key code - */ + * Map from GLFW key codes to windows key codes, supported by JS and CEF. + * See http://keycode.info/ for lookup + * + * \param key + * \return the key code, if mapped or the GLFW key code + */ int mapFromGlfwToWindows(openspace::Key key) { switch (key) { case openspace::Key::BackSpace: return 8; @@ -192,34 +191,114 @@ void EventHandler::initialize() { return false; } ); + + global::callback::touchDetected.emplace_back( + [&](TouchInput input) -> bool { + if (!_browserInstance) { + return false; + } + + const glm::vec2 windowPos = input.currentWindowCoordinates(); + const bool hasContent = _browserInstance->hasContent( + static_cast(windowPos.x), + static_cast(windowPos.y) + ); + if (!hasContent) { + return false; + } + + if (_validTouchStates.empty()) { + _mousePosition.x = windowPos.x; + _mousePosition.y = windowPos.y; + _leftButton.down = true; + _browserInstance->sendMouseClickEvent( + mouseEvent(), + MBT_LEFT, + false, + BrowserInstance::SingleClick + ); + _validTouchStates.emplace_back(input); + } + else { + _validTouchStates.emplace_back(input); + } + return true; + } + ); + + global::callback::touchUpdated.emplace_back( + [&](TouchInput input) -> bool { + if (!_browserInstance) { + return false; + } + if (_validTouchStates.empty()) { + return false; + } + + auto it = std::find_if( + _validTouchStates.cbegin(), + _validTouchStates.cend(), + [&](const TouchInput& state){ + return state.fingerId == input.fingerId && + state.touchDeviceId == input.touchDeviceId; + } + ); + + if (it == _validTouchStates.cbegin()) { + glm::vec2 windowPos = input.currentWindowCoordinates(); + _mousePosition.x = windowPos.x; + _mousePosition.y = windowPos.y; + _leftButton.down = true; + _browserInstance->sendMouseMoveEvent(mouseEvent()); + return true; + } + else if (it != _validTouchStates.cend()){ + return true; + } + return false; + } + ); + + global::callback::touchExit.emplace_back( + [&](TouchInput input) { + if (!_browserInstance) { + return; + } + if (_validTouchStates.empty()) { + return; + } + + const auto found = std::find_if( + _validTouchStates.cbegin(), + _validTouchStates.cend(), + [&](const TouchInput& state){ + return state.fingerId == input.fingerId && + state.touchDeviceId == input.touchDeviceId; + } + ); + + if (found == _validTouchStates.cend()) { + return; + } + + _validTouchStates.erase(found); + if (_validTouchStates.empty()) { + glm::vec2 windowPos = input.currentWindowCoordinates(); + _mousePosition.x = windowPos.x; + _mousePosition.y = windowPos.y; + _leftButton.down = false; + _browserInstance->sendMouseClickEvent( + mouseEvent(), + MBT_LEFT, + true, + BrowserInstance::SingleClick + ); + } + } + ); } -void EventHandler::touchPressCallback(const double x, const double y) { - if (_browserInstance) { - _mousePosition.x = static_cast(x); - _mousePosition.y = static_cast(y); - - int clickCount = BrowserInstance::SingleClick; - _browserInstance->sendMouseClickEvent(mouseEvent(), MBT_LEFT, false, clickCount); - } -} - -void EventHandler::touchReleaseCallback(const double x, const double y) { - if (_browserInstance) { - _mousePosition.x = static_cast(x); - _mousePosition.y = static_cast(y); - - int clickCount = BrowserInstance::SingleClick; - _browserInstance->sendMouseClickEvent(mouseEvent(), MBT_LEFT, true, clickCount); - } -} - -bool EventHandler::hasContentCallback(const double x, const double y) { - return _browserInstance->hasContent(static_cast(x), static_cast(y)); -} - -bool EventHandler::mouseButtonCallback(MouseButton button, - MouseAction action, +bool EventHandler::mouseButtonCallback(MouseButton button, MouseAction action, KeyModifier mods) { if (button != MouseButton::Left && button != MouseButton::Right) { @@ -234,10 +313,12 @@ bool EventHandler::mouseButtonCallback(MouseButton button, // click or release? if (action == MouseAction::Release) { state.down = false; - } else { + } + else { if (isDoubleClick(state)) { ++clickCount; - } else { + } + else { state.lastClickTime = std::chrono::high_resolution_clock::now(); } @@ -256,6 +337,7 @@ bool EventHandler::mouseButtonCallback(MouseButton button, bool EventHandler::isDoubleClick(const MouseButtonState& button) const { // check time using namespace std::chrono; + auto now = high_resolution_clock::now(); milliseconds maxTimeDifference(doubleClickTime()); auto requiredTime = button.lastClickTime + maxTimeDifference; @@ -336,11 +418,7 @@ bool EventHandler::specialKeyEvent(Key key, KeyModifier mod, KeyAction) { } cef_key_event_type_t EventHandler::keyEventType(KeyAction action) { - if (action == KeyAction::Release) { - return KEYEVENT_KEYUP; - } else { - return KEYEVENT_KEYDOWN; - } + return action == KeyAction::Release ? KEYEVENT_KEYUP : KEYEVENT_KEYDOWN; } CefMouseEvent EventHandler::mouseEvent(KeyModifier mods) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bba42b68da..836e42e3cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -195,6 +195,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/util/timemanager.cpp ${OPENSPACE_BASE_DIR}/src/util/time_lua.inl ${OPENSPACE_BASE_DIR}/src/util/timerange.cpp + ${OPENSPACE_BASE_DIR}/src/util/touch.cpp ${OPENSPACE_BASE_DIR}/src/util/transformationmanager.cpp ${OPENSPACE_BASE_DIR}/src/util/versionchecker.cpp ) @@ -389,6 +390,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/util/timeline.inl ${OPENSPACE_BASE_DIR}/include/openspace/util/timemanager.h ${OPENSPACE_BASE_DIR}/include/openspace/util/timerange.h + ${OPENSPACE_BASE_DIR}/include/openspace/util/touch.h ${OPENSPACE_BASE_DIR}/include/openspace/util/updatestructures.h ${OPENSPACE_BASE_DIR}/include/openspace/util/versionchecker.h ${OPENSPACE_BASE_DIR}/include/openspace/util/transformationmanager.h diff --git a/src/engine/globalscallbacks.cpp b/src/engine/globalscallbacks.cpp index 93f7fe0d0a..2bba9d4560 100644 --- a/src/engine/globalscallbacks.cpp +++ b/src/engine/globalscallbacks.cpp @@ -96,6 +96,21 @@ std::vector>& gMouseScrollWheel() { return g; } +std::vector>& gTouchDetected() { + static std::vector> g; + return g; +} + +std::vector>& gTouchUpdated() { + static std::vector> g; + return g; +} + +std::vector>& gTouchExit() { + static std::vector> g; + return g; +} + } // namespace openspace::global::detail namespace openspace::global::callback { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 5ca2fdfec6..f907f0087f 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -1295,6 +1295,34 @@ void OpenSpaceEngine::mouseScrollWheelCallback(double posX, double posY) { global::interactionMonitor.markInteraction(); } +void OpenSpaceEngine::touchDetectionCallback(TouchInput input) { + using F = std::function; + for (const F& func : global::callback::touchDetected) { + bool isConsumed = func(input); + if (isConsumed) { + return; + } + } +} + +void OpenSpaceEngine::touchUpdateCallback(TouchInput input) { + using F = std::function; + for (const F& func : global::callback::touchUpdated) { + bool isConsumed = func(input); + if (isConsumed) { + return; + } + } +} + +void OpenSpaceEngine::touchExitCallback(TouchInput input) { + using F = std::function; + for (const F& func : global::callback::touchExit) { + func(input); + } +} + + std::vector OpenSpaceEngine::encode() { std::vector buffer = global::syncEngine.encodeSyncables(); return buffer; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index a6b327149b..0a6dd0ab57 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1020,9 +1020,6 @@ void FramebufferRenderer::updateHDRAndFiltering() { absPath("${SHADERS}/framebuffer/hdrAndFiltering.vert"), absPath("${SHADERS}/framebuffer/hdrAndFiltering.frag") ); - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - //_hdrFilteringProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - //_hdrFilteringProgram->setIgnoreUniformLocationError(IgnoreError::Yes); } void FramebufferRenderer::updateFXAA() { @@ -1031,9 +1028,6 @@ void FramebufferRenderer::updateFXAA() { absPath("${SHADERS}/framebuffer/fxaa.vert"), absPath("${SHADERS}/framebuffer/fxaa.frag") ); - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - //_fxaaProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - //_fxaaProgram->setIgnoreUniformLocationError(IgnoreError::Yes); } void FramebufferRenderer::updateDownscaledVolume() { @@ -1042,9 +1036,6 @@ void FramebufferRenderer::updateDownscaledVolume() { absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.vert"), absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.frag") ); - using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; - //_downscaledVolumeProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); - //_downscaledVolumeProgram->setIgnoreUniformLocationError(IgnoreError::Yes); } void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) { diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 918f5638f2..d8dcbd7b65 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -335,7 +335,7 @@ RenderEngine::RenderEngine() _hue.onChange([this]() { if (_renderer) { - const float h = _hue / 360.0; + const float h = _hue / 360.f; _renderer->setHue(h); } }); diff --git a/src/util/touch.cpp b/src/util/touch.cpp new file mode 100644 index 0000000000..ab16c23ed4 --- /dev/null +++ b/src/util/touch.cpp @@ -0,0 +1,185 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2020 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#include + +#include +#include +#include + +namespace openspace { + +TouchInput::TouchInput(size_t touchDeviceId, size_t fingerId, float x, float y, + double timestamp) + : touchDeviceId(touchDeviceId) + , fingerId(fingerId) + , x(x) + , y(y) + , timestamp(timestamp) +{} + +glm::vec2 TouchInput::screenCoordinates(glm::vec2 resolution) const { + return { std::floor(x * resolution.x + 0.5f), std::floor(y * resolution.y + 0.5f) }; +} + +glm::vec2 TouchInput::currentWindowCoordinates() const { + glm::vec2 res = global::windowDelegate.currentWindowSize(); + return { std::floor(x * res.x + 0.5f), std::floor(y * res.y + 0.5f) }; +} + +bool TouchInput::isMoving() const { + return dx != 0.f || dy != 0.f; +} + +float TouchInput::distanceToPos(float otherX, float otherY) const { + const float distX = x - otherX; + const float distY = y - otherY; + return std::sqrt(distX*distX + distY*distY); +} + +float TouchInput::angleToPos(float otherX, float otherY) const { + const float side = x - otherX; + const float height = y - otherY; + const float distance = distanceToPos(otherX, otherY); + + float angle = glm::half_pi() + std::asin(side / distance); + if (height < 0.f) { + angle = 2.f * glm::pi() - angle; + } + + return angle; +} + +TouchInputHolder::TouchInputHolder(TouchInput input) + : _inputs{ input } + , _touchDeviceId(input.touchDeviceId) + , _fingerId(input.fingerId) +{} + +bool TouchInputHolder::tryAddInput(TouchInput input) { + constexpr const double ONE_MS = 0.001; + const TouchInput& lastInput = latestInput(); + input.dx = input.x - lastInput.x; + input.dy = input.y - lastInput.y; + + const bool sameTimeAsLastInput = (input.timestamp - lastInput.timestamp) > ONE_MS; + bool wasInserted = false; + if (isMoving()) { + _inputs.emplace_front(input); + wasInserted = true; + } + else if (sameTimeAsLastInput && input.isMoving()) { + _inputs.emplace_front(input); + wasInserted = true; + } + + constexpr const int MaxInputs = 128; + if (_inputs.size() > MaxInputs) { + _inputs.pop_back(); + } + return wasInserted; +} + +void TouchInputHolder::clearInputs() { + _inputs.clear(); +} + +bool TouchInputHolder::holdsInput(const TouchInput &input) const { + return input.fingerId == _fingerId && input.touchDeviceId == _touchDeviceId; +} + +size_t TouchInputHolder::touchDeviceId() const { + return _touchDeviceId; +} + +size_t TouchInputHolder::fingerId() const { + return _fingerId; +} + +float TouchInputHolder::speedX() const { + if (_inputs.size() <= 1) { + return 0.f; + } + const TouchInput& currentInput = _inputs[0]; + const TouchInput& previousInput = _inputs[1]; + const float dt = static_cast(currentInput.timestamp - previousInput.timestamp); + return currentInput.dx / dt; +} + +float TouchInputHolder::speedY() const { + if(_inputs.size() <= 1) { + return 0.f; + } + const TouchInput& currentInput = _inputs[0]; + const TouchInput& previousInput = _inputs[1]; + const float dt = static_cast(currentInput.timestamp - previousInput.timestamp); + + return currentInput.dy / dt; +} + +bool TouchInputHolder::isMoving() const { + if (_inputs.size() <= 1) { + return false; + } + const TouchInput& currentInput = _inputs[0]; + return currentInput.dx != 0.f || currentInput.dy != 0.f; +} + +float TouchInputHolder::gestureDistance() const { + if (_inputs.size() <= 1) { + return 0.f; + } + float distX = 0.f; + float distY = 0.f; + const float startX = _inputs.front().x; + const float startY = _inputs.front().y; + for (const TouchInput& input : _inputs) { + distX += std::abs(input.x - startX); + distY += std::abs(input.y - startY); + } + return std::sqrt(distX*distX + distY*distY); +} + +double TouchInputHolder::gestureTime() const { + if (_inputs.size() <= 1) { + return 0.0; + } + const double before = _inputs.back().timestamp; + const double after = _inputs.front().timestamp; + return after - before; +} + +size_t TouchInputHolder::numInputs() const { + return _inputs.size(); +} + +const TouchInput& TouchInputHolder::latestInput() const { + return _inputs.front(); +} + +const std::deque& TouchInputHolder::peekInputs() const { + return _inputs; +} + +} // namespace openspace From 629597f3d07abbb6fda06a6cc7182ff1953fc780 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Mon, 13 Jan 2020 09:55:10 +0100 Subject: [PATCH 115/214] Added TouchActive as a field in TouchModule This can be used to inactivate navigational touch input --- modules/touch/touchmodule.cpp | 19 ++++++++++++++----- modules/touch/touchmodule.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index a436f1107a..14887290b4 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -42,9 +42,13 @@ using namespace TUIO; namespace { - constexpr const double ONE_MS = 0.001; -} // namespace - + constexpr openspace::properties::Property::PropertyInfo TouchActiveInfo = { + "TouchActive", + "True if we want to use touch input as 3d navigation", + "Use this if we want to turn on or off Touch input navigation. " + "Disabling this will reset all current touch inputs to the navigation. " + }; +} namespace openspace { bool TouchModule::processNewInput() { @@ -157,7 +161,7 @@ void TouchModule::removeTouchInput(TouchInput input) { //Magic values taken from tuioear.cpp: const bool isWithinTapTime = totalTime < 0.18; const bool wasStationary = totalDistance < 0.0004f; - if (isWithinTapTime && wasStationary && _touchPoints.size() == 1 && + if (isWithinTapTime && wasStationary && _touchPoints.size() == 1 && _deferredRemovals.size() == 1) { _tap = true; @@ -169,9 +173,14 @@ void TouchModule::removeTouchInput(TouchInput input) { TouchModule::TouchModule() : OpenSpaceModule("Touch") + , _touchActive(TouchActiveInfo, true) { addPropertySubOwner(_touch); addPropertySubOwner(_markers); + _touchActive.onChange([&] { + _touch.resetAfterInput(); + _lastTouchInputs.clear(); + }); } TouchModule::~TouchModule() { @@ -224,7 +233,7 @@ void TouchModule::internalInitialize(const ghoul::Dictionary& /*dictionary*/){ _touch.setCamera(global::navigationHandler.camera()); _touch.setFocusNode(global::navigationHandler.orbitalNavigator().anchorNode()); - if (processNewInput() && global::windowDelegate.isMaster()) { + if (processNewInput() && global::windowDelegate.isMaster() && _touchActive) { _touch.updateStateFromInput(_touchPoints, _lastTouchInputs); } else if (_touchPoints.empty()) { diff --git a/modules/touch/touchmodule.h b/modules/touch/touchmodule.h index f32b28d854..9ce8b73f92 100644 --- a/modules/touch/touchmodule.h +++ b/modules/touch/touchmodule.h @@ -64,6 +64,7 @@ private: std::vector _deferredRemovals; std::vector _lastTouchInputs; + properties::BoolProperty _touchActive; // contains an id and the Point that was processed last frame glm::ivec2 _webPositionCallback = glm::ivec2(0,0); #ifdef WIN32 From ebf3672bab8564369ef1962b71818526e1d1fad1 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Mon, 13 Jan 2020 09:55:55 +0100 Subject: [PATCH 116/214] Reworked zoom in boundaries in touch navigation Should be able to focus a larger body and go back to a smaller one now. --- modules/touch/src/touchinteraction.cpp | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/modules/touch/src/touchinteraction.cpp b/modules/touch/src/touchinteraction.cpp index 36d30b6154..367fef5668 100644 --- a/modules/touch/src/touchinteraction.cpp +++ b/modules/touch/src/touchinteraction.cpp @@ -277,8 +277,8 @@ TouchInteraction::TouchInteraction() 0.25f ) , _zoomBoundarySphereMultiplier(ZoomBoundarySphereMultiplierInfo, 1.001f, 1.f, 1.01f) - , _zoomOutLimit(ZoomOutLimitInfo, std::numeric_limits::max(), 1000.0f, std::numeric_limits::max()) - , _zoomInLimit(ZoomInLimitInfo, -1.0f, 0.0f, std::numeric_limits::max()) + , _zoomOutLimit(ZoomOutLimitInfo, std::numeric_limits::max(), 1000.0, std::numeric_limits::max()) + , _zoomInLimit(ZoomInLimitInfo, -1.0, 0.0, std::numeric_limits::max()) , _inputStillThreshold(InputSensitivityInfo, 0.0005f, 0.f, 0.001f) // used to void wrongly interpreted roll interactions , _centroidStillThreshold(StationaryCentroidInfo, 0.0018f, 0.f, 0.01f) @@ -1024,7 +1024,7 @@ void TouchInteraction::step(double dt) { const double boundingSphere = anchor->boundingSphere(); const double distance = std::max(length(centerToCamera) - boundingSphere, 0.0); - _currentRadius = boundingSphere / + _currentRadius = boundingSphere / std::max(distance * _projectionScaleFactor, 1.0); { @@ -1069,13 +1069,11 @@ void TouchInteraction::step(double dt) { // Zooming // This is a rough estimate of the node surface - const double zoomInBounds = boundingSphere * _zoomBoundarySphereMultiplier; + // If nobody has set another zoom in limit, use this as default zoom in bounds + double zoomInBounds = boundingSphere * _zoomBoundarySphereMultiplier; + bool isZoomInLimitSet = (_zoomInLimit.value() >= 0.0); - // If nobody has set another zoom in limit, use the default zoom in bounds - if (_zoomInLimit.value() < 0) { - _zoomInLimit.setValue(zoomInBounds); - } - else if (_zoomInLimit.value() < zoomInBounds) { + if (isZoomInLimitSet && _zoomInLimit.value() < zoomInBounds) { // If zoom in limit is less than the estimated node radius we need to // make sure we do not get too close to possible height maps SurfacePositionHandle posHandle = anchor->calculateSurfacePositionHandle( @@ -1094,12 +1092,12 @@ void TouchInteraction::step(double dt) { LINFO(fmt::format("{}: Zoom In limit should be larger than anchor " "center to surface, setting it to {}", _loggerCat, zoomInBounds)); #endif - _zoomInLimit.setValue(zoomInBounds); + zoomInBounds = _zoomInLimit.value(); } } // Make sure zoom in limit is not larger than zoom out limit - if (_zoomInLimit.value() > _zoomOutLimit.value()) { + if (zoomInBounds > _zoomOutLimit.value()) { LWARNING(fmt::format( "{}: Zoom In Limit should be smaller than Zoom Out Limit", _loggerCat, _zoomOutLimit.value() @@ -1116,10 +1114,11 @@ void TouchInteraction::step(double dt) { (currentPosDistance >= _zoomOutLimit.value()); const bool willNewPositionViolateZoomOutLimit = (newPosDistance >= _zoomOutLimit.value()); - const bool willNewPositionViolateZoomInLimit = - (newPosDistance < _zoomInLimit.value()); + bool willNewPositionViolateZoomInLimit = + (newPosDistance < zoomInBounds); - if (!willNewPositionViolateZoomInLimit && !willNewPositionViolateZoomOutLimit){ + if (!willNewPositionViolateZoomInLimit + && !willNewPositionViolateZoomOutLimit) { camPos += zoomDistanceIncrement; } else if (currentPosViolatingZoomOutLimit) { From f3659c2249c5ffe94b8ed96caa58652b972138f4 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Tue, 14 Jan 2020 08:07:23 +0100 Subject: [PATCH 117/214] Forgot to add the property --- modules/touch/touchmodule.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/touch/touchmodule.cpp b/modules/touch/touchmodule.cpp index 14887290b4..721d2280ac 100644 --- a/modules/touch/touchmodule.cpp +++ b/modules/touch/touchmodule.cpp @@ -177,6 +177,7 @@ TouchModule::TouchModule() { addPropertySubOwner(_touch); addPropertySubOwner(_markers); + addProperty(_touchActive); _touchActive.onChange([&] { _touch.resetAfterInput(); _lastTouchInputs.clear(); From 2a99bf02fc2bb8f131100ba320c8acdacbd82097 Mon Sep 17 00:00:00 2001 From: GPayne Date: Tue, 14 Jan 2020 13:49:13 -0700 Subject: [PATCH 118/214] Corrected SBDB position using SPICE ECLIPJ2000 frame for sun --- .../scene/solarsystem/sssb/sssb_shared.asset | 2 +- .../scene/solarsystem/sun/transforms.asset | 24 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/data/assets/scene/solarsystem/sssb/sssb_shared.asset b/data/assets/scene/solarsystem/sssb/sssb_shared.asset index ae54c5eba1..a660fd3087 100644 --- a/data/assets/scene/solarsystem/sssb/sssb_shared.asset +++ b/data/assets/scene/solarsystem/sssb/sssb_shared.asset @@ -34,7 +34,7 @@ local registerSssbGroupObjects = function(containingAsset, filename, sssbFolder, function sssBodies(title, file, color) return { Identifier = title, - Parent = transforms.SolarSystemBarycenter.Identifier, + Parent = transforms.SunECLIPJ2000.Identifier, Renderable = { Type = "RenderableSmallBody", Path = file, diff --git a/data/assets/scene/solarsystem/sun/transforms.asset b/data/assets/scene/solarsystem/sun/transforms.asset index b80dc222b9..ea76c08add 100644 --- a/data/assets/scene/solarsystem/sun/transforms.asset +++ b/data/assets/scene/solarsystem/sun/transforms.asset @@ -42,6 +42,26 @@ local SunIAU = { } } +local SunECLIPJ2000 = { + Identifier = "SunECLIPJ2000", + Parent = SolarSystemBarycenter.Identifier, + Transform = { + Translation = { + Type = "SpiceTranslation", + Target = "SUN", + Observer = "SSB" + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "ECLIPJ2000", + DestinationFrame = "GALACTIC" + } + }, + GUI = { + Name = "SUN J2000", + Path = "/Solar System/Sun", + Hidden = true + } +} - -assetHelper.registerSceneGraphNodesAndExport(asset, { SolarSystemBarycenter, SunIAU }) +assetHelper.registerSceneGraphNodesAndExport(asset, { SolarSystemBarycenter, SunIAU, SunECLIPJ2000 }) From 904350d89b4b948f7fd0b920bb8f1c3bdd129620 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 22 Jan 2020 09:50:16 -0500 Subject: [PATCH 119/214] Improved shadow blending. --- modules/globebrowsing/shaders/renderer_fs.glsl | 2 +- modules/globebrowsing/shaders/rings_fs.glsl | 5 ++++- modules/globebrowsing/src/ringscomponent.cpp | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index e7633d405e..ec97d0d3f1 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -287,7 +287,7 @@ Fragment getFragment() { sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); shadow = sum / (8.0 * nShadowSamples + 1.f); } - frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.5, 0.0, 1.0) : shadow; + frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow; #endif return frag; diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 12ba8b4e74..bae6535326 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -69,6 +69,9 @@ Fragment getFragment() { // to normalize the transparency value to [0,1] if (colorValue < 3.0 * transparency) { diffuse.a = pow(colorValue / (3.0 * transparency), 1); + //diffuse.a = (colorValue / 3.0) * transparency; + if (diffuse.a < 0.65) + discard; } // shadow == 1.0 means it is not in shadow @@ -114,7 +117,7 @@ Fragment getFragment() { Fragment frag; - frag.color = (0.55 * diffuse * shadow) + diffuse * 0.45; + frag.color = (0.65 * diffuse * shadow) + diffuse * 0.35; frag.depth = vs_screenSpaceDepth; frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); frag.gNormal = vec4(normal, 1.0); diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 3195237b20..ae65411e93 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -346,7 +346,6 @@ void RingsComponent::draw(const RenderData& data, glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); _shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit); - } else if (renderPass == GeometryOnly) { _geometryOnlyShader->setUniform( From 8ae8d53629e0ff6b93d4720e01da75c7f2bf3a3a Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 22 Jan 2020 11:33:19 -0500 Subject: [PATCH 120/214] Fixed blinking (precision) problems. --- modules/base/rendering/renderabletrail.cpp | 18 ++++++++++++++++++ modules/base/rendering/renderabletrail.h | 2 ++ .../base/rendering/renderabletrailorbit.cpp | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index ef0cea3264..51aee515ff 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -418,6 +418,24 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { 0 : _primaryRenderInformation.first; + // Culling + const double scaledRadius = glm::length( + glm::dmat3(modelTransform) * glm::dvec3(_boundingSphere, 0.0, 0.0) + ); + + glm::dvec3 trailPosWorld = glm::dvec3( + modelTransform * _primaryRenderInformation._localTransform * + glm::dvec4(0.0, 0.0, 0.0, 1.0) + ); + const double distance = glm::distance( + trailPosWorld, + data.camera.eyePositionVec3() + ); + + if (distance > scaledRadius * DISTANCE_CULLING_RADII) { + return; + } + // Render the primary batch of vertices render(_primaryRenderInformation, totalNumber, primaryOffset); diff --git a/modules/base/rendering/renderabletrail.h b/modules/base/rendering/renderabletrail.h index 1507f7e4a8..a7d0873c29 100644 --- a/modules/base/rendering/renderabletrail.h +++ b/modules/base/rendering/renderabletrail.h @@ -72,6 +72,8 @@ class Translation; class RenderableTrail : public Renderable { public: +const double DISTANCE_CULLING_RADII = 800.0; + struct Appearance : properties::PropertyOwner { Appearance(); /// Specifies the base color of the line before fading diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp index f92385d35f..87836132bd 100644 --- a/modules/base/rendering/renderabletrailorbit.cpp +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -356,6 +356,25 @@ void RenderableTrailOrbit::update(const UpdateData& data) { glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glBindVertexArray(0); + + // Updating bounding sphere + glm::vec3 maxVertex(std::numeric_limits::min()); + glm::vec3 minVertex(std::numeric_limits::max()); + + auto setMax = [&maxVertex, &minVertex](TrailVBOLayout &vertexData) + { + maxVertex.x = maxVertex.x < vertexData.x ? vertexData.x : maxVertex.x; + maxVertex.y = maxVertex.y < vertexData.y ? vertexData.y : maxVertex.y; + maxVertex.z = maxVertex.z < vertexData.z ? vertexData.z : maxVertex.z; + + minVertex.x = minVertex.x > vertexData.x ? vertexData.x : minVertex.x; + minVertex.y = minVertex.y > vertexData.y ? vertexData.y : minVertex.y; + minVertex.z = minVertex.z > vertexData.z ? vertexData.z : minVertex.z; + }; + + std::for_each(_vertexArray.begin(), _vertexArray.end(), setMax); + + setBoundingSphere(glm::distance(maxVertex, minVertex) / 2.0); } RenderableTrailOrbit::UpdateReport RenderableTrailOrbit::updateTrails( From e3b3aec1ed511a1fea5ec4b5c92c3859a13f8358 Mon Sep 17 00:00:00 2001 From: eriksunden Date: Fri, 24 Jan 2020 15:53:29 +0100 Subject: [PATCH 121/214] Fixed issue 1049(using first viewport size as framebuffer size) and 554(loading and ending screen will be visible on the first viewport only). Also fixed such that Lua Console adapts to window size and not framebuffer size. --- apps/OpenSpace/main.cpp | 21 ++++++------- config/single_sbs_stereo.xml | 30 +++++++++++++++++++ include/openspace/engine/windowdelegate.h | 2 -- .../base/rendering/screenspacedashboard.cpp | 2 +- .../base/rendering/screenspaceframebuffer.cpp | 15 ++++------ modules/cefwebgui/cefwebguimodule.cpp | 9 ++++-- .../rendering/renderablebillboardscloud.cpp | 2 +- modules/imgui/imguimodule.cpp | 4 +-- modules/webbrowser/include/browserinstance.h | 2 ++ modules/webbrowser/src/browserinstance.cpp | 3 +- openspace.cfg | 3 ++ src/rendering/framebufferrenderer.cpp | 8 ++--- src/rendering/loadingscreen.cpp | 4 +-- src/rendering/luaconsole.cpp | 4 +-- src/rendering/renderengine.cpp | 14 ++++----- src/rendering/screenspacerenderable.cpp | 4 +-- src/scene/scenegraphnode.cpp | 2 +- src/util/touch.cpp | 2 +- 18 files changed, 84 insertions(+), 47 deletions(-) create mode 100644 config/single_sbs_stereo.xml diff --git a/apps/OpenSpace/main.cpp b/apps/OpenSpace/main.cpp index 8f119dd707..0d4a5c7c86 100644 --- a/apps/OpenSpace/main.cpp +++ b/apps/OpenSpace/main.cpp @@ -890,6 +890,11 @@ void setSgctDelegateFunctions() { }; sgctDelegate.currentSubwindowSize = []() { auto window = sgct::Engine::instance()->getCurrentWindowPtr(); + if (sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfViewports() > 1) { + sgct_core::Viewport* viewport = + sgct::Engine::instance()->getCurrentWindowPtr()->getViewport(0); + return glm::ivec2(window->getXResolution()*viewport->getXSize(), window->getYResolution()*viewport->getYSize()); + } switch (window->getStereoMode()) { case sgct::SGCTWindow::Side_By_Side_Stereo: case sgct::SGCTWindow::Side_By_Side_Inverted_Stereo: @@ -915,6 +920,12 @@ void setSgctDelegateFunctions() { int res = viewport->getNonLinearProjectionPtr()->getCubemapResolution(); return glm::ivec2(res, res); } + else if (sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfViewports() > 1) { + int x, y; + auto window = sgct::Engine::instance()->getCurrentWindowPtr(); + window->getFinalFBODimensions(x, y); + return glm::ivec2(x*viewport->getXSize(), y*viewport->getYSize()); + } else { int x, y; auto window = sgct::Engine::instance()->getCurrentWindowPtr(); @@ -944,16 +955,6 @@ void setSgctDelegateFunctions() { sgctDelegate.currentNumberOfAaSamples = []() { return sgct::Engine::instance()->getCurrentWindowPtr()->getNumberOfAASamples(); }; - sgctDelegate.isRegularRendering = []() { - sgct::SGCTWindow* w = sgct::Engine::instance()->getCurrentWindowPtr(); - ghoul_assert( - w->getNumberOfViewports() > 0, - "At least one viewport must exist at this time" - ); - sgct_core::Viewport* vp = w->getViewport(0); - sgct_core::NonLinearProjection* nlp = vp->getNonLinearProjectionPtr(); - return nlp == nullptr; - }; sgctDelegate.hasGuiWindow = []() { auto engine = sgct::Engine::instance(); for (size_t i = 0; i < engine->getNumberOfWindows(); ++i) { diff --git a/config/single_sbs_stereo.xml b/config/single_sbs_stereo.xml new file mode 100644 index 0000000000..87ee3a33ec --- /dev/null +++ b/config/single_sbs_stereo.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/include/openspace/engine/windowdelegate.h b/include/openspace/engine/windowdelegate.h index 70f6f21d3d..677bed9a3d 100644 --- a/include/openspace/engine/windowdelegate.h +++ b/include/openspace/engine/windowdelegate.h @@ -74,8 +74,6 @@ struct WindowDelegate { int (*currentNumberOfAaSamples)() = []() { return 1; }; - bool (*isRegularRendering)() = []() { return true; }; - bool (*hasGuiWindow)() = []() { return false; }; bool (*isGuiWindow)() = []() { return false; }; diff --git a/modules/base/rendering/screenspacedashboard.cpp b/modules/base/rendering/screenspacedashboard.cpp index c0530f8491..e252807e1f 100644 --- a/modules/base/rendering/screenspacedashboard.cpp +++ b/modules/base/rendering/screenspacedashboard.cpp @@ -201,7 +201,7 @@ bool ScreenSpaceDashboard::isReady() const { void ScreenSpaceDashboard::update() { if (global::windowDelegate.windowHasResized()) { - const glm::ivec2 size = global::windowDelegate.currentWindowResolution(); + const glm::ivec2 size = global::windowDelegate.currentDrawBufferResolution(); _size = { 0.f, 0.f, size.x, size.y }; createFramebuffer(); } diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index 5a94669b99..035e38b618 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -77,7 +77,7 @@ ScreenSpaceFramebuffer::ScreenSpaceFramebuffer(const ghoul::Dictionary& dictiona setGuiName("ScreenSpaceFramebuffer " + std::to_string(iIdentifier)); } - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); addProperty(_size); _size.set(glm::vec4(0, 0, resolution.x,resolution.y)); } @@ -103,13 +103,15 @@ bool ScreenSpaceFramebuffer::deinitializeGL() { } void ScreenSpaceFramebuffer::render() { - const glm::vec2& resolution = global::windowDelegate.currentWindowResolution(); + const glm::vec2& resolution = global::windowDelegate.currentDrawBufferResolution(); const glm::vec4& size = _size.value(); const float xratio = resolution.x / (size.z - size.x); const float yratio = resolution.y / (size.w - size.y);; if (!_renderFunctions.empty()) { + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); glViewport( static_cast(-size.x * xratio), static_cast(-size.y * yratio), @@ -127,12 +129,7 @@ void ScreenSpaceFramebuffer::render() { _framebuffer->deactivate(); glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); - glViewport( - 0, - 0, - static_cast(resolution.x), - static_cast(resolution.y) - ); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); const glm::mat4 globalRotation = globalRotationMatrix(); const glm::mat4 translation = translationMatrix(); @@ -170,7 +167,7 @@ void ScreenSpaceFramebuffer::removeAllRenderFunctions() { } void ScreenSpaceFramebuffer::createFramebuffer() { - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); _framebuffer = std::make_unique(); _framebuffer->activate(); diff --git a/modules/cefwebgui/cefwebguimodule.cpp b/modules/cefwebgui/cefwebguimodule.cpp index e0a1de88e7..8a6951f8de 100644 --- a/modules/cefwebgui/cefwebguimodule.cpp +++ b/modules/cefwebgui/cefwebguimodule.cpp @@ -103,6 +103,10 @@ void CefWebGuiModule::startOrStopGui() { new GUIKeyboardHandler ); _instance->initialize(); + _instance->reshape(static_cast( + static_cast(global::windowDelegate.currentSubwindowSize()) * + global::windowDelegate.dpiScaling() + )); if (!_url.value().empty()) { _instance->loadUrl(_url); } @@ -200,11 +204,12 @@ void CefWebGuiModule::internalInitialize(const ghoul::Dictionary& configuration) const bool isMaster = global::windowDelegate.isMaster(); if (isGuiWindow && isMaster && _instance) { - if (global::windowDelegate.windowHasResized()) { + if (global::windowDelegate.windowHasResized() || _instance->_shouldReshape) { _instance->reshape(static_cast( - static_cast(global::windowDelegate.currentWindowSize()) * + static_cast(global::windowDelegate.currentSubwindowSize()) * global::windowDelegate.dpiScaling() )); + _instance->_shouldReshape = false; } if (_visible) { _instance->draw(); diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index c5a6032e25..9ef2a3a9a9 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -1731,7 +1731,7 @@ void RenderableBillboardsCloud::renderToTexture(GLuint textureToRenderTo, glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureToRenderTo, 0); - glViewport(0, 0, textureWidth, textureHeight); + glViewport(viewport[0], viewport[1], textureWidth, textureHeight); loadPolygonGeometryForRendering(); renderPolygonGeometry(_polygonVao); diff --git a/modules/imgui/imguimodule.cpp b/modules/imgui/imguimodule.cpp index a8ee5aacff..7ee1293e2d 100644 --- a/modules/imgui/imguimodule.cpp +++ b/modules/imgui/imguimodule.cpp @@ -151,8 +151,8 @@ ImGUIModule::ImGUIModule() : OpenSpaceModule(Name) { WindowDelegate& delegate = global::windowDelegate; const bool showGui = delegate.hasGuiWindow() ? delegate.isGuiWindow() : true; if (delegate.isMaster() && showGui) { - const glm::ivec2 windowSize = delegate.currentWindowSize(); - const glm::ivec2 resolution = delegate.currentWindowResolution(); + const glm::ivec2 windowSize = delegate.currentSubwindowSize(); + const glm::ivec2 resolution = delegate.currentDrawBufferResolution(); if (windowSize.x <= 0 || windowSize.y <= 0) { return; diff --git a/modules/webbrowser/include/browserinstance.h b/modules/webbrowser/include/browserinstance.h index 5aa1cc71de..688949963d 100644 --- a/modules/webbrowser/include/browserinstance.h +++ b/modules/webbrowser/include/browserinstance.h @@ -119,6 +119,8 @@ public: bool hasContent(int x, int y); + bool _shouldReshape = false; + private: CefRefPtr _renderHandler; CefRefPtr _keyboardHandler; diff --git a/modules/webbrowser/src/browserinstance.cpp b/modules/webbrowser/src/browserinstance.cpp index 3622a4583e..61f14ad7ad 100644 --- a/modules/webbrowser/src/browserinstance.cpp +++ b/modules/webbrowser/src/browserinstance.cpp @@ -74,10 +74,11 @@ BrowserInstance::~BrowserInstance() { void BrowserInstance::initialize() { reshape(static_cast( - static_cast(global::windowDelegate.currentWindowSize()) * + static_cast(global::windowDelegate.currentSubwindowSize()) * global::windowDelegate.dpiScaling() )); _isInitialized = true; + _shouldReshape = true; } void BrowserInstance::loadUrl(std::string url) { diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..30cff1afed 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -32,6 +32,9 @@ SGCTConfig = sgct.config.single{} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} +-- A side-by-side test of mutiple viewport (also with different eyes) +-- SGCTConfig = "${CONFIG}/single_sbs_stereo.xml" + -- Spout exit -- SGCTConfig = "${CONFIG}/spout_output.xml" diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 0a6dd0ab57..579319a6cb 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1137,8 +1137,6 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); } - glViewport(0, 0, _resolution.x, _resolution.y); - // Apply the selected TMO on the results and resolve the result for the default FBO applyTMO(blackoutFactor); @@ -1155,6 +1153,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindFramebuffer(GL_FRAMEBUFFER, _exitFramebuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); ghoul::opengl::ProgramObject* exitProgram = _exitPrograms[raycaster].get(); if (exitProgram) { @@ -1166,7 +1166,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); - glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); + glViewport(viewport[0], viewport[1], viewport[2] * scaleDown, viewport[3] * scaleDown); if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; updateDownscaleTextures(); @@ -1259,7 +1259,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycaster->downscaleRender() < 1.f) { - glViewport(0, 0, _resolution.x, _resolution.y); + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); } diff --git a/src/rendering/loadingscreen.cpp b/src/rendering/loadingscreen.cpp index 7a876ef8ab..6ef24cdb46 100644 --- a/src/rendering/loadingscreen.cpp +++ b/src/rendering/loadingscreen.cpp @@ -159,7 +159,7 @@ void LoadingScreen::render() { const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const glm::ivec2 res = - glm::vec2(global::windowDelegate.currentDrawBufferResolution()) / dpiScaling; + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; float screenAspectRatio = static_cast(res.x) / static_cast(res.y); @@ -178,7 +178,7 @@ void LoadingScreen::render() { // glClearColor(0.f, 0.f, 0.f, 1.f); glClear(ClearBufferMask::GL_COLOR_BUFFER_BIT); - + glViewport(0, 0, res.x, res.y); glDisable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/rendering/luaconsole.cpp b/src/rendering/luaconsole.cpp index d4c02f3a16..d32a1ace4c 100644 --- a/src/rendering/luaconsole.cpp +++ b/src/rendering/luaconsole.cpp @@ -615,7 +615,7 @@ void LuaConsole::update() { // Update the current height. // The current height is the offset that is used to slide // the console in from the top. - const glm::ivec2 res = global::windowDelegate.currentWindowResolution(); + const glm::ivec2 res = global::windowDelegate.currentSubwindowSize(); const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const double dHeight = (_targetHeight - _currentHeight) * std::pow(0.98, 1.0 / (ConsoleOpenSpeed / dpiScaling.y * frametime)); @@ -636,7 +636,7 @@ void LuaConsole::render() { const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); const glm::ivec2 res = - glm::vec2(global::windowDelegate.currentWindowResolution()) / dpiScaling; + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; // Render background diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index d8dcbd7b65..5fde95806a 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -555,12 +555,7 @@ void RenderEngine::updateScreenSpaceRenderables() { } glm::ivec2 RenderEngine::renderingResolution() const { - if (global::windowDelegate.isRegularRendering()) { - return global::windowDelegate.currentWindowResolution(); - } - else { - return global::windowDelegate.currentDrawBufferResolution(); - } + return global::windowDelegate.currentDrawBufferResolution(); } glm::ivec2 RenderEngine::fontResolution() const { @@ -569,7 +564,7 @@ glm::ivec2 RenderEngine::fontResolution() const { return global::windowDelegate.currentViewportSize(); } else { - return global::windowDelegate.currentWindowSize(); + return global::windowDelegate.currentSubwindowSize(); } } @@ -771,6 +766,11 @@ void RenderEngine::renderEndscreen() { glm::vec4(0.f, 0.f, 0.f, 0.5f) ); + const glm::vec2 dpiScaling = global::windowDelegate.dpiScaling(); + const glm::ivec2 res = + glm::vec2(global::windowDelegate.currentSubwindowSize()) / dpiScaling; + glViewport(0, 0, res.x, res.y); + using FR = ghoul::fontrendering::FontRenderer; using BBox = FR::BoundingBoxInformation; BBox size = FR::defaultRenderer().boundingBox( diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index 6fe7813bc8..ce8ea4511c 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -515,7 +515,7 @@ float ScreenSpaceRenderable::depth() { void ScreenSpaceRenderable::createShaders() { ghoul::Dictionary dict = ghoul::Dictionary(); - auto res = global::windowDelegate.currentWindowResolution(); + auto res = global::windowDelegate.currentDrawBufferResolution(); ghoul::Dictionary rendererData = { { "fragmentRendererPath", "${SHADERS}/framebuffer/renderframebuffer.frag" }, { "windowWidth" , res.x }, @@ -537,7 +537,7 @@ void ScreenSpaceRenderable::createShaders() { } glm::mat4 ScreenSpaceRenderable::scaleMatrix() { - glm::vec2 resolution = global::windowDelegate.currentWindowResolution(); + glm::vec2 resolution = global::windowDelegate.currentDrawBufferResolution(); //to scale the plane float textureRatio = diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index fd9e731817..f56d29b136 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -684,7 +684,7 @@ void SceneGraphNode::computeScreenSpaceData(RenderData& newData) { return; } - glm::ivec2 res = global::windowDelegate.currentWindowSize(); + glm::ivec2 res = global::windowDelegate.currentSubwindowSize(); // Get the radius of node double nodeRadius = static_cast(this->boundingSphere()); diff --git a/src/util/touch.cpp b/src/util/touch.cpp index ab16c23ed4..995e871850 100644 --- a/src/util/touch.cpp +++ b/src/util/touch.cpp @@ -44,7 +44,7 @@ glm::vec2 TouchInput::screenCoordinates(glm::vec2 resolution) const { } glm::vec2 TouchInput::currentWindowCoordinates() const { - glm::vec2 res = global::windowDelegate.currentWindowSize(); + glm::vec2 res = global::windowDelegate.currentSubwindowSize(); return { std::floor(x * res.x + 0.5f), std::floor(y * res.y + 0.5f) }; } From 182857cfb8a169d59afb0c233456b2e447aa63c2 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 24 Jan 2020 19:38:27 +0100 Subject: [PATCH 122/214] Update Ghoul and SGCT repositories --- apps/OpenSpace/ext/sgct | 2 +- ext/ghoul | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/OpenSpace/ext/sgct b/apps/OpenSpace/ext/sgct index 25c8d30bde..7492a4fdd6 160000 --- a/apps/OpenSpace/ext/sgct +++ b/apps/OpenSpace/ext/sgct @@ -1 +1 @@ -Subproject commit 25c8d30bde216066840d197e4443def196c70e17 +Subproject commit 7492a4fdd60ccd5ef7ed5200c1aaa26853f97d0d diff --git a/ext/ghoul b/ext/ghoul index e6ef5101e7..48d3b96434 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit e6ef5101e7dd5e5ba19329ed9f5e5806e257b5ed +Subproject commit 48d3b96434497cc2cdcf266255374fa722ad2d8a From 32caf0ab8cfb22611fb4af6c44e4a3484fef31b4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 24 Jan 2020 19:51:24 +0100 Subject: [PATCH 123/214] Update location of SGCT repository --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3e4cfb738b..516a853c2b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,7 +16,7 @@ branch = OpenSpace [submodule "apps/OpenSpace/ext/sgct"] path = apps/OpenSpace/ext/sgct - url = https://github.com/opensgct/sgct + url = https://github.com/sgct/sgct [submodule "modules/fitsfilereader/ext/CCfits"] path = modules/fitsfilereader/ext/CCfits url = https://github.com/OpenSpace/CCfits.git From 87805f1db854e73aeb43febef60e5e3ab93ec7a6 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 24 Jan 2020 21:08:54 +0100 Subject: [PATCH 124/214] Coding style fixes --- modules/base/rendering/renderablelabels.cpp | 72 +++++---------- modules/base/rendering/renderablelabels.h | 2 +- modules/base/rendering/renderablenodeline.cpp | 89 ++++++++++--------- modules/base/rendering/renderablenodeline.h | 11 +-- .../rendering/renderabledistancelabel.cpp | 35 +++++--- .../rendering/renderabledistancelabel.h | 2 +- modules/vislab/vislabmodule.cpp | 5 +- modules/vislab/vislabmodule.h | 2 - 8 files changed, 98 insertions(+), 120 deletions(-) diff --git a/modules/base/rendering/renderablelabels.cpp b/modules/base/rendering/renderablelabels.cpp index d5f84a2427..1cd59dee12 100644 --- a/modules/base/rendering/renderablelabels.cpp +++ b/modules/base/rendering/renderablelabels.cpp @@ -31,19 +31,19 @@ #include #include #include -#include +#include #include -#include -#include -#include -#include +#include #include #include +#include +#include +#include #include +#include #include #include #include -#include #include namespace { @@ -175,7 +175,6 @@ namespace { "Fade-In/-Out ending speed.", "Fade-In/-Out ending speed." }; - } // namespace namespace openspace { @@ -641,8 +640,8 @@ void RenderableLabels::render(const RenderData& data, RendererTasks&) { data.camera.positionVec3(), data.modelTransform.translation ); - float sUnit = getUnit(_fadeStartUnitOption); - float eUnit = getUnit(_fadeEndUnitOption); + float sUnit = unit(_fadeStartUnitOption); + float eUnit = unit(_fadeEndUnitOption); float startX = _fadeStartDistance * sUnit; float endX = _fadeEndDistance * eUnit; //fadeInVariable = changedPerlinSmoothStepFunc(distanceNodeToCamera, startX, endX); @@ -767,49 +766,22 @@ float RenderableLabels::linearSmoothStepFunc(float x, float startX, float endX, } } -float RenderableLabels::getUnit(int unit) const { - - float scale = 0.f; +float RenderableLabels::unit(int unit) const { switch (static_cast(unit)) { - case Meter: - scale = 1.f; - break; - case Kilometer: - scale = 1e3; - break; - case Megameter: - scale = 1e6; - break; - case Gigameter: - scale = 1e9; - break; - case AU: - scale = 149597870700.f; - break; - case Terameter: - scale = 1e12; - break; - case Petameter: - scale = 1e15; - break; - case Parsec: - scale = static_cast(PARSEC); - break; - case Kiloparsec: - scale = static_cast(1e3 * PARSEC); - break; - case Megaparsec: - scale = static_cast(1e6 * PARSEC); - break; - case Gigaparsec: - scale = static_cast(1e9 * PARSEC); - break; - case GigalightYears: - scale = static_cast(306391534.73091 * PARSEC); - break; + case Meter: return 1.f; + case Kilometer: return 1e3; + case Megameter: return 1e6; + case Gigameter: return 1e9; + case AU: return 149597870700.f; + case Terameter: return 1e12; + case Petameter: return 1e15; + case Parsec: return static_cast(PARSEC); + case Kiloparsec: return static_cast(1e3 * PARSEC); + case Megaparsec: return static_cast(1e6 * PARSEC); + case Gigaparsec: return static_cast(1e9 * PARSEC); + case GigalightYears: return static_cast(306391534.73091 * PARSEC); + default: throw std::logic_error("Missing case label"); } - - return scale; } } // namespace openspace diff --git a/modules/base/rendering/renderablelabels.h b/modules/base/rendering/renderablelabels.h index 4546ad9211..df69d50544 100644 --- a/modules/base/rendering/renderablelabels.h +++ b/modules/base/rendering/renderablelabels.h @@ -72,7 +72,7 @@ public: protected: properties::OptionProperty _blendMode; - float getUnit(int unit) const; + float unit(int unit) const; // Data may require some type of transformation prior the spice transformation being // applied. diff --git a/modules/base/rendering/renderablenodeline.cpp b/modules/base/rendering/renderablenodeline.cpp index 8d809df5f4..7725b8e4ab 100644 --- a/modules/base/rendering/renderablenodeline.cpp +++ b/modules/base/rendering/renderablenodeline.cpp @@ -67,6 +67,22 @@ namespace { "Line Width", "This value specifies the line width." }; + + // Returns a position that is relative to the current anchor node. This is a method to + // handle precision problems that occur when approaching a line end point + glm::dvec3 coordinatePosFromAnchorNode(const glm::dvec3& worldPos) { + using namespace openspace; + glm::dvec3 anchorNodePos(0.0); + + const interaction::OrbitalNavigator& nav = + global::navigationHandler.orbitalNavigator(); + + if (nav.anchorNode()) { + anchorNodePos = nav.anchorNode()->worldPosition(); + } + glm::dvec3 diffPos = worldPos - anchorNodePos; + return diffPos; + } } // namespace namespace openspace { @@ -143,19 +159,16 @@ RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary) addProperty(_opacity); } -double RenderableNodeLine::getDistance() -{ +double RenderableNodeLine::distance() const { return glm::distance(_startPos, _endPos); } -const std::string RenderableNodeLine::getStart() -{ - return _start.value(); +std::string RenderableNodeLine::start() const { + return _start; } -const std::string RenderableNodeLine::getEnd() -{ - return _end.value(); +std::string RenderableNodeLine::end() const { + return _end; } void RenderableNodeLine::initializeGL() { @@ -183,7 +196,6 @@ void RenderableNodeLine::initializeGL() { } void RenderableNodeLine::deinitializeGL() { - glDeleteVertexArrays(1, &_vaoId); _vaoId = 0; @@ -210,19 +222,21 @@ void RenderableNodeLine::unbindGL() { glBindVertexArray(0); } -void RenderableNodeLine::bindGL() -{ +void RenderableNodeLine::bindGL() { glBindVertexArray(_vaoId); glBindBuffer(GL_ARRAY_BUFFER, _vBufferId); } -void RenderableNodeLine::updateVertexData() -{ +void RenderableNodeLine::updateVertexData() { _vertexArray.clear(); // Update the positions of the nodes - _startPos = getCoordinatePosFromAnchorNode(global::renderEngine.scene()->sceneGraphNode(_start)->worldPosition()); - _endPos = getCoordinatePosFromAnchorNode(global::renderEngine.scene()->sceneGraphNode(_end)->worldPosition()); + _startPos = coordinatePosFromAnchorNode( + global::renderEngine.scene()->sceneGraphNode(_start)->worldPosition() + ); + _endPos = coordinatePosFromAnchorNode( + global::renderEngine.scene()->sceneGraphNode(_end)->worldPosition() + ); _vertexArray.push_back(_startPos.x); _vertexArray.push_back(_startPos.y); @@ -242,14 +256,13 @@ void RenderableNodeLine::updateVertexData() GL_DYNAMIC_DRAW ); - //update vertex attributes + // update vertex attributes glVertexAttribPointer(_locVertex, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr); unbindGL(); } void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { - updateVertexData(); _program->activate(); @@ -257,7 +270,10 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { glm::dmat4 anchorTranslation(1.0); // Update anchor node information, used to counter precision problems if (global::navigationHandler.orbitalNavigator().anchorNode()) { - anchorTranslation = glm::translate(glm::dmat4(1.0), global::navigationHandler.orbitalNavigator().anchorNode()->worldPosition()); + anchorTranslation = glm::translate( + glm::dmat4(1.0), + global::navigationHandler.orbitalNavigator().anchorNode()->worldPosition() + ); } const glm::dmat4 modelTransform = @@ -278,8 +294,12 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { GLfloat currentLineWidth; glGetFloatv(GL_LINE_WIDTH, ¤tLineWidth); - GLenum blendEquationRGB, blendEquationAlpha, blendDestAlpha, - blendDestRGB, blendSrcAlpha, blendSrcRGB; + GLenum blendEquationRGB; + GLenum blendEquationAlpha; + GLenum blendDestAlpha; + GLenum blendDestRGB; + GLenum blendSrcAlpha; + GLenum blendSrcRGB; glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); @@ -311,34 +331,19 @@ void RenderableNodeLine::render(const RenderData& data, RendererTasks&) { } } -void RenderableNodeLine::validateNodes() -{ +void RenderableNodeLine::validateNodes() { if (!global::renderEngine.scene()->sceneGraphNode(_start)) { - LERROR(fmt::format("There is no scenegraph node with id {}, defaults to 'Root'", _start)); + LERROR(fmt::format( + "There is no scenegraph node with id {}, defaults to 'Root'", _start + )); _start = Root; } if (!global::renderEngine.scene()->sceneGraphNode(_end)) { - LERROR(fmt::format("There is no scenegraph node with id {}, defaults to 'Root'", _end)); + LERROR(fmt::format( + "There is no scenegraph node with id {}, defaults to 'Root'", _end + )); _end = Root; } } - -/* Returns a position that is relative to the current - anchor node. This is a method to handle precision - problems that occur when approaching a line end point */ -glm::dvec3 RenderableNodeLine::getCoordinatePosFromAnchorNode(glm::dvec3 worldPos) { - - glm::dvec3 anchorNodePos(0); - - if (global::navigationHandler.orbitalNavigator().anchorNode()) { - anchorNodePos = global::navigationHandler.orbitalNavigator().anchorNode()->worldPosition(); - } - glm::dvec3 diffPos = glm::dvec3(worldPos.x - anchorNodePos.x, worldPos.y - anchorNodePos.y, - worldPos.z - anchorNodePos.z); - - return diffPos; -} - - } // namespace openspace diff --git a/modules/base/rendering/renderablenodeline.h b/modules/base/rendering/renderablenodeline.h index 53cd54a860..5c7f4f6a88 100644 --- a/modules/base/rendering/renderablenodeline.h +++ b/modules/base/rendering/renderablenodeline.h @@ -34,11 +34,10 @@ #include namespace ghoul::opengl { class ProgramObject; } +namespace openspace::documentation { struct Documentation; } namespace openspace { -namespace documentation { struct Documentation; } - class Translation; /** @@ -52,10 +51,10 @@ public: static documentation::Documentation Documentation(); // Get the distance between the start and end node - double getDistance(); + double distance() const; - const std::string getStart(); - const std::string getEnd(); + std::string start() const; + std::string end() const; private: void initializeGL() override; @@ -69,8 +68,6 @@ private: void unbindGL(); void bindGL(); - glm::dvec3 getCoordinatePosFromAnchorNode(glm::dvec3 worldPos); - ghoul::opengl::ProgramObject* _program; /// The vertex attribute location for position /// must correlate to layout location in vertex shader diff --git a/modules/vislab/rendering/renderabledistancelabel.cpp b/modules/vislab/rendering/renderabledistancelabel.cpp index 3ff5082758..1d2cac67b8 100644 --- a/modules/vislab/rendering/renderabledistancelabel.cpp +++ b/modules/vislab/rendering/renderabledistancelabel.cpp @@ -24,13 +24,13 @@ #include -#include #include #include #include #include #include #include +#include #include namespace { @@ -39,8 +39,8 @@ namespace { constexpr openspace::properties::Property::PropertyInfo NodeLineInfo = { "NodeLine", "Node Line", - "Property to track a nodeline. When tracking the label text will be updating the distance " - "from the nodeline start and end. " + "Property to track a nodeline. When tracking the label text will be updating the " + "distance from the nodeline start and end." }; } @@ -78,38 +78,45 @@ RenderableDistanceLabel::RenderableDistanceLabel(const ghoul::Dictionary& dictio } } -void RenderableDistanceLabel::update(const UpdateData& data) { +void RenderableDistanceLabel::update(const UpdateData&) { + if (_errorThrown) { + return; + } - SceneGraphNode* nodelineNode = global::renderEngine.scene()->sceneGraphNode(_nodelineId); - - if (nodelineNode && !_errorThrown) { + RenderEngine& RE = global::renderEngine; + SceneGraphNode* nodelineNode = RE.scene()->sceneGraphNode(_nodelineId); + if (nodelineNode) { // Calculate distance - RenderableNodeLine* nodeline = dynamic_cast(nodelineNode->renderable()); + RenderableNodeLine* nodeline = dynamic_cast( + nodelineNode->renderable() + ); if (!nodeline) { LERROR("Expected renderable to be of type 'RenderableNodeLine'"); _errorThrown = true; return; } - double myDistance = nodeline->getDistance(); + double myDistance = nodeline->distance(); // Format string - float scale = getUnit(Kilometer); + float scale = unit(Kilometer); std::string distanceText = std::to_string(std::round(myDistance / scale)); - int pos = distanceText.find("."); + int pos = static_cast(distanceText.find(".")); std::string subStr = distanceText.substr(pos); distanceText.erase(pos, subStr.size()); std::string finalText = distanceText + " Km"; setLabelText(finalText); // Update placement of label with transformation matrix - glm::dvec3 start = global::renderEngine.scene()->sceneGraphNode(nodeline->getStart())->worldPosition(); - glm::dvec3 end = global::renderEngine.scene()->sceneGraphNode(nodeline->getEnd())->worldPosition(); + SceneGraphNode* startNode = RE.scene()->sceneGraphNode(nodeline->start()); + glm::dvec3 start = startNode->worldPosition(); + SceneGraphNode* endNode = RE.scene()->sceneGraphNode(nodeline->end()); + glm::dvec3 end = endNode->worldPosition(); glm::dvec3 goalPos = start + (end - start) / 2.0; _transformationMatrix = glm::translate(glm::dmat4(1.0), goalPos); } - else if (!_errorThrown) { + else { LERROR(fmt::format("There is no scenegraph node with id {}", _nodelineId)); _errorThrown = true; } diff --git a/modules/vislab/rendering/renderabledistancelabel.h b/modules/vislab/rendering/renderabledistancelabel.h index d6eee298f4..42f0f4165d 100644 --- a/modules/vislab/rendering/renderabledistancelabel.h +++ b/modules/vislab/rendering/renderabledistancelabel.h @@ -22,7 +22,6 @@ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ - #ifndef __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ #define __OPENSPACE_MODULE_VISLAB___RENDERABLEDISTANCELABEL___H__ @@ -38,6 +37,7 @@ public: void update(const UpdateData& data) override; static documentation::Documentation Documentation(); +private: properties::StringProperty _nodelineId; bool _errorThrown = false; diff --git a/modules/vislab/vislabmodule.cpp b/modules/vislab/vislabmodule.cpp index ac49e60b77..9546cc9704 100644 --- a/modules/vislab/vislabmodule.cpp +++ b/modules/vislab/vislabmodule.cpp @@ -25,14 +25,13 @@ #include #include +#include #include #include -#include namespace openspace { -VisLabModule::VisLabModule() : OpenSpaceModule(Name) { -} +VisLabModule::VisLabModule() : OpenSpaceModule(Name) {} void VisLabModule::internalInitialize(const ghoul::Dictionary&) { auto renderableFactory = FactoryManager::ref().factory(); diff --git a/modules/vislab/vislabmodule.h b/modules/vislab/vislabmodule.h index 7e43152cac..797fcde9f5 100644 --- a/modules/vislab/vislabmodule.h +++ b/modules/vislab/vislabmodule.h @@ -25,7 +25,6 @@ #ifndef __OPENSPACE_MODULE_VISLAB___VISLABMODULE___H__ #define __OPENSPACE_MODULE_VISLAB___VISLABMODULE___H__ - #include namespace openspace { @@ -38,7 +37,6 @@ public: private: void internalInitialize(const ghoul::Dictionary&) override; - }; } // namespace openspace From 4cef2be366f918ee779ef539ef7b85b0c1b5ee4f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 24 Jan 2020 21:40:09 +0100 Subject: [PATCH 125/214] Small cleanup --- modules/base/rendering/renderabletrailorbit.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/modules/base/rendering/renderabletrailorbit.cpp b/modules/base/rendering/renderabletrailorbit.cpp index 87836132bd..4a06aaf182 100644 --- a/modules/base/rendering/renderabletrailorbit.cpp +++ b/modules/base/rendering/renderabletrailorbit.cpp @@ -358,18 +358,17 @@ void RenderableTrailOrbit::update(const UpdateData& data) { glBindVertexArray(0); // Updating bounding sphere - glm::vec3 maxVertex(std::numeric_limits::min()); + glm::vec3 maxVertex(-std::numeric_limits::max()); glm::vec3 minVertex(std::numeric_limits::max()); - auto setMax = [&maxVertex, &minVertex](TrailVBOLayout &vertexData) - { - maxVertex.x = maxVertex.x < vertexData.x ? vertexData.x : maxVertex.x; - maxVertex.y = maxVertex.y < vertexData.y ? vertexData.y : maxVertex.y; - maxVertex.z = maxVertex.z < vertexData.z ? vertexData.z : maxVertex.z; + auto setMax = [&maxVertex, &minVertex](const TrailVBOLayout& vertexData) { + maxVertex.x = std::max(maxVertex.x, vertexData.x); + maxVertex.y = std::max(maxVertex.y, vertexData.y); + maxVertex.z = std::max(maxVertex.z, vertexData.z); - minVertex.x = minVertex.x > vertexData.x ? vertexData.x : minVertex.x; - minVertex.y = minVertex.y > vertexData.y ? vertexData.y : minVertex.y; - minVertex.z = minVertex.z > vertexData.z ? vertexData.z : minVertex.z; + minVertex.x = std::min(minVertex.x, vertexData.x); + minVertex.y = std::min(minVertex.y, vertexData.y); + minVertex.z = std::min(minVertex.z, vertexData.z); }; std::for_each(_vertexArray.begin(), _vertexArray.end(), setMax); From 4440a2a554d9b31558c6f047f6bb44874bbf87f3 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 24 Jan 2020 21:41:06 +0100 Subject: [PATCH 126/214] Update Ghoul reference --- ext/ghoul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/ghoul b/ext/ghoul index d73b914734..48d3b96434 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit d73b9147347140932bf0691788183db92ccfaf14 +Subproject commit 48d3b96434497cc2cdcf266255374fa722ad2d8a From ad29ea53f5ab7bb817b11cd3b4c25fe5bf1587cf Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 26 Jan 2020 09:13:48 -0500 Subject: [PATCH 127/214] csv bookmark files --- .../assets/customization/localbookmarks.asset | 7 ++ data/assets/customization/localbookmarks.csv | 2 + data/assets/util/generate_bookmarks.asset | 80 +++++++++++++++++++ data/assets/util/openspacebookmarks.asset | 27 +++++++ 4 files changed, 116 insertions(+) create mode 100644 data/assets/customization/localbookmarks.asset create mode 100644 data/assets/customization/localbookmarks.csv create mode 100644 data/assets/util/generate_bookmarks.asset create mode 100644 data/assets/util/openspacebookmarks.asset diff --git a/data/assets/customization/localbookmarks.asset b/data/assets/customization/localbookmarks.asset new file mode 100644 index 0000000000..0373993830 --- /dev/null +++ b/data/assets/customization/localbookmarks.asset @@ -0,0 +1,7 @@ +local assetHelper = asset.require("util/asset_helper") +local bookmarkHelper = asset.require("util/generate_bookmarks") + +local nodes = bookmarkHelper.getBookmarks("Local Bookmarks",'${ASSETS}/customization/localbookmarks.csv') +assetHelper.registerSceneGraphNodesAndExport(asset, nodes); + + diff --git a/data/assets/customization/localbookmarks.csv b/data/assets/customization/localbookmarks.csv new file mode 100644 index 0000000000..5a3187d162 --- /dev/null +++ b/data/assets/customization/localbookmarks.csv @@ -0,0 +1,2 @@ +Group (optional),Name (required),Globe (optional),Lat (required if globe),Lon (required if globe),Altitude (optional if globe),x (required if not globe),y (required if not globe),z (required if not globe),Scale (optional),LineWidth (optional) +Local Bookmarks,Murrow,Earth,40.619,-73.959,,,,,, diff --git a/data/assets/util/generate_bookmarks.asset b/data/assets/util/generate_bookmarks.asset new file mode 100644 index 0000000000..0aac179b49 --- /dev/null +++ b/data/assets/util/generate_bookmarks.asset @@ -0,0 +1,80 @@ +local assetHelper = asset.require('util/asset_helper') + +local getBookmarks = function (guiPath, bookmarkfile) + local genBookmarks = {}; + local notFirstLine = false; + local PARSEC_CONSTANT = 3.0856776E16; + for line in io.lines(openspace.absPath(bookmarkfile)) do + if (notFirstLine) then + local matchstring = "(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-)$" + local group, name, globe, lat, lon, altitude, x, y, z, scale, linewitdh = line:match(matchstring) + + scale = (scale == '' and 75000 or scale) + linewitdh = (linewitdh == '' and 2.0 or tonumber(linewitdh)) + group = (group == "" and globe or group) + + local parent = (globe == "" and 'Root' or globe) + + local sgn = { + Identifier = guiPath .. "-" .. name, + Parent = parent, + Transform = { + Translation = { + }, + Scale = { + Type = "StaticScale", + Scale = tonumber(scale); + } + }, + Renderable = { + Type = "RenderableSphericalGrid", + Enabled = false, + GridColor = { 0.3, 0.84, 1.0, 0.3}, + LineWidth = linewitdh, + GridMatrix = { -0.05487554, 0.4941095, -0.8676661 , 0.0, + -0.9938214 , -0.1109906, -0.0003515167, 0.0, + -0.09647644, 0.8622859, 0.4971472 , 0.0, + 0.0 , 0.0 , 0.0 , 1.0 } + }, + GUI = { + Name = name, + Path = "/" .. guiPath + } + } + + if (group ~= "") then + sgn.GUI.Path = sgn.GUI.Path .. "/" .. group + end + + if (globe == "") then + sgn.Transform.Translation = { + Type = "StaticTranslation", + Position = {tonumber(x) * PARSEC_CONSTANT, tonumber(y) * PARSEC_CONSTANT , tonumber(z) * PARSEC_CONSTANT} + } + else + sgn.Transform.Translation = { + Type = "GlobeTranslation", + Globe = globe, + Latitude = tonumber(lat), + Longitude = tonumber(lon), + } + if (altitude == nil) then + sgn.Transform.Translation.UseHeightMap = true; + else + sgn.Transform.Translation.UseHeightMap = false; + sgn.Transform.Translation.Altitude = tonumber(altitude); + end + + end + + + table.insert(genBookmarks, sgn); + else + notFirstLine = true + end + end + return genBookmarks +end + +asset.export("getBookmarks", getBookmarks) + diff --git a/data/assets/util/openspacebookmarks.asset b/data/assets/util/openspacebookmarks.asset new file mode 100644 index 0000000000..8e8c4f6d7d --- /dev/null +++ b/data/assets/util/openspacebookmarks.asset @@ -0,0 +1,27 @@ +local assetHelper = asset.require("util/asset_helper") +local bookmarkHelper = asset.require("util/generate_bookmarks") + +local dataProvider = "https://pastebin.com/raw/k17aC8VW" -- "http://data.openspaceproject.com/bookmarks.csv" + +local bookmarksCSV = asset.syncedResource({ + Identifier = "openspace_bookmarks", + Name = "OpenSpace Bookmarks", + Type = "UrlSynchronization", + UseHash = false, + Override = true, + Url = dataProvider +}) + +asset.onInitialize(function () + local nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') + for i, n in ipairs(nodes) do + openspace.addSceneGraphNode(n); + end +end) + +asset.onDeinitialize(function () + local nodes = bookmarkHelper.addBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') + for i, n in ipairs(nodes) do + openspace.removeSceneGraphNode(n); + end +end) From 0bc8bd5593e1b761d84254c09662199c5ba57282 Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 26 Jan 2020 09:18:10 -0500 Subject: [PATCH 128/214] fix spaces and url --- data/assets/util/openspacebookmarks.asset | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/data/assets/util/openspacebookmarks.asset b/data/assets/util/openspacebookmarks.asset index 8e8c4f6d7d..262dd52212 100644 --- a/data/assets/util/openspacebookmarks.asset +++ b/data/assets/util/openspacebookmarks.asset @@ -1,7 +1,7 @@ local assetHelper = asset.require("util/asset_helper") local bookmarkHelper = asset.require("util/generate_bookmarks") -local dataProvider = "https://pastebin.com/raw/k17aC8VW" -- "http://data.openspaceproject.com/bookmarks.csv" +local dataProvider = "http://data.openspaceproject.com/bookmarks.csv" local bookmarksCSV = asset.syncedResource({ Identifier = "openspace_bookmarks", @@ -13,15 +13,15 @@ local bookmarksCSV = asset.syncedResource({ }) asset.onInitialize(function () - local nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') - for i, n in ipairs(nodes) do - openspace.addSceneGraphNode(n); - end + local nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') + for i, n in ipairs(nodes) do + openspace.addSceneGraphNode(n); + end end) asset.onDeinitialize(function () - local nodes = bookmarkHelper.addBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') - for i, n in ipairs(nodes) do - openspace.removeSceneGraphNode(n); - end + local nodes = bookmarkHelper.addBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') + for i, n in ipairs(nodes) do + openspace.removeSceneGraphNode(n); + end end) From 2332d6199eb19ab23f0c56c809e137f34fcf49a9 Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 26 Jan 2020 12:24:43 -0500 Subject: [PATCH 129/214] update local and fix openspace --- data/assets/customization/localbookmarks.csv | 2 +- data/assets/util/openspacebookmarks.asset | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/data/assets/customization/localbookmarks.csv b/data/assets/customization/localbookmarks.csv index 5a3187d162..138adef2cf 100644 --- a/data/assets/customization/localbookmarks.csv +++ b/data/assets/customization/localbookmarks.csv @@ -1,2 +1,2 @@ Group (optional),Name (required),Globe (optional),Lat (required if globe),Lon (required if globe),Altitude (optional if globe),x (required if not globe),y (required if not globe),z (required if not globe),Scale (optional),LineWidth (optional) -Local Bookmarks,Murrow,Earth,40.619,-73.959,,,,,, +NASA,Kenedy Space Center,Earth,28.6658276,-80.70282839,,,,,, diff --git a/data/assets/util/openspacebookmarks.asset b/data/assets/util/openspacebookmarks.asset index 262dd52212..a577487048 100644 --- a/data/assets/util/openspacebookmarks.asset +++ b/data/assets/util/openspacebookmarks.asset @@ -12,16 +12,17 @@ local bookmarksCSV = asset.syncedResource({ Url = dataProvider }) +local nodes = {} + asset.onInitialize(function () - local nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') + nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/bookmarks.csv') for i, n in ipairs(nodes) do openspace.addSceneGraphNode(n); end end) asset.onDeinitialize(function () - local nodes = bookmarkHelper.addBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/k17aC8VW') for i, n in ipairs(nodes) do - openspace.removeSceneGraphNode(n); + openspace.removeSceneGraphNode(n.Identifier); end end) From ba4972310d8887cdc3b59c4e2cbc43c3bbb26230 Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 26 Jan 2020 12:35:27 -0500 Subject: [PATCH 130/214] added sequenceTypeImageAndInstrumentTimes as option for patially complete missions --- .../util/imagesequencer.cpp | 2 ++ .../util/projectioncomponent.cpp | 26 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/modules/spacecraftinstruments/util/imagesequencer.cpp b/modules/spacecraftinstruments/util/imagesequencer.cpp index 15465a5aa3..872923e61a 100644 --- a/modules/spacecraftinstruments/util/imagesequencer.cpp +++ b/modules/spacecraftinstruments/util/imagesequencer.cpp @@ -416,6 +416,8 @@ void ImageSequencer::runSequenceParser(SequenceParser& parser) { source.begin(), source.end() ); + + _subsetMap[key]._range.include(it.second._range); } _instrumentTimes.insert( diff --git a/modules/spacecraftinstruments/util/projectioncomponent.cpp b/modules/spacecraftinstruments/util/projectioncomponent.cpp index 990af24184..107d1bb2fd 100644 --- a/modules/spacecraftinstruments/util/projectioncomponent.cpp +++ b/modules/spacecraftinstruments/util/projectioncomponent.cpp @@ -51,12 +51,14 @@ namespace { constexpr const char* keyInstrumentAspect = "Instrument.Aspect"; constexpr const char* keyTranslation = "DataInputTranslation"; + constexpr const char* keyTimesTranslation = "TimesDataInputTranslation"; constexpr const char* keyProjObserver = "Observer"; constexpr const char* keyProjTarget = "Target"; constexpr const char* keyProjAberration = "Aberration"; constexpr const char* keySequenceDir = "Sequence"; + constexpr const char* keyTimesSequenceDir = "TimesSequence"; constexpr const char* keySequenceType = "SequenceType"; constexpr const char* keyNeedsTextureMapDilation = "TextureMap"; @@ -67,6 +69,7 @@ namespace { constexpr const char* sequenceTypePlaybook = "playbook"; constexpr const char* sequenceTypeHybrid = "hybrid"; constexpr const char* sequenceTypeInstrumentTimes = "instrument-times"; + constexpr const char* sequenceTypeImageAndInstrumentTimes = "image-and-instrument-times"; constexpr const char* placeholderFile = "${DATA}/placeholder.png"; @@ -149,7 +152,7 @@ documentation::Documentation ProjectionComponent::Documentation() { keySequenceType, new StringInListVerifier( { sequenceTypeImage, sequenceTypePlaybook, sequenceTypeHybrid, - sequenceTypeInstrumentTimes } + sequenceTypeInstrumentTimes, sequenceTypeImageAndInstrumentTimes } ), Optional::Yes, "This value determines which type of sequencer is used for generating " @@ -369,6 +372,27 @@ void ProjectionComponent::initialize(const std::string& identifier, ) ); } + else if (sequenceType == sequenceTypeImageAndInstrumentTimes) { + parsers.push_back( + std::make_unique( + identifier, + std::move(sequenceSource), + translationDictionary + ) + ); + + std::string timesSequenceSource = absPath(dictionary.value(keyTimesSequenceDir)); + ghoul::Dictionary timesTranslationDictionary; + dictionary.getValue(keyTimesTranslation, timesTranslationDictionary); + + parsers.push_back( + std::make_unique( + identifier, + std::move(timesSequenceSource), + timesTranslationDictionary + ) + ); + } } for (std::unique_ptr& parser : parsers) { From 9be53ef77ffc99679ac561f1af4c69be12e469b6 Mon Sep 17 00:00:00 2001 From: Micah Date: Sun, 26 Jan 2020 16:31:44 -0500 Subject: [PATCH 131/214] adding bounding sphere to renderabeltrailtrajectory --- .../rendering/renderabletrailtrajectory.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/base/rendering/renderabletrailtrajectory.cpp b/modules/base/rendering/renderabletrailtrajectory.cpp index ee019b8827..476e064e43 100644 --- a/modules/base/rendering/renderabletrailtrajectory.cpp +++ b/modules/base/rendering/renderabletrailtrajectory.cpp @@ -333,6 +333,25 @@ void RenderableTrailTrajectory::update(const UpdateData& data) { } glBindVertexArray(0); + + // Updating bounding sphere + glm::vec3 maxVertex(-std::numeric_limits::max()); + glm::vec3 minVertex(std::numeric_limits::max()); + + auto setMax = [&maxVertex, &minVertex](const TrailVBOLayout& vertexData) { + maxVertex.x = std::max(maxVertex.x, vertexData.x); + maxVertex.y = std::max(maxVertex.y, vertexData.y); + maxVertex.z = std::max(maxVertex.z, vertexData.z); + + minVertex.x = std::min(minVertex.x, vertexData.x); + minVertex.y = std::min(minVertex.y, vertexData.y); + minVertex.z = std::min(minVertex.z, vertexData.z); + }; + + std::for_each(_vertexArray.begin(), _vertexArray.end(), setMax); + + setBoundingSphere(glm::distance(maxVertex, minVertex) / 2.0); + } } // namespace openspace From f0a304dd1974d6b9a30c71e481ac5ee59e90e3b9 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Mon, 27 Jan 2020 10:45:21 -0500 Subject: [PATCH 132/214] Added option for using Utah Sync server (commented-out) --- openspace.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..c23119b2cd 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -97,6 +97,7 @@ ModuleConfigurations = { SynchronizationRoot = "${SYNC}", HttpSynchronizationRepositories = { "http://data.openspaceproject.com/request" + -- "http://openspace.sci.utah.edu/request" } }, Server = { From bba51efd70c32ef5582191176bf98e1d07a5c8b4 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 27 Jan 2020 18:01:01 +0100 Subject: [PATCH 133/214] Cleanup of asset files --- .../assets/customization/localbookmarks.asset | 8 ++-- data/assets/util/generate_bookmarks.asset | 44 +++++++++---------- data/assets/util/openspacebookmarks.asset | 18 ++++---- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/data/assets/customization/localbookmarks.asset b/data/assets/customization/localbookmarks.asset index 0373993830..18fd5b408e 100644 --- a/data/assets/customization/localbookmarks.asset +++ b/data/assets/customization/localbookmarks.asset @@ -1,7 +1,5 @@ -local assetHelper = asset.require("util/asset_helper") -local bookmarkHelper = asset.require("util/generate_bookmarks") +local assetHelper = asset.require('util/asset_helper') +local bookmarkHelper = asset.require('util/generate_bookmarks') -local nodes = bookmarkHelper.getBookmarks("Local Bookmarks",'${ASSETS}/customization/localbookmarks.csv') +local nodes = bookmarkHelper.getBookmarks('Local Bookmarks', '${ASSETS}/customization/localbookmarks.csv') assetHelper.registerSceneGraphNodesAndExport(asset, nodes); - - diff --git a/data/assets/util/generate_bookmarks.asset b/data/assets/util/generate_bookmarks.asset index 0aac179b49..c312b0cfee 100644 --- a/data/assets/util/generate_bookmarks.asset +++ b/data/assets/util/generate_bookmarks.asset @@ -6,31 +6,29 @@ local getBookmarks = function (guiPath, bookmarkfile) local PARSEC_CONSTANT = 3.0856776E16; for line in io.lines(openspace.absPath(bookmarkfile)) do if (notFirstLine) then - local matchstring = "(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-)$" - local group, name, globe, lat, lon, altitude, x, y, z, scale, linewitdh = line:match(matchstring) + local matchstring = '(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-),(.-)$' + local group, name, globe, lat, lon, altitude, x, y, z, scale, linewidth = line:match(matchstring) scale = (scale == '' and 75000 or scale) - linewitdh = (linewitdh == '' and 2.0 or tonumber(linewitdh)) - group = (group == "" and globe or group) + linewidth = (linewidth == '' and 2.0 or tonumber(linewidth)) + group = (group == '' and globe or group) - local parent = (globe == "" and 'Root' or globe) + local parent = (globe == '' and 'Root' or globe) local sgn = { - Identifier = guiPath .. "-" .. name, + Identifier = guiPath .. '-' .. name, Parent = parent, Transform = { - Translation = { - }, Scale = { - Type = "StaticScale", + Type = 'StaticScale', Scale = tonumber(scale); } }, Renderable = { - Type = "RenderableSphericalGrid", + Type = 'RenderableSphericalGrid', Enabled = false, GridColor = { 0.3, 0.84, 1.0, 0.3}, - LineWidth = linewitdh, + LineWidth = linewidth, GridMatrix = { -0.05487554, 0.4941095, -0.8676661 , 0.0, -0.9938214 , -0.1109906, -0.0003515167, 0.0, -0.09647644, 0.8622859, 0.4971472 , 0.0, @@ -38,25 +36,29 @@ local getBookmarks = function (guiPath, bookmarkfile) }, GUI = { Name = name, - Path = "/" .. guiPath + Path = '/' .. guiPath } } - if (group ~= "") then - sgn.GUI.Path = sgn.GUI.Path .. "/" .. group + if (group ~= '') then + sgn.GUI.Path = sgn.GUI.Path .. '/' .. group end - if (globe == "") then + if (globe == '') then sgn.Transform.Translation = { - Type = "StaticTranslation", - Position = {tonumber(x) * PARSEC_CONSTANT, tonumber(y) * PARSEC_CONSTANT , tonumber(z) * PARSEC_CONSTANT} + Type = 'StaticTranslation', + Position = { + tonumber(x) * PARSEC_CONSTANT, + tonumber(y) * PARSEC_CONSTANT, + tonumber(z) * PARSEC_CONSTANT + } } else sgn.Transform.Translation = { - Type = "GlobeTranslation", + Type = 'GlobeTranslation', Globe = globe, Latitude = tonumber(lat), - Longitude = tonumber(lon), + Longitude = tonumber(lon) } if (altitude == nil) then sgn.Transform.Translation.UseHeightMap = true; @@ -64,10 +66,8 @@ local getBookmarks = function (guiPath, bookmarkfile) sgn.Transform.Translation.UseHeightMap = false; sgn.Transform.Translation.Altitude = tonumber(altitude); end - end - table.insert(genBookmarks, sgn); else notFirstLine = true @@ -76,5 +76,5 @@ local getBookmarks = function (guiPath, bookmarkfile) return genBookmarks end -asset.export("getBookmarks", getBookmarks) +asset.export('getBookmarks', getBookmarks) diff --git a/data/assets/util/openspacebookmarks.asset b/data/assets/util/openspacebookmarks.asset index a577487048..65ec8fdc52 100644 --- a/data/assets/util/openspacebookmarks.asset +++ b/data/assets/util/openspacebookmarks.asset @@ -1,12 +1,12 @@ -local assetHelper = asset.require("util/asset_helper") -local bookmarkHelper = asset.require("util/generate_bookmarks") +local assetHelper = asset.require('util/asset_helper') +local bookmarkHelper = asset.require('util/generate_bookmarks') -local dataProvider = "http://data.openspaceproject.com/bookmarks.csv" +local dataProvider = 'http://data.openspaceproject.com/bookmarks.csv' local bookmarksCSV = asset.syncedResource({ - Identifier = "openspace_bookmarks", - Name = "OpenSpace Bookmarks", - Type = "UrlSynchronization", + Identifier = 'openspace_bookmarks', + Name = 'OpenSpace Bookmarks', + Type = 'UrlSynchronization', UseHash = false, Override = true, Url = dataProvider @@ -15,14 +15,14 @@ local bookmarksCSV = asset.syncedResource({ local nodes = {} asset.onInitialize(function () - nodes = bookmarkHelper.getBookmarks("OpenSpace Bookmarks", bookmarksCSV .. '/bookmarks.csv') - for i, n in ipairs(nodes) do + nodes = bookmarkHelper.getBookmarks('OpenSpace Bookmarks', bookmarksCSV .. '/bookmarks.csv') + for _, n in ipairs(nodes) do openspace.addSceneGraphNode(n); end end) asset.onDeinitialize(function () - for i, n in ipairs(nodes) do + for _, n in ipairs(nodes) do openspace.removeSceneGraphNode(n.Identifier); end end) From b19147fba736100f5442d85300f54e56f7e5b886 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 27 Jan 2020 12:07:15 -0500 Subject: [PATCH 134/214] Fixed bug was making atm disapear when night/water layer weren't active. --- modules/globebrowsing/shaders/renderer_fs.glsl | 6 +++--- modules/globebrowsing/src/renderableglobe.cpp | 7 +++---- openspace.cfg | 2 +- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index ec97d0d3f1..c08f078622 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -51,9 +51,9 @@ uniform Layer WaterMasks[NUMLAYERS_WATERMASK]; uniform vec2 vertexResolution; #endif -#if USE_NIGHTTEXTURE || USE_WATERMASK || PERFORM_SHADING +//#if USE_NIGHTTEXTURE || USE_WATERMASK || PERFORM_SHADING uniform vec3 lightDirectionCameraSpace; -#endif +//#endif #if PERFORM_SHADING uniform float orenNayarRoughness; @@ -239,7 +239,7 @@ Fragment getFragment() { // Water reflectance is added to the G-Buffer. frag.gNormal.w = waterReflectance; #else - frag.gNormal.w = 0; + frag.gNormal.w = 0.0; #endif // Normal is written View Space (Including SGCT View Matrix). frag.gNormal.xyz = normal; diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index ff436a2f9e..988f6f0caa 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -1102,10 +1102,9 @@ void RenderableGlobe::renderChunks(const RenderData& data, RendererTasks&, const bool hasWaterLayer = !_layerManager.layerGroup( layergroupid::GroupID::WaterMasks ).activeLayers().empty(); - if (hasNightLayers || hasWaterLayer || _generalProperties.performShading) { - _globalRenderer.program->setUniform("modelViewTransform", modelViewTransform); - } - + + _globalRenderer.program->setUniform("modelViewTransform", modelViewTransform); + const bool hasHeightLayer = !_layerManager.layerGroup( layergroupid::HeightLayers ).activeLayers().empty(); diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..9cdc1e6149 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -131,7 +131,7 @@ ModuleConfigurations = { WebSocketInterface = "DefaultWebSocketInterface" }, CefWebGui = { - -- GuiScale = 2.0, + GuiScale = 2.1, Enabled = true, Visible = true } From e2f0321e7a16ddf1595d78be83617ae048df31c9 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 27 Jan 2020 12:18:30 -0500 Subject: [PATCH 135/214] Commented gui size again. --- openspace.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openspace.cfg b/openspace.cfg index 571958c466..a4e93df633 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -135,7 +135,7 @@ ModuleConfigurations = { WebSocketInterface = "DefaultWebSocketInterface" }, CefWebGui = { - GuiScale = 2.1, + --GuiScale = 2.1, Enabled = true, Visible = true } From 975e46e4b224da4e4eab64c3ad8ba786e997b43b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 27 Jan 2020 18:20:17 +0100 Subject: [PATCH 136/214] Move local bookmarks file to new global asset folder --- data/assets/{customization => global}/localbookmarks.asset | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename data/assets/{customization => global}/localbookmarks.asset (100%) diff --git a/data/assets/customization/localbookmarks.asset b/data/assets/global/localbookmarks.asset similarity index 100% rename from data/assets/customization/localbookmarks.asset rename to data/assets/global/localbookmarks.asset From 947a78a2048e743c4250e5d7d738c652806c064f Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 27 Jan 2020 14:58:05 -0500 Subject: [PATCH 137/214] Changed night color behavior. --- .../shaders/atmosphere_deferred_fs.glsl | 108 +----------------- 1 file changed, 4 insertions(+), 104 deletions(-) diff --git a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl index d19c53fa47..54a356dcc4 100644 --- a/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl +++ b/modules/atmosphere/shaders/atmosphere_deferred_fs.glsl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2019 * + * Copyright (c) 2014-2020 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * @@ -279,7 +279,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor const vec3 v, const vec3 s, out float r, out float mu, out vec3 attenuation, const vec3 fragPosObj, out bool groundHit, const double maxLength, const double pixelDepth, - const vec4 spaceColor, const float sunIntensity, const vec3 normal) { + const vec4 spaceColor, const float sunIntensity) { const float INTERPOLATION_EPS = 0.004f; // precision const from Brunetton @@ -301,11 +301,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor // we will subtract the attenuated scattering light from that path in the // current path. vec4 inscatterRadiance = max(texture4D(inscatterTexture, r, mu, muSun, nu), 0.0); -<<<<<<< HEAD - -======= ->>>>>>> master // After removing the initial path from camera pos to top of atmosphere (for an // observer in the space) we test if the light ray is hitting the atmosphere vec3 x0 = fragPosObj; @@ -352,11 +348,7 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if (abs(mu - muHorizon) < INTERPOLATION_EPS) { // We want an interpolation value close to 1/2, so the // contribution of each radiance value is almost the same -<<<<<<< HEAD - // or it has a hevy weight if from above or below horizon -======= // or it has a heavy weight if from above or below horizon ->>>>>>> master float interpolationValue = ((mu - muHorizon) + INTERPOLATION_EPS) / (2.0f * INTERPOLATION_EPS); //float t2 = t * t; @@ -421,18 +413,11 @@ vec3 inscatterRadiance(inout vec3 x, inout float t, inout float irradianceFactor if (groundHit) { return finalScatteringRadiance; } else { -<<<<<<< HEAD - // The final color is given by the attenuated light arriving at the observer's eye - // plus the scattered light in the atmosphere (only inscattered light taken into account here) - return attenuation * (spaceColor.rgb * backgroundConstant) + finalScatteringRadiance; -======= //return ((r-Rg) * invRtMinusRg)*spaceColor.rgb + finalScatteringRadiance; - return attenuation * spaceColor.rgb + finalScatteringRadiance; + return spaceColor.rgb + finalScatteringRadiance; // return attenuation * spaceColor.rgb + // (vec3(1.0) - attenuation) * finalScatteringRadiance; ->>>>>>> master - } - + } } /* @@ -570,17 +555,10 @@ void main() { double offset = 0.0; // in Km double maxLength = 0.0; // in Km -<<<<<<< HEAD - for (int i = 0; i < nSamples; i++) { - // Color from G-Buffer - //vec4 color = texelFetch(mainColorTexture, fragCoords, i); - vec4 color = colorArray[i]; -======= bool intersectATM = false; intersectATM = dAtmosphereIntersection(planetPositionObjectCoords.xyz, ray, Rt - (ATM_EPSILON * 0.001), insideATM, offset, maxLength); ->>>>>>> master if ( intersectATM ) { // Now we check is if the atmosphere is occluded, i.e., if the distance to the pixel @@ -681,76 +659,6 @@ void main() { color, normal.xyz, irradianceFactor, normal.a, sunIntensityGround); } else { -<<<<<<< HEAD - // Following paper nomenclature - double t = offset; - vec3 attenuation; - - // Moving observer from camera location to top atmosphere - // If the observer is already inside the atm, offset = 0.0 - // and no changes at all. - vec3 x = vec3(ray.origin.xyz + t*ray.direction.xyz); - float r = 0.0f;//length(x); - vec3 v = vec3(ray.direction.xyz); - float mu = 0.0f;//dot(x, v) / r; - vec3 s = vec3(sunDirectionObj); - float tF = float(maxLength - t); - - // Because we may move the camera origin to the top of atmosphere - // we also need to adjust the pixelDepth for tdCalculateRayRenderableGlobe' offset so the - // next comparison with the planet's ground make sense: - pixelDepth -= offset; - - dvec4 onATMPos = dModelTransformMatrix * dvec4(x * 1000.0, 1.0); - vec4 eclipseShadowATM = calcShadow(shadowDataArray, onATMPos.xyz, false); - float sunIntensityInscatter = sunRadiance * eclipseShadowATM.x; - - float irradianceFactor = 0.0; - - bool groundHit = false; - vec3 inscatterColor = inscatterRadiance(x, tF, irradianceFactor, v, - s, r, mu, attenuation, - vec3(positionObjectsCoords.xyz), - groundHit, maxLength, pixelDepth, - color, sunIntensityInscatter, - normal.xyz); - vec3 groundColorV = vec3(0.0); - vec3 sunColorV = vec3(0.0); - if (groundHit) { - vec4 eclipseShadowPlanet = calcShadow(shadowDataArray, positionWorldCoords.xyz, true); - float sunIntensityGround = sunRadiance * eclipseShadowPlanet.x; - groundColorV = groundColor(x, tF, v, s, r, mu, attenuation, - color, normal.xyz, irradianceFactor, - normal.a, sunIntensityGround); - } else { - // In order to get better performance, we are not tracing - // multiple rays per pixel when the ray doesn't intersect - // the ground. - sunColorV = sunColor(x, tF, v, s, r, mu, irradianceFactor); - } - - // Final Color of ATM plus terrain: - vec4 finalRadiance = vec4(HDR(inscatterColor + groundColorV + sunColorV, atmExposure), 1.0); - - atmosphereFinalColor += finalRadiance; - } - } - else { // no intersection - atmosphereFinalColor += vec4(HDR(color.xyz * backgroundConstant, atmExposure), color.a); - } - } - - renderTarget = atmosphereFinalColor / float(nSamples); - renderTarget.a *= blackoutFactor; - // if (complex) - // renderTarget = vec4(1.0, 0.0, 0.0, 1.0); - } - else { // culling - if (firstPaint) { - vec4 bColor = vec4(0.0f); - for (int f = 0; f < nAaSamples; f++) { - bColor += texelFetch(mainColorTexture, fragCoords, f); -======= // In order to get better performance, we are not tracing // multiple rays per pixel when the ray doesn't intersect // the ground. @@ -761,15 +669,8 @@ void main() { vec4 finalRadiance = vec4(inscatterColor + groundColorV + sunColorV, 1.0); atmosphereFinalColor += finalRadiance; ->>>>>>> master } } -<<<<<<< HEAD - else { - discard; - } - //renderTarget = vec4(1.0, 0.0, 0.0, 1.0); -======= else { // no intersection // Buffer color atmosphereFinalColor += color; @@ -781,7 +682,6 @@ void main() { else { // culling vec4 bColor = texture(mainColorTexture, texCoord); renderTarget = bColor; ->>>>>>> master } } From 8a8748daaa5eda2d244a678691245ff333b79e00 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 27 Jan 2020 22:17:08 +0100 Subject: [PATCH 138/214] Small fixes --- openspace.cfg | 8 +- scripts/convertProfileToScene.lua | 474 --------------------------- scripts/convert_profile_to_scene.lua | 473 ++++++++++++++++++++++++++ src/engine/configuration.cpp | 7 - src/engine/openspaceengine.cpp | 23 +- 5 files changed, 497 insertions(+), 488 deletions(-) delete mode 100644 scripts/convertProfileToScene.lua create mode 100644 scripts/convert_profile_to_scene.lua diff --git a/openspace.cfg b/openspace.cfg index d71e10768c..4479fc7163 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -42,8 +42,7 @@ SGCTConfig = sgct.config.single{} -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace -Profile = "newhorizons" --- Asset = "default" +--Asset = "default" -- Asset = "default_full" -- Asset = "newhorizons" -- Asset = "rosetta" @@ -57,6 +56,11 @@ Profile = "newhorizons" -- Asset = "apollo_sites" -- Asset = "touch" +-- Sets the profile that should be loaded by OpenSpace. Profiles are going to replace +-- assets in a future versions and shouldn't be used at the same time as the 'Asset' +-- setting above +Profile = "default" + -- These scripts are executed after the initialization of each scene, thus making -- it possible to have global overrides to default values or execute other scripts -- regardless of the scene that is loaded diff --git a/scripts/convertProfileToScene.lua b/scripts/convertProfileToScene.lua deleted file mode 100644 index bc1d34de86..0000000000 --- a/scripts/convertProfileToScene.lua +++ /dev/null @@ -1,474 +0,0 @@ -version = "" -modulesTable = {} -assetsTable = {} -propertiesTable = {} -timeTable = {} -cameraTable = {} -markNodesTable = {} -keybindingsTable = {} -resultTable = {} -insideSection = false -currFunction = "None" -currSection = "None" -numLinesVersion = 0 -lineIndex = 1 - - -function printError(message) - print("Error @ line "..lineIndex..": "..message) -end - -function splitByTab(inputstr) - sep = "\t" - t = {} - for match in (inputstr..sep):gmatch("(.-)"..sep) do - table.insert(t, match) - end - return t; -end - -function parseVersion(line) - numLinesVersion = numLinesVersion + 1 - if numLinesVersion > 1 then - printError("Too many lines in Version section.") - os.exit() - else - lineS = splitByTab(line) - if tableLen(lineS) > 1 then - printError("No tabs allowed in version entry.") - os.exit() - else - version = line - end - end -end - -function parseMarkNodes(line) - lineS = splitByTab(line) - if tableLen(lineS) > 1 then - printError("No tabs allowed in MarkNodes entry.") - os.exit() - else - table.insert(markNodesTable, line) - end -end - -function parseModule(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 3 then - printError("3 fields requried in a Module entry.") - os.exit() - else - table.insert(modulesTable, t) - end -end - -function parseAsset(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 2 then - printError("2 fields required in a Asset entry.") - os.exit() - else - local req = "required" - if t[2] == "requested" then - req = "requested" - end - table.insert(assetsTable, {t[1], req}) - end -end - -function parseProperty(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 3 then - printError("3 fields required in a Property entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Property set command (arg 1/3) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Property name (arg 2/3) is required.") - os.exit() - elseif isBlank(t[3]) then - printError("Property value to set (arg 3/3) is required.") - os.exit() - end - - if t[1] ~= "setPropertyValue" and t[1] ~= "setPropertyValueSingle" then - printError("Property set command '"..t[1].."' is not supported.") - os.exit() - end - - table.insert(propertiesTable, t) -end - -function parseKeybinding(line) - local numReqFields = 6 - t = {} - t = splitByTab(line) - if tableLen(t) < numReqFields then - printError(numReqFields.." fields required in a Keybinding entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Keybinding key (arg 1/6) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Keybinding documentation (arg 2/6) is required.") - os.exit() - elseif isBlank(t[3]) then - printError("Keybinding name (arg 3/6) is required.") - os.exit() - elseif isBlank(t[4]) then - printError("Keybinding GuiPath (arg 4/6) is required.") - os.exit() - elseif isBlank(t[5]) then - printError("Keybinding local(T/F) (arg 5/6) is required.") - os.exit() - elseif isBlank(t[6]) then - printError("Keybinding script to execute (arg 6/6) is required.") - os.exit() - end - - --If there are more than 6 fields then combine the final fields together - --assuming that this is a lua script that contains tabs - if tableLen(t) > numReqFields then - for i=(numReqFields + 1),tableLen(t) do - t[numReqFields] = t[numReqFields]..t[i] - end - end - - if t[5] ~= "true" and t[5] ~= "false" then - printError("Keybinding local arg must be true or false.") - os.exit() - end - - table.insert(keybindingsTable, {t[1], t[2], t[3], t[4], t[5], t[6]}) -end - -function parseTime(line) - t = {} - t = splitByTab(line) - if tableLen(t) ~= 2 then - printError("2 fields required in a Time entry.") - os.exit() - elseif isBlank(t[1]) then - printError("Time set type (arg 1/2) is required.") - os.exit() - elseif isBlank(t[2]) then - printError("Time value to set (arg 2/2) is required.") - os.exit() - end - - if t[1] ~= "absolute" and t[1] ~= "relative" then - printError("Time set type '"..t[1].."' is not supported.") - os.exit() - end - - table.insert(timeTable, t) -end - -function parseCamera(line) - t = {} - t = splitByTab(line) - - local cmd = t[1] - if cmd == "setNavigationState" then - if tableLen(t) ~= 8 then - printError("8 fields required in camera 'setNavigationState' line.") - os.exit() - elseif isBlank(t[2]) then - printError("Camera setNavigationState Anchor (arg 1/7) is required.") - os.exit() - elseif isBlank(t[5]) then - printError("Camera setNavigationState position vector (arg 4/7) is required.") - os.exit() - end - elseif cmd == "goToGeo" then - if tableLen(t) ~= 5 then - printError("5 fields required in camera 'goToGeo' line.") - os.exit() - elseif isBlank(t[3]) then - printError("Camera goToGeo Latitude (arg 2/4) is required.") - os.exit() - elseif isBlank(t[4]) then - printError("Camera goToGeo Longitude (arg 3/4) is required.") - os.exit() - end - else - printError("Camera position command '"..cmd.."' is not supported.") - os.exit() - end - - table.insert(cameraTable, t) -end - -function file_exists(file) - local f = io.open(file, "rb") - if f then - f:close() - end - return f ~= nil -end - -function lines_from(file) - if not file_exists(file) then - return {} - end - lines = {} - for line in io.lines(file) do - lines[#lines + 1] = line - end - return lines -end - -function determineSection(header) - header = header:sub(2) - for _,i in pairs(parsingSections) do - if i.section == header then - currSection = i.section - currFunction = i.func - return true - end - end - return false -end - -function isBlank(line) - return line:match("%S") == nil -end - -function parseCurrentSection(line) - currFunction(line) -end - -function tableLen(T) - local size = 0 - for _ in pairs(T) do - size = size + 1 - end - return size -end - -function parseProfile(fileIn) - local lines = lines_from(fileIn) - - for k,v in pairs(lines) do - if insideSection then - if isBlank(v) then - insideSection = false - else - parseCurrentSection(v) - end - elseif v:sub(1, 1) == "#" then - if determineSection(v) then - insideSection = true - end - end - lineIndex = lineIndex + 1 - end - - resultTable["Version"] = version - resultTable["Module"] = modulesTable - resultTable["Asset"] = assetsTable - resultTable["Property"] = propertiesTable - resultTable["Time"] = timeTable - resultTable["Camera"] = cameraTable - resultTable["MarkNodes"] = markNodesTable - resultTable["Keybinding"] = keybindingsTable - - return resultTable -end - -function tableSize(T) - local size = 0 - for _ in pairs(T) do - size = size + 1 - end - return size -end - -function generateAsset(T, fileOut) - file = io.open(fileOut, "w") - io.output(file) - - --Module section - for i,j in pairs(T["Module"]) do - if not isBlank(j[2]) and not isBlank(j[3]) then - ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[2].."\nelse\n".." "..j[3].."\nend\n" - elseif not isBlank(j[3]) then - ModuleStr = ModuleStr.."if not openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[3].."\nend\n" - elseif not isBlank(j[2]) then - ModuleStr = ModuleStr.."if openspace.modules.isLoaded('"..j[1].."') then\n" - ModuleStr = ModuleStr.." "..j[2].."\nend\n" - end - end - - --Asset section - AssetStr = AssetStr.."asset.require('base');\n" - AssetStr = AssetStr.."local assetHelper = asset.require('util/asset_helper')\n" - AssetStr = AssetStr.."local propertyHelper = asset.require('util/property_helper')\n" - AssetStr = AssetStr.."local sceneHelper = asset.require('util/scene_helper')\n" - AssetStr = AssetStr.."local renderableHelper = asset.require('util/renderable_helper')\n" - local assetType = "" - for i,j in pairs(T["Asset"]) do - if isBlank(j[2]) then - assetType = "require" - else - if (j[2] == "required") then - assetType = "require" - elseif (j[2] == "requested") then - assetType = "request" - else - printError("Asset arg 2/2 must be either 'required' or 'requested'.") - os.exit() - end - end - AssetStr = AssetStr.."asset."..assetType.."('"..j[1].."')\n" - end - - --Keybindings section - if not (tableSize(T["Keybinding"]) == 0) then - KeyStr = KeyStr.."local Keybindings = {\n" - for i,j in pairs(T["Keybinding"]) do - KeyStr = KeyStr.." {\n" - KeyStr = KeyStr.." Key = \""..j[1].."\",\n" - KeyStr = KeyStr.." Documentation = \""..j[2].."\",\n" - KeyStr = KeyStr.." Name = \""..j[3].."\",\n" - KeyStr = KeyStr.." GuiPath = \""..j[4].."\",\n" - KeyStr = KeyStr.." Local = "..j[5]..",\n" - KeyStr = KeyStr.." Command = "..j[6].."\n" - KeyStr = KeyStr.." },\n" - end - KeyStr = KeyStr.."}\n" - end - - --Time section - for i,j in pairs(T["Time"]) do - if not (j[1] == "absolute") and not (j[1] == "relative") then - printError("Time arg 1/1 must be either 'absolute' or 'relative'.") - os.exit() - elseif (j[1] == "absolute") then - TimeStr = TimeStr.." openspace.time.setTime(\""..j[2].."\")\n" - elseif (j[1] == "relative") then - TimeStr = TimeStr.." local now = openspace.time.currentWallTime();" - TimeStr = TimeStr.." openspace.time.setTime(" - TimeStr = TimeStr.."openspace.time.advancedTime(now, \"" - TimeStr = TimeStr..j[2].."\"))\n" - end - end - - --MarkNodes section - mkNodLen = tableSize(T["MarkNodes"]) - if not (mkNodLen == 0) then - MarkNodesStr = MarkNodesStr.." openspace.markInterestingNodes({" - for i,j in pairs(T["MarkNodes"]) do - MarkNodesStr = MarkNodesStr.."\""..j.."\"" - if (i < mkNodLen) then - MarkNodesStr = MarkNodesStr..", " - end - end - MarkNodesStr = MarkNodesStr.."})\n" - end - - --Property section - for i,j in pairs(T["Property"]) do - if not (j[1] == "setPropertyValue") and not (j[1] == "setPropertyValueSingle") then - printError("Property arg 1/1 must be 'setPropertyValue[Single]'.") - os.exit() - else - PropertyStr = PropertyStr.." openspace."..j[1].."('"..j[2].."', "..j[3]..")\n" - end - end - - --Camera section - for i,j in pairs(T["Camera"]) do - if (j[1] == "setNavigationState") then - CameraStr = CameraStr.." openspace.navigation.setNavigationState({" - CameraStr = CameraStr.."Anchor = "..j[2]..", " - if not isBlank(j[3]) then - CameraStr = CameraStr.."Aim = "..j[3]..", " - end - if not isBlank(j[4]) then - CameraStr = CameraStr.."ReferenceFrame = "..j[4]..", " - end - CameraStr = CameraStr.."Position = {"..j[5].."}, " - if not isBlank(j[6]) then - CameraStr = CameraStr.."Up = {"..j[6].."}, " - end - if not isBlank(j[7]) then - CameraStr = CameraStr.."Yaw = "..j[7]..", " - end - if not isBlank(j[8]) then - CameraStr = CameraStr.."Pitch = "..j[8] - end - CameraStr = CameraStr.."})\n" - elseif (j[1] == "goToGeo") then - CameraStr = CameraStr.." openspace.globebrowsing.goToGeo(" - if not isBlank(j[2]) then - CameraStr = CameraStr..j[2]..", " - end - CameraStr = CameraStr..j[3]..", "..j[4] - if not isBlank(j[5]) then - CameraStr = CameraStr..", "..j[5] - end - CameraStr = CameraStr..")\n" - else - printError("Camera arg 1/1 must be 'setNavigationState' or 'goToGeo'.") - os.exit() - end - end - - --Write the file - io.write(ModuleStr.."\n") - io.write(AssetStr.."\n") - io.write(KeyStr.."\n") - io.write("asset.onInitialize(function ()\n") - io.write(TimeStr.."\n") - if not (tableSize(T["Keybinding"]) == 0) then - io.write(" sceneHelper.bindKeys(Keybindings)\n") - end - io.write(MarkNodesStr.."\n") - io.write(PropertyStr.."\n") - io.write(CameraStr.."\n") - io.write("end)\n") - - io.close(file) -end - ---[[ -########################################################################################## - M a i n -########################################################################################## -]]-- - -ModuleStr = "" -AssetStr = "" -KeyStr = "" -TimeStr = "" -MarkNodesStr = "" -PropertyStr = "" -CameraStr = "" - -parsingSections = { - {section = "Version", func = parseVersion}, - {section = "Module", func = parseModule}, - {section = "Asset", func = parseAsset}, - {section = "Property", func = parseProperty}, - {section = "Keybinding", func = parseKeybinding}, - {section = "Time", func = parseTime}, - {section = "Camera", func = parseCamera}, - {section = "MarkNodes", func = parseMarkNodes} -} - -profilePathIn = openspace.profile.getProfileInputPath() -scenePathOut = openspace.profile.getSceneOutputPath() - -profileIn = profilePathIn..".profile" -assetOut = scenePathOut..".scene" - -local resultTable = parseProfile(profileIn) -generateAsset(resultTable, assetOut) diff --git a/scripts/convert_profile_to_scene.lua b/scripts/convert_profile_to_scene.lua new file mode 100644 index 0000000000..0b852fe290 --- /dev/null +++ b/scripts/convert_profile_to_scene.lua @@ -0,0 +1,473 @@ +version = '' +modulesTable = {} +assetsTable = {} +propertiesTable = {} +timeTable = {} +cameraTable = {} +markNodesTable = {} +keybindingsTable = {} +resultTable = {} +insideSection = false +currFunction = 'None' +currSection = 'None' +numLinesVersion = 0 +lineIndex = 1 + + +function printError(message) + print('Error @ line ' .. lineIndex .. ': ' .. message) +end + +function splitByTab(inputstr) + sep = "\t" + t = {} + for match in (inputstr .. sep):gmatch('(.-)' .. sep) do + table.insert(t, match) + end + return t; +end + +function parseVersion(line) + numLinesVersion = numLinesVersion + 1 + if numLinesVersion > 1 then + printError('Too many lines in Version section') + os.exit() + else + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError('No tabs allowed in version entry') + os.exit() + else + version = line + end + end +end + +function parseMarkNodes(line) + lineS = splitByTab(line) + if tableLen(lineS) > 1 then + printError('No tabs allowed in MarkNodes entry') + os.exit() + else + table.insert(markNodesTable, line) + end +end + +function parseModule(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError('3 fields requried in a Module entry') + os.exit() + else + table.insert(modulesTable, t) + end +end + +function parseAsset(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError('2 fields required in a Asset entry') + os.exit() + else + local req = 'required' + if t[2] == 'requested' then + req = 'requested' + end + table.insert(assetsTable, {t[1], req}) + end +end + +function parseProperty(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 3 then + printError('3 fields required in a Property entry') + os.exit() + elseif isBlank(t[1]) then + printError('Property set command (arg 1/3) is required') + os.exit() + elseif isBlank(t[2]) then + printError('Property name (arg 2/3) is required') + os.exit() + elseif isBlank(t[3]) then + printError('Property value to set (arg 3/3) is required') + os.exit() + end + + if t[1] ~= 'setPropertyValue' and t[1] ~= 'setPropertyValueSingle' then + printError('Property set command "' .. t[1] .. '" is not supported') + os.exit() + end + + table.insert(propertiesTable, t) +end + +function parseKeybinding(line) + local numReqFields = 6 + t = {} + t = splitByTab(line) + if tableLen(t) < numReqFields then + printError(numReqFields .. ' fields required in a Keybinding entry') + os.exit() + elseif isBlank(t[1]) then + printError('Keybinding key (arg 1/6) is required') + os.exit() + elseif isBlank(t[2]) then + printError('Keybinding documentation (arg 2/6) is required') + os.exit() + elseif isBlank(t[3]) then + printError('Keybinding name (arg 3/6) is required') + os.exit() + elseif isBlank(t[4]) then + printError('Keybinding GuiPath (arg 4/6) is required') + os.exit() + elseif isBlank(t[5]) then + printError('Keybinding local(T/F) (arg 5/6) is required') + os.exit() + elseif isBlank(t[6]) then + printError('Keybinding script to execute (arg 6/6) is required') + os.exit() + end + + --If there are more than 6 fields then combine the final fields together + --assuming that this is a lua script that contains tabs + if tableLen(t) > numReqFields then + for i=(numReqFields + 1),tableLen(t) do + t[numReqFields] = t[numReqFields]..t[i] + end + end + + if t[5] ~= 'true' and t[5] ~= 'false' then + printError('Keybinding local arg must be true or false') + os.exit() + end + + table.insert(keybindingsTable, { t[1], t[2], t[3], t[4], t[5], t[6] }) +end + +function parseTime(line) + t = {} + t = splitByTab(line) + if tableLen(t) ~= 2 then + printError('2 fields required in a Time entry') + os.exit() + elseif isBlank(t[1]) then + printError('Time set type (arg 1/2) is required') + os.exit() + elseif isBlank(t[2]) then + printError('Time value to set (arg 2/2) is required') + os.exit() + end + + if t[1] ~= 'absolute' and t[1] ~= 'relative' then + printError('Time set type "' .. t[1] .. '" is not supported') + os.exit() + end + + table.insert(timeTable, t) +end + +function parseCamera(line) + t = {} + t = splitByTab(line) + + local cmd = t[1] + if cmd == 'setNavigationState' then + if tableLen(t) ~= 8 then + printError('8 fields required in camera "setNavigationState" line') + os.exit() + elseif isBlank(t[2]) then + printError('Camera setNavigationState Anchor (arg 1/7) is required') + os.exit() + elseif isBlank(t[5]) then + printError('Camera setNavigationState position vector (arg 4/7) is required') + os.exit() + end + elseif cmd == 'goToGeo' then + if tableLen(t) ~= 5 then + printError('5 fields required in camera "goToGeo" line') + os.exit() + elseif isBlank(t[3]) then + printError('Camera goToGeo Latitude (arg 2/4) is required') + os.exit() + elseif isBlank(t[4]) then + printError('Camera goToGeo Longitude (arg 3/4) is required') + os.exit() + end + else + printError('Camera position command "' .. cmd .. '" is not supported') + os.exit() + end + + table.insert(cameraTable, t) +end + +function file_exists(file) + local f = io.open(file, 'rb') + if f then + f:close() + end + return f ~= nil +end + +function lines_from(file) + if not file_exists(file) then + return {} + end + lines = {} + for line in io.lines(file) do + lines[#lines + 1] = line + end + return lines +end + +function determineSection(header) + header = header:sub(2) + for _,i in pairs(parsingSections) do + if i.section == header then + currSection = i.section + currFunction = i.func + return true + end + end + return false +end + +function isBlank(line) + return line:match('%S') == nil +end + +function parseCurrentSection(line) + currFunction(line) +end + +function tableLen(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function parseProfile(fileIn) + local lines = lines_from(fileIn) + + for k,v in pairs(lines) do + if insideSection then + if isBlank(v) then + insideSection = false + else + parseCurrentSection(v) + end + elseif v:sub(1, 1) == '#' then + if determineSection(v) then + insideSection = true + end + end + lineIndex = lineIndex + 1 + end + + resultTable['Version'] = version + resultTable['Module'] = modulesTable + resultTable['Asset'] = assetsTable + resultTable['Property'] = propertiesTable + resultTable['Time'] = timeTable + resultTable['Camera'] = cameraTable + resultTable['MarkNodes'] = markNodesTable + resultTable['Keybinding'] = keybindingsTable + + return resultTable +end + +function tableSize(T) + local size = 0 + for _ in pairs(T) do + size = size + 1 + end + return size +end + +function generateAsset(T, fileOut) + file = io.open(fileOut, 'w') + io.output(file) + + --Module section + for i,j in pairs(T['Module']) do + if not isBlank(j[2]) and not isBlank(j[3]) then + ModuleStr = ModuleStr .. 'if openspace.modules.isLoaded("' .. j[1] .. '") then\n' + ModuleStr = ModuleStr .. ' ' .. j[2] .. '\nelse\n' .. ' ' .. j[3] .. '\nend\n' + elseif not isBlank(j[3]) then + ModuleStr = ModuleStr .. 'if not openspace.modules.isLoaded("' .. j[1] .. '") then\n' + ModuleStr = ModuleStr .. ' ' .. j[3] .. '\nend\n' + elseif not isBlank(j[2]) then + ModuleStr = ModuleStr .. 'if openspace.modules.isLoaded("' .. j[1] .. '") then\n' + ModuleStr = ModuleStr .. ' ' .. j[2] .. '\nend\n' + end + end + + --Asset section + AssetStr = AssetStr .. 'asset.require("base");\n' + AssetStr = AssetStr .. 'local assetHelper = asset.require("util/asset_helper")\n' + AssetStr = AssetStr .. 'local propertyHelper = asset.require("util/property_helper")\n' + AssetStr = AssetStr .. 'local sceneHelper = asset.require("util/scene_helper")\n' + AssetStr = AssetStr .. 'local renderableHelper = asset.require("util/renderable_helper")\n' + local assetType = '' + for i,j in pairs(T['Asset']) do + if isBlank(j[2]) then + assetType = 'require' + else + if (j[2] == 'required') then + assetType = 'require' + elseif (j[2] == 'requested') then + assetType = 'request' + else + printError('Asset arg 2/2 must be either "required" or "requested"') + os.exit() + end + end + AssetStr = AssetStr .. 'asset.' .. assetType .. '("' .. j[1] .. '")\n' + end + + --Keybindings section + if not (tableSize(T['Keybinding']) == 0) then + KeyStr = KeyStr .. 'local Keybindings = {\n' + for i,j in pairs(T['Keybinding']) do + KeyStr = KeyStr..' {\n' + KeyStr = KeyStr..' Key = "' .. j[1] .. '",\n' + KeyStr = KeyStr..' Documentation = "' .. j[2] .. '",\n' + KeyStr = KeyStr..' Name = "' .. j[3] .. '",\n' + KeyStr = KeyStr..' GuiPath = "' .. j[4] .. '",\n' + KeyStr = KeyStr..' Local = ' .. j[5] .. ',\n' + KeyStr = KeyStr..' Command = ' .. j[6] .. '\n' + KeyStr = KeyStr..' },\n' + end + KeyStr = KeyStr.."}\n" + end + + --Time section + for i,j in pairs(T['Time']) do + if not (j[1] == 'absolute') and not (j[1] == 'relative') then + printError('Time arg 1/1 must be either "absolute" or "relative"') + os.exit() + elseif (j[1] == 'absolute') then + TimeStr = TimeStr .. ' openspace.time.setTime("' .. j[2] .. '")\n' + elseif (j[1] == 'relative') then + TimeStr = TimeStr .. ' local now = openspace.time.currentWallTime();' + TimeStr = TimeStr .. ' openspace.time.setTime(' + TimeStr = TimeStr .. 'openspace.time.advancedTime(now, "' .. j[2] .. '"))\n' + end + end + + --MarkNodes section + mkNodLen = tableSize(T['MarkNodes']) + if not (mkNodLen == 0) then + MarkNodesStr = MarkNodesStr .. ' openspace.markInterestingNodes({' + for i, j in pairs(T['MarkNodes']) do + MarkNodesStr = MarkNodesStr .. '"' .. j .. '"' + if (i < mkNodLen) then + MarkNodesStr = MarkNodesStr .. ', ' + end + end + MarkNodesStr = MarkNodesStr .. '})\n' + end + + --Property section + for i, j in pairs(T['Property']) do + if not (j[1] == 'setPropertyValue') and not (j[1] == 'setPropertyValueSingle') then + printError('Property arg 1/1 must be "setPropertyValue[Single]"') + os.exit() + else + PropertyStr = PropertyStr .. ' openspace.' .. j[1] .. '("' .. j[2] .. '", ' .. j[3] .. ')\n' + end + end + + --Camera section + for i,j in pairs(T['Camera']) do + if (j[1] == 'setNavigationState') then + CameraStr = CameraStr .. ' openspace.navigation.setNavigationState({' + CameraStr = CameraStr .. 'Anchor = ' .. j[2] .. ', ' + if not isBlank(j[3]) then + CameraStr = CameraStr .. 'Aim = ' .. j[3] .. ', ' + end + if not isBlank(j[4]) then + CameraStr = CameraStr .. 'ReferenceFrame = ' .. j[4] .. ', ' + end + CameraStr = CameraStr .. 'Position = {' .. j[5] .. '}, ' + if not isBlank(j[6]) then + CameraStr = CameraStr .. 'Up = {' .. j[6] .. '}, ' + end + if not isBlank(j[7]) then + CameraStr = CameraStr .. 'Yaw = ' .. j[7] .. ', ' + end + if not isBlank(j[8]) then + CameraStr = CameraStr .. 'Pitch = ' .. j[8] + end + CameraStr = CameraStr .. '})\n' + elseif (j[1] == 'goToGeo') then + CameraStr = CameraStr .. ' openspace.globebrowsing.goToGeo(' + if not isBlank(j[2]) then + CameraStr = CameraStr .. j[2] .. ', ' + end + CameraStr = CameraStr .. j[3] .. ', ' .. j[4] + if not isBlank(j[5]) then + CameraStr = CameraStr .. ', ' .. j[5] + end + CameraStr = CameraStr .. ')\n' + else + printError('Camera arg 1/1 must be "setNavigationState" or "goToGeo"') + os.exit() + end + end + + --Write the file + io.write(ModuleStr .. '\n') + io.write(AssetStr .. '\n') + io.write(KeyStr .. '\n') + io.write('asset.onInitialize(function ()\n') + io.write(TimeStr .. '\n') + if not (tableSize(T['Keybinding']) == 0) then + io.write(' sceneHelper.bindKeys(Keybindings)\n') + end + io.write(MarkNodesStr .. '\n') + io.write(PropertyStr .. '\n') + io.write(CameraStr .. '\n') + io.write('end)\n') + + io.close(file) +end + +--[[ +########################################################################################## + M a i n +########################################################################################## +]]-- + +ModuleStr = '' +AssetStr = '' +KeyStr = '' +TimeStr = '' +MarkNodesStr = '' +PropertyStr = '' +CameraStr = '' + +parsingSections = { + { section = 'Version', func = parseVersion }, + { section = 'Module', func = parseModule }, + { section = 'Asset', func = parseAsset }, + { section = 'Property', func = parseProperty }, + { section = 'Keybinding', func = parseKeybinding }, + { section = 'Time', func = parseTime }, + { section = 'Camera', func = parseCamera }, + { section = 'MarkNodes', func = parseMarkNodes } +} + +profilePathIn = openspace.profile.getProfileInputPath() +scenePathOut = openspace.profile.getSceneOutputPath() + +profileIn = profilePathIn .. '.profile' +assetOut = scenePathOut .. '.scene' + +local resultTable = parseProfile(profileIn) +generateAsset(resultTable, assetOut) diff --git a/src/engine/configuration.cpp b/src/engine/configuration.cpp index 6c2b2fe043..0bb27b3a89 100644 --- a/src/engine/configuration.cpp +++ b/src/engine/configuration.cpp @@ -358,13 +358,6 @@ Configuration loadConfigurationFromFile(const std::string& filename) { parseLuaState(result); - // Set asset name to that of the profile because a new scene file will be - // created with that name, and also because the profile name will override - // an asset name if both are provided. - if (!result.profile.empty()) { - result.asset = "../../temp/" + result.profile; - } - return result; } diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index 6684cef46d..9716e99a3c 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -100,7 +100,7 @@ namespace { constexpr const char* _loggerCat = "OpenSpaceEngine"; constexpr const int CacheVersion = 1; constexpr const char* ProfileToSceneConverter - = "${BASE}/scripts/convertProfileToScene.lua"; + = "${BASE}/scripts/convert_profile_to_scene.lua"; } // namespace @@ -298,11 +298,15 @@ void OpenSpaceEngine::initialize() { // Convert profile to scene file (if was provided in configuration file) if (!global::configuration.profile.empty()) { - LINFO(fmt::format("Run Lua script to convert {}.profile to scene", - global::configuration.profile)); + LINFO( + fmt::format("Run Lua script to convert {}.profile to scene", + global::configuration.profile) + ); ghoul::lua::LuaState lState; - std::string inputProfilePath = generateFilePath("${BASE}/data/assets"); + // We can't use the absPath function here because we pass the path into the Lua + // function, which requires additional escaping + std::string inputProfilePath = generateFilePath("${ASSETS}"); std::string outputScenePath = generateFilePath("${TEMPORARY}"); std::string setProfileFilenameInLuaState = fmt::format(R"( @@ -318,11 +322,20 @@ void OpenSpaceEngine::initialize() { return "{}" end )", - global::configuration.profile, inputProfilePath, outputScenePath + global::configuration.profile, + inputProfilePath, + outputScenePath ); ghoul::lua::runScript(lState, setProfileFilenameInLuaState); ghoul::lua::runScriptFile(lState, absPath(ProfileToSceneConverter)); + + + // Set asset name to that of the profile because a new scene file will be + // created with that name, and also because the profile name will override + // an asset name if both are provided. + global::configuration.asset = + absPath("${TEMPORARY}/") + global::configuration.profile; } // Set up asset loader From f56022414387cb449c4810a86c363dfbf6d56230 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 27 Jan 2020 16:49:36 -0500 Subject: [PATCH 139/214] GetProperty filter on groupname and update in base.asset --- data/assets/base.asset | 18 +++------- src/scene/scene_lua.inl | 76 +++++++++++++++++++++++++---------------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/data/assets/base.asset b/data/assets/base.asset index 6ef26ab294..34a64b783b 100644 --- a/data/assets/base.asset +++ b/data/assets/base.asset @@ -57,27 +57,19 @@ local Keybindings = { }, { Key = "h", - Name="Toggle Trails", - Command = "local list = openspace.getProperty('*Trail.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end", - Documentation = "Toggles the visibility of all trails", + Name="Toggle Planet Trails", + Command = "local list = openspace.getProperty('{planetTrail_solarSystem}.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end", + Documentation = "Toggles the visibility of planet trails", GuiPath = "/Rendering", Local = false }, { Key = "l", - Name = "Turn on labels", - Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', true)", + Name = "Toggle planet labels", + Command = "local list = openspace.getProperty('{solarsystem_labels}.Renderable.Enabled'); for _,v in pairs(list) do openspace.setPropertyValueSingle(v, not openspace.getPropertyValue(v)) end", Documentation = "Turns on visibility for all solar system labels", GuiPath = "/Rendering", Local = false - }, - { - Key = "Shift+l", - Name = "Turn off labels", - Command = "openspace.setPropertyValue('{solarsystem_labels}.Renderable.Enabled', false)", - Documentation = "Turns off visibility for all solar system labels", - GuiPath = "/Rendering", - Local = false } } diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index e137ddedb6..ee8b2d6258 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -2,7 +2,7 @@ * * * OpenSpace * * * - * Copyright (c) 2014-2019 * + * Copyright (c) 2014-2020 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * @@ -29,13 +29,14 @@ #include #include +#pragma optimize ("", off) namespace openspace { namespace { template properties::PropertyOwner* findPropertyOwnerWithMatchingGroupTag(T* prop, - const std::string& tagToMatch) + const std::string& tagToMatch) { properties::PropertyOwner* tagMatchOwner = nullptr; properties::PropertyOwner* owner = prop->owner(); @@ -59,10 +60,10 @@ properties::PropertyOwner* findPropertyOwnerWithMatchingGroupTag(T* prop, } void applyRegularExpression(lua_State* L, const std::string& regex, - const std::vector& properties, - double interpolationDuration, - const std::string& groupName, - ghoul::EasingFunction easingFunction) + const std::vector& properties, + double interpolationDuration, + const std::string& groupName, + ghoul::EasingFunction easingFunction) { using ghoul::lua::errorLocation; using ghoul::lua::luaTypeToString; @@ -105,7 +106,8 @@ void applyRegularExpression(lua_State* L, const std::string& regex, luaTypeToString(prop->typeLua()) ) ); - } else { + } + else { foundMatching = true; if (interpolationDuration == 0.0) { @@ -143,7 +145,8 @@ bool doesUriContainGroupTag(const std::string& command, std::string& groupName) if (name.front() == '{' && name.back() == '}') { groupName = name.substr(1, name.length() - 2); return true; - } else { + } + else { return false; } } @@ -164,8 +167,8 @@ std::string extractUriWithoutGroupName(std::string uri) { namespace openspace::luascriptfunctions { int setPropertyCall_single(properties::Property& prop, const std::string& uri, - lua_State* L, double duration, - ghoul::EasingFunction eastingFunction) + lua_State* L, double duration, + ghoul::EasingFunction easingFunction) { using ghoul::lua::errorLocation; using ghoul::lua::luaTypeToString; @@ -194,7 +197,7 @@ int setPropertyCall_single(properties::Property& prop, const std::string& uri, global::renderEngine.scene()->addPropertyInterpolation( &prop, static_cast(duration), - eastingFunction + easingFunction ); } } @@ -387,7 +390,7 @@ int property_getValue(lua_State* L) { L, 1, ghoul::lua::PopValue::Yes - ); + ); openspace::properties::Property* prop = property(uri); if (!prop) { @@ -401,7 +404,8 @@ int property_getValue(lua_State* L) { ); ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack"); return 0; - } else { + } + else { prop->getLuaValue(L); } @@ -410,16 +414,22 @@ int property_getValue(lua_State* L) { } /** - * \ingroup LuaScripts - * getProperty - * Returns a list of property identifiers that match the passed regular expression - */ +* \ingroup LuaScripts +* getProperty +* Returns a list of property identifiers that match the passed regular expression +*/ int property_getProperty(lua_State* L) { ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::property_getProperty"); std::string regex = ghoul::lua::value(L, 1); lua_pop(L, 1); + std::string groupName; + if (doesUriContainGroupTag(regex, groupName)) { + std::string pathRemainderToMatch = extractUriWithoutGroupName(regex); + // Remove group name from start of regex and replace with '.*' + regex = replaceUriWithGroupName(regex, ".*"); + } // Replace all wildcards * with the correct regex (.*) size_t startPos = regex.find("*"); @@ -429,8 +439,7 @@ int property_getProperty(lua_State* L) { startPos = regex.find("*", startPos); } - - + // Get all matching property uris and save to res std::regex r(regex); std::vector props = allProperties(); std::vector res; @@ -439,7 +448,21 @@ int property_getProperty(lua_State* L) { const std::string& id = prop->fullyQualifiedIdentifier(); if (std::regex_match(id, r)) { - res.push_back(id); + // Filter on the groupname if there was one + if (!groupName.empty()) { + properties::PropertyOwner* matchingTaggedOwner = + findPropertyOwnerWithMatchingGroupTag( + prop, + groupName + ); + if (!matchingTaggedOwner) { + continue; + } + res.push_back(id); + } + else { + res.push_back(id); + } } } @@ -454,12 +477,6 @@ int property_getProperty(lua_State* L) { return 1; } -/** - * \ingroup LuaScripts - * getPropertyValue(string): - * Returns the value of the property identified by the passed URI as a Lua object that can - * be passed to the setPropertyValue method. - */ int loadScene(lua_State* L) { ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadScene"); @@ -497,7 +514,8 @@ int addSceneGraphNode(lua_State* L) { fmt::format("Error loading scene graph node: {}: {}", e.what(), ghoul::to_string(e.result)) ); - } catch (const ghoul::RuntimeError& e) { + } + catch (const ghoul::RuntimeError& e) { return ghoul::lua::luaError( L, fmt::format("Error loading scene graph node: {}", e.what()) @@ -610,7 +628,7 @@ int hasSceneGraphNode(lua_State* L) { L, 1, ghoul::lua::PopValue::Yes - ); + ); SceneGraphNode* node = global::renderEngine.scene()->sceneGraphNode(nodeName); ghoul::lua::push(L, node != nullptr); @@ -626,7 +644,7 @@ int addInterestingTime(lua_State* L) { std::string time = ghoul::lua::value(L, 2, ghoul::lua::PopValue::No); lua_pop(L, 2); - global::renderEngine.scene()->addInterestingTime({std::move(name), std::move(time)}); + global::renderEngine.scene()->addInterestingTime({ std::move(name), std::move(time) }); ghoul_assert(lua_gettop(L) == 0, "Incorrect number of items left on stack"); return 0; From 607451e04bca2311a60e792a402d70a9b3fe6a72 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 27 Jan 2020 17:23:05 -0500 Subject: [PATCH 140/214] Changes to fix Dawn scene. --- .../solarsystem/missions/dawn/dawn.asset | 26 +++++++++++++------ .../missions/dawn/dawn_kernels.asset | 2 +- .../solarsystem/missions/dawn/vesta.asset | 3 ++- openspace.cfg | 3 ++- src/rendering/renderable.cpp | 15 +++++++++-- 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/data/assets/scene/solarsystem/missions/dawn/dawn.asset b/data/assets/scene/solarsystem/missions/dawn/dawn.asset index f630ad8b8f..e7fc3a3747 100644 --- a/data/assets/scene/solarsystem/missions/dawn/dawn.asset +++ b/data/assets/scene/solarsystem/missions/dawn/dawn.asset @@ -666,11 +666,17 @@ local Dawn = { local DawnSolarArray1 = { Identifier = "DawnSolar1", Parent = Dawn.Identifier, - Transformation = { + Transform = { + -- JCC: Spice rotations are commented because spice ck files + -- are not present. + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "DAWN_SA-Y", + -- DestinationFrame = "DAWN_SPACECRAFT" + -- } Rotation = { - Type = "SpiceRotation", - SourceFrame = "DAWN_SA-Y", - DestinationFrame = "DAWN_SPACECRAFT" + Type = "StaticRotation", + Rotation = {0.0, 4.71225, 0.0} } }, Renderable = { @@ -693,11 +699,15 @@ local DawnSolarArray1 = { local DawnSolarArray2 = { Identifier = "DawnSolar2", Parent = Dawn.Identifier, - Transformation = { + Transform = { + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "DAWN_SA+Y", + -- DestinationFrame = "DAWN_SPACECRAFT" + -- } Rotation = { - Type = "SpiceRotation", - SourceFrame = "DAWN_SA+Y", - DestinationFrame = "DAWN_SPACECRAFT" + Type = "StaticRotation", + Rotation = {3.1415, 1.57075, 0.0} } }, Renderable = { diff --git a/data/assets/scene/solarsystem/missions/dawn/dawn_kernels.asset b/data/assets/scene/solarsystem/missions/dawn/dawn_kernels.asset index 6ee7f55abc..bac98c64a6 100644 --- a/data/assets/scene/solarsystem/missions/dawn/dawn_kernels.asset +++ b/data/assets/scene/solarsystem/missions/dawn/dawn_kernels.asset @@ -2,7 +2,7 @@ local Kernels = asset.syncedResource({ Name = "Dawn Kernels", Type = "HttpSynchronization", Identifier = "dawn_kernels", - Version = 1 + Version = 2 }) asset.export("Kernels", Kernels) \ No newline at end of file diff --git a/data/assets/scene/solarsystem/missions/dawn/vesta.asset b/data/assets/scene/solarsystem/missions/dawn/vesta.asset index 64bfabfca8..75c1ed63f1 100644 --- a/data/assets/scene/solarsystem/missions/dawn/vesta.asset +++ b/data/assets/scene/solarsystem/missions/dawn/vesta.asset @@ -47,8 +47,9 @@ local Vesta = { Type = "RenderableModelProjection", Geometry = { Type = "MultiModelGeometry", - GeometryFile = models .. "/VestaComet/VestaComet_5000.obj" + GeometryFile = models .. "/VestaComet_5000.obj" }, + BoundingSphereRadius = 10.0, ColorTexture = textures .. "/dummy.jpg", Projection = { Sequence = images, diff --git a/openspace.cfg b/openspace.cfg index a4e93df633..e0d12fdc4b 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -59,6 +59,7 @@ Asset = "default" -- Asset = "apollo8" -- Asset = "apollo_sites" -- Asset = "touch" +-- Asset = "dawn" -- These scripts are executed after the initialization of each scene, thus making -- it possible to have global overrides to default values or execute other scripts @@ -135,7 +136,7 @@ ModuleConfigurations = { WebSocketInterface = "DefaultWebSocketInterface" }, CefWebGui = { - --GuiScale = 2.1, + GuiScale = 2.1, Enabled = true, Visible = true } diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 2ef60cb2c2..3ec1221272 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -141,15 +141,26 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary) } if (dictionary.hasKey(OpacityInfo.identifier)) { - _opacity = static_cast(dictionary.value(OpacityInfo.identifier)); + _opacity = static_cast(dictionary.value( + OpacityInfo.identifier) + ); } addProperty(_enabled); //set type for UI if (dictionary.hasKey(RenderableTypeInfo.identifier)) { - _renderableType = dictionary.value(RenderableTypeInfo.identifier); + _renderableType = dictionary.value( + RenderableTypeInfo.identifier + ); } + + if (dictionary.hasKey(BoundingSphereInfo.identifier)) { + _boundingSphere = static_cast( + dictionary.value(BoundingSphereInfo.identifier) + ); + } + addProperty(_renderableType); addProperty(_boundingSphere); } From aa5e4c05ff142770c1ff1cf38288d8c4b8fbe37a Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 27 Jan 2020 23:23:42 +0100 Subject: [PATCH 141/214] Use the default scene instead of the profile again --- openspace.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openspace.cfg b/openspace.cfg index 39cba26018..a8ad3309c4 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -45,7 +45,7 @@ SGCTConfig = sgct.config.single{} -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace ---Asset = "default" +Asset = "default" -- Asset = "default_full" -- Asset = "newhorizons" -- Asset = "rosetta" @@ -62,7 +62,7 @@ SGCTConfig = sgct.config.single{} -- Sets the profile that should be loaded by OpenSpace. Profiles are going to replace -- assets in a future versions and shouldn't be used at the same time as the 'Asset' -- setting above -Profile = "default" +-- Profile = "default" -- These scripts are executed after the initialization of each scene, thus making -- it possible to have global overrides to default values or execute other scripts From 55ecf2f6ef0e637f4fc7b8ec3ebafec577f05cbf Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 27 Jan 2020 18:18:58 -0500 Subject: [PATCH 142/214] Changing conflicting keybindings in rosetta scene --- data/assets/rosetta.scene | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/assets/rosetta.scene b/data/assets/rosetta.scene index 315c8804fc..f1470372a1 100644 --- a/data/assets/rosetta.scene +++ b/data/assets/rosetta.scene @@ -32,8 +32,8 @@ local Keybindings = { Local = false }, { - Key = "F5", - Command = "openspace.time.setTime('2014-08-01T03:05:18.101')", + Key = "Shift+F6", + Command = "openspace.time.setTime('2014-08-01T03:05:18.10')", Documentation = "Jumps to the time of initial approach of Rosetta to 67P.", Name = "Set initial approach time", GuiPath = "/Missions/Rosetta", @@ -81,7 +81,7 @@ local Keybindings = { Local = false }, { - Key = "g", + Key = "o", Command = renderableHelper.toggle('Scene.PhilaeTrail'), Documentation = "Toggles the visibility of Philae's trail.", Name = "Toggle Philae trail", From 199ddb629228cbd75975bce32ab72d4ecaf14a48 Mon Sep 17 00:00:00 2001 From: Gene Payne Date: Mon, 27 Jan 2020 16:26:55 -0700 Subject: [PATCH 143/214] Added missing sun marker asset to osiris-rex asset --- data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset | 1 + 1 file changed, 1 insertion(+) diff --git a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset index 1444106adc..ed12d60ba9 100644 --- a/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset +++ b/data/assets/scene/solarsystem/missions/osirisrex/osirisrex.asset @@ -1,6 +1,7 @@ asset.request('./bennu') asset.request('./model') asset.request('./trail') +asset.request('scene/solarsystem/sun/marker') asset.require('./script_schedule') From 826caf6954ef039e9c341c37b0b0709de2e77cbb Mon Sep 17 00:00:00 2001 From: Lovisa Hassler Date: Sun, 12 Jan 2020 22:21:12 +0100 Subject: [PATCH 144/214] Adding iss asset as a renderablesatellite --- .../planets/earth/satellites/misc/iss.asset | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset new file mode 100644 index 0000000000..27e3f964dd --- /dev/null +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -0,0 +1,11 @@ +local assetHelper = asset.require('util/asset_helper') +local shared = asset.require('../satellites_shared') + +local group = { + Title = "ISS", + Url = "https://live.ariss.org/iss.txt", + TrailColor = { 0.0, 1.0, 0.0 } +} + +local tle = shared.downloadTLEFile(asset, group.Url, group.Title) +shared.registerSatelliteGroupObjects(asset, group, tle, true) From 12b04f38bdb0822d4b74408b2a1c22f8f64ed733 Mon Sep 17 00:00:00 2001 From: Micah Acinapura Date: Wed, 29 Jan 2020 21:43:06 -0500 Subject: [PATCH 145/214] macos compile and build (still needs ring shader const fix) --- apps/OpenSpace/CMakeLists.txt | 10 +++++++++- data/assets/base_profile.asset | 1 - include/openspace/scripting/scriptengine.h | 2 +- modules/globebrowsing/src/renderableglobe.cpp | 6 +++--- modules/globebrowsing/src/shadowcomponent.cpp | 2 +- modules/globebrowsing/src/tileprovider.cpp | 2 +- openspace.cfg | 2 +- src/interaction/navigationhandler.cpp | 6 +++--- src/interaction/navigationhandler_lua.inl | 2 +- src/interaction/orbitalnavigator.cpp | 8 ++++---- src/scripting/scriptengine.cpp | 2 +- src/util/versionchecker.cpp | 2 +- 12 files changed, 26 insertions(+), 19 deletions(-) diff --git a/apps/OpenSpace/CMakeLists.txt b/apps/OpenSpace/CMakeLists.txt index ba74ba4315..eaf641b286 100644 --- a/apps/OpenSpace/CMakeLists.txt +++ b/apps/OpenSpace/CMakeLists.txt @@ -72,7 +72,15 @@ if (SGCT_SPOUT_SUPPORT AND NOT OPENSPACE_MODULE_SPOUT) set(OPENSPACE_MODULE_SPOUT ON CACHE BOOL "Build OPENSPACE_MODULE_SPOUTModule" FORCE) endif () -set(MACOSX_BUNDLE_ICON_FILE openspace.icns) + +##### +# macos +##### +if (APPLE) + set(MACOSX_BUNDLE_ICON_FILE openspace.icns) + set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version" FORCE) + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep" CACHE STRING "Other Code Signing Flags" FORCE) +endif() create_new_application(OpenSpace ${SGCT_OPENVR_FILES} diff --git a/data/assets/base_profile.asset b/data/assets/base_profile.asset index 67e5ba0556..f4a9b7b265 100644 --- a/data/assets/base_profile.asset +++ b/data/assets/base_profile.asset @@ -15,7 +15,6 @@ asset.require('util/default_joystick') -- Load web gui asset.require('util/webgui') -asset.request('customization/globebrowsing') asset.onInitialize(function () openspace.setDefaultGuiSorting() diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index 0ca40db7f0..430b2da22c 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -50,7 +50,7 @@ namespace openspace::scripting { */ class ScriptEngine : public Syncable, public DocumentationGenerator { public: - using ScriptCallback = std::optional>; + using ScriptCallback = std::function; BooleanType(RemoteScripting); struct QueueItem { diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 988f6f0caa..d2e075bfd0 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -186,7 +186,7 @@ namespace { constexpr openspace::properties::Property::PropertyInfo ShadowMappingInfo = { "ShadowMapping", - "Shadow Mapping", + "Shadow-Mapping", "Enables shadow mapping algorithm. Used by renderable rings too." }; @@ -303,7 +303,7 @@ BoundingHeights boundingHeightsForChunk(const Chunk& chunk, const LayerManager& const bool hasTileMetaData = chunkTile.tile.metaData.has_value(); if (goodTile && hasTileMetaData) { - const TileMetaData& tileMetaData = chunkTile.tile.metaData.value(); + const TileMetaData& tileMetaData = *chunkTile.tile.metaData; const float minValue = settings->performLayerSettings( tileMetaData.minValues[HeightChannel] @@ -524,7 +524,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) FloatProperty(OrenNayarRoughnessInfo, 0.f, 0.f, 1.f), IntProperty(NActiveLayersInfo, 0, 0, OpenGLCap.maxTextureUnits() / 3) }) - , _shadowMappingPropertyOwner({ "Shadow Mapping" }) + , _shadowMappingPropertyOwner({ "Shadow-Mapping" }) , _debugPropertyOwner({ "Debug" }) , _grid(DefaultSkirtedGridSegments, DefaultSkirtedGridSegments) , _leftRoot(Chunk(LeftHemisphereIndex)) diff --git a/modules/globebrowsing/src/shadowcomponent.cpp b/modules/globebrowsing/src/shadowcomponent.cpp index 2a2e5a9c7b..4e528f1ef0 100644 --- a/modules/globebrowsing/src/shadowcomponent.cpp +++ b/modules/globebrowsing/src/shadowcomponent.cpp @@ -166,7 +166,7 @@ documentation::Documentation ShadowComponent::Documentation() { } ShadowComponent::ShadowComponent(const ghoul::Dictionary& dictionary) - : properties::PropertyOwner({ "Shadows Component" }) + : properties::PropertyOwner({ "Shadows-Component" }) , _saveDepthTexture(SaveDepthTextureInfo) , _distanceFraction(DistanceFractionInfo, 20, 1, 10000) , _enabled({ "Enabled", "Enabled", "Enable/Disable Shadows" }, true) diff --git a/modules/globebrowsing/src/tileprovider.cpp b/modules/globebrowsing/src/tileprovider.cpp index ad72426685..46f7420b9f 100644 --- a/modules/globebrowsing/src/tileprovider.cpp +++ b/modules/globebrowsing/src/tileprovider.cpp @@ -168,7 +168,7 @@ bool initTexturesFromLoadedData(DefaultTileProvider& t) { if (tile) { const cache::ProviderTileKey key = { tile->tileIndex, t.uniqueIdentifier }; ghoul_assert(!t.tileCache->exist(key), "Tile must not be existing in cache"); - t.tileCache->createTileAndPut(key, std::move(tile.value())); + t.tileCache->createTileAndPut(key, std::move(*tile)); return true; } } diff --git a/openspace.cfg b/openspace.cfg index 058d110b52..bf18c5ab08 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -140,7 +140,7 @@ ModuleConfigurations = { WebSocketInterface = "DefaultWebSocketInterface" }, CefWebGui = { - GuiScale = 2.1, + GuiScale = 1.0, Enabled = true, Visible = true } diff --git a/src/interaction/navigationhandler.cpp b/src/interaction/navigationhandler.cpp index 9c85dbbd3a..0fc2d0e09a 100644 --- a/src/interaction/navigationhandler.cpp +++ b/src/interaction/navigationhandler.cpp @@ -77,7 +77,7 @@ ghoul::Dictionary NavigationHandler::NavigationState::dictionary() const { cameraDict.setValue(KeyAim, aim); } if (up.has_value()) { - cameraDict.setValue(KeyUp, up.value()); + cameraDict.setValue(KeyUp, *up); if (std::abs(yaw) > Epsilon) { cameraDict.setValue(KeyYaw, yaw); @@ -213,7 +213,7 @@ void NavigationHandler::updateCamera(double deltaTime) { ghoul_assert(_camera != nullptr, "Camera must not be nullptr"); if (_pendingNavigationState.has_value()) { - applyNavigationState(_pendingNavigationState.value()); + applyNavigationState(*_pendingNavigationState); _orbitalNavigator.resetVelocities(); _pendingNavigationState.reset(); } @@ -269,7 +269,7 @@ void NavigationHandler::applyNavigationState(const NavigationHandler::Navigation glm::dvec3(referenceFrameTransform * glm::dvec4(ns.position, 1.0)); glm::dvec3 up = ns.up.has_value() ? - glm::normalize(referenceFrameTransform * ns.up.value()) : + glm::normalize(referenceFrameTransform * *ns.up) : glm::dvec3(0.0, 1.0, 0.0); // Construct vectors of a "neutral" view, i.e. when the aim is centered in view. diff --git a/src/interaction/navigationhandler_lua.inl b/src/interaction/navigationhandler_lua.inl index c7fe94143d..2b37abbd58 100644 --- a/src/interaction/navigationhandler_lua.inl +++ b/src/interaction/navigationhandler_lua.inl @@ -101,7 +101,7 @@ int getNavigationState(lua_State* L) { if (state.up.has_value()) { ghoul::lua::push(L, "Up"); - pushVector(L, state.up.value()); + pushVector(L, *state.up); lua_rawset(L, -3); } if (state.yaw != 0) { diff --git a/src/interaction/orbitalnavigator.cpp b/src/interaction/orbitalnavigator.cpp index 29a0e2d844..ef27b995bc 100644 --- a/src/interaction/orbitalnavigator.cpp +++ b/src/interaction/orbitalnavigator.cpp @@ -424,7 +424,7 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) { const glm::dvec3 prevCameraPosition = _camera->positionVec3(); const glm::dvec3 anchorDisplacement = _previousAnchorNodePosition.has_value() ? - (anchorPos - _previousAnchorNodePosition.value()) : + (anchorPos - *_previousAnchorNodePosition) : glm::dvec3(0.0); CameraPose pose = { @@ -464,10 +464,10 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) { if (_aimNode && _aimNode != _anchorNode && hasPreviousPositions) { const glm::dvec3 aimPos = _aimNode->worldPosition(); const glm::dvec3 cameraToAnchor = - _previousAnchorNodePosition.value() - prevCameraPosition; + *_previousAnchorNodePosition - prevCameraPosition; Displacement anchorToAim = { - _previousAimNodePosition.value() - _previousAnchorNodePosition.value(), + *_previousAimNodePosition - *_previousAnchorNodePosition, aimPos - anchorPos }; @@ -502,7 +502,7 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) { glm::quat_cast(_anchorNode->worldRotationMatrix()); glm::dquat anchorNodeRotationDiff = _previousAnchorNodeRotation.has_value() ? - _previousAnchorNodeRotation.value() * glm::inverse(anchorRotation) : + *_previousAnchorNodeRotation * glm::inverse(anchorRotation) : glm::dquat(); _previousAnchorNodeRotation = anchorRotation; diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index 8728f0d0a4..7acba93ab3 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -168,7 +168,7 @@ bool ScriptEngine::runScript(const std::string& script, ScriptCallback callback) if (callback) { ghoul::Dictionary returnValue = ghoul::lua::loadArrayDictionaryFromString(script, _state); - callback.value()(returnValue); + callback(returnValue); } else { ghoul::lua::runScript(_state, script); } diff --git a/src/util/versionchecker.cpp b/src/util/versionchecker.cpp index 6ab9ffad73..c8236ed8f8 100644 --- a/src/util/versionchecker.cpp +++ b/src/util/versionchecker.cpp @@ -132,7 +132,7 @@ void VersionChecker::cancel() { } VersionChecker::SemanticVersion VersionChecker::latestVersion() { - return _latestVersion.value(); + return *_latestVersion; } bool operator<(const VersionChecker::SemanticVersion a, From b6b1817160da896508c8a257150d9b0d5b5806d4 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 30 Jan 2020 15:10:15 -0500 Subject: [PATCH 146/214] Number of shadow samples are now a compiling constant. --- modules/globebrowsing/shaders/rings_fs.glsl | 24 +++++++------ modules/globebrowsing/src/ringscomponent.cpp | 37 ++++++++++++++------ modules/globebrowsing/src/ringscomponent.h | 4 +-- modules/globebrowsing/src/shadowcomponent.h | 11 +++--- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index bae6535326..608ac8e7aa 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -25,6 +25,8 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" +#define NSSamples #{nShadowSamples} + in vec2 vs_st; in float vs_screenSpaceDepth; in vec4 shadowCoords; @@ -36,7 +38,7 @@ uniform float transparency; uniform vec3 sunPosition; uniform float _nightFactor; -uniform int nShadowSamples; +//uniform int nShadowSamples; uniform float zFightingPercentage; // temp @@ -83,18 +85,18 @@ Fragment getFragment() { normalizedShadowCoords.w = 1.0; float sum = 0; - for (int i = 0; i < nShadowSamples; ++i) { - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); + for (int i = 0; i < NSSamples; ++i) { + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, -NSSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, NSSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, -NSSamples + i)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, NSSamples - i)); } sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.0 * nShadowSamples + 1.f); + shadow = sum / (8.0 * NSSamples + 1.f); } // The normal for the one plane depends on whether we are dealing diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index ae65411e93..a0ad50e103 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -49,10 +49,12 @@ #include namespace { - constexpr const std::array UniformNames = { + constexpr const char* _loggerCat = "RingsComponent"; + + constexpr const std::array UniformNames = { "modelViewProjectionMatrix", "textureOffset", "transparency", "_nightFactor", "sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture", - "nShadowSamples", "zFightingPercentage" + "zFightingPercentage" }; constexpr const std::array GeomUniformNames = { @@ -243,6 +245,7 @@ void RingsComponent::initialize() { if (_ringsDictionary.hasKey(NumberShadowSamplesInfo.identifier)) { _nShadowSamples = _ringsDictionary.value(NumberShadowSamplesInfo.identifier); } + _nShadowSamples.onChange([this]() { compileShadowShader(); }); addProperty(_nShadowSamples); addProperty(_transparency); @@ -253,11 +256,7 @@ bool RingsComponent::isReady() const { } void RingsComponent::initializeGL() { - _shader = global::renderEngine.buildRenderProgram( - "RingsProgram", - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), - absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl") - ); + compileShadowShader(); _geometryOnlyShader = global::renderEngine.buildRenderProgram( "RingsGeomOnlyProgram", @@ -326,7 +325,7 @@ void RingsComponent::draw(const RenderData& data, _shader->setUniform(_uniformCache.transparency, _transparency); _shader->setUniform(_uniformCache.nightFactor, _nightFactor); _shader->setUniform(_uniformCache.sunPosition, _sunPosition); - _shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); + //_shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); _shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage); ringTextureUnit.activate(); @@ -377,8 +376,8 @@ void RingsComponent::draw(const RenderData& data, void RingsComponent::update(const UpdateData& data) { if (_shader->isDirty()) { - _shader->rebuildFromFile(); - ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); + //_shader->rebuildFromFile(); + compileShadowShader(); } if (_geometryOnlyShader->isDirty()) { @@ -474,6 +473,24 @@ void RingsComponent::createPlane() { ); } +void RingsComponent::compileShadowShader() { + ghoul::Dictionary dict; + dict.setValue("nShadowSamples", std::to_string(_nShadowSamples.value())); + + try { + _shader = global::renderEngine.buildRenderProgram( + "RingsProgram", + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), + absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl"), + dict + ); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.message); + } + ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames); +} + bool RingsComponent::isEnabled() const { return _enabled; } diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index b42313e692..d0373325f0 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -77,6 +77,7 @@ public: private: void loadTexture(); void createPlane(); + void compileShadowShader(); properties::StringProperty _texturePath; properties::FloatProperty _size; @@ -90,8 +91,7 @@ private: std::unique_ptr _shader; std::unique_ptr _geometryOnlyShader; UniformCache(modelViewProjectionMatrix, textureOffset, transparency, nightFactor, - sunPosition, ringTexture, shadowMatrix, shadowMapTexture, nShadowSamples, - zFightingPercentage + sunPosition, ringTexture, shadowMatrix, shadowMapTexture, zFightingPercentage ) _uniformCache; UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture) _geomUniformCache; diff --git a/modules/globebrowsing/src/shadowcomponent.h b/modules/globebrowsing/src/shadowcomponent.h index 6be4766419..4c6699d889 100644 --- a/modules/globebrowsing/src/shadowcomponent.h +++ b/modules/globebrowsing/src/shadowcomponent.h @@ -108,13 +108,10 @@ private: int _shadowDepthTextureWidth = 4096; bool _dynamicDepthTextureRes = true; - // All of these initializations should probably be 0 since they are GLuints? - GLuint _shadowDepthTexture = -1; - GLuint _positionInLightSpaceTexture = -1; - GLuint _shadowFBO = -1; - GLuint _firstPassSubroutine = -1; - GLuint _secondPassSubroutine = 1; - GLint _defaultFBO = -1; + GLuint _shadowDepthTexture = 0; + GLuint _positionInLightSpaceTexture = 0; + GLuint _shadowFBO = 0; + GLint _defaultFBO = 0; GLint _mViewport[4]; GLboolean _faceCulling; From 823e83047dcb069ff45ee063991336c6f2297ae3 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 30 Jan 2020 17:46:53 -0500 Subject: [PATCH 147/214] Second round adding constant parameters. --- .../globebrowsing/shaders/renderer_fs.glsl | 44 +++++++++++++------ modules/globebrowsing/shaders/rings_fs.glsl | 32 ++++++++------ modules/globebrowsing/src/renderableglobe.cpp | 10 ++++- modules/globebrowsing/src/ringscomponent.cpp | 7 +-- 4 files changed, 61 insertions(+), 32 deletions(-) diff --git a/modules/globebrowsing/shaders/renderer_fs.glsl b/modules/globebrowsing/shaders/renderer_fs.glsl index c08f078622..03276eac18 100644 --- a/modules/globebrowsing/shaders/renderer_fs.glsl +++ b/modules/globebrowsing/shaders/renderer_fs.glsl @@ -60,9 +60,13 @@ uniform float orenNayarRoughness; #endif #if SHADOW_MAPPING_ENABLED + +#define NSSamplesMinusOne #{nShadowSamples} +#define NSSamples (NSSamplesMinusOne + 1) + in vec4 shadowCoords; uniform sampler2DShadow shadowMapTexture; -uniform int nShadowSamples; +//uniform int nShadowSamples; uniform float zFightingPercentage; #endif @@ -273,19 +277,33 @@ Fragment getFragment() { normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w; normalizedShadowCoords.w = 1.0; - float sum = 0; - for (int i = 0; i < nShadowSamples; ++i) { - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); - } + float sum = 0; + // for (int i = 0; i < nShadowSamples; ++i) { + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, -nShadowSamples + i)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, 0)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-nShadowSamples + i, nShadowSamples - i)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -nShadowSamples + i)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , nShadowSamples - i)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, -nShadowSamples + i)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, 0)); + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( nShadowSamples - i, nShadowSamples - i)); + // } + // sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); + // shadow = sum / (8.0 * nShadowSamples + 1.f); + + #for i in 0..#{nShadowSamples} + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); + //} + #endfor sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.0 * nShadowSamples + 1.f); + shadow = sum / (8.0 * NSSamples + 1.f); } frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow; #endif diff --git a/modules/globebrowsing/shaders/rings_fs.glsl b/modules/globebrowsing/shaders/rings_fs.glsl index 608ac8e7aa..7aaa3f0e8d 100644 --- a/modules/globebrowsing/shaders/rings_fs.glsl +++ b/modules/globebrowsing/shaders/rings_fs.glsl @@ -25,7 +25,8 @@ #include "PowerScaling/powerScaling_fs.hglsl" #include "fragment.glsl" -#define NSSamples #{nShadowSamples} +#define NSSamplesMinusOne #{nShadowSamples} +#define NSSamples (NSSamplesMinusOne + 1) in vec2 vs_st; in float vs_screenSpaceDepth; @@ -44,6 +45,7 @@ uniform float zFightingPercentage; // temp in vec4 fragPosInLightSpace; + Fragment getFragment() { // Moving the origin to the center vec2 st = (vs_st - vec2(0.5)) * 2.0; @@ -85,20 +87,22 @@ Fragment getFragment() { normalizedShadowCoords.w = 1.0; float sum = 0; - for (int i = 0; i < NSSamples; ++i) { - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, -NSSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + i, NSSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, -NSSamples + i)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, 0)); - sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - i, NSSamples - i)); - } + //for (int i = 0; i < NSSamples; ++i) { + #for i in 0..#{nShadowSamples} + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i})); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0)); + sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i})); + //} + #endfor sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0)); - shadow = sum / (8.0 * NSSamples + 1.f); + shadow = clamp(sum / (8.0 * NSSamples + 1.f), 0.35, 1.0); } - + // The normal for the one plane depends on whether we are dealing // with a front facing or back facing fragment vec3 normal; @@ -119,7 +123,7 @@ Fragment getFragment() { Fragment frag; - frag.color = (0.65 * diffuse * shadow) + diffuse * 0.35; + frag.color = diffuse * shadow; frag.depth = vs_screenSpaceDepth; frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0); frag.gNormal = vec4(normal, 1.0); diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index 988f6f0caa..b8357a6548 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -565,6 +565,9 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) _shadowMappingPropertyOwner.addProperty(_generalProperties.shadowMapping); _shadowMappingPropertyOwner.addProperty(_generalProperties.zFightingPercentage); _shadowMappingPropertyOwner.addProperty(_generalProperties.nShadowSamples); + _generalProperties.nShadowSamples.onChange([&]() { + _shadersNeedRecompilation = true; + }); addPropertySubOwner(_shadowMappingPropertyOwner); _generalProperties.targetLodScaleFactor.onChange([this]() { @@ -1330,7 +1333,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData& glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); program.setUniform("shadowMapTexture", shadowMapUnit); - program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); + //program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage); } @@ -1458,7 +1461,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); program.setUniform("shadowMapTexture", shadowMapUnit); - program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); + //program.setUniform("nShadowSamples", _generalProperties.nShadowSamples); program.setUniform("zFightingPercentage", _generalProperties.zFightingPercentage); } @@ -1726,6 +1729,9 @@ void RenderableGlobe::recompileShaders() { shaderDictionary.setValue(p.first, p.second); } + // Shadow Mapping Samples + shaderDictionary.setValue("nShadowSamples", _generalProperties.nShadowSamples - 1); + // // Create local shader // diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index a0ad50e103..afa5319d0d 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -176,7 +176,7 @@ RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) , _transparency(TransparencyInfo, 0.15f, 0.f, 1.f) , _enabled({ "Enabled", "Enabled", "Enable/Disable Rings" }, true) , _zFightingPercentage(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f) - , _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 20) + , _nShadowSamples(NumberShadowSamplesInfo, 2, 1, 7) , _ringsDictionary(dictionary) { using ghoul::filesystem::File; @@ -327,7 +327,7 @@ void RingsComponent::draw(const RenderData& data, _shader->setUniform(_uniformCache.sunPosition, _sunPosition); //_shader->setUniform(_uniformCache.nShadowSamples, _nShadowSamples); _shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage); - + ringTextureUnit.activate(); _texture->bind(); _shader->setUniform(_uniformCache.ringTexture, ringTextureUnit); @@ -475,9 +475,10 @@ void RingsComponent::createPlane() { void RingsComponent::compileShadowShader() { ghoul::Dictionary dict; - dict.setValue("nShadowSamples", std::to_string(_nShadowSamples.value())); + dict.setValue("nShadowSamples", std::to_string(_nShadowSamples - 1)); try { + global::renderEngine.removeRenderProgram(_shader.get()); _shader = global::renderEngine.buildRenderProgram( "RingsProgram", absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"), From 4651f6db3831033309230f8704bdd3c9811f6ed8 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Thu, 30 Jan 2020 18:10:16 -0500 Subject: [PATCH 148/214] Set the maximum number of samples to 7. --- modules/globebrowsing/src/renderableglobe.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/globebrowsing/src/renderableglobe.cpp b/modules/globebrowsing/src/renderableglobe.cpp index b8357a6548..0392bad123 100644 --- a/modules/globebrowsing/src/renderableglobe.cpp +++ b/modules/globebrowsing/src/renderableglobe.cpp @@ -517,7 +517,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary) BoolProperty(EclipseHardShadowsInfo, false), BoolProperty(ShadowMappingInfo, false), FloatProperty(ZFightingPercentageInfo, 0.995f, 0.000001f, 1.f), - IntProperty(NumberShadowSamplesInfo, 5, 1, 20), + IntProperty(NumberShadowSamplesInfo, 5, 1, 7), FloatProperty(TargetLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CurrentLodScaleFactorInfo, 15.f, 1.f, 50.f), FloatProperty(CameraMinHeightInfo, 100.f, 0.f, 1000.f), From b05df8778ef962c5903677916876c0fbc5e1ba8d Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 30 Jan 2020 18:15:38 -0500 Subject: [PATCH 149/214] Iss asset with model added --- .../planets/earth/satellites/misc/iss.asset | 129 ++++++++++++++++-- .../earth/satellites/satellites_shared.asset | 92 +++++++++---- modules/sync/syncs/urlsynchronization.cpp | 33 ++++- modules/sync/syncs/urlsynchronization.h | 1 + 4 files changed, 219 insertions(+), 36 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset index 27e3f964dd..9f18fb85f7 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -1,11 +1,124 @@ local assetHelper = asset.require('util/asset_helper') -local shared = asset.require('../satellites_shared') +local satelliteHelper = asset.require('../satellites_shared') +local transforms = asset.require('scene/solarsystem/planets/earth/transforms') +local sunTransforms = asset.require('scene/solarsystem/sun/transforms') -local group = { - Title = "ISS", - Url = "https://live.ariss.org/iss.txt", - TrailColor = { 0.0, 1.0, 0.0 } -} +local url = "https://celestrak.com/satcat/tle.php?CATNR=25544" +local identifier = "ISS" +local filename = "ISS.txt" +local nodes = {} -local tle = shared.downloadTLEFile(asset, group.Url, group.Title) -shared.registerSatelliteGroupObjects(asset, group, tle, true) +local modelsLocation = asset.syncedResource({ + Name = "ISS Models", + Type = "HttpSynchronization", + Identifier = "iss_model", + Version = 1 +}) + + +local tle = satelliteHelper.downloadTLEFile(asset, url, identifier, filename) + +local initializeAndAddNodes = function() + + local lineElement = satelliteHelper.makeSingleLineElement(tle, filename) + local period = satelliteHelper.getPeriodFromElement(lineElement) + local path = tle .. "\\" .. filename + + local iss = { + Identifier = identifier, + Parent = transforms.EarthInertial.Identifier, + Transform = { + Translation = { + Type = "TLETranslation", + Body = identifier, + Observer = transforms.EarthInertial.Identifier, + File = path, + LineNumber = 1 + }, + Scale = { + Type = "StaticScale", + Scale = 1 + } + }, + Tag = { "earth_satellite", "ISS" }, + GUI = { + Path = "/Solar System/Planets/Earth/Satellites/ISS" + } + } + + local issModel = { + Identifier = identifier .. "_model", + Parent = iss.Identifier, + Renderable = { + Type = "RenderableModel", + Geometry = { + Type = "MultiModelGeometry", + GeometryFile = modelsLocation .. "/iss.obj" + }, + ColorTexture = modelsLocation .. "/gray.png", + --ModelTransform = RotationMatrix, + LightSources = { + { + Type = "SceneGraphLightSource", + Identifier = "Sun", + Node = sunTransforms.SolarSystemBarycenter.Identifier, + Intensity = 1.0 + }, + { + Type = "SceneGraphLightSource", + Identifier = "Earth", + Node = "Earth", + Intensity = 1.0 + }, + { + Identifier = "Camera", + Type = "CameraLightSource", + Intensity = 0.5 + } + } + }, + Tag = { "earth_satellite", "ISS" }, + GUI = { + Path = "/Solar System/Planets/Earth/Satellites/ISS/Model" + } + } + + local issTrail = { + Identifier = identifier .. "_trail", + Parent = transforms.EarthInertial.Identifier, + Renderable = { + Type = "RenderableTrailOrbit", + Translation = { + Type = "TLETranslation", + Body = identifier, + Observer = transforms.EarthInertial.Identifier, + File = path, + LineNumber = 1 + }, + Color = { 0.9, 0.0, 0.0 }, + Period = period, + Resolution = 160 + }, + Tag = { "earth_satellite", "ISS" }, + GUI = { + Path = "/Solar System/Planets/Earth/Satellites/ISS/Trail" + } + } + + local myNodes = { iss, issModel, issTrail } + + for _, node in ipairs(myNodes) do + openspace.addSceneGraphNode(node) + end + + return myNodes +end + +asset.onInitialize(function () + nodes = initializeAndAddNodes() +end) + +asset.onDeinitialize(function () + openspace.removeSceneGraphNode(nodes[3].Identifier) -- Removing trail + openspace.removeSceneGraphNode(nodes[1].Identifier) -- Removing ISS and model recursively +end) diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset index e5fde6d30c..05825e4c0f 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/satellites_shared.asset @@ -8,17 +8,77 @@ local satImageFolder = asset.syncedResource({ Version = 1 }) -function downloadTLEFile(sceneAsset, url, name) +function downloadTLEFile(sceneAsset, url, name, filename) local identifier = name identifier = identifier:gsub(" ", "") identifier = identifier:gsub("&", "") identifier = identifier:gsub("-", "") - return sceneAsset.syncedResource({ + + local resTable = { Name = "Satellite TLE Data (" .. name .. ")", Type = "UrlSynchronization", Identifier = "satellite_tle_data_" .. identifier, Url = url - }) + } + + if (filename ~= '') then + resTable.Filename = filename + end + + return sceneAsset.syncedResource(resTable) +end + +-- Check format of a set of 3 TLE file lines and return nonzero if there is a format error +function isValidTLEFileFormat(lineArr) + function isEmpty(s) return s == nil or s == '' end + + if isEmpty(lineArr[1]) or isEmpty(lineArr[2]) or isEmpty(lineArr[3]) then + return false + end + if string.sub(lineArr[2], 1, 2) ~= "1 " then + return false + end + if string.sub(lineArr[3], 1, 2) ~= "2 " then + return false + end + return true +end + +local makeSingleLineElement = function(tle, filename) + local path = tle .. "\\" .. filename + local file = io.open(path, "r") + assert(file, "File not found: " .. path) + + local line = { + file:read('*l'), --title line + file:read('*l'), + file:read('*l') + } + + assert(isValidTLEFileFormat(line), "TLE file syntax error on line " .. 1 .. ": " .. path) + + -- Trim string + line[1] = line[1]:gsub("^%s*(.-)%s*$", "%1") + line[1] = line[1]:gsub("%s+", "_") + line[1] = line[1]:gsub("[%-()]", "") + --local title = line[1] + + return line +end + +function numLinesInFile(filename) + local ctr = 0 + for _ in io.lines(filename) do ctr = ctr + 1 end + return ctr +end + +local getPeriodFromElement = function(element) + -- Get period from correct location of the string + local per = tonumber(string.sub(element[3], 53, 63)) + -- Trail for 2x a single revolution + per = 1.0 / per * 2.0 + + return per end local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder, shouldAddDuplicates) @@ -27,28 +87,6 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder local path = tleFolder .. "/" .. filename - function numLinesInFile(filename) - local ctr = 0 - for _ in io.lines(filename) do ctr = ctr + 1 end - return ctr - end - - -- Check format of a set of 3 TLE file lines and return nonzero if there is a format error - function isValidTLEFileFormat(lineArr) - function isEmpty(s) return s == nil or s == '' end - - if isEmpty(lineArr[1]) or isEmpty(lineArr[2]) or isEmpty(lineArr[3]) then - return false - end - if string.sub(lineArr[2], 1, 2) ~= "1 " then - return false - end - if string.sub(lineArr[3], 1, 2) ~= "2 " then - return false - end - return true - end - function satellites(title, file, color) return { Identifier = title, @@ -72,4 +110,8 @@ local registerSatelliteGroupObjects = function(containingAsset, group, tleFolder end asset.export("downloadTLEFile", downloadTLEFile) +asset.export("isValidTLEFileFormat", isValidTLEFileFormat) +asset.export("numLinesInFile", numLinesInFile) +asset.export("makeSingleLineElement", makeSingleLineElement) +asset.export("getPeriodFromElement", getPeriodFromElement) asset.export("registerSatelliteGroupObjects", registerSatelliteGroupObjects) diff --git a/modules/sync/syncs/urlsynchronization.cpp b/modules/sync/syncs/urlsynchronization.cpp index ecb2e71f5b..75d52cee1b 100644 --- a/modules/sync/syncs/urlsynchronization.cpp +++ b/modules/sync/syncs/urlsynchronization.cpp @@ -43,8 +43,10 @@ namespace { constexpr const char* KeyIdentifier = "Identifier"; constexpr const char* KeyOverride = "Override"; constexpr const char* KeyUseHash = "UseHash"; + constexpr const char* KeyFilename = "Filename"; constexpr const char* TempSuffix = ".tmp"; + constexpr const char* ext = ".txt"; } // namespace namespace openspace { @@ -90,6 +92,13 @@ documentation::Documentation UrlSynchronization::Documentation() { "circumstances. If this is not desired, the URLSynchronization use the " "bare directory name alone if this value is 'false'. If this value is " "'false', the identifier has to be specified." + }, + { + KeyFilename, + new StringVerifier, + Optional::Yes, + "Optional to provide filename to override the one which is automatically " + "created from the url. " } } }; @@ -117,6 +126,14 @@ UrlSynchronization::UrlSynchronization(const ghoul::Dictionary& dict, } } + if (dict.hasValue(KeyFilename)) { + _filename = dict.value(KeyFilename); + std::size_t foundExt = _filename.find(ext); + if (foundExt == std::string::npos) { + _filename += ext; + } + } + bool useHash = true; if (dict.hasValue(KeyUseHash)) { useHash = dict.value(KeyUseHash); @@ -181,11 +198,21 @@ void UrlSynchronization::start() { std::vector> downloads; for (const std::string& url : _urls) { - const size_t lastSlash = url.find_last_of('/'); - const std::string filename = url.substr(lastSlash + 1); + if (_filename.empty()) { + const size_t lastSlash = url.find_last_of('/'); + std::string lastPartOfUrl = url.substr(lastSlash + 1); + + lastPartOfUrl.erase(std::remove(lastPartOfUrl.begin(), lastPartOfUrl.end(), '?'), lastPartOfUrl.end()); + + std::size_t foundExt = lastPartOfUrl.find(ext); + if (foundExt == std::string::npos) { + lastPartOfUrl += ext; + } + _filename = lastPartOfUrl; + } std::string fileDestination = directory() + - ghoul::filesystem::FileSystem::PathSeparator + filename + TempSuffix; + ghoul::filesystem::FileSystem::PathSeparator + _filename + TempSuffix; std::unique_ptr download = std::make_unique( diff --git a/modules/sync/syncs/urlsynchronization.h b/modules/sync/syncs/urlsynchronization.h index b3e6ce4a98..12406e5a8a 100644 --- a/modules/sync/syncs/urlsynchronization.h +++ b/modules/sync/syncs/urlsynchronization.h @@ -58,6 +58,7 @@ private: bool _forceOverride = false; std::string _synchronizationRoot; std::string _identifier; + std::string _filename; std::atomic_bool _nTotalBytesKnown = false; std::atomic_size_t _nTotalBytes = 0; From 685579cd4f694b60ebde25dc986893b614f1b282 Mon Sep 17 00:00:00 2001 From: GPayne Date: Thu, 30 Jan 2020 16:16:06 -0700 Subject: [PATCH 150/214] Work in progress for new quantization scheme --- modules/globebrowsing/src/timequantizer.cpp | 62 +++++++++++++++++++++ modules/globebrowsing/src/timequantizer.h | 32 +++++++++++ 2 files changed, 94 insertions(+) diff --git a/modules/globebrowsing/src/timequantizer.cpp b/modules/globebrowsing/src/timequantizer.cpp index 102ade1661..09f9f5b83c 100644 --- a/modules/globebrowsing/src/timequantizer.cpp +++ b/modules/globebrowsing/src/timequantizer.cpp @@ -48,6 +48,8 @@ double TimeQuantizer::parseTimeResolutionStr(const std::string& resolutionStr) { char* p; double value = strtol(numberString.c_str(), &p, 10); + _resolutionValue = value; + _resolutionUnit = unit; if (*p) { // not a number throw ghoul::RuntimeError("Cannot convert " + numberString + " to number"); } @@ -124,4 +126,64 @@ std::vector