From 6d56b1d38a1a40d8606dfbdff80dfa7311a66efe Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 19 Aug 2016 16:56:57 +0200 Subject: [PATCH 001/205] implement shadow mapping for image projections on non-convex bodies --- data/scene/rosetta/67P/67P.mod | 5 +- .../rendering/renderablemodelprojection.cpp | 52 +++++++-- .../rendering/renderablemodelprojection.h | 2 +- .../rendering/renderableplanetprojection.cpp | 13 ++- .../shaders/renderableModelDepth_fs.glsl | 30 +++++ .../shaders/renderableModelDepth_vs.glsl | 36 ++++++ .../shaders/renderableModelProjection_fs.glsl | 33 +++--- .../shaders/renderableModelProjection_vs.glsl | 16 +-- .../newhorizons/util/projectioncomponent.cpp | 110 ++++++++++++++---- .../newhorizons/util/projectioncomponent.h | 13 ++- 10 files changed, 240 insertions(+), 70 deletions(-) create mode 100644 modules/newhorizons/shaders/renderableModelDepth_fs.glsl create mode 100644 modules/newhorizons/shaders/renderableModelDepth_vs.glsl diff --git a/data/scene/rosetta/67P/67P.mod b/data/scene/rosetta/67P/67P.mod index a6ec406f4c..e925538385 100644 --- a/data/scene/rosetta/67P/67P.mod +++ b/data/scene/rosetta/67P/67P.mod @@ -62,10 +62,9 @@ return { Method = "ELLIPSOID", Aberration = "NONE", Fovy = 5.00, - Aspect = 1, - Near = 0.01, - Far = 1000000, + Aspect = 1 }, + BoundingSphereRadius = 5000.0 }, Ephemeris = { diff --git a/modules/newhorizons/rendering/renderablemodelprojection.cpp b/modules/newhorizons/rendering/renderablemodelprojection.cpp index 477e2b62ca..5f0adfa4db 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.cpp +++ b/modules/newhorizons/rendering/renderablemodelprojection.cpp @@ -40,6 +40,7 @@ namespace { const std::string keyDestination = "Rotation.Destination"; const std::string keyBody = "Body"; const std::string keyGeometry = "Geometry"; + const std::string keyBoundingSphereRadius = "BoundingSphereRadius"; const std::string keyTextureColor = "Textures.Color"; const std::string keyTextureProject = "Textures.Project"; @@ -97,7 +98,10 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di completeSuccess &= _projectionComponent.initializeProjectionSettings(dictionary); openspace::SpiceManager::ref().addFrame(_target, _source); - setBoundingSphere(pss(1.f, 9.f)); + + float boundingSphereRadius = 1.0e9; + dictionary.getValue(keyBoundingSphereRadius, boundingSphereRadius); + setBoundingSphere(PowerScaledScalar::CreatePSS(boundingSphereRadius)); Renderable::addProperty(_performShading); Renderable::addProperty(_rotation); @@ -130,11 +134,20 @@ bool RenderableModelProjection::initialize() { ghoul::opengl::ProgramObject::IgnoreError::Yes ); + _depthFboProgramObject = ghoul::opengl::ProgramObject::Build("DepthPass", + "${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_vs.glsl", + "${MODULE_NEWHORIZONS}/shaders/renderableModelDepth_fs.glsl"); + + completeSuccess &= loadTextures(); completeSuccess &= _projectionComponent.initialize(); + + auto bs = getBoundingSphere(); completeSuccess &= _geometry->initialize(this); + setBoundingSphere(bs); // ignore bounding sphere set by geometry. + completeSuccess &= !_source.empty(); completeSuccess &= !_destination.empty(); @@ -164,7 +177,6 @@ void RenderableModelProjection::render(const RenderData& data) { if (_projectionComponent.needsClearProjection()) _projectionComponent.clearAllProjections(); - _camScaling = data.camera.scaling(); _up = data.camera.lookUpVectorCameraSpace(); if (_capture && _projectionComponent.doesPerformProjection()) @@ -205,6 +217,9 @@ void RenderableModelProjection::update(const UpdateData& data) { if (_fboProgramObject->isDirty()) _fboProgramObject->rebuildFromFile(); + if (_depthFboProgramObject->isDirty()) + _depthFboProgramObject->rebuildFromFile(); + _time = data.time; if (openspace::ImageSequencer::ref().isReady()) { @@ -236,8 +251,18 @@ void RenderableModelProjection::update(const UpdateData& data) { void RenderableModelProjection::imageProjectGPU( std::shared_ptr projectionTexture) { - _projectionComponent.imageProjectBegin(); + _projectionComponent.depthMapRenderBegin(); + _depthFboProgramObject->activate(); + _depthFboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); + _depthFboProgramObject->setUniform("ModelTransform", _transform); + _geometry->setUniforms(*_fboProgramObject); + _geometry->render(); + + _depthFboProgramObject->deactivate(); + _projectionComponent.depthMapRenderEnd(); + + _projectionComponent.imageProjectBegin(); _fboProgramObject->activate(); ghoul::opengl::TextureUnit unitFbo; @@ -245,9 +270,17 @@ void RenderableModelProjection::imageProjectGPU( projectionTexture->bind(); _fboProgramObject->setUniform("projectionTexture", unitFbo); + ghoul::opengl::TextureUnit unitDepthFbo; + unitDepthFbo.activate(); + _projectionComponent.depthTexture().bind(); + _fboProgramObject->setUniform("depthTexture", unitDepthFbo); + + glm::vec4 debugVector(0.0, 0.0, 0.0, 1.0); + glm::vec4 debugTransformed = _projectorMatrix * _transform * debugVector; + debugTransformed /= debugTransformed.w; + _fboProgramObject->setUniform("ProjectorMatrix", _projectorMatrix); _fboProgramObject->setUniform("ModelTransform", _transform); - _fboProgramObject->setUniform("_scaling", _camScaling); _fboProgramObject->setUniform("boresight", _boresight); _geometry->setUniforms(*_fboProgramObject); @@ -309,19 +342,24 @@ void RenderableModelProjection::attitudeParameters(double time) { time, lightTime); psc position = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - position[3] += (3 + _camScaling[1]); + position[3] += 3; glm::vec3 cpos = position.vec3(); + float distance = glm::length(cpos); + float radius = getBoundingSphere().lengthf(); + _projectorMatrix = _projectionComponent.computeProjectorMatrix( cpos, boresight, _up, _instrumentMatrix, _projectionComponent.fieldOfViewY(), _projectionComponent.aspectRatio(), - _projectionComponent.nearPlane(), - _projectionComponent.farPlane(), + distance - radius, + distance + radius, _boresight ); } + + void RenderableModelProjection::project() { for (auto img : _imageTimes) { attitudeParameters(img.startTime); diff --git a/modules/newhorizons/rendering/renderablemodelprojection.h b/modules/newhorizons/rendering/renderablemodelprojection.h index 644af7b905..e91d8c1283 100644 --- a/modules/newhorizons/rendering/renderablemodelprojection.h +++ b/modules/newhorizons/rendering/renderablemodelprojection.h @@ -74,6 +74,7 @@ private: std::unique_ptr _programObject; std::unique_ptr _fboProgramObject; + std::unique_ptr _depthFboProgramObject; std::unique_ptr _baseTexture; @@ -100,7 +101,6 @@ private: bool _capture; psc _sunPosition; - properties::BoolProperty _performShading; }; diff --git a/modules/newhorizons/rendering/renderableplanetprojection.cpp b/modules/newhorizons/rendering/renderableplanetprojection.cpp index 13516f1e5f..727bfefbe5 100644 --- a/modules/newhorizons/rendering/renderableplanetprojection.cpp +++ b/modules/newhorizons/rendering/renderableplanetprojection.cpp @@ -47,6 +47,7 @@ namespace { const std::string keyFrame = "Frame"; const std::string keyGeometry = "Geometry"; + const std::string keyRadius = "Geometry.Radius"; const std::string keyShading = "PerformShading"; const std::string keyBody = "Body"; const std::string _mainFrame = "GALACTIC"; @@ -103,6 +104,10 @@ RenderablePlanetProjection::RenderablePlanetProjection(const ghoul::Dictionary& if (success) _heightMapTexturePath = absPath(heightMapPath); + glm::vec2 radius = glm::vec2(1.0, 9.0); + dictionary.getValue(keyRadius, radius); + setBoundingSphere(pss(radius)); + addPropertySubOwner(_geometry.get()); addPropertySubOwner(_projectionComponent); @@ -136,7 +141,6 @@ bool RenderablePlanetProjection::initialize() { completeSuccess &= loadTextures(); completeSuccess &= _projectionComponent.initialize(); - completeSuccess &= _geometry->initialize(this); if (completeSuccess) { @@ -287,6 +291,9 @@ void RenderablePlanetProjection::attitudeParameters(double time) { //position[3] += 3; glm::vec3 cpos = position.vec3(); + float distance = glm::length(cpos); + float radius = getBoundingSphere().lengthf(); + _projectorMatrix = _projectionComponent.computeProjectorMatrix( cpos, bs, @@ -294,8 +301,8 @@ void RenderablePlanetProjection::attitudeParameters(double time) { _instrumentMatrix, _projectionComponent.fieldOfViewY(), _projectionComponent.aspectRatio(), - _projectionComponent.nearPlane(), - _projectionComponent.farPlane(), + distance - radius, + distance + radius, _boresight ); } diff --git a/modules/newhorizons/shaders/renderableModelDepth_fs.glsl b/modules/newhorizons/shaders/renderableModelDepth_fs.glsl new file mode 100644 index 0000000000..2b7bcfdaec --- /dev/null +++ b/modules/newhorizons/shaders/renderableModelDepth_fs.glsl @@ -0,0 +1,30 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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__ + +void main() { + gl_FragColor = vec4(1.0); + //gl_FragDepth = gl_FragCoord.z; +} diff --git a/modules/newhorizons/shaders/renderableModelDepth_vs.glsl b/modules/newhorizons/shaders/renderableModelDepth_vs.glsl new file mode 100644 index 0000000000..574a349ad4 --- /dev/null +++ b/modules/newhorizons/shaders/renderableModelDepth_vs.glsl @@ -0,0 +1,36 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 vec4 in_position; + +uniform mat4 ProjectorMatrix; +uniform mat4 ModelTransform; + +void main() { + gl_Position = ProjectorMatrix * ModelTransform * psc_to_meter(in_position, vec2(1.0, 0.0)); +} diff --git a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl index 0d0bcbec89..9f052c5889 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl @@ -24,42 +24,41 @@ #version __CONTEXT__ +#include "PowerScaling/powerScalingMath.hglsl" #include "PowerScaling/powerScaling_vs.hglsl" + in vec4 vs_position; +in vec4 vs_ndc; in vec4 vs_normal; -in vec2 vs_uv; -in vec4 ProjTexCoord; out vec4 color; uniform sampler2D projectionTexture; +uniform sampler2D depthTexture; uniform mat4 ModelTransform; -uniform vec2 _scaling; uniform vec3 boresight; +uniform vec4 debugColor; bool inRange(float x, float a, float b) { return (x >= a && x <= b); } void main() { - vec2 uv = vec2(0.5,0.5)*vs_uv+vec2(0.5,0.5); - vec3 n = normalize(vs_normal.xyz); - vec4 projected = ProjTexCoord; + vec4 projected = vs_ndc; + vec2 uv = vec2(0.5) * projected.xy + vec2(0.5); - //normalize - projected.x /= projected.w; - projected.y /= projected.w; - //invert gl coordinates - projected.x = 1 - projected.x; - - if ((inRange(projected.x, 0, 1) && inRange(projected.y, 0, 1)) && (dot(n, boresight) < 0)) { - color = texture(projectionTexture, projected.xy); + float thisDepth = projected.z * 0.5 + 0.5; + float closestDepth = texture(depthTexture, uv).r; + float epsilon = 0.001; + + if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) && + dot(n, boresight) < 0 && thisDepth <= closestDepth + epsilon) { + color = texture(projectionTexture, uv); color.a = 1.0; - } - else { - color = vec4(vec3(0.0), 1.0); + } else { + color = vec4(vec3(0.0), 0.0); } } diff --git a/modules/newhorizons/shaders/renderableModelProjection_vs.glsl b/modules/newhorizons/shaders/renderableModelProjection_vs.glsl index 20c64bd812..2be32b0119 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_vs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_vs.glsl @@ -33,26 +33,20 @@ layout(location = 2) in vec3 in_normal; out vec4 vs_position; out vec4 vs_normal; out vec2 vs_uv; -out vec4 ProjTexCoord; +out vec4 vs_ndc; uniform mat4 ProjectorMatrix; uniform mat4 ModelTransform; -uniform vec2 _scaling; uniform vec3 boresight; void main() { - vs_position = in_position; - - vec4 tmp = in_position; - vec4 position = pscTransform(tmp, ModelTransform); - vs_position = position; - - vec4 raw_pos = psc_to_meter(in_position, _scaling); - ProjTexCoord = ProjectorMatrix * ModelTransform * raw_pos; + vec4 raw_pos = psc_to_meter(in_position, vec2(1.0, 0.0)); + vs_position = ProjectorMatrix * ModelTransform * raw_pos; vs_normal = normalize(ModelTransform * vec4(in_normal,0)); - + vs_ndc = vs_position / vs_position.w; + //match clipping plane vec2 texco = (in_st * 2) - 1; vs_uv = texco; diff --git a/modules/newhorizons/util/projectioncomponent.cpp b/modules/newhorizons/util/projectioncomponent.cpp index 56548b1d88..048eb1bf7a 100644 --- a/modules/newhorizons/util/projectioncomponent.cpp +++ b/modules/newhorizons/util/projectioncomponent.cpp @@ -41,8 +41,6 @@ namespace { const std::string keyInstrument = "Instrument.Name"; const std::string keyInstrumentFovy = "Instrument.Fovy"; const std::string keyInstrumentAspect = "Instrument.Aspect"; - const std::string keyInstrumentNear = "Instrument.Near"; - const std::string keyInstrumentFar = "Instrument.Far"; const std::string keyProjObserver = "Projection.Observer"; const std::string keyProjTarget = "Projection.Target"; @@ -81,8 +79,10 @@ ProjectionComponent::ProjectionComponent() } bool ProjectionComponent::initialize() { - bool a = generateProjectionLayerTexture(); - bool b = auxiliaryRendertarget(); + bool success = generateProjectionLayerTexture(); + success &= generateDepthTexture(); + success &= auxiliaryRendertarget(); + success &= depthRendertarget(); using std::unique_ptr; using ghoul::opengl::Texture; @@ -98,7 +98,7 @@ bool ProjectionComponent::initialize() { } _placeholderTexture = std::move(texture); - return a && b; + return success; } bool ProjectionComponent::deinitialize() { @@ -120,8 +120,7 @@ bool ProjectionComponent::initializeProjectionSettings(const Dictionary& diction completeSuccess &= dictionary.getValue(keyProjTarget, _projecteeID); completeSuccess &= dictionary.getValue(keyInstrumentFovy, _fovy); completeSuccess &= dictionary.getValue(keyInstrumentAspect, _aspectRatio); - completeSuccess &= dictionary.getValue(keyInstrumentNear, _nearPlane); - completeSuccess &= dictionary.getValue(keyInstrumentFar, _farPlane); + ghoul_assert(completeSuccess, "All neccessary attributes not found in modfile"); std::string a = "NONE"; @@ -227,11 +226,63 @@ void ProjectionComponent::imageProjectBegin() { ); } +ghoul::opengl::Texture& ProjectionComponent::depthTexture() { + return *_depthTexture; +} + +void ProjectionComponent::depthMapRenderBegin() { + // keep handle to the current bound FBO + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); + glGetIntegerv(GL_VIEWPORT, _viewport); + + glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID); + glEnable(GL_DEPTH_TEST); + + glViewport( + 0, 0, + static_cast(_depthTexture->width()), + static_cast(_depthTexture->height()) + ); + + glClear(GL_DEPTH_BUFFER_BIT); +} + +void ProjectionComponent::depthMapRenderEnd() { + glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); + glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]); +} + + + void ProjectionComponent::imageProjectEnd() { glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]); } + +bool ProjectionComponent::depthRendertarget() { + GLint defaultFBO; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO); + // setup FBO + glGenFramebuffers(1, &_depthFboID); + glBindFramebuffer(GL_FRAMEBUFFER, _depthFboID); + glFramebufferTexture2D( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + GL_TEXTURE_2D, + *_depthTexture, + 0); + + glDrawBuffer(GL_NONE); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) + return false; + + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + return true; +} + bool ProjectionComponent::auxiliaryRendertarget() { bool completeSuccess = true; @@ -266,26 +317,27 @@ glm::mat4 ProjectionComponent::computeProjectorMatrix(const glm::vec3 loc, glm:: float nearPlane, float farPlane, glm::vec3& boreSight) { + //rotate boresight into correct alignment boreSight = instrumentMatrix*aim; glm::vec3 uptmp(instrumentMatrix*glm::dvec3(up)); // create view matrix - glm::vec3 e3 = glm::normalize(boreSight); + glm::vec3 e3 = glm::normalize(-boreSight); glm::vec3 e1 = glm::normalize(glm::cross(uptmp, e3)); glm::vec3 e2 = glm::normalize(glm::cross(e3, e1)); + + + + glm::mat4 projViewMatrix = glm::mat4(e1.x, e2.x, e3.x, 0.f, e1.y, e2.y, e3.y, 0.f, e1.z, e2.z, e3.z, 0.f, - -glm::dot(e1, loc), -glm::dot(e2, loc), -glm::dot(e3, loc), 1.f); + glm::dot(e1, -loc), glm::dot(e2, -loc), glm::dot(e3, -loc), 1.f); // create perspective projection matrix glm::mat4 projProjectionMatrix = glm::perspective(glm::radians(fieldOfViewY), aspectRatio, nearPlane, farPlane); - // bias matrix - glm::mat4 projNormalizationMatrix = glm::mat4(0.5f, 0, 0, 0, - 0, 0.5f, 0, 0, - 0, 0, 0.5f, 0, - 0.5f, 0.5f, 0.5f, 1); - return projNormalizationMatrix*projProjectionMatrix*projViewMatrix; + + return projProjectionMatrix*projViewMatrix; } bool ProjectionComponent::doesPerformProjection() const { @@ -328,14 +380,6 @@ float ProjectionComponent::aspectRatio() const { return _aspectRatio; } -float ProjectionComponent::nearPlane() const { - return _nearPlane; -} - -float ProjectionComponent::farPlane() const { - return _farPlane; -} - void ProjectionComponent::clearAllProjections() { // keep handle to the current bound FBO GLint defaultFBO; @@ -402,4 +446,24 @@ bool ProjectionComponent::generateProjectionLayerTexture() { } +bool ProjectionComponent::generateDepthTexture() { + int maxSize = OpenGLCap.max2DTextureSize() / 2; + + LINFO( + "Creating depth texture of size '" << maxSize / 2 << ", " << maxSize / 2 << "'" + ); + + _depthTexture = std::make_unique( + glm::uvec3(maxSize / 2, maxSize / 2, 1), + ghoul::opengl::Texture::Format::DepthComponent, + GL_DEPTH_COMPONENT32F + ); + + if (_depthTexture) + _depthTexture->uploadTexture(); + + return _depthTexture != nullptr; + +} + } // namespace openspace diff --git a/modules/newhorizons/util/projectioncomponent.h b/modules/newhorizons/util/projectioncomponent.h index 197a886dc4..34aa7a5225 100644 --- a/modules/newhorizons/util/projectioncomponent.h +++ b/modules/newhorizons/util/projectioncomponent.h @@ -46,11 +46,17 @@ public: bool initializeProjectionSettings(const ghoul::Dictionary& dictionary); bool initializeParser(const ghoul::Dictionary& dictionary); + ghoul::opengl::Texture& ProjectionComponent::depthTexture(); void imageProjectBegin(); void imageProjectEnd(); + void depthMapRenderBegin(); + void depthMapRenderEnd(); + bool generateProjectionLayerTexture(); + bool generateDepthTexture(); bool auxiliaryRendertarget(); + bool depthRendertarget(); std::shared_ptr loadProjectionTexture( const std::string& texturePath, @@ -82,8 +88,6 @@ public: float fieldOfViewY() const; float aspectRatio() const; - float nearPlane() const; - float farPlane() const; protected: properties::BoolProperty _performProjection; @@ -91,7 +95,7 @@ protected: properties::FloatProperty _projectionFading; std::unique_ptr _projectionTexture; - + std::unique_ptr _depthTexture; std::shared_ptr _placeholderTexture; std::string _instrumentID; @@ -101,10 +105,9 @@ protected: std::vector _potentialTargets; float _fovy; float _aspectRatio; - float _nearPlane; - float _farPlane; GLuint _fboID; + GLuint _depthFboID; GLint _defaultFBO; GLint _viewport[4]; From 3d000a5bb13ede78c0f0c8a45501fbad125147e4 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 24 Aug 2016 11:38:32 +0200 Subject: [PATCH 002/205] flip texture access to correct projection error --- modules/newhorizons/shaders/renderableModelProjection_fs.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl index 9f052c5889..1cf1c09c94 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl @@ -56,7 +56,7 @@ void main() { if (inRange(uv.x, 0.0, 1.0) && inRange(uv.y, 0.0, 1.0) && dot(n, boresight) < 0 && thisDepth <= closestDepth + epsilon) { - color = texture(projectionTexture, uv); + color = texture(projectionTexture, vec2(1.0) - uv); color.a = 1.0; } else { color = vec4(vec3(0.0), 0.0); From d0ec7ac73566a14a6b2e11bdb3c58568a3ce4d5d Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Thu, 25 Aug 2016 16:32:27 +0200 Subject: [PATCH 003/205] render trails with additive blending --- modules/base/rendering/renderabletrail.cpp | 14 ++++++++++++++ modules/base/shaders/ephemeris_fs.glsl | 3 ++- shaders/abuffer/renderabuffer.frag | 17 +++++++++++++---- shaders/abuffer/resolveabuffer.frag | 2 +- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index b41a42e13d..265321f8ae 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -179,6 +179,14 @@ void RenderableTrail::render(const RenderData& data) { // _programObject->setUniform("forceFade", _distanceFade); //} + bool usingFramebufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; + + if (usingFramebufferRenderer) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + glLineWidth(_lineWidth); glBindVertexArray(_vaoID); @@ -194,6 +202,12 @@ void RenderableTrail::render(const RenderData& data) { glBindVertexArray(0); } + + if (usingFramebufferRenderer) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + } + _programObject->deactivate(); } diff --git a/modules/base/shaders/ephemeris_fs.glsl b/modules/base/shaders/ephemeris_fs.glsl index 49453927c1..26b9de2d89 100644 --- a/modules/base/shaders/ephemeris_fs.glsl +++ b/modules/base/shaders/ephemeris_fs.glsl @@ -36,10 +36,11 @@ Fragment getFragment() { vec4 position = vs_point_position; float depth = pscDepth(position); - vec4 c = vec4(color, fade*forceFade); + vec4 c = vec4(color * fade * forceFade, 1.0); Fragment frag; frag.color = c; frag.depth = depth; + frag.blend = BLEND_MODE_ADDITIVE; return frag; } diff --git a/shaders/abuffer/renderabuffer.frag b/shaders/abuffer/renderabuffer.frag index d3abc97ddf..0dfd046983 100644 --- a/shaders/abuffer/renderabuffer.frag +++ b/shaders/abuffer/renderabuffer.frag @@ -36,10 +36,19 @@ void main() { if (frag.depth < 0) { // discard; } - - //frag.forceFboRendering = true; - // todo: calculate full sample mask from nAaSamples instead of hardcoded 255. - if (!frag.forceFboRendering && (frag.color.a < 1.0 || sampleMask != 255)) { + + bool storeInAbuffer = false; + + if (frag.forceFboRendering) { + storeInAbuffer = false; + } else { + storeInAbuffer = frag.color.a < 1.0 || + sampleMask != 255 || + frag.blend != BLEND_MODE_NORMAL; + // todo: calculate full sample mask from nAaSamples instead of hardcoded 255. + } + + if (storeInAbuffer) { uint newHead = atomicCounterIncrement(atomicCounterBuffer); if (newHead >= #{rendererData.maxTotalFragments}) { discard; // ABuffer is full! diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 38cb3269a5..a722c4f02d 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -113,7 +113,7 @@ void main() { //normalBlend(finalColor, color); } else if (blend == BLEND_MODE_ADDITIVE) { - accumulatedColor += (1 - accumulatedAlpha) * color.rgb; + accumulatedColor += (1 - accumulatedAlpha) * color.rgb * color.a; //additiveBlend(finalColor, color); } } From bc586234679e21e7679829b7158748706749561f Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Thu, 25 Aug 2016 18:26:59 +0200 Subject: [PATCH 004/205] add render bins to improve rendering of transparent objects using framebuffer renderer --- include/openspace/rendering/renderable.h | 12 ++++++++++++ include/openspace/util/updatestructures.h | 2 ++ modules/base/rendering/renderabletrail.cpp | 1 + src/rendering/abufferrenderer.cpp | 8 +++++++- src/rendering/framebufferrenderer.cpp | 11 +++++++++-- src/rendering/renderable.cpp | 14 ++++++++++++++ src/scene/scenegraphnode.cpp | 9 ++++++++- 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 7d618b1f3a..50a8c4d16c 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -51,6 +51,13 @@ class PowerScaledCoordinate; class Renderable : public properties::PropertyOwner { public: + enum class RenderBin : int { + Background = 1, + Opaque = 2, + Transparent = 4, + Overlay = 8 + }; + static Renderable* createFromDictionary(const ghoul::Dictionary& dictionary); // constructors & destructor @@ -72,6 +79,10 @@ public: virtual void postRender(const RenderData& data); virtual void update(const UpdateData& data); + RenderBin renderBin() const; + void setRenderBin(RenderBin bin); + bool matchesRenderBinMask(int binMask); + bool isVisible() const; bool hasTimeInterval(); @@ -89,6 +100,7 @@ protected: properties::BoolProperty _enabled; private: + RenderBin _renderBin; PowerScaledScalar boundingSphere_; std::string _startTime; std::string _endTime; diff --git a/include/openspace/util/updatestructures.h b/include/openspace/util/updatestructures.h index 08ea000572..6de6df88e5 100644 --- a/include/openspace/util/updatestructures.h +++ b/include/openspace/util/updatestructures.h @@ -43,10 +43,12 @@ struct UpdateData { bool doPerformanceMeasurement; }; + struct RenderData { const Camera& camera; psc position; bool doPerformanceMeasurement; + int renderBinMask; }; struct RaycasterTask { diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 265321f8ae..e6fa38c991 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -124,6 +124,7 @@ bool RenderableTrail::initialize() { "${MODULE_BASE}/shaders/ephemeris_vs.glsl", "${MODULE_BASE}/shaders/ephemeris_fs.glsl"); + setRenderBin(Renderable::RenderBin::Overlay); if (!_programObject) return false; diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 234c2b205c..c38e3c9487 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -260,7 +261,12 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32UI); // Render the scene to the fragment buffer. Collect renderer tasks (active raycasters) - RenderData data{ *_camera, psc(), doPerformanceMeasurements }; + int renderBinMask = static_cast(Renderable::RenderBin::Background) | + static_cast(Renderable::RenderBin::Opaque) | + static_cast(Renderable::RenderBin::Transparent) | + static_cast(Renderable::RenderBin::Overlay); + + RenderData data{ *_camera, psc(), doPerformanceMeasurements, renderBinMask }; RendererTasks tasks; _scene->render(data, tasks); diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index bd6b920987..af1c2c23c2 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -329,7 +330,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - RenderData data = { *_camera, psc(), doPerformanceMeasurements }; + RenderData data = { *_camera, psc(), doPerformanceMeasurements, 0 }; RendererTasks tasks; // Capture standard fbo @@ -339,7 +340,13 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // bind new fbo A with color and depth buffer. + data.renderBinMask = static_cast(Renderable::RenderBin::Background); + _scene->render(data, tasks); + data.renderBinMask = static_cast(Renderable::RenderBin::Opaque); + _scene->render(data, tasks); + data.renderBinMask = static_cast(Renderable::RenderBin::Transparent); + _scene->render(data, tasks); + data.renderBinMask = static_cast(Renderable::RenderBin::Overlay); _scene->render(data, tasks); for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) { diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 767920c5c1..65ec2f24ae 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -72,6 +72,7 @@ Renderable* Renderable::createFromDictionary(const ghoul::Dictionary& dictionary Renderable::Renderable() : _enabled("enabled", "Is Enabled", true) + , _renderBin(RenderBin::Opaque) , _startTime("") , _endTime("") , _targetBody("") @@ -83,6 +84,7 @@ Renderable::Renderable() Renderable::Renderable(const ghoul::Dictionary& dictionary) : _enabled("enabled", "Is Enabled", true) + , _renderBin(RenderBin::Opaque) , _startTime("") , _endTime("") , _targetBody("") @@ -148,6 +150,18 @@ void Renderable::setPscUniforms( program.setUniform("scaling", camera.scaling()); } +Renderable::RenderBin Renderable::renderBin() const { + return _renderBin; +} + +void Renderable::setRenderBin(RenderBin bin) { + _renderBin = bin; +} + +bool Renderable::matchesRenderBinMask(int binMask) { + return binMask & static_cast(renderBin()); +} + bool Renderable::isVisible() const { return _enabled; } diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 2adc913240..d4ccb44110 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -248,7 +248,14 @@ void SceneGraphNode::render(const RenderData& data, RendererTasks& tasks) { RenderData newData = {data.camera, thisPosition, data.doPerformanceMeasurement}; _performanceRecord.renderTime = 0; - if (_renderableVisible && _renderable->isVisible() && _renderable->isReady() && _renderable->isEnabled()) { + + bool visible = _renderableVisible && + _renderable->isVisible() && + _renderable->isReady() && + _renderable->isEnabled() && + _renderable->matchesRenderBinMask(data.renderBinMask); + + if (visible) { if (data.doPerformanceMeasurement) { glFinish(); auto start = std::chrono::high_resolution_clock::now(); From 14aad40e6c46881fac3ad2690e92c6beb6149600 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Thu, 25 Aug 2016 13:50:46 -0400 Subject: [PATCH 005/205] Fix bug that caused crash when switching on and off night textures and water masks for RenderableGlobe --- modules/globebrowsing/chunk/chunkrenderer.cpp | 8 ++++++-- modules/globebrowsing/globes/renderableglobe.cpp | 2 +- modules/globebrowsing/shaders/tilefragcolor.hglsl | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/globebrowsing/chunk/chunkrenderer.cpp b/modules/globebrowsing/chunk/chunkrenderer.cpp index 4dedcf3aaa..f828fd26ab 100644 --- a/modules/globebrowsing/chunk/chunkrenderer.cpp +++ b/modules/globebrowsing/chunk/chunkrenderer.cpp @@ -382,7 +382,9 @@ namespace openspace { programObject->setUniform("radiiSquared", vec3(ellipsoid.radiiSquared())); if (_tileProviderManager->getTileProviderGroup( - LayeredTextures::NightTextures).getActiveTileProviders().size() > 0) { + LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || + _tileProviderManager->getTileProviderGroup( + LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = @@ -459,7 +461,9 @@ namespace openspace { programObject->setUniform("projectionTransform", data.camera.projectionMatrix()); if (_tileProviderManager->getTileProviderGroup( - LayeredTextures::NightTextures).getActiveTileProviders().size() > 0) { + LayeredTextures::NightTextures).getActiveTileProviders().size() > 0 || + _tileProviderManager->getTileProviderGroup( + LayeredTextures::WaterMasks).getActiveTileProviders().size() > 0) { glm::vec3 directionToSunWorldSpace = glm::normalize(-data.modelTransform.translation); glm::vec3 directionToSunCameraSpace = diff --git a/modules/globebrowsing/globes/renderableglobe.cpp b/modules/globebrowsing/globes/renderableglobe.cpp index 0033c6701f..6254cd430b 100644 --- a/modules/globebrowsing/globes/renderableglobe.cpp +++ b/modules/globebrowsing/globes/renderableglobe.cpp @@ -118,7 +118,7 @@ namespace openspace { // Add all tile layers as being toggleable for each category for (int i = 0; i < LayeredTextures::NUM_TEXTURE_CATEGORIES; i++){ LayeredTextures::TextureCategory category = (LayeredTextures::TextureCategory) i; - std::string categoryName = std::to_string(i+1) + ". " + LayeredTextures::TEXTURE_CATEGORY_NAMES[i]; + std::string categoryName = LayeredTextures::TEXTURE_CATEGORY_NAMES[i]; auto selection = std::make_unique(categoryName, categoryName); auto& categoryProviders = _tileProviderManager->getTileProviderGroup(category); diff --git a/modules/globebrowsing/shaders/tilefragcolor.hglsl b/modules/globebrowsing/shaders/tilefragcolor.hglsl index 884b7b9df0..502f47d3c2 100644 --- a/modules/globebrowsing/shaders/tilefragcolor.hglsl +++ b/modules/globebrowsing/shaders/tilefragcolor.hglsl @@ -43,7 +43,6 @@ uniform Tile ColorTexturesParent2[NUMLAYERS_COLORTEXTURE]; uniform Tile NightTextures[NUMLAYERS_NIGHTTEXTURE]; uniform Tile NightTexturesParent1[NUMLAYERS_NIGHTTEXTURE]; uniform Tile NightTexturesParent2[NUMLAYERS_NIGHTTEXTURE]; -uniform vec3 lightDirectionCameraSpace; #endif // USE_NIGHTTEXTURE #if USE_OVERLAY @@ -68,11 +67,14 @@ uniform Tile WaterMasksParent2[NUMLAYERS_WATERMASK]; uniform vec2 vertexResolution; #endif - #if USE_ATMOSPHERE // TODO atmosphere uniforms here #endif // USE_ATMOSPHERE +#if USE_NIGHTTEXTURE || USE_WATERMASK + uniform vec3 lightDirectionCameraSpace; +#endif + in vec4 fs_position; in vec2 fs_uv; in vec3 ellipsoidNormalCameraSpace; From b6be6da9748b9e9ca9d7cef6f6a50e6f21462ec9 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Thu, 25 Aug 2016 20:22:07 +0200 Subject: [PATCH 006/205] add support for additive blending in renderable plane --- data/scene/sun/sun.mod | 3 ++- modules/base/rendering/renderableplane.cpp | 31 +++++++++++++++++++++- modules/base/rendering/renderableplane.h | 6 +++++ modules/base/shaders/plane_fs.glsl | 6 +++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/data/scene/sun/sun.mod b/data/scene/sun/sun.mod index 288335bb39..db9d83a9e8 100644 --- a/data/scene/sun/sun.mod +++ b/data/scene/sun/sun.mod @@ -50,7 +50,8 @@ return { Size = {1.3, 10.5}, Origin = "Center", Billboard = true, - Texture = "textures/sun-glare.png" + Texture = "textures/sun-glare.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Spice", diff --git a/modules/base/rendering/renderableplane.cpp b/modules/base/rendering/renderableplane.cpp index b16652745d..d86a216269 100644 --- a/modules/base/rendering/renderableplane.cpp +++ b/modules/base/rendering/renderableplane.cpp @@ -60,6 +60,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) , _shader(nullptr) , _textureIsDirty(false) , _texture(nullptr) + , _blendMode(BlendMode::Normal) , _quad(0) , _vertexPositionBuffer(0) { @@ -67,7 +68,7 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) dictionary.getValue("Size", size); _size = size; - if (dictionary.hasKey("Name")){ + if (dictionary.hasKey("Name")) { dictionary.getValue("Name", _nodeName); } @@ -102,6 +103,13 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary) } } + std::string blendMode; + if (dictionary.getValue("BlendMode", blendMode)) { + if (blendMode == "Additive") { + _blendMode = BlendMode::Additive; + setRenderBin(Renderable::RenderBin::Transparent); + } + } std::string texturePath = ""; bool success = dictionary.getValue("Texture", texturePath); @@ -213,9 +221,30 @@ void RenderablePlane::render(const RenderData& data) { _texture->bind(); _shader->setUniform("texture1", unit); + bool usingFramebufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::Framebuffer; + + bool usingABufferRenderer = + OsEng.renderEngine().rendererImplementation() == RenderEngine::RendererImplementation::ABuffer; + + if (usingABufferRenderer) { + _shader->setUniform("additiveBlending", _blendMode == BlendMode::Additive); + } + + bool additiveBlending = _blendMode == BlendMode::Additive && usingFramebufferRenderer; + if (additiveBlending) { + glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + glBindVertexArray(_quad); glDrawArrays(GL_TRIANGLES, 0, 6); + if (additiveBlending) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask(true); + } + _shader->deactivate(); } diff --git a/modules/base/rendering/renderableplane.h b/modules/base/rendering/renderableplane.h index eaa5cf4445..fc4e8f795c 100644 --- a/modules/base/rendering/renderableplane.h +++ b/modules/base/rendering/renderableplane.h @@ -51,6 +51,11 @@ class RenderablePlane : public Renderable { }; public: + enum class BlendMode : int { + Normal = 0, + Additive + }; + RenderablePlane(const ghoul::Dictionary& dictionary); ~RenderablePlane(); @@ -79,6 +84,7 @@ private: std::unique_ptr _shader; bool _textureIsDirty; std::unique_ptr _texture; + BlendMode _blendMode; ghoul::filesystem::File* _textureFile; GLuint _quad; GLuint _vertexPositionBuffer; diff --git a/modules/base/shaders/plane_fs.glsl b/modules/base/shaders/plane_fs.glsl index 778763430e..1c4aeed1ee 100644 --- a/modules/base/shaders/plane_fs.glsl +++ b/modules/base/shaders/plane_fs.glsl @@ -24,6 +24,7 @@ uniform float time; uniform sampler2D texture1; +uniform bool additiveBlending; in vec2 vs_st; in vec4 vs_position; @@ -52,6 +53,11 @@ Fragment getFragment() { Fragment frag; frag.color = diffuse; frag.depth = depth; + + if (additiveBlending) { + frag.blend = BLEND_MODE_ADDITIVE; + } + return frag; } From 64187aca5de48286f5d80287176cc911b39c7a20 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Thu, 25 Aug 2016 20:17:17 -0400 Subject: [PATCH 007/205] fix but in InstrumentTimesParser that caused sequence time to be overwritten. --- data/scene/osirisrex/bennu/bennu.mod | 13 ++-- data/scene/osirisrex/osirisrex/osirisrex.mod | 7 +- .../util/instrumenttimesparser.cpp | 66 ++++++++++++------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod index 7c558e16f8..962e208b3b 100644 --- a/data/scene/osirisrex/bennu/bennu.mod +++ b/data/scene/osirisrex/bennu/bennu.mod @@ -27,7 +27,7 @@ return { Body = BENNU_BODY, Geometry = { Type = "MultiModelGeometry", - GeometryFile = "models/BennuResized.obj", + GeometryFile = "models/BennuResizedTextured.obj", Magnification = 0, }, Shading = { @@ -48,9 +48,10 @@ return { Projection = { Sequence = "InstrumentTimes", SequenceType = "instrument-times", - Observer = "SUN", + Observer = "OSIRIS-REX", Target = BENNU_BODY, Aberration = "NONE", + TextureMap = true, }, DataInputTranslation = { Instruments = { @@ -60,9 +61,9 @@ return { Files = { "BaseballDiamond_PolyCam.txt", "OrbitalB_Site08_PolyCamImages.txt", - "Recon_225m_Equatorial_PolyCam", + "Recon_225m_Equatorial_PolyCam.txt", }, - }, + },--[[ ORX_REXIS = { DetectorType = "Camera", Spice = {"ORX_REXIS"}, @@ -71,7 +72,7 @@ return { "Recon_225m_Equatorial_spectrometers.txt", "Recon_525m_Equatorial_spectrometers.txt", }, - }, + },]] }, Target = { Body = BENNU_BODY, -- Do we need this? @@ -82,7 +83,7 @@ return { Name = "ORX_OCAMS_POLYCAM", Method = "ELLIPSOID", Aberration = "NONE", - Fovy = 5.00, + Fovy = 0.792, Aspect = 1, Near = 0.01, Far = 1000000, diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index f3e2c214c7..0cfa8f34e2 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -74,7 +74,7 @@ return { }, GuiName = "/Solar/ORX_OCAMS_POLYCAM" }, - + --[[ { Name = "ORX_REXIS", Parent = "OsirisRex", @@ -108,7 +108,7 @@ return { }, }, GuiName = "/Solar/ORX_REXIS" - }, + },]] { Name = "POLYCAM FOV", @@ -134,7 +134,7 @@ return { }, GuiName = "/Solar/POLYCAM FOV" }, - + --[[ { Name = "REXIS FOV", Parent = "ORX_REXIS", @@ -159,6 +159,7 @@ return { }, GuiName = "/Solar/REXIS FOV" }, + ]] --[[ -- Latest image taken by POLYCAM { diff --git a/modules/newhorizons/util/instrumenttimesparser.cpp b/modules/newhorizons/util/instrumenttimesparser.cpp index 2d058e2dee..de20b5b2bb 100644 --- a/modules/newhorizons/util/instrumenttimesparser.cpp +++ b/modules/newhorizons/util/instrumenttimesparser.cpp @@ -96,43 +96,65 @@ bool InstrumentTimesParser::create() { std::string instrumentID = it->first; for (std::string filename: it->second) { std::string filepath = FileSys.pathByAppendingComponent(sequenceDir.path(), filename); + + if (!FileSys.fileExists(filepath)) { + LERROR("Unable to read file " << filepath << ". Skipping file."); + continue; + } // Read file into string - std::ifstream in(filepath); + std::ifstream inFile(filepath); + std::string line; std::smatch matches; TimeRange instrumentActiveTimeRange; + bool sucessfulRead = false; - while (std::getline(in, line)) { + while (std::getline(inFile, line)) { if (std::regex_match(line, matches, _pattern)) { - ghoul_assert(matches.size() == 3, "Bad event data formatting. Must have regex 3 matches (source string, start time, stop time)."); - std::string start = matches[1].str(); - std::string stop = matches[2].str(); + try { + if (matches.size() != 3) { + throw ghoul::RuntimeError("Bad event data formatting. Must \ + have regex 3 matches (source string, start time, stop time)."); + } + std::string start = matches[1].str(); + std::string stop = matches[2].str(); - TimeRange captureTimeRange; - captureTimeRange.start = SpiceManager::ref().ephemerisTimeFromDate(start); - captureTimeRange.end = SpiceManager::ref().ephemerisTimeFromDate(stop); + TimeRange captureTimeRange; + captureTimeRange.start = SpiceManager::ref().ephemerisTimeFromDate(start); + captureTimeRange.end = SpiceManager::ref().ephemerisTimeFromDate(stop); - instrumentActiveTimeRange.include(captureTimeRange); + instrumentActiveTimeRange.include(captureTimeRange); - //_instrumentTimes.push_back({ instrumentID, timeRange }); - _targetTimes.push_back({ captureTimeRange.start, _target }); - _captureProgression.push_back(captureTimeRange.start); + //_instrumentTimes.push_back({ instrumentID, timeRange }); + _targetTimes.push_back({ captureTimeRange.start, _target }); + _captureProgression.push_back(captureTimeRange.start); - Image image; - image.timeRange = captureTimeRange; - image.path = ""; - image.isPlaceholder = true; - image.activeInstruments.push_back(instrumentID); - image.target = _target; - image.projected = false; + Image image; + image.timeRange = captureTimeRange; + image.path = ""; + image.isPlaceholder = true; + image.activeInstruments.push_back(instrumentID); + image.target = _target; + image.projected = false; - _subsetMap[_target]._subset.push_back(image); + _subsetMap[_target]._subset.push_back(image); + + sucessfulRead = true; + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.what()); + sucessfulRead = false; + continue; + } } } - _subsetMap[_target]._range = instrumentActiveTimeRange; - _instrumentTimes.push_back({ instrumentID, instrumentActiveTimeRange }); + if (sucessfulRead) + { + _subsetMap[_target]._range.include(instrumentActiveTimeRange); + _instrumentTimes.push_back({ instrumentID, instrumentActiveTimeRange }); + } } } From 64fca6e08ddecf8918131602266eb489e7ad3e7f Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Thu, 25 Aug 2016 20:18:16 -0400 Subject: [PATCH 008/205] Update start time for osiris rex --- data/scene/osirisrex.scene | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index a20c35d1aa..ba42cfe1e8 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -144,7 +144,8 @@ function preInitialization() -- openspace.time.setTime("2018-12-20T22:47:00.00") --openspace.time.setTime("2019-05-25T03:57:55.00") - openspace.time.setTime("2016 SEP 8 23:05:00.50") + --openspace.time.setTime("2016 SEP 8 23:05:00.50") + openspace.time.setTime("2019 APR 16 12:03:00.00") openspace.time.setDeltaTime(0) end From 47583327ec168fb1538bf54c03c410b1ae593f33 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Fri, 26 Aug 2016 10:31:02 +0200 Subject: [PATCH 009/205] use additive blending for white planet markers to avoid z-fighting --- data/scene/atmosphereearth/atmosphereearth.mod | 3 ++- data/scene/earth/earth.mod | 3 ++- data/scene/newhorizons/jupiter/callisto/callisto.mod | 3 ++- data/scene/newhorizons/jupiter/europa/europa.mod | 3 ++- data/scene/newhorizons/jupiter/ganymede/ganymede.mod | 3 ++- data/scene/newhorizons/jupiter/io/io.mod | 3 ++- data/scene/newhorizons/jupiter/jupiter/jupiter.mod | 3 ++- data/scene/newhorizons/pluto/charon/charon.mod | 3 ++- data/scene/newhorizons/pluto/pluto/pluto.mod | 3 ++- data/scene/newhorizons/pluto/styx/styx.mod | 3 ++- data/scene/sun/sun.mod | 3 ++- 11 files changed, 22 insertions(+), 11 deletions(-) diff --git a/data/scene/atmosphereearth/atmosphereearth.mod b/data/scene/atmosphereearth/atmosphereearth.mod index 7ab2b2121e..166a0bdbad 100644 --- a/data/scene/atmosphereearth/atmosphereearth.mod +++ b/data/scene/atmosphereearth/atmosphereearth.mod @@ -129,7 +129,8 @@ return { Size = {3.0, 11.0}, Origin = "Center", Billboard = true, - Texture = "textures/marker.png" + Texture = "textures/marker.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/earth/earth.mod b/data/scene/earth/earth.mod index 3b23d70ee5..d62fd62f32 100644 --- a/data/scene/earth/earth.mod +++ b/data/scene/earth/earth.mod @@ -64,7 +64,8 @@ return { Size = {3.0, 11.0}, Origin = "Center", Billboard = true, - Texture = "textures/marker.png" + Texture = "textures/marker.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/jupiter/callisto/callisto.mod b/data/scene/newhorizons/jupiter/callisto/callisto.mod index 5bb6ed57f7..3fc6377bcc 100644 --- a/data/scene/newhorizons/jupiter/callisto/callisto.mod +++ b/data/scene/newhorizons/jupiter/callisto/callisto.mod @@ -60,7 +60,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Callisto-Text.png" + Texture = "textures/Callisto-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/jupiter/europa/europa.mod b/data/scene/newhorizons/jupiter/europa/europa.mod index ff14b3448c..1c8878a6c5 100644 --- a/data/scene/newhorizons/jupiter/europa/europa.mod +++ b/data/scene/newhorizons/jupiter/europa/europa.mod @@ -60,7 +60,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Europa-Text.png" + Texture = "textures/Europa-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/jupiter/ganymede/ganymede.mod b/data/scene/newhorizons/jupiter/ganymede/ganymede.mod index 5c92635c06..4fc4a6673c 100644 --- a/data/scene/newhorizons/jupiter/ganymede/ganymede.mod +++ b/data/scene/newhorizons/jupiter/ganymede/ganymede.mod @@ -60,7 +60,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Ganymede-Text.png" + Texture = "textures/Ganymede-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/jupiter/io/io.mod b/data/scene/newhorizons/jupiter/io/io.mod index 75053e1904..60b42e1645 100644 --- a/data/scene/newhorizons/jupiter/io/io.mod +++ b/data/scene/newhorizons/jupiter/io/io.mod @@ -60,7 +60,8 @@ return { Size = {1.0, 7.4}, Origin = "Center", Billboard = true, - Texture = "textures/Io-Text.png" + Texture = "textures/Io-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod index 542a2b1eac..c85879b7e4 100644 --- a/data/scene/newhorizons/jupiter/jupiter/jupiter.mod +++ b/data/scene/newhorizons/jupiter/jupiter/jupiter.mod @@ -106,7 +106,8 @@ return { Size = {1.0, 7.5}, Origin = "Center", Billboard = true, - Texture = "textures/Jupiter-text.png" + Texture = "textures/Jupiter-text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/pluto/charon/charon.mod b/data/scene/newhorizons/pluto/charon/charon.mod index 674cb55892..ac01096cdc 100644 --- a/data/scene/newhorizons/pluto/charon/charon.mod +++ b/data/scene/newhorizons/pluto/charon/charon.mod @@ -77,7 +77,8 @@ return { Size = {1.0, 6.3}, Origin = "Center", Billboard = true, - Texture = "textures/Charon-Text.png" + Texture = "textures/Charon-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/pluto/pluto/pluto.mod b/data/scene/newhorizons/pluto/pluto/pluto.mod index e5447cc48e..a23974d47d 100644 --- a/data/scene/newhorizons/pluto/pluto/pluto.mod +++ b/data/scene/newhorizons/pluto/pluto/pluto.mod @@ -194,7 +194,8 @@ return { Size = {1.0, 6.3}, Origin = "Center", Billboard = true, - Texture = "textures/Pluto-Text.png" + Texture = "textures/Pluto-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/newhorizons/pluto/styx/styx.mod b/data/scene/newhorizons/pluto/styx/styx.mod index 02d6ad7a30..f34abbc84e 100644 --- a/data/scene/newhorizons/pluto/styx/styx.mod +++ b/data/scene/newhorizons/pluto/styx/styx.mod @@ -49,7 +49,8 @@ return { Size = {1.0, 6.3}, Origin = "Center", Billboard = true, - Texture = "textures/Styx-Text.png" + Texture = "textures/Styx-Text.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", diff --git a/data/scene/sun/sun.mod b/data/scene/sun/sun.mod index db9d83a9e8..17caf205be 100644 --- a/data/scene/sun/sun.mod +++ b/data/scene/sun/sun.mod @@ -71,7 +71,8 @@ return { Size = {3.0, 11.0}, Origin = "Center", Billboard = true, - Texture = "textures/marker.png" + Texture = "textures/marker.png", + BlendMode = "Additive" }, Ephemeris = { Type = "Static", From 475d4c9ec66d5b63d3259f323a2adc931d24f672 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 26 Aug 2016 17:33:13 -0400 Subject: [PATCH 010/205] Break and proceed with next file if instrument times file parsing fails --- .../util/instrumenttimesparser.cpp | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/modules/newhorizons/util/instrumenttimesparser.cpp b/modules/newhorizons/util/instrumenttimesparser.cpp index de20b5b2bb..4b0b679a12 100644 --- a/modules/newhorizons/util/instrumenttimesparser.cpp +++ b/modules/newhorizons/util/instrumenttimesparser.cpp @@ -104,54 +104,50 @@ bool InstrumentTimesParser::create() { // Read file into string std::ifstream inFile(filepath); - std::string line; std::smatch matches; - TimeRange instrumentActiveTimeRange; - bool sucessfulRead = false; - + bool successfulRead = true; while (std::getline(inFile, line)) { if (std::regex_match(line, matches, _pattern)) { - try { - if (matches.size() != 3) { - throw ghoul::RuntimeError("Bad event data formatting. Must \ + if (matches.size() != 3) { + LERROR("Bad event data formatting. Must \ have regex 3 matches (source string, start time, stop time)."); - } + successfulRead = false; + break; + } + + TimeRange captureTimeRange; + try { // parse date strings std::string start = matches[1].str(); std::string stop = matches[2].str(); - - TimeRange captureTimeRange; captureTimeRange.start = SpiceManager::ref().ephemerisTimeFromDate(start); captureTimeRange.end = SpiceManager::ref().ephemerisTimeFromDate(stop); - - instrumentActiveTimeRange.include(captureTimeRange); - - //_instrumentTimes.push_back({ instrumentID, timeRange }); - _targetTimes.push_back({ captureTimeRange.start, _target }); - _captureProgression.push_back(captureTimeRange.start); - - Image image; - image.timeRange = captureTimeRange; - image.path = ""; - image.isPlaceholder = true; - image.activeInstruments.push_back(instrumentID); - image.target = _target; - image.projected = false; - - _subsetMap[_target]._subset.push_back(image); - - sucessfulRead = true; } - catch (const ghoul::RuntimeError& e) { + catch (const SpiceManager::SpiceException& e){ LERROR(e.what()); - sucessfulRead = false; - continue; + successfulRead = false; + break; } + + instrumentActiveTimeRange.include(captureTimeRange); + + //_instrumentTimes.push_back({ instrumentID, timeRange }); + _targetTimes.push_back({ captureTimeRange.start, _target }); + _captureProgression.push_back(captureTimeRange.start); + + Image image; + image.timeRange = captureTimeRange; + image.path = ""; + image.isPlaceholder = true; + image.activeInstruments.push_back(instrumentID); + image.target = _target; + image.projected = false; + + _subsetMap[_target]._subset.push_back(image); } } - if (sucessfulRead) - { + if (successfulRead){ _subsetMap[_target]._range.include(instrumentActiveTimeRange); _instrumentTimes.push_back({ instrumentID, instrumentActiveTimeRange }); } From ef94fe35331a09dd96e25d9605a279ed2c4bac3c Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 26 Aug 2016 17:36:43 -0400 Subject: [PATCH 011/205] Add key bindings file for OsirisRex scene --- data/scene/osirisrex.scene | 5 +++-- scripts/bind_keys_osirisrex.lua | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 scripts/bind_keys_osirisrex.lua diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index ba42cfe1e8..65d1e13774 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -10,8 +10,6 @@ function preInitialization() critical objects. ]]-- - dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) - -- Load Spice Kernels openspace.spice.loadKernel("${OPENSPACE_DATA}/spice/de430_1850-2150.bsp") @@ -142,6 +140,9 @@ function preInitialization() -- Load planetary constants openspace.spice.loadKernel("${SPICE}/pck00010.tpc") + dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) + dofile(openspace.absPath('${SCRIPTS}/bind_keys_osirisrex.lua')) + -- openspace.time.setTime("2018-12-20T22:47:00.00") --openspace.time.setTime("2019-05-25T03:57:55.00") --openspace.time.setTime("2016 SEP 8 23:05:00.50") diff --git a/scripts/bind_keys_osirisrex.lua b/scripts/bind_keys_osirisrex.lua new file mode 100644 index 0000000000..14dce2872a --- /dev/null +++ b/scripts/bind_keys_osirisrex.lua @@ -0,0 +1,31 @@ +--[[ OpenSpace keybinding script ]]-- + +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) + +--openspace.clearKeys() +helper.setCommonKeys() + +-- Set focuses +openspace.bindKey("o", "openspace.setPropertyValue('Interaction.origin', 'OsirisRex')") +openspace.bindKey("b", "openspace.setPropertyValue('Interaction.origin', 'Bennu2')") + + +-- Quickfix backjumps in Osiris rex +openspace.bindKey("F6" , "openspace.printInfo('Set time: Launch'); openspace.time.setTime('2016 SEP 08 23:05:00');") +openspace.bindKey("F7" , "openspace.printInfo('Set time: Gravity Assist'); openspace.time.setTime('2017 SEP 22 15:00:00');") +openspace.bindKey("F8" , "openspace.printInfo('Set time: Approach'); openspace.time.setTime('2018-SEP-11 21:31:01.183');") +openspace.bindKey("F9" , "openspace.printInfo('Set time: Preliminary Survey'); openspace.time.setTime('2018-NOV-20 01:13:12.183');") +openspace.bindKey("F10", "openspace.printInfo('Set time: Orbital B'); openspace.time.setTime('2019-APR-08 10:35:27.186');") +openspace.bindKey("F11", "openspace.printInfo('Set time: Recon'); openspace.time.setTime('2019-MAY-25 03:50:31.195');") +-- OBS!! Avoid key F12 +-- Pressing F12 triggers a breakpoint on AMNH Windows machine, with with the following stack trace: +-- ntdll.dll!DbgBreakPoint() +-- ntdll.dll!DbgUiRemoteBreakin() +-- kernel32.dll!BaseThreadInitThunk() +-- ntdll.dll!RtUserThreadStart() + +openspace.bindKey("q", helper.property.invert('SunMarker.renderable.enabled')) +openspace.bindKey("e", helper.property.invert('EarthMarker.renderable.enabled')) + +openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('osiris2016');openspace.parallel.connect();") From 8b4e6e855f891aa2023a875c3a4c0f24004d2e28 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 26 Aug 2016 17:41:44 -0400 Subject: [PATCH 012/205] Mkae DeltaTimeKeys map to values relating to minutes, hours, days, years, etc --- scripts/bind_keys.lua | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/bind_keys.lua b/scripts/bind_keys.lua index 3dba610ecf..1a0c56dcad 100644 --- a/scripts/bind_keys.lua +++ b/scripts/bind_keys.lua @@ -6,10 +6,19 @@ dofile(openspace.absPath('${SCRIPTS}/common.lua')) openspace.clearKeys() helper.setCommonKeys() helper.setDeltaTimeKeys({ - 1, 5, 10, 20, 40, 60, 120, 360, 720, 1440, - 2880, 5760, 11520, 23040, 46080, 92160, 184320, 368640, 737280, 1474560, - 2949120, 5898240, 11796480, 23592960, 47185920, 94371840, 188743680, 377487360 +-- 1 2 3 4 5 6 7 8 9 0 +-------------------------------------------------------------------------------------------------------------------------- +-- 1s 2s 5s 10s 30s 1m 2m 5m 10m 30 min + 1, 2, 5, 10, 30, 60, 120, 300, 600, 1800, + +-- 1h 2h 3h 6h 12h 1d 2d 4d 1w 2w + 3600, 7200, 10800, 21600, 43200, 86400, 172800, 345600, 604800, 1209600, + +-- 1mo 2mo 3mo 6mo 1yr 2y 5y 10y 20y 50y + 2592000, 5184000, 7776000, 15552000, 31536000, 63072000, 157680000, 315360000, 630720000, 1576800000 }) +-- OBS: One month (1mo) is approximated by 30 days. + openspace.bindKey("q", helper.renderable.toggle('SunMarker')) openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) From 547807a8d1c51f67069d8fc0979b2a186c7b6a3c Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Fri, 26 Aug 2016 17:54:15 -0400 Subject: [PATCH 013/205] Fix problem with projection texture getting overwritten upon image projection. --- data/scene/osirisrex/bennu/bennu.mod | 1 - modules/newhorizons/shaders/renderableModelProjection_fs.glsl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod index 962e208b3b..e30d24cd02 100644 --- a/data/scene/osirisrex/bennu/bennu.mod +++ b/data/scene/osirisrex/bennu/bennu.mod @@ -51,7 +51,6 @@ return { Observer = "OSIRIS-REX", Target = BENNU_BODY, Aberration = "NONE", - TextureMap = true, }, DataInputTranslation = { Instruments = { diff --git a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl index 30d4da79dd..fdedd40957 100644 --- a/modules/newhorizons/shaders/renderableModelProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderableModelProjection_fs.glsl @@ -62,7 +62,7 @@ void main() { stencil = vec4(1.0); } else { - color = vec4(vec3(0.0), 1.0); + color = vec4(0.0);//vec4(vec3(0.0), 1.0); stencil = vec4(0.0); } } From 4c502b1258ac5f9a84f574ff944b6b03e4d6de6f Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Fri, 26 Aug 2016 18:13:09 -0400 Subject: [PATCH 014/205] Avoid bind common keys twice --- scripts/bind_keys_osirisrex.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bind_keys_osirisrex.lua b/scripts/bind_keys_osirisrex.lua index 14dce2872a..7ee1c1b45f 100644 --- a/scripts/bind_keys_osirisrex.lua +++ b/scripts/bind_keys_osirisrex.lua @@ -4,7 +4,7 @@ dofile(openspace.absPath('${SCRIPTS}/common.lua')) --openspace.clearKeys() -helper.setCommonKeys() +--helper.setCommonKeys() -- Set focuses openspace.bindKey("o", "openspace.setPropertyValue('Interaction.origin', 'OsirisRex')") From a82ad66374caf33f8af3969703202ac174d1a36b Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Fri, 26 Aug 2016 20:32:08 -0400 Subject: [PATCH 015/205] Add scale as a property of every scenegraph node. --- include/openspace/scene/scale.h | 3 ++- modules/base/scale/staticscale.cpp | 10 +++++++--- modules/base/scale/staticscale.h | 6 +++--- src/scene/scenegraphnode.cpp | 3 +++ 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/openspace/scene/scale.h b/include/openspace/scene/scale.h index d7f0ce9703..d95cec819c 100644 --- a/include/openspace/scene/scale.h +++ b/include/openspace/scene/scale.h @@ -27,10 +27,11 @@ #include #include +#include namespace openspace { -class Scale { +class Scale : public properties::PropertyOwner { public: static Scale* createFromDictionary(const ghoul::Dictionary& dictionary); diff --git a/modules/base/scale/staticscale.cpp b/modules/base/scale/staticscale.cpp index ff1573e61c..99d961c50c 100644 --- a/modules/base/scale/staticscale.cpp +++ b/modules/base/scale/staticscale.cpp @@ -25,24 +25,28 @@ #include namespace { + const std::string _loggerCat = "StaticScale"; const std::string KeyValue = "Scale"; } namespace openspace { StaticScale::StaticScale(const ghoul::Dictionary& dictionary) - : _scaleValue(1.0) + : _scaleValue("scale", "Scale", 1.0, 1.0, 1000.0) { const bool hasValue = dictionary.hasKeyAndValue(KeyValue); if (hasValue) { - dictionary.getValue(KeyValue, _scaleValue); + float value; + dictionary.getValue(KeyValue, value); + _scaleValue.setValue(value); } + Scale::addProperty(_scaleValue); } StaticScale::~StaticScale() {} double StaticScale::scaleValue() const { - return _scaleValue; + return _scaleValue.value(); } void StaticScale::update(const UpdateData&) {} diff --git a/modules/base/scale/staticscale.h b/modules/base/scale/staticscale.h index 68f2d65c1b..196956d9ab 100644 --- a/modules/base/scale/staticscale.h +++ b/modules/base/scale/staticscale.h @@ -31,13 +31,13 @@ namespace openspace { class StaticScale: public Scale { public: - StaticScale(const ghoul::Dictionary& dictionary - = ghoul::Dictionary()); + StaticScale(const ghoul::Dictionary& dictionary = ghoul::Dictionary()); virtual ~StaticScale(); virtual double scaleValue() const; virtual void update(const UpdateData& data) override; private: - double _scaleValue; + properties::FloatProperty _scaleValue; + //double _scaleValue; }; } // namespace openspace diff --git a/src/scene/scenegraphnode.cpp b/src/scene/scenegraphnode.cpp index 5482dbddaa..68afc19761 100644 --- a/src/scene/scenegraphnode.cpp +++ b/src/scene/scenegraphnode.cpp @@ -150,6 +150,9 @@ SceneGraphNode* SceneGraphNode::createFromDictionary(const ghoul::Dictionary& di //parentNode->addNode(result); + result->_scale->setName("Transform"); + result->addPropertySubOwner(result->_scale); + LDEBUG("Successfully created SceneGraphNode '" << result->name() << "'"); return result; From e55cbaff8cb5207ab7b6485f64a4468f309c03b4 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Mon, 29 Aug 2016 13:48:05 -0400 Subject: [PATCH 016/205] Normalize surface normal in for Rednerable globe shader and enable water mask and night texture for LodEarth in osirisrex. --- data/scene/osirisrex.scene | 5 +++-- modules/globebrowsing/shaders/tilefragcolor.hglsl | 13 ++++--------- openspace.cfg | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 65d1e13774..406a55af52 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -167,8 +167,9 @@ function postInitialization() openspace.setPropertyValue("MilkyWay.renderable.transparency", 0.55) openspace.setPropertyValue("MilkyWay.renderable.segments", 50) - -- Rotate Osiris Rex model to match the specification in the spice data - openspace.setPropertyValue("OsirisRex.renderable.modelrotation", {90.0, 0.0, 0.0}) + -- Activate night textures and water masks + openspace.setPropertyValue("LodEarth.RenderableGlobe.WaterMasks", {0, 1}); + openspace.setPropertyValue("LodEarth.RenderableGlobe.NightTextures", {0, 1}); openspace.printInfo("Done setting default values") openspace.loadMission("${OPENSPACE_DATA}/scene/osirisrex/osirisrex/osirisrex.mission") diff --git a/modules/globebrowsing/shaders/tilefragcolor.hglsl b/modules/globebrowsing/shaders/tilefragcolor.hglsl index 502f47d3c2..51856dabe8 100644 --- a/modules/globebrowsing/shaders/tilefragcolor.hglsl +++ b/modules/globebrowsing/shaders/tilefragcolor.hglsl @@ -167,8 +167,6 @@ vec4 getTileFragColor(){ #endif // USE_COLORTEXTURE #if USE_WATERMASK - // TODO: Jonathas magic goes here here - // TODO: This function needs more parameters and should update the fragment color for water color = calculateWater( color, fs_uv, @@ -176,15 +174,13 @@ vec4 getTileFragColor(){ WaterMasks, WaterMasksParent1, WaterMasksParent2, - ellipsoidNormalCameraSpace, - lightDirectionCameraSpace, + normalize(ellipsoidNormalCameraSpace), + lightDirectionCameraSpace, // Should already be normalized positionCameraSpace); #endif // USE_WATERMASK #if USE_NIGHTTEXTURE - // TODO: Jonathas magic goes here here - // TODO: This function needs more parameters and should update the fragment color for night texture color = calculateNight( color, fs_uv, @@ -192,13 +188,12 @@ vec4 getTileFragColor(){ NightTextures, NightTexturesParent1, NightTexturesParent2, - ellipsoidNormalCameraSpace, - lightDirectionCameraSpace); + normalize(ellipsoidNormalCameraSpace), + lightDirectionCameraSpace); // Should already be normalized #endif // USE_NIGHTTEXTURE #if USE_ATMOSPHERE - // TODO: Jonathas magic goes here here color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now #endif // USE_ATMOSPHERE diff --git a/openspace.cfg b/openspace.cfg index 61a05dd721..70414aa5bd 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -7,13 +7,13 @@ return { -- 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 - Scene = "${SCENE}/default.scene", + --Scene = "${SCENE}/default.scene", -- Scene = "${SCENE}/globebrowsing.scene", -- Scene = "${SCENE}/rosetta.scene", -- Scene = "${SCENE}/dawn.scene", -- Scene = "${SCENE}/newhorizons.scene", - -- Scene = "${SCENE}/osirisrex.scene", + Scene = "${SCENE}/osirisrex.scene", Paths = { SGCT = "${BASE_PATH}/config/sgct", From b74b01d294946a8b8e5696a41974d40fee4e65ab Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Mon, 29 Aug 2016 16:16:11 -0400 Subject: [PATCH 017/205] Add new class ScriptScheduler together with example input file: data/scene/osirisrex/scheduled_scripts.lua --- data/scene/osirisrex.scene | 11 +- data/scene/osirisrex/scheduled_scripts.lua | 17 ++ include/openspace/engine/openspaceengine.h | 3 + include/openspace/scripting/scriptscheduler.h | 86 ++++++++ src/CMakeLists.txt | 2 + src/engine/openspaceengine.cpp | 19 +- src/scripting/scriptscheduler.cpp | 186 ++++++++++++++++++ 7 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 data/scene/osirisrex/scheduled_scripts.lua create mode 100644 include/openspace/scripting/scriptscheduler.h create mode 100644 src/scripting/scriptscheduler.cpp diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 65d1e13774..4f0016adf7 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -143,11 +143,18 @@ function preInitialization() dofile(openspace.absPath('${SCRIPTS}/bind_keys.lua')) dofile(openspace.absPath('${SCRIPTS}/bind_keys_osirisrex.lua')) + local startTime = "2019 APR 16 12:03:00.00"; -- openspace.time.setTime("2018-12-20T22:47:00.00") --openspace.time.setTime("2019-05-25T03:57:55.00") --openspace.time.setTime("2016 SEP 8 23:05:00.50") - openspace.time.setTime("2019 APR 16 12:03:00.00") + openspace.time.setTime(startTime) openspace.time.setDeltaTime(0) + + openspace.scriptScheduler.load("${OPENSPACE_DATA}/scene/osirisrex/scheduled_scripts.lua") + + -- Removing the line below will cause all scripts prior to to be executed during initialization + openspace.scriptScheduler.skipTo(startTime); + end function postInitialization() @@ -173,6 +180,8 @@ function postInitialization() openspace.printInfo("Done setting default values") openspace.loadMission("${OPENSPACE_DATA}/scene/osirisrex/osirisrex/osirisrex.mission") + + openspace.resetCameraDirection() end diff --git a/data/scene/osirisrex/scheduled_scripts.lua b/data/scene/osirisrex/scheduled_scripts.lua new file mode 100644 index 0000000000..5f58a00218 --- /dev/null +++ b/data/scene/osirisrex/scheduled_scripts.lua @@ -0,0 +1,17 @@ +return +{ + { + Time = "2016 SEP 08 23:10:13", + ReversibleLuaScript = { + Forward = "openspace.printInfo('forward test 1');", + Backward = "openspace.printInfo('backward test 1');", + } + }, + { + Time = "2016 SEP 09 00:08:13", + ReversibleLuaScript = { + Forward = "openspace.printInfo('forward test 2');", + Backward = "openspace.printInfo('backward test 2');", + } + }, +} \ No newline at end of file diff --git a/include/openspace/engine/openspaceengine.h b/include/openspace/engine/openspaceengine.h index 99b6507d78..3af650bcf7 100644 --- a/include/openspace/engine/openspaceengine.h +++ b/include/openspace/engine/openspaceengine.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -80,6 +81,7 @@ public: interaction::InteractionHandler& interactionHandler(); RenderEngine& renderEngine(); scripting::ScriptEngine& scriptEngine(); + scripting::ScriptScheduler& scriptScheduler(); NetworkEngine& networkEngine(); LuaConsole& console(); ModuleEngine& moduleEngine(); @@ -138,6 +140,7 @@ private: std::unique_ptr _interactionHandler; std::unique_ptr _renderEngine; std::unique_ptr _scriptEngine; + std::unique_ptr _scriptScheduler; std::unique_ptr _networkEngine; std::unique_ptr _commandlineParser; std::unique_ptr _console; diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h new file mode 100644 index 0000000000..75c45e1e71 --- /dev/null +++ b/include/openspace/scripting/scriptscheduler.h @@ -0,0 +1,86 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 __SCRIPTSCHEDULER_H__ +#define __SCRIPTSCHEDULER_H__ + +#include + +#include + +#include +#include + +namespace openspace { + +namespace scripting { + + + +struct ReversibleLuaScript { + std::string forwardScript; + std::string backwardScript; +}; + +struct ScheduledScript { + ScheduledScript() : time(-DBL_MAX) { } + ScheduledScript(const ghoul::Dictionary& dict); + + double time; + ReversibleLuaScript script; +}; + + +/** + * Maintains an ordered list of \code ScheduledScripts. + */ +class ScriptScheduler { +public: + + void loadScripts(const std::string& filename); + void loadScripts(const ghoul::Dictionary& dict); + + void skipTo(double time); + void skipTo(const std::string& timeStr); + + std::queue scheduledScripts(double newTime); + std::queue scheduledScripts(const std::string& timeStr); + + const std::vector& allScripts() const { return _scheduledScripts; }; + + static LuaLibrary luaLibrary(); + +private: + + std::vector _scheduledScripts; + + size_t _currentIndex = 0; + double _lastTime; + +}; + +} // namespace scripting +} // namespace openspace + +#endif // __SCRIPTSCHEDULER_H__ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 718429a4e2..0edb26d5f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,6 +82,7 @@ set(OPENSPACE_SOURCE ${OPENSPACE_BASE_DIR}/src/scene/scenegraphnode.cpp ${OPENSPACE_BASE_DIR}/src/scripting/lualibrary.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine.cpp + ${OPENSPACE_BASE_DIR}/src/scripting/scriptscheduler.cpp ${OPENSPACE_BASE_DIR}/src/scripting/scriptengine_lua.inl ${OPENSPACE_BASE_DIR}/src/util/blockplaneintersectiongeometry.cpp ${OPENSPACE_BASE_DIR}/src/util/boxgeometry.cpp @@ -169,6 +170,7 @@ set(OPENSPACE_HEADER ${OPENSPACE_BASE_DIR}/include/openspace/scripting/lualibrary.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/script_helper.h ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptengine.h + ${OPENSPACE_BASE_DIR}/include/openspace/scripting/scriptscheduler.h ${OPENSPACE_BASE_DIR}/include/openspace/util/blockplaneintersectiongeometry.h ${OPENSPACE_BASE_DIR}/include/openspace/util/boxgeometry.h ${OPENSPACE_BASE_DIR}/include/openspace/util/camera.h diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index c6c58c861e..e0751a3066 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include + #include #include #include @@ -64,6 +66,7 @@ #include #include +#include #ifdef OPENSPACE_MODULE_ONSCREENGUI_ENABLED #include @@ -123,6 +126,7 @@ OpenSpaceEngine::OpenSpaceEngine(std::string programName, , _interactionHandler(new interaction::InteractionHandler) , _renderEngine(new RenderEngine) , _scriptEngine(new scripting::ScriptEngine) + , _scriptScheduler(new scripting::ScriptScheduler) , _networkEngine(new NetworkEngine) , _commandlineParser(new ghoul::cmdparser::CommandlineParser( programName, ghoul::cmdparser::CommandlineParser::AllowUnknownCommands::Yes @@ -386,6 +390,7 @@ bool OpenSpaceEngine::initialize() { _scriptEngine->addLibrary(gui::GUI::luaLibrary()); _scriptEngine->addLibrary(network::ParallelConnection::luaLibrary()); _scriptEngine->addLibrary(ModuleEngine::luaLibrary()); + _scriptEngine->addLibrary(ScriptScheduler::luaLibrary()); #ifdef OPENSPACE_MODULE_ISWA_ENABLED _scriptEngine->addLibrary(IswaManager::luaLibrary()); @@ -748,6 +753,12 @@ void OpenSpaceEngine::preSynchronization() { Time::ref().advanceTime(dt); Time::ref().preSynchronization(); + auto scheduledScripts = _scriptScheduler->scheduledScripts(Time::ref().currentTime()); + while(scheduledScripts.size()){ + _scriptEngine->queueScript(scheduledScripts.front()); + scheduledScripts.pop(); + } + _scriptEngine->preSynchronization(); _renderEngine->preSynchronization(); @@ -771,7 +782,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { } Time::ref().postSynchronizationPreDraw(); - + _scriptEngine->postSynchronizationPreDraw(); _renderEngine->postSynchronizationPreDraw(); @@ -782,6 +793,7 @@ void OpenSpaceEngine::postSynchronizationPreDraw() { _interactionHandler->postSynchronizationPreDraw(); // Update the synched variables in the camera class + _renderEngine->camera()->preSynchronization(); _renderEngine->camera()->postSynchronizationPreDraw(); @@ -1019,6 +1031,11 @@ ScriptEngine& OpenSpaceEngine::scriptEngine() { return *_scriptEngine; } +ScriptScheduler& OpenSpaceEngine::scriptScheduler(){ + ghoul_assert(_scriptScheduler, "ScriptScheduler must not be nullptr"); + return *_scriptScheduler; +} + LuaConsole& OpenSpaceEngine::console() { ghoul_assert(_console, "LuaConsole must not be nullptr"); return *_console; diff --git a/src/scripting/scriptscheduler.cpp b/src/scripting/scriptscheduler.cpp new file mode 100644 index 0000000000..ef73fb4a13 --- /dev/null +++ b/src/scripting/scriptscheduler.cpp @@ -0,0 +1,186 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * 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 // parse time +#include +#include + + +namespace openspace { +namespace scripting { + +namespace { + const std::string _loggerCat = "ScriptScheduler"; + + const std::string KEY_TIME = "Time"; + const std::string KEY_FORWARD_SCRIPT = "ReversibleLuaScript.Forward"; + const std::string KEY_BACKWARD_SCRIPT = "ReversibleLuaScript.Backward"; +} + + +ScheduledScript::ScheduledScript(const ghoul::Dictionary& dict) + : ScheduledScript() // default init first +{ + std::string timeStr; + if (dict.getValue(KEY_TIME, timeStr)) { + time = SpiceManager::ref().ephemerisTimeFromDate(timeStr); + + if (!dict.getValue(KEY_FORWARD_SCRIPT, script.forwardScript)) { + LERROR("Unable to read " << KEY_FORWARD_SCRIPT); + } + if (!dict.getValue(KEY_BACKWARD_SCRIPT, script.backwardScript)) { + LERROR("Unable to read " << KEY_BACKWARD_SCRIPT); + } + } + else { + LERROR("Unable to read " << KEY_TIME); + } +} + +void ScriptScheduler::loadScripts(const std::string& filepath) { + ghoul::Dictionary timedScriptsDict; + try { + ghoul::lua::loadDictionaryFromFile(absPath(filepath), timedScriptsDict); + } + catch (const ghoul::RuntimeError& e) { + LERROR(e.what()); + return; + } + loadScripts(timedScriptsDict); +} + +void ScriptScheduler::loadScripts(const ghoul::Dictionary& dict) { + for (size_t i = 0; i < dict.size(); ++i) { + std::string id = std::to_string(i + 1); + const ghoul::Dictionary& timedScriptDict = dict.value(id); + _scheduledScripts.push_back(ScheduledScript(timedScriptDict)); + } +} + +void ScriptScheduler::skipTo(double newTime) { + if (newTime > _lastTime) { + while (_currentIndex < _scheduledScripts.size() && _scheduledScripts[_currentIndex].time <= newTime) { + _currentIndex++; + } + } + else { + while (0 < _currentIndex && _scheduledScripts[_currentIndex - 1].time > newTime) { + _currentIndex--; + } + } +} + +void ScriptScheduler::skipTo(const std::string& timeStr) { + skipTo(SpiceManager::ref().ephemerisTimeFromDate(timeStr)); +} + + +std::queue ScriptScheduler::scheduledScripts(double newTime) { + std::queue triggeredScripts; + if (newTime > _lastTime) { + while(_currentIndex < _scheduledScripts.size() && _scheduledScripts[_currentIndex].time <= newTime){ + triggeredScripts.push(_scheduledScripts[_currentIndex].script.forwardScript); + _currentIndex++; + } + } + else { + while (0 < _currentIndex && _scheduledScripts[_currentIndex - 1].time > newTime) { + triggeredScripts.push(_scheduledScripts[_currentIndex - 1].script.backwardScript); + _currentIndex--; + } + } + + _lastTime = newTime; + return triggeredScripts; +} + +std::queue ScriptScheduler::scheduledScripts(const std::string& timeStr) { + return std::move(scheduledScripts(SpiceManager::ref().ephemerisTimeFromDate(timeStr))); +} + + +///////////////////////////////////////////////////////////////////// +// Lua library functions // +///////////////////////////////////////////////////////////////////// + +namespace luascriptfunctions { + int loadTimedScripts(lua_State* L) { + using ghoul::lua::luaTypeToString; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + std::string missionFileName = luaL_checkstring(L, -1); + if (missionFileName.empty()) { + return luaL_error(L, "filepath string is empty"); + } + + OsEng.scriptScheduler().loadScripts(missionFileName); + } + + int skipTo(lua_State* L) { + using ghoul::lua::luaTypeToString; + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + std::string dateStr = luaL_checkstring(L, -1); + if (dateStr.empty()) { + return luaL_error(L, "date string is empty"); + } + + OsEng.scriptScheduler().skipTo(dateStr); + } +} // namespace luascriptfunction + + + +LuaLibrary ScriptScheduler::luaLibrary() { + return { + "scriptScheduler", + { + { + "load", + &luascriptfunctions::loadTimedScripts, + "string", + "Load timed scripts from file" + }, + { + "skipTo", + &luascriptfunctions::skipTo, + "string", + "skip to a time without executing scripts" + }, + } + }; +} + +} // namespace scripting + +} // namespace openspace From 99309b3cb33d61aa062a89f662fee754c8160b0c Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Mon, 29 Aug 2016 16:52:18 -0400 Subject: [PATCH 018/205] Use more explicit names for different osiris rex trails --- data/scene/osirisrex/osirisrex/osirisrex.mod | 70 +++++++++++--------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index 0cfa8f34e2..f15b2b52cd 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -198,35 +198,10 @@ return { }, }, ]] + + -- Trail relative to Earth { - Name = "OsirisRexTrailLocal", - Parent = "BennuBarycenter", - Renderable = { - Type = "RenderableTrailNew", - -- Spice - Body = "OSIRIS-REX", - Frame = "GALACTIC", - Observer = BENNU_BODY, - -- Optional rendering properties - LineColor = { 0.9, 0.2, 0.9 }, - PointColor = { 0.9, 0.2, 0.9 }, - LineFade = 0.5, -- [0,1] - RenderPart = 0.06, - LineWidth = 2, - ShowTimeStamps = false, - RenderFullTrail = false, - -- Time interval - TimeRange = { - Start = "2016 SEP 8 23:05:00.50", - End = "2023 SEP 24 12:00:00", - }, - SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, - }, - GuiName = "OsirisRexTrailLocal" - }, - { - Name = "OsirisRexTrailGlobal", + Name = "OsirisRexTrailEarth", Parent = "LodEarth", Renderable = { Type = "RenderableTrailNew", @@ -250,10 +225,12 @@ return { SampleDeltaTime = 60, -- Seconds between each point SubSamples = 59, }, - GuiName = "OsirisRexTrailGlobal" + GuiName = "OsirisRexTrailEarth" }, + + -- Trail relative to solar system barycenter { - Name = "OsirisRexTrailSolar", + Name = "OsirisRexTrailSolarSystem", Parent = "SolarSystemBarycenter", Renderable = { Type = "RenderableTrailNew", @@ -277,6 +254,37 @@ return { SampleDeltaTime = 3600, -- Seconds between each point SubSamples = 0, }, - GuiName = "OsirisRexTrailSolar" + GuiName = "OsirisRexTrailSolarSystem" }, + + -- Trail relative to Bennu + { + Name = "OsirisRexTrailBennu", + Parent = "BennuBarycenter", + Renderable = { + Type = "RenderableTrailNew", + -- Spice + Body = "OSIRIS-REX", + Frame = "GALACTIC", + Observer = BENNU_BODY, + -- Optional rendering properties + LineColor = { 0.9, 0.2, 0.9 }, + PointColor = { 0.9, 0.2, 0.9 }, + LineFade = 0.5, -- [0,1] + RenderPart = 0.06, + LineWidth = 2, + ShowTimeStamps = false, + RenderFullTrail = false, + -- Time interval + TimeRange = { + Start = "2016 SEP 8 23:05:00.50", + End = "2023 SEP 24 12:00:00", + }, + SampleDeltaTime = 3600, -- Seconds between each point + SubSamples = 3, + }, + GuiName = "OsirisRexTrailBennu" + }, + + } From d7ea0f8eadb2fdd5daeb41cd3a62a8ceab107664 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 01:26:43 +0200 Subject: [PATCH 019/205] Enable the use of a separate model transform in RenderableModel --- modules/base/rendering/renderablemodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 376fe8cf81..f562c3427e 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -211,7 +211,7 @@ void RenderableModel::render(const RenderData& data) { glm::dmat4 modelTransform = glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * // Translation glm::dmat4(data.modelTransform.rotation) * // Spice rotation - glm::dmat4(glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale))); + glm::dmat4(glm::scale(glm::dmat4(_modelTransform), glm::dvec3(data.modelTransform.scale))); debugModelRotation; // debug model rotation controlled from GUI glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * modelTransform; From e4bc8385fb57b2a372ef1a146b2907242fecfae0 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 01:27:11 +0200 Subject: [PATCH 020/205] Fix the StaticScale to correctly request only a single double --- modules/base/scale/staticscale.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/base/scale/staticscale.cpp b/modules/base/scale/staticscale.cpp index ff1573e61c..ed9fddd71c 100644 --- a/modules/base/scale/staticscale.cpp +++ b/modules/base/scale/staticscale.cpp @@ -33,9 +33,9 @@ namespace openspace { StaticScale::StaticScale(const ghoul::Dictionary& dictionary) : _scaleValue(1.0) { - const bool hasValue = dictionary.hasKeyAndValue(KeyValue); + bool hasValue = dictionary.hasKeyAndValue(KeyValue); if (hasValue) { - dictionary.getValue(KeyValue, _scaleValue); + _scaleValue = dictionary.value(KeyValue); } } From 2a244f42b75c9205cc9ba6cbc404728e113a5751 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 01:30:54 +0200 Subject: [PATCH 021/205] Updated Rosetta kernels Removed old kernel torrent files Cleaned .gitignore --- .gitignore | 70 +---- data/scene/rosetta.scene | 3 +- data/scene/rosetta/rosetta/Rosetta.torrent | Bin 0 -> 18841 bytes .../rosetta/rosetta/RosettaKernels.torrent | Bin 23149 -> 0 bytes .../rosetta/RosettaKernels_New.torrent | Bin 12539 -> 0 bytes data/scene/rosetta/rosetta/rosetta.data | 3 +- data/scene/rosetta/rosetta/rosetta.mod | 250 +++++++++--------- 7 files changed, 148 insertions(+), 178 deletions(-) create mode 100644 data/scene/rosetta/rosetta/Rosetta.torrent delete mode 100644 data/scene/rosetta/rosetta/RosettaKernels.torrent delete mode 100644 data/scene/rosetta/rosetta/RosettaKernels_New.torrent diff --git a/.gitignore b/.gitignore index c413fb7c41..29d61f2358 100644 --- a/.gitignore +++ b/.gitignore @@ -37,60 +37,29 @@ shaders/ABuffer/constants.hglsl LuaScripting.txt Properties.txt log.html -gui/externaltimecontrol/CMakeLists.txt -gui/externaltimecontrol/main.cpp -gui/externaltimecontrol/mainwindow.cpp -gui/externaltimecontrol/mainwindow.h data/scene/rosetta/67P/obj/67P_rotated_5_130.obj data/spice/NewHorizonsKernels/ -data/spice/RosettaKernels/ data/scene/newhorizons/pluto/pluto/textures/ data/scene/newhorizons/pluto/pluto/utcEvents.txt -data/scene/rosetta/rosetta/obj/mainbodyros.obj -data/scene/rosetta/rosetta/obj/solarpanelleft.obj -data/scene/rosetta/rosetta/obj/solarpanelright.obj -data/scene/rosetta/rosetta/textures/defaultProj.png -data/scene/rosetta/rosetta/textures/glare_blue.png -data/scene/rosetta/rosetta/textures/gray.png -data/scene/rosetta/rosetta/textures/squarefov.png +data/scene/rosetta/rosetta/textures/* data/scene/saturn/textures/saturn.jpg data/scene/stars/colorbv.cmap data/scene/stars/speck/stars.speck data/scene/stars/textures/glare.png data/scene/stars/textures/halo.png -data/scene/sun/textures/marker.png -data/scene/sun/textures/sun-glare.png -data/scene/sun/textures/sun.jpg +data/scene/sun/textures/ data/scene/uranus/textures/uranus.jpg data/scene/venus/textures/venus.jpg data/scene/dawn/vestaprojection/VestaComet/VestaComet_5000.obj data/spice/DawnKernels/ data/scene/newhorizons/jupiter/jupiter/ProjectionsOfInterest/ -data/scene/rosetta/67P/textures/black.jpg -data/scene/rosetta/67P/textures/defaultProj.png -data/scene/rosetta/67P/textures/gray.jpg -data/scene/rosetta/67P/textures/gray.png -data/scene/rosetta/67P/textures/texmapflipped.jpg -data/scene/rosetta/67P/textures/white.jpg -data/scene/rosetta/67P/textures/white.png +data/scene/rosetta/67P/textures data/scene/newhorizons/jupiter/callisto/textures/callisto.jpg data/scene/dawn/ceres/textures/gray.png -data/scene/newhorizons/pluto/charon/textures/Charon-Text.png -data/scene/newhorizons/pluto/charon/textures/charon_highres.jpg -data/scene/newhorizons/pluto/charon/textures/charon_highres_annotated.jpg -data/scene/newhorizons/pluto/charon/textures/defaultProj.png -data/scene/dawn/dawn/obj/mainbodydawn.obj -data/scene/dawn/dawn/obj/solarpanelleft.obj -data/scene/dawn/dawn/obj/solarpanelright.obj -data/scene/dawn/dawn/textures/glare_blue.png -data/scene/dawn/dawn/textures/gray.png -data/scene/earth/textures/ToastMapOfEarth.jpg -data/scene/earth/textures/earth_bluemarble.jpg -data/scene/earth/textures/earth_bluemarble_height.jpg -data/scene/earth/textures/earth_night.jpg -data/scene/earth/textures/marker.png -data/scene/earth/textures/earth_clouds.jpg -data/scene/earth/textures/earth_reflectance.png +data/scene/newhorizons/pluto/charon/textures/ +data/scene/dawn/dawn/obj/ +data/scene/dawn/dawn/textures/ +data/scene/earth/textures/ data/scene/moon/textures/Moon16k.dds data/scene/newhorizons/jupiter/europa/textures/europa.jpg data/scene/newhorizons/jupiter/ganymede/textures/ganymede.jpg @@ -100,11 +69,8 @@ data/scene/mars/textures/mars.jpg data/scene/mercury/textures/mercury.jpg data/scene/milkyway/textures/DarkUniverse_mellinger_8k.jpg data/scene/neptune/textures/neptune.jpg -data/scene/newhorizons/newhorizons/models/Labels.obj -data/scene/newhorizons/newhorizons/models/NewHorizonsCleanModel.obj -data/scene/newhorizons/newhorizons/textures/NHTexture.jpg -data/scene/newhorizons/newhorizons/textures/goldfoilbump.tif -data/scene/newhorizons/newhorizons/textures/labels.png +data/scene/newhorizons/newhorizons/models/ +data/scene/newhorizons/newhorizons/textures/ data/scene/pluto/textures/ data/scene/pluto/textures/Shenk_180.jpg data/scene/pluto/textures/pluto_highres_180.jpg @@ -112,10 +78,7 @@ data/scene/newhorizons/pluto/pluto/assets/core_v9h_obs_getmets_v8_time_fix_nofrc data/scene/newhorizons/pluto/pluto/textures/3.jpg data/scene/newhorizons/pluto/pluto/textures/Pluto-Text.png data/scene/dawn/vestaprojection/VestaComet/VestaComet.mtl -data/scene/dawn/vestaprojection/textures/defaultProj_backup.png -data/scene/dawn/vestaprojection/textures/dummy.jpg -data/scene/dawn/vestaprojection/textures/glare.png -data/scene/dawn/vestaprojection/textures/projectMe.png +data/scene/dawn/vestaprojection/textures/ data/spice/MAR063.BSP data/spice/de430_1850-2150.bsp data/spice/jup260.bsp @@ -134,7 +97,6 @@ data/scene/stars-denver/speck/stars.speck data/scene/stars-denver/textures/halo.png data/scene/newhorizons/pluto/pluto/full_images/ data/scene/rosetta/67P/rosettaimages/ -data/spice/RosettaKernels_New/ data/scene/newhorizons/pluto/charon/utcEvents.txt data/scene/rosetta/67P/obj/67P_HD_2015-05-09.obj data/scene/rosetta/67P/obj/may9_map.jpg @@ -143,21 +105,15 @@ data/scene/newhorizons/pluto/charon/textures/cpdem-Mcolor2-MLorriCA-lr-5_ZMfs-cy data/scene/newhorizons/pluto/charon/textures/cpmap_cyl_HR_0e.jpg data/scene/volumetricmilkyway/milkyway/ ScriptLog.txt -data/scene/atmosphereearth/textures/ToastMapOfEarth.jpg -data/scene/atmosphereearth/textures/earth_bluemarble.jpg -data/scene/atmosphereearth/textures/earth_bluemarble_height.jpg -data/scene/atmosphereearth/textures/earth_clouds.jpg -data/scene/atmosphereearth/textures/earth_night.jpg -data/scene/atmosphereearth/textures/earth_reflectance.png -data/scene/atmosphereearth/textures/marker.png +data/scene/atmosphereearth/textures/ data/scene/juno/juno/textures data/scene/juno/juno/spice data/scene/juno/juno/Juno.mtl data/scene/juno/juno/Juno.obj KeyboardMapping.txt saturn_rings.png -data/scene/debugglobe/textures/earth_clouds.jpg -data/scene/debugglobe/textures/earth_reflectance.png +data/scene/debugglobe/textures/ data/scene/rosetta/rosetta/obj/Rosetta.obj data/scene/rosetta/rosetta/rosetta/ data/scene/rosetta/rosetta/textures/ +data/spice/Rosetta/ diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene index 4701468832..32a635067b 100644 --- a/data/scene/rosetta.scene +++ b/data/scene/rosetta.scene @@ -10,6 +10,7 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/pck00010.tpc") openspace.time.setTime("2014-08-15T03:05:18.101") + -- openspace.time.setTime("2016-08-20T03:05:18.101") -- openspace.time.setTime("2014-11-17T03:05:18.101") -- openspace.time.setTime("2015-07-29T06:02:10.000") -- openspace.time.setTime("2014 AUG 21 18:00:00") @@ -50,7 +51,7 @@ return { "venus", "earth", "mars", - "jupiter", + "jupiter/jupiter", "saturn", "uranus", "neptune", diff --git a/data/scene/rosetta/rosetta/Rosetta.torrent b/data/scene/rosetta/rosetta/Rosetta.torrent new file mode 100644 index 0000000000000000000000000000000000000000..c714826b8c0fbc05a193aad66d0f959c1db1b7c0 GIT binary patch literal 18841 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 diff --git a/data/scene/rosetta/rosetta/RosettaKernels_New.torrent b/data/scene/rosetta/rosetta/RosettaKernels_New.torrent deleted file mode 100644 index cdb32f8b5dd8dfc9181f2175e5ccf6ed6c52c4a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12539 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 SZV7jBbGCz9{&|-H{(k_RlhP0X diff --git a/data/scene/rosetta/rosetta/rosetta.data b/data/scene/rosetta/rosetta/rosetta.data index f49beed4ff..fbef76bd99 100644 --- a/data/scene/rosetta/rosetta/rosetta.data +++ b/data/scene/rosetta/rosetta/rosetta.data @@ -4,7 +4,6 @@ return { { Identifier = "rosetta_textures", Destination = "textures", Version = 2 } }, TorrentFiles = { - { File = "RosettaKernels.torrent", Destination = "${SPICE}" }, - { File = "RosettaKernels_New.torrent", Destination = "${SPICE}" } + { File = "Rosetta.torrent", Destination = "${SPICE}" }, } } \ No newline at end of file diff --git a/data/scene/rosetta/rosetta/rosetta.mod b/data/scene/rosetta/rosetta/rosetta.mod index 0796af4c13..19339a6612 100644 --- a/data/scene/rosetta/rosetta/rosetta.mod +++ b/data/scene/rosetta/rosetta/rosetta.mod @@ -1,58 +1,61 @@ RosettaKernels = { - --needed - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", - -- SPK - --long term orbits loaded first - -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORL_DL_006_01____H__00156.BSP', - -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORL_DL_006_01____H__00156.BSP', - -- '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORL_DL_006_01____H__00156.BSP', + "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_243_01___T19_00325.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_223_01___T19_00302.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_145_01___T19_00216.BSP", - --Jan 2014 - May 2015 (version match with 00162 ck files) - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORB_DV_097_01_______00162.BSP", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORB_DV_097_01_______00162.BSP", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORB_DV_097_01_______00162.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_236_01___T19_00318.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_223_01___T19_00302.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/LORB_DV_145_01___T19_00216.BSP", + + "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_243_01___T19_00325.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_223_01___T19_00302.BSP", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/RORB_DV_145_01___T19_00216.BSP", - --IK - "${OPENSPACE_DATA}/spice/RosettaKernels_New/IK/ROS_NAVCAM_V01.TI", - "${OPENSPACE_DATA}/spice/RosettaKernels/IK/ROS_NAVCAM_V00-20130102.TI", + "${OPENSPACE_DATA}/spice/Rosetta/CK/ATNR_P040302093352_00127.BC", - --SCLK - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/ROS_STRUCT_V5.BSP", - -- FK - -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_CHURYUMOV_V01.TF", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF", + "${OPENSPACE_DATA}/spice/Rosetta/IK/ROS_NAVCAM_V01.TI", + + "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ROS_160718_STEP.TSC", + "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ros_triv.tsc", + + "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_CHURYUMOV_V01.TF", + "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_V26.TF", -- CK - -- '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC', - -- "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC", + -- Rosetta attitude + "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_243_01_01____00325.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_223_01_01____00302.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/RATT_DV_145_01_01____00216.BC", - --SCLK - -- "${OPENSPACE_DATA}/spice/RosettaKernels/SCLK/ROS_150227_STEP.TSC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SCLK/ROS_160425_STEP.TSC", + -- Comet attitude + "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_243_01_______00325.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_223_01_______00302.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/CATT_DV_145_01_______00216.BC", - -- FK + -- High gain antenna + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2016_V0035.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2015_V0053.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_HGA_2014_V0044.BC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_CHURYUMOV_V01.TF", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/FK/ROS_V26.TF", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/FK/ROS_V24.TF", - -- CK - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/RATT_DV_211_01_01____00288.BC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/CATT_DV_211_01_______00288.BC", - '${OPENSPACE_DATA}/spice/RosettaKernels/CK/RATT_DV_097_01_01____00162.BC', - "${OPENSPACE_DATA}/spice/RosettaKernels/CK/CATT_DV_097_01_______00162.BC", - - -- PCK - "${OPENSPACE_DATA}/spice/RosettaKernels_New/PCK/ROS_CGS_RSOC_V03.TPC", - -- "${OPENSPACE_DATA}/spice/RosettaKernels/PCK/ROS_CGS_RSOC_V03.TPC", + -- Solar arrays + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2016_V0034.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2015_V0042.BC", + "${OPENSPACE_DATA}/spice/Rosetta/CK/ROS_SA_2014_V0047.BC", - - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2014_V0047.BC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2015_V0042.BC", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/CK/ROS_SA_2016_V0019.BC", + "${OPENSPACE_DATA}/spice/Rosetta/PCK/ROS_CGS_RSOC_V03.TPC", } +RotationMatrix = { + 0, 1, 0, + 0, 0, 1, + 1, 0, 0 +} + + + return { { Name = "Rosetta", @@ -64,7 +67,7 @@ return { Reference = "GALACTIC", Observer = "SUN", Kernels = RosettaKernels - }, + }, Rotation = { Type = "SpiceRotation", SourceFrame = "ROS_SPACECRAFT", @@ -73,8 +76,19 @@ return { } }, { - Name = "Rosetta_black_foil", + Name = "RosettaModel", Parent = "Rosetta", + Transform = { + Scale = { + Type = "StaticScale", + -- The scale of the model is in cm; OpenSpace is in m + Scale = 0.01 + } + } + }, + { + Name = "Rosetta_black_foil", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -85,12 +99,13 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } } }, { Name = "Rosetta_black_parts", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -101,12 +116,13 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } } }, { Name = "Rosetta_dish", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -117,12 +133,21 @@ return { Textures = { Type = "simple", Color = "textures/dish_AO.png" + }, + Rotation = { ModelTransform = RotationMatrix } + + }, + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "-226071", -- ROS_HGA + DestinationFrame = "ROS_SPACECRAFT", } } }, { Name = "Rosetta_parts", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -133,12 +158,14 @@ return { Textures = { Type = "simple", Color = "textures/parts2_AO.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { Name = "Rosetta_silver_foil", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -149,12 +176,14 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { Name = "Rosetta_vents", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -165,12 +194,14 @@ return { Textures = { Type = "simple", Color = "textures/tex_01.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { Name = "Rosetta_wing_a", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -181,12 +212,21 @@ return { Textures = { Type = "simple", Color = "textures/tex_01.png" + }, + Rotation = { ModelTransform = RotationMatrix } + + }, + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "-226015", -- ROS_SA + DestinationFrame = "ROS_SPACECRAFT", } } }, { Name = "Rosetta_wing_b", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -197,12 +237,21 @@ return { Textures = { Type = "simple", Color = "textures/tex_01.png" + }, + Rotation = { ModelTransform = RotationMatrix } + + }, + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "-226025", -- ROS_SA + DestinationFrame = "ROS_SPACECRAFT", } } }, { Name = "Rosetta_yellow_foil", - Parent = "Rosetta", + Parent = "RosettaModel", Renderable = { Type = "RenderableModel", Body = "ROSETTA", @@ -213,12 +262,14 @@ return { Textures = { Type = "simple", Color = "textures/foil_gold_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { Name = "Philae", - Parent = "Rosetta" + Parent = "RosettaModel" -- This should need a transform, but currently the model is intrinsically -- translated }, @@ -235,7 +286,9 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -251,7 +304,9 @@ return { Textures = { Type = "simple", Color = "textures/parts2_AO.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -267,7 +322,9 @@ return { Textures = { Type = "simple", Color = "textures/foil_silver_ramp.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, { @@ -283,55 +340,12 @@ return { Textures = { Type = "simple", Color = "textures/tex_01.png" - } + }, + Rotation = { ModelTransform = RotationMatrix } + } }, - --[[ -- Rosetta Trail Module - { - Name = "RosettaTrail", - Parent = "67P", - Renderable = { - Type = "RenderableTrail", - Body = "ROSETTA", - Frame = "GALACTIC", - Observer = "SUN", - -- 3 Dummy values for compilation: - TropicalOrbitPeriod = 10000.0, - EarthOrbitRatio = 2, - DayLength = 50, - -- End of Dummy values - RGB = { 0.7, 0.7, 0.4 }, - Textures = { - Type = "simple", - Color = "textures/glare.png" - }, - }, - GuiName = "RosettaTrail" - }, --]] - -- Comet Dance trail - --[[{ - Name = "RosettaCometTrail", - Parent = "67P", - Renderable = { - Type = "RenderableTrail", - Body = "ROSETTA", - Frame = "GALACTIC", - Observer = "CHURYUMOV-GERASIMENKO", - TropicalOrbitPeriod = 20000.0, - EarthOrbitRatio = 2, - DayLength = 25, - RGB = { 0.9, 0.2, 0.9 }, - Textures = { - Type = "simple", - Color = "textures/glare.png" - }, - StartTime = "2014 AUG 01 12:00:00", - EndTime = "2016 MAY 26 12:00:00" - }, - GuiName = "RosettaCometTrail" - }, - ]] - { + { Name = "RosettaCometTrail", Parent = "67PBarycenter", Renderable = { @@ -341,7 +355,7 @@ return { Frame = "GALACTIC", Observer = "CHURYUMOV-GERASIMENKO", -- Optional rendering properties - LineColor = { 0.9, 0.2, 0.9 }, + LineColor = { 0.288, 0.375, 0.934 }, PointColor = { 0.9, 0.2, 0.9 }, LineFade = 0.0, -- [0,1] RenderPart = 0.5, -- [0,1] @@ -351,23 +365,23 @@ return { -- Time interval TimeRange = { Start = "2014 AUG 01 12:00:00", - End = "2016 MAY 26 12:00:00" + End = "2016 SEP 30 12:00:00" }, SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 3, + SubSamples = 0, }, GuiName = "/Solar/RosettaCometTrail" }, { Name = "NAVCAM", Parent = "Rosetta", - -- Transform = { - -- Rotation = { - -- Type = "SpiceRotation", - -- SourceFrame = "NAVCAM", - -- DestinationFrame = "ROS_SPACECRAFT", - -- }, - -- }, + Transform = { + Rotation = { + Type = "SpiceRotation", + SourceFrame = "NAVCAM", + DestinationFrame = "ROS_SPACECRAFT", + }, + }, GuiName = "/Solar/Rosetta_navcam" }, { From c06b7bce11728186e6ccb6921ae8fbaacb4bfec1 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 10:48:12 +0200 Subject: [PATCH 022/205] Adding Philae trail --- data/scene/rosetta.scene | 4 +- data/scene/rosetta/67P/67P.mod | 22 ------ data/scene/rosetta/rosetta/rosetta.mod | 95 +++++++++++++++++--------- 3 files changed, 64 insertions(+), 57 deletions(-) diff --git a/data/scene/rosetta.scene b/data/scene/rosetta.scene index 32a635067b..0aa3c75884 100644 --- a/data/scene/rosetta.scene +++ b/data/scene/rosetta.scene @@ -9,9 +9,9 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/naif0011.tls") openspace.spice.loadKernel("${SPICE}/pck00010.tpc") - openspace.time.setTime("2014-08-15T03:05:18.101") + -- openspace.time.setTime("2014-08-15T03:05:18.101") -- openspace.time.setTime("2016-08-20T03:05:18.101") - -- openspace.time.setTime("2014-11-17T03:05:18.101") + openspace.time.setTime("2014-11-12T09:00:18.101") -- openspace.time.setTime("2015-07-29T06:02:10.000") -- openspace.time.setTime("2014 AUG 21 18:00:00") -- openspace.time.setTime("2015 SEP 10 19:39:00") diff --git a/data/scene/rosetta/67P/67P.mod b/data/scene/rosetta/67P/67P.mod index 27e25f8959..9c14de2e59 100644 --- a/data/scene/rosetta/67P/67P.mod +++ b/data/scene/rosetta/67P/67P.mod @@ -9,28 +9,6 @@ return { Body = "CHURYUMOV-GERASIMENKO", Reference = "GALACTIC", Observer = "SUN", - Kernels = { - --needed - "${OPENSPACE_DATA}/spice/de430_1850-2150.bsp", - -- SPK - --long term orbits loaded first - '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORL_DL_009_02____P__00268.BSP', - '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORL_DL_009_02____P__00268.BSP', - '${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORL_DL_009_02____P__00268.BSP', - - '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORL_DL_006_01____H__00156.BSP', - '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORL_DL_006_01____H__00156.BSP', - '${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORL_DL_006_01____H__00156.BSP', - - --Jan 2014 - May 2015 (version match with 00162 ck files) - "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/CORB_DV_097_01_______00162.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/RORB_DV_097_01_______00162.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels/SPK/LORB_DV_097_01_______00162.BSP", - - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/CORB_DV_211_01_______00288.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/RORB_DV_211_01_______00288.BSP", - "${OPENSPACE_DATA}/spice/RosettaKernels_New/SPK/LORB_DV_211_01_______00288.BSP", - } }, }, GuiName = "/Solar/67PBarycenter", diff --git a/data/scene/rosetta/rosetta/rosetta.mod b/data/scene/rosetta/rosetta/rosetta.mod index 19339a6612..fd489a5f23 100644 --- a/data/scene/rosetta/rosetta/rosetta.mod +++ b/data/scene/rosetta/rosetta/rosetta.mod @@ -1,4 +1,7 @@ RosettaKernels = { + "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ROS_160718_STEP.TSC", + "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ros_triv.tsc", + "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_243_01___T19_00325.BSP", "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_223_01___T19_00302.BSP", "${OPENSPACE_DATA}/spice/Rosetta/SPK/CORB_DV_145_01___T19_00216.BSP", @@ -17,9 +20,6 @@ RosettaKernels = { "${OPENSPACE_DATA}/spice/Rosetta/IK/ROS_NAVCAM_V01.TI", - "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ROS_160718_STEP.TSC", - "${OPENSPACE_DATA}/spice/Rosetta/SCLK/ros_triv.tsc", - "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_CHURYUMOV_V01.TF", "${OPENSPACE_DATA}/spice/Rosetta/FK/ROS_V26.TF", @@ -137,13 +137,13 @@ return { Rotation = { ModelTransform = RotationMatrix } }, - Transform = { - Rotation = { - Type = "SpiceRotation", - SourceFrame = "-226071", -- ROS_HGA - DestinationFrame = "ROS_SPACECRAFT", - } - } + -- Transform = { + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "-226071", -- ROS_HGA + -- DestinationFrame = "ROS_SPACECRAFT", + -- } + -- } }, { Name = "Rosetta_parts", @@ -216,13 +216,13 @@ return { Rotation = { ModelTransform = RotationMatrix } }, - Transform = { - Rotation = { - Type = "SpiceRotation", - SourceFrame = "-226015", -- ROS_SA - DestinationFrame = "ROS_SPACECRAFT", - } - } + -- Transform = { + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "-226015", -- ROS_SA + -- DestinationFrame = "ROS_SPACECRAFT", + -- } + -- } }, { Name = "Rosetta_wing_b", @@ -241,13 +241,13 @@ return { Rotation = { ModelTransform = RotationMatrix } }, - Transform = { - Rotation = { - Type = "SpiceRotation", - SourceFrame = "-226025", -- ROS_SA - DestinationFrame = "ROS_SPACECRAFT", - } - } + -- Transform = { + -- Rotation = { + -- Type = "SpiceRotation", + -- SourceFrame = "-226025", -- ROS_SA + -- DestinationFrame = "ROS_SPACECRAFT", + -- } + -- } }, { Name = "Rosetta_yellow_foil", @@ -269,9 +269,18 @@ return { }, { Name = "Philae", - Parent = "RosettaModel" + Parent = "RosettaModel", -- This should need a transform, but currently the model is intrinsically -- translated + -- Transform = { + -- Translation = { + -- Type = "SpiceEphemeris", + -- Body = "PHILAE", + -- Reference = "GALACTIC", + -- Observer = "ROSETTA", + -- Kernels = RosettaKernels + -- } + -- } }, { Name = "Philae_foil", @@ -368,20 +377,40 @@ return { End = "2016 SEP 30 12:00:00" }, SampleDeltaTime = 3600, -- Seconds between each point - SubSamples = 0, + SubSamples = 3, }, GuiName = "/Solar/RosettaCometTrail" }, + { + Name = "PhilaeTrail", + Parent = "67PBarycenter", + Renderable = { + Type = "RenderableTrailNew", + -- Spice + Body = "PHILAE", + Frame = "GALACTIC", + Observer = "CHURYUMOV-GERASIMENKO", + -- Optional rendering properties + LineColor = { 1.0, 1.0, 1.0 }, + PointColor = { 0.9, 0.2, 0.9 }, + LineFade = 0.0, -- [0,1] + RenderPart = 0.5, -- [0,1] + LineWidth = 2, + ShowTimeStamps = false, + RenderFullTrail = false, + -- Time interval + TimeRange = { + Start = "2014 NOV 12 08:35:00", + End = "2014 NOV 12 17:00:00" + }, + SampleDeltaTime = 2, -- Seconds between each point + SubSamples = 0, + }, + GuiName = "/Solar/RosettaCometTrail" + }, { Name = "NAVCAM", Parent = "Rosetta", - Transform = { - Rotation = { - Type = "SpiceRotation", - SourceFrame = "NAVCAM", - DestinationFrame = "ROS_SPACECRAFT", - }, - }, GuiName = "/Solar/Rosetta_navcam" }, { From 705f7b43aa8e66c5fe81c4b0912920d20e4a7952 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 10:48:26 +0200 Subject: [PATCH 023/205] Make SpiceEphemeris check for the kernel existence before trying to load --- modules/base/ephemeris/spiceephemeris.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/base/ephemeris/spiceephemeris.cpp b/modules/base/ephemeris/spiceephemeris.cpp index 36c81ac26a..85df8a21c9 100644 --- a/modules/base/ephemeris/spiceephemeris.cpp +++ b/modules/base/ephemeris/spiceephemeris.cpp @@ -27,6 +27,8 @@ #include #include +#include + namespace { const std::string _loggerCat = "SpiceEphemeris"; //const std::string keyGhosting = "EphmerisGhosting"; @@ -59,8 +61,15 @@ SpiceEphemeris::SpiceEphemeris(const ghoul::Dictionary& dictionary) for (size_t i = 1; i <= kernels.size(); ++i) { std::string kernel; bool success = kernels.getValue(std::to_string(i), kernel); - if (!success) + if (!success) { LERROR("'" << KeyKernels << "' has to be an array-style table"); + break; + } + + if (!FileSys.fileExists(kernel)) { + LERROR("Kernel '" << kernel << "' does not exist"); + continue; + } try { SpiceManager::ref().loadKernel(kernel); From 453c583fb137ee0e580626aa69e587e0e4d9c819 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 10:48:37 +0200 Subject: [PATCH 024/205] Always render the date even if showInfo is false --- src/rendering/renderengine.cpp | 544 ++++++++++++++++----------------- 1 file changed, 272 insertions(+), 272 deletions(-) diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 2991099afd..26f4f2efa7 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -420,9 +420,7 @@ void RenderEngine::render(const glm::mat4& projectionMatrix, const glm::mat4& vi // Print some useful information on the master viewport if (OsEng.isMaster() && OsEng.windowWrapper().isSimpleRendering()) { - if (_showInfo) { - renderInformation(); - } + renderInformation(); } for (auto screenSpaceRenderable : _screenSpaceRenderables) { @@ -1284,7 +1282,7 @@ void RenderEngine::renderInformation() { using Font = ghoul::fontrendering::Font; using ghoul::fontrendering::RenderFont; - if (_showInfo && _fontDate && _fontInfo) { + if (_fontDate) { glm::vec2 penPosition = glm::vec2( 10.f, OsEng.windowWrapper().viewportPixelCoordinates().w @@ -1297,298 +1295,300 @@ void RenderEngine::renderInformation() { Time::ref().currentTimeUTC().c_str() ); - RenderFontCr(*_fontInfo, - penPosition, - "Simulation increment (s): %.0f", - Time::ref().deltaTime() + if (_showInfo && _fontInfo) { + RenderFontCr(*_fontInfo, + penPosition, + "Simulation increment (s): %.0f", + Time::ref().deltaTime() ); - switch (_frametimeType) { - case FrametimeType::DtTimeAvg: - RenderFontCr(*_fontInfo, - penPosition, - "Avg. Frametime: %.5f", - OsEng.windowWrapper().averageDeltaTime() - ); - break; - case FrametimeType::FPS: - RenderFontCr(*_fontInfo, - penPosition, - "FPS: %3.2f", - 1.0 / OsEng.windowWrapper().deltaTime() - ); - break; - case FrametimeType::FPSAvg: - RenderFontCr(*_fontInfo, - penPosition, - "Avg. FPS: %3.2f", - 1.0 / OsEng.windowWrapper().averageDeltaTime() - ); - break; - default: - RenderFontCr(*_fontInfo, - penPosition, - "Avg. Frametime: %.5f", - OsEng.windowWrapper().averageDeltaTime() - ); - break; - } + switch (_frametimeType) { + case FrametimeType::DtTimeAvg: + RenderFontCr(*_fontInfo, + penPosition, + "Avg. Frametime: %.5f", + OsEng.windowWrapper().averageDeltaTime() + ); + break; + case FrametimeType::FPS: + RenderFontCr(*_fontInfo, + penPosition, + "FPS: %3.2f", + 1.0 / OsEng.windowWrapper().deltaTime() + ); + break; + case FrametimeType::FPSAvg: + RenderFontCr(*_fontInfo, + penPosition, + "Avg. FPS: %3.2f", + 1.0 / OsEng.windowWrapper().averageDeltaTime() + ); + break; + default: + RenderFontCr(*_fontInfo, + penPosition, + "Avg. Frametime: %.5f", + OsEng.windowWrapper().averageDeltaTime() + ); + break; + } #ifdef OPENSPACE_MODULE_NEWHORIZONS_ENABLED - bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons"); - double currentTime = Time::ref().currentTime(); + bool hasNewHorizons = scene()->sceneGraphNode("NewHorizons"); + double currentTime = Time::ref().currentTime(); - if (MissionManager::ref().hasCurrentMission()) { + if (MissionManager::ref().hasCurrentMission()) { - const Mission& mission = MissionManager::ref().currentMission(); + const Mission& mission = MissionManager::ref().currentMission(); - if (mission.phases().size() > 0) { + if (mission.phases().size() > 0) { - static const glm::vec4 nextMissionColor(0.7, 0.3, 0.3, 1); - //static const glm::vec4 missionProgressColor(0.4, 1.0, 1.0, 1); - static const glm::vec4 currentMissionColor(0.0, 0.5, 0.5, 1); - static const glm::vec4 missionProgressColor = currentMissionColor;// (0.4, 1.0, 1.0, 1); - static const glm::vec4 currentLeafMissionColor = missionProgressColor; - static const glm::vec4 nonCurrentMissionColor(0.3, 0.3, 0.3, 1); + static const glm::vec4 nextMissionColor(0.7, 0.3, 0.3, 1); + //static const glm::vec4 missionProgressColor(0.4, 1.0, 1.0, 1); + static const glm::vec4 currentMissionColor(0.0, 0.5, 0.5, 1); + static const glm::vec4 missionProgressColor = currentMissionColor;// (0.4, 1.0, 1.0, 1); + static const glm::vec4 currentLeafMissionColor = missionProgressColor; + static const glm::vec4 nonCurrentMissionColor(0.3, 0.3, 0.3, 1); - // Add spacing - RenderFontCr(*_fontInfo, penPosition, nonCurrentMissionColor, " "); + // Add spacing + RenderFontCr(*_fontInfo, penPosition, nonCurrentMissionColor, " "); - std::list phaseTrace = mission.phaseTrace(currentTime); + std::list phaseTrace = mission.phaseTrace(currentTime); - if (phaseTrace.size()) { - std::string title = "Current Mission Phase: " + phaseTrace.back()->name(); - RenderFontCr(*_fontInfo, penPosition, missionProgressColor, title.c_str()); - double remaining = phaseTrace.back()->timeRange().end - currentTime; - float t = static_cast(1.0 - remaining / phaseTrace.back()->timeRange().duration()); - std::string progress = progressToStr(25, t); - //RenderFontCr(*_fontInfo, penPosition, missionProgressColor, - // "%.0f s %s %.1f %%", remaining, progress.c_str(), t * 100); - } - else { - RenderFontCr(*_fontInfo, penPosition, nextMissionColor, "Next Mission:"); - double remaining = mission.timeRange().start - currentTime; - RenderFontCr(*_fontInfo, penPosition, nextMissionColor, - "%.0f s", remaining); - } - - bool showAllPhases = false; - - typedef std::pair PhaseWithDepth; - std::stack S; - int pixelIndentation = 20; - S.push({ &mission, 0 }); - while (!S.empty()) { - const MissionPhase* phase = S.top().first; - int depth = S.top().second; - S.pop(); - - bool isCurrentPhase = phase->timeRange().includes(currentTime); - - penPosition.x += depth * pixelIndentation; - if (isCurrentPhase) { - double remaining = phase->timeRange().end - currentTime; - float t = static_cast(1.0 - remaining / phase->timeRange().duration()); + if (phaseTrace.size()) { + std::string title = "Current Mission Phase: " + phaseTrace.back()->name(); + RenderFontCr(*_fontInfo, penPosition, missionProgressColor, title.c_str()); + double remaining = phaseTrace.back()->timeRange().end - currentTime; + float t = static_cast(1.0 - remaining / phaseTrace.back()->timeRange().duration()); std::string progress = progressToStr(25, t); - RenderFontCr(*_fontInfo, penPosition, currentMissionColor, - "%s %s %.1f %%", - phase->name().c_str(), - progress.c_str(), - t * 100 - ); + //RenderFontCr(*_fontInfo, penPosition, missionProgressColor, + // "%.0f s %s %.1f %%", remaining, progress.c_str(), t * 100); } else { - RenderFontCr(*_fontInfo, penPosition, nonCurrentMissionColor, phase->name().c_str()); + RenderFontCr(*_fontInfo, penPosition, nextMissionColor, "Next Mission:"); + double remaining = mission.timeRange().start - currentTime; + RenderFontCr(*_fontInfo, penPosition, nextMissionColor, + "%.0f s", remaining); } - penPosition.x -= depth * pixelIndentation; - if (isCurrentPhase || showAllPhases) { - // phases are sorted increasingly by start time, and will be popped - // last-in-first-out from the stack, so add them in reversed order. - int indexLastPhase = phase->phases().size() - 1; - for (int i = indexLastPhase; 0 <= i; --i) { - S.push({ &phase->phase(i), depth + 1 }); - } - } - } - } - } + bool showAllPhases = false; + typedef std::pair PhaseWithDepth; + std::stack S; + int pixelIndentation = 20; + S.push({ &mission, 0 }); + while (!S.empty()) { + const MissionPhase* phase = S.top().first; + int depth = S.top().second; + S.pop(); + bool isCurrentPhase = phase->timeRange().includes(currentTime); - if (openspace::ImageSequencer::ref().isReady()) { - penPosition.y -= 25.f; - - glm::vec4 targetColor(0.00, 0.75, 1.00, 1); - - if (hasNewHorizons) { - try { - double lt; - glm::dvec3 p = - SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", {}, currentTime, lt); - psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); - float a, b, c; - glm::dvec3 radii; - SpiceManager::ref().getValue("PLUTO", "RADII", radii); - a = radii.x; - b = radii.y; - float radius = (a + b) / 2.f; - float distToSurf = glm::length(nhPos.vec3()) - radius; - - RenderFont(*_fontInfo, - penPosition, - "Distance to Pluto: % .1f (KM)", - distToSurf - ); - penPosition.y -= _fontInfo->height(); - } - catch (...) { - } - } - - double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; - float t = static_cast(1.0 - remaining / openspace::ImageSequencer::ref().getIntervalLength()); - - std::string str = SpiceManager::ref().dateFromEphemerisTime( - ImageSequencer::ref().getNextCaptureTime(), - "YYYY MON DD HR:MN:SC" - ); - - glm::vec4 active(0.6, 1, 0.00, 1); - glm::vec4 brigther_active(0.9, 1, 0.75, 1); - - if (remaining > 0) { - - std::string progress = progressToStr(25, t); - brigther_active *= (1 - t); - - RenderFontCr(*_fontInfo, - penPosition, - active * t + brigther_active, - "Next instrument activity:" - ); - - RenderFontCr(*_fontInfo, - penPosition, - active * t + brigther_active, - "%.0f s %s %.1f %%", - remaining, progress.c_str(), t * 100 - ); - - RenderFontCr(*_fontInfo, - penPosition, - active, - "Data acquisition time: %s", - str.c_str() - ); - } - std::pair nextTarget = ImageSequencer::ref().getNextTarget(); - std::pair currentTarget = ImageSequencer::ref().getCurrentTarget(); - - if (currentTarget.first > 0.0) { - int timeleft = static_cast(nextTarget.first - currentTime); - - int hour = timeleft / 3600; - int second = timeleft % 3600; - int minute = second / 60; - second = second % 60; - - std::string hh, mm, ss; - - if (hour < 10) - hh.append("0"); - if (minute < 10) - mm.append("0"); - if (second < 10) - ss.append("0"); - - hh.append(std::to_string(hour)); - mm.append(std::to_string(minute)); - ss.append(std::to_string(second)); - - RenderFontCr(*_fontInfo, - penPosition, - targetColor, - "Data acquisition adjacency: [%s:%s:%s]", - hh.c_str(), mm.c_str(), ss.c_str() - ); - -#if 0 -// Why is it (2) in the original? ---abock - //std::pair> incidentTargets = ImageSequencer::ref().getIncidentTargetList(0); - //std::pair> incidentTargets = ImageSequencer::ref().getIncidentTargetList(2); - std::string space; - glm::vec4 color; - size_t isize = incidentTargets.second.size(); - for (size_t p = 0; p < isize; p++) { - double t = static_cast(p + 1) / static_cast(isize + 1); - t = (p > isize / 2) ? 1 - t : t; - t += 0.3; - color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); - - RenderFont(*_fontInfo, - penPosition, - color, - "%s%s", - space.c_str(), incidentTargets.second[p].c_str() - ); - - - for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) - space += " "; - } -#endif - penPosition.y -= _fontInfo->height(); - - std::map activeMap = ImageSequencer::ref().getActiveInstruments(); - glm::vec4 firing(0.58 - t, 1 - t, 1 - t, 1); - glm::vec4 notFiring(0.5, 0.5, 0.5, 1); - - RenderFontCr(*_fontInfo, - penPosition, - active, - "Active Instruments:" - ); - - for (auto t : activeMap) { - if (t.second == false) { - RenderFont(*_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "| |" - ); - RenderFontCr(*_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " %5s", - t.first.c_str() - ); - - } - else { - RenderFont(*_fontInfo, - penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - "|" - ); - if (t.first == "NH_LORRI") { - RenderFont(*_fontInfo, - penPosition, - firing, - " + " + penPosition.x += depth * pixelIndentation; + if (isCurrentPhase) { + double remaining = phase->timeRange().end - currentTime; + float t = static_cast(1.0 - remaining / phase->timeRange().duration()); + std::string progress = progressToStr(25, t); + RenderFontCr(*_fontInfo, penPosition, currentMissionColor, + "%s %s %.1f %%", + phase->name().c_str(), + progress.c_str(), + t * 100 ); } + else { + RenderFontCr(*_fontInfo, penPosition, nonCurrentMissionColor, phase->name().c_str()); + } + penPosition.x -= depth * pixelIndentation; + + if (isCurrentPhase || showAllPhases) { + // phases are sorted increasingly by start time, and will be popped + // last-in-first-out from the stack, so add them in reversed order. + int indexLastPhase = phase->phases().size() - 1; + for (int i = indexLastPhase; 0 <= i; --i) { + S.push({ &phase->phase(i), depth + 1 }); + } + } + } + } + } + + + + if (openspace::ImageSequencer::ref().isReady()) { + penPosition.y -= 25.f; + + glm::vec4 targetColor(0.00, 0.75, 1.00, 1); + + if (hasNewHorizons) { + try { + double lt; + glm::dvec3 p = + SpiceManager::ref().targetPosition("PLUTO", "NEW HORIZONS", "GALACTIC", {}, currentTime, lt); + psc nhPos = PowerScaledCoordinate::CreatePowerScaledCoordinate(p.x, p.y, p.z); + float a, b, c; + glm::dvec3 radii; + SpiceManager::ref().getValue("PLUTO", "RADII", radii); + a = radii.x; + b = radii.y; + float radius = (a + b) / 2.f; + float distToSurf = glm::length(nhPos.vec3()) - radius; + + RenderFont(*_fontInfo, + penPosition, + "Distance to Pluto: % .1f (KM)", + distToSurf + ); + penPosition.y -= _fontInfo->height(); + } + catch (...) { + } + } + + double remaining = openspace::ImageSequencer::ref().getNextCaptureTime() - currentTime; + float t = static_cast(1.0 - remaining / openspace::ImageSequencer::ref().getIntervalLength()); + + std::string str = SpiceManager::ref().dateFromEphemerisTime( + ImageSequencer::ref().getNextCaptureTime(), + "YYYY MON DD HR:MN:SC" + ); + + glm::vec4 active(0.6, 1, 0.00, 1); + glm::vec4 brigther_active(0.9, 1, 0.75, 1); + + if (remaining > 0) { + + std::string progress = progressToStr(25, t); + brigther_active *= (1 - t); + + RenderFontCr(*_fontInfo, + penPosition, + active * t + brigther_active, + "Next instrument activity:" + ); + + RenderFontCr(*_fontInfo, + penPosition, + active * t + brigther_active, + "%.0f s %s %.1f %%", + remaining, progress.c_str(), t * 100 + ); + + RenderFontCr(*_fontInfo, + penPosition, + active, + "Data acquisition time: %s", + str.c_str() + ); + } + std::pair nextTarget = ImageSequencer::ref().getNextTarget(); + std::pair currentTarget = ImageSequencer::ref().getCurrentTarget(); + + if (currentTarget.first > 0.0) { + int timeleft = static_cast(nextTarget.first - currentTime); + + int hour = timeleft / 3600; + int second = timeleft % 3600; + int minute = second / 60; + second = second % 60; + + std::string hh, mm, ss; + + if (hour < 10) + hh.append("0"); + if (minute < 10) + mm.append("0"); + if (second < 10) + ss.append("0"); + + hh.append(std::to_string(hour)); + mm.append(std::to_string(minute)); + ss.append(std::to_string(second)); + + RenderFontCr(*_fontInfo, + penPosition, + targetColor, + "Data acquisition adjacency: [%s:%s:%s]", + hh.c_str(), mm.c_str(), ss.c_str() + ); + + #if 0 + // Why is it (2) in the original? ---abock + //std::pair> incidentTargets = ImageSequencer::ref().getIncidentTargetList(0); + //std::pair> incidentTargets = ImageSequencer::ref().getIncidentTargetList(2); + std::string space; + glm::vec4 color; + size_t isize = incidentTargets.second.size(); + for (size_t p = 0; p < isize; p++) { + double t = static_cast(p + 1) / static_cast(isize + 1); + t = (p > isize / 2) ? 1 - t : t; + t += 0.3; + color = (p == isize / 2) ? targetColor : glm::vec4(t, t, t, 1); + RenderFont(*_fontInfo, penPosition, - glm::vec4(0.3, 0.3, 0.3, 1), - " |" - ); - RenderFontCr(*_fontInfo, - penPosition, - active, - " %5s", - t.first.c_str() + color, + "%s%s", + space.c_str(), incidentTargets.second[p].c_str() ); + + + for (int k = 0; k < incidentTargets.second[p].size() + 2; k++) + space += " "; + } + #endif + penPosition.y -= _fontInfo->height(); + + std::map activeMap = ImageSequencer::ref().getActiveInstruments(); + glm::vec4 firing(0.58 - t, 1 - t, 1 - t, 1); + glm::vec4 notFiring(0.5, 0.5, 0.5, 1); + + RenderFontCr(*_fontInfo, + penPosition, + active, + "Active Instruments:" + ); + + for (auto t : activeMap) { + if (t.second == false) { + RenderFont(*_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "| |" + ); + RenderFontCr(*_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " %5s", + t.first.c_str() + ); + + } + else { + RenderFont(*_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + "|" + ); + if (t.first == "NH_LORRI") { + RenderFont(*_fontInfo, + penPosition, + firing, + " + " + ); + } + RenderFont(*_fontInfo, + penPosition, + glm::vec4(0.3, 0.3, 0.3, 1), + " |" + ); + RenderFontCr(*_fontInfo, + penPosition, + active, + " %5s", + t.first.c_str() + ); + } } } } From b5c99604cded40507eda245ee3907b3c92a3ea86 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 10:56:41 +0200 Subject: [PATCH 025/205] Render Philae separately from Rosetta --- data/scene/rosetta/rosetta/rosetta.mod | 30 +++++++++++++++++--------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/data/scene/rosetta/rosetta/rosetta.mod b/data/scene/rosetta/rosetta/rosetta.mod index fd489a5f23..70572026ac 100644 --- a/data/scene/rosetta/rosetta/rosetta.mod +++ b/data/scene/rosetta/rosetta/rosetta.mod @@ -269,18 +269,28 @@ return { }, { Name = "Philae", - Parent = "RosettaModel", + Parent = "67PBarycenter", -- This should need a transform, but currently the model is intrinsically -- translated - -- Transform = { - -- Translation = { - -- Type = "SpiceEphemeris", - -- Body = "PHILAE", - -- Reference = "GALACTIC", - -- Observer = "ROSETTA", - -- Kernels = RosettaKernels - -- } - -- } + Transform = { + Translation = { + Type = "SpiceEphemeris", + Body = "PHILAE", + Reference = "GALACTIC", + Observer = "CHURYUMOV-GERASIMENKO", + Kernels = RosettaKernels + }, + Rotation = { + Type = "SpiceRotation", + SourceFrame = "ROS_SPACECRAFT", + DestinationFrame = "GALACTIC", + }, + Scale = { + Type = "StaticScale", + -- The scale of the model is in cm; OpenSpace is in m + Scale = 0.01 + } + } }, { Name = "Philae_foil", From abb40e24b677f091741a05a3c283c1f99c74b01b Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 11:06:58 +0200 Subject: [PATCH 026/205] Space cleanup --- config/sgct/VRArenaSimCenter.xml | 158 +++++++++++++++--------------- config/sgct/single.xml | 32 +++--- config/sgct/single_fisheye.xml | 68 ++++++------- config/sgct/single_gui.xml | 48 ++++----- config/sgct/single_sbs_stereo.xml | 28 +++--- config/sgct/single_stereo.xml | 44 ++++----- config/sgct/single_two_win.xml | 74 +++++++------- config/sgct/two_nodes.xml | 82 ++++++++-------- 8 files changed, 267 insertions(+), 267 deletions(-) diff --git a/config/sgct/VRArenaSimCenter.xml b/config/sgct/VRArenaSimCenter.xml index 3ce0236e5f..f57ec51789 100644 --- a/config/sgct/VRArenaSimCenter.xml +++ b/config/sgct/VRArenaSimCenter.xml @@ -1,82 +1,82 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/sgct/single.xml b/config/sgct/single.xml index 62aea727b1..7b20bcb10c 100644 --- a/config/sgct/single.xml +++ b/config/sgct/single.xml @@ -1,24 +1,24 @@ - - - - - - - + + + + + + + - - - + + + - - - - - - + + + + + + diff --git a/config/sgct/single_fisheye.xml b/config/sgct/single_fisheye.xml index b72758eb6c..b9bc7415dd 100644 --- a/config/sgct/single_fisheye.xml +++ b/config/sgct/single_fisheye.xml @@ -1,37 +1,37 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/config/sgct/single_gui.xml b/config/sgct/single_gui.xml index e0d1b6bfa8..a3956e40f6 100644 --- a/config/sgct/single_gui.xml +++ b/config/sgct/single_gui.xml @@ -1,37 +1,37 @@ - - - - - - - + + + + + + + - - - + + + - - - - - + + + + + - - - + + + - - - - - - + + + + + + diff --git a/config/sgct/single_sbs_stereo.xml b/config/sgct/single_sbs_stereo.xml index ab3d4826fb..d92f95ed66 100644 --- a/config/sgct/single_sbs_stereo.xml +++ b/config/sgct/single_sbs_stereo.xml @@ -1,21 +1,21 @@ - - - - - - - - + + + + + + + + - - - - - - + + + + + + \ No newline at end of file diff --git a/config/sgct/single_stereo.xml b/config/sgct/single_stereo.xml index 71f83845c3..8497af6188 100644 --- a/config/sgct/single_stereo.xml +++ b/config/sgct/single_stereo.xml @@ -1,25 +1,25 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/sgct/single_two_win.xml b/config/sgct/single_two_win.xml index 7286afb127..4cd802423a 100644 --- a/config/sgct/single_two_win.xml +++ b/config/sgct/single_two_win.xml @@ -1,40 +1,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/config/sgct/two_nodes.xml b/config/sgct/two_nodes.xml index 456976ebe5..9ec00bf7bc 100644 --- a/config/sgct/two_nodes.xml +++ b/config/sgct/two_nodes.xml @@ -1,44 +1,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 29d50e85fe2001d7fceee2358c56599f0d98bd0c Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Tue, 30 Aug 2016 11:07:13 +0200 Subject: [PATCH 027/205] Bind keys to disable outer planets orbits --- scripts/bind_keys_rosetta.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/bind_keys_rosetta.lua b/scripts/bind_keys_rosetta.lua index 47bb50541c..6c1ec594a3 100644 --- a/scripts/bind_keys_rosetta.lua +++ b/scripts/bind_keys_rosetta.lua @@ -21,6 +21,6 @@ openspace.bindKey("F8", "openspace.setPropertyValue('67P.renderable.ProjectionCo openspace.bindKey("i", helper.renderable.toggle('ImagePlaneRosetta')) openspace.bindKey("q", helper.renderable.toggle('SunMarker')) -openspace.bindKey("e", helper.renderable.toggle('EarthMarker')) +openspace.bindKey("e", helper.renderable.toggle('JupiterTrail') .. helper.renderable.toggle('SaturnTrail') .. helper.renderable.toggle('UranusTrail') .. helper.renderable.toggle('NeptuneTrail')) openspace.bindKey("c", "openspace.parallel.setAddress('130.236.142.51');openspace.parallel.setPassword('newhorizons-20150714');openspace.parallel.connect();") From 86a0661aefa7bb5d57e853ad5c021894d6126941 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Tue, 30 Aug 2016 13:36:57 +0200 Subject: [PATCH 028/205] perform bias matrix operation in shader instead of on cpu, for renderableplanetprojection --- modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl b/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl index 3f6e2be3ba..d95b7a66b9 100644 --- a/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl +++ b/modules/newhorizons/shaders/renderablePlanetProjection_fs.glsl @@ -71,6 +71,8 @@ void main() { projected.x /= projected.w; projected.y /= projected.w; + projected = projected * 0.5 + vec4(0.5); + vec3 normal = normalize((ModelTransform*vec4(vertex.xyz,0)).xyz); vec3 v_b = normalize(boresight); From 0ee638f447c88b87fedac72fc3c13583e96be580 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 12:26:10 -0400 Subject: [PATCH 029/205] Enable clearing scheduled scripts --- include/openspace/scripting/scriptscheduler.h | 2 ++ src/scripting/scriptscheduler.cpp | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h index 75c45e1e71..e0783d7c27 100644 --- a/include/openspace/scripting/scriptscheduler.h +++ b/include/openspace/scripting/scriptscheduler.h @@ -64,6 +64,8 @@ public: void skipTo(double time); void skipTo(const std::string& timeStr); + void clearSchedule(); + std::queue scheduledScripts(double newTime); std::queue scheduledScripts(const std::string& timeStr); diff --git a/src/scripting/scriptscheduler.cpp b/src/scripting/scriptscheduler.cpp index ef73fb4a13..fa2bd0d03b 100644 --- a/src/scripting/scriptscheduler.cpp +++ b/src/scripting/scriptscheduler.cpp @@ -100,6 +100,10 @@ void ScriptScheduler::skipTo(const std::string& timeStr) { skipTo(SpiceManager::ref().ephemerisTimeFromDate(timeStr)); } +void ScriptScheduler::clearSchedule() { + _scheduledScripts.clear(); + _currentIndex = 0; +} std::queue ScriptScheduler::scheduledScripts(double newTime) { std::queue triggeredScripts; @@ -157,6 +161,15 @@ namespace luascriptfunctions { OsEng.scriptScheduler().skipTo(dateStr); } + + int clear(lua_State* L) { + using ghoul::lua::luaTypeToString; + int nArguments = lua_gettop(L); + if (nArguments != 0) + return luaL_error(L, "Expected %i arguments, got %i", 0, nArguments); + + OsEng.scriptScheduler().clearSchedule(); + } } // namespace luascriptfunction @@ -177,6 +190,12 @@ LuaLibrary ScriptScheduler::luaLibrary() { "string", "skip to a time without executing scripts" }, + { + "clear", + &luascriptfunctions::clear, + "", + "clears all scheduled scripts" + }, } }; } From 06b7c0776e4554acf6f6e05487791b4f4dba85c4 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 12:28:35 -0400 Subject: [PATCH 030/205] Press F4 to reload scheduled scripts from file during run time --- scripts/bind_keys_osirisrex.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/bind_keys_osirisrex.lua b/scripts/bind_keys_osirisrex.lua index 7ee1c1b45f..536a63cd1a 100644 --- a/scripts/bind_keys_osirisrex.lua +++ b/scripts/bind_keys_osirisrex.lua @@ -25,6 +25,8 @@ openspace.bindKey("F11", "openspace.printInfo('Set time: Recon'); o -- kernel32.dll!BaseThreadInitThunk() -- ntdll.dll!RtUserThreadStart() +openspace.bindKey("F4", "openspace.scriptScheduler.clear(); openspace.scriptScheduler.load('${OPENSPACE_DATA}/scene/osirisrex/scheduled_scripts.lua');") + openspace.bindKey("q", helper.property.invert('SunMarker.renderable.enabled')) openspace.bindKey("e", helper.property.invert('EarthMarker.renderable.enabled')) From 357462adacc9552d647b42afd7b5f232a1d0c5bb Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Tue, 30 Aug 2016 13:01:55 -0400 Subject: [PATCH 031/205] Update osirisrex.mod and spice kernel loading order --- data/scene/osirisrex.scene | 87 ++++++++++++-------- data/scene/osirisrex/bennu/bennu.mod | 6 +- data/scene/osirisrex/osirisrex/osirisrex.mod | 12 +-- 3 files changed, 58 insertions(+), 47 deletions(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 406a55af52..f9c743c557 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -37,6 +37,7 @@ function preInitialization() -- Low res SPK openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160917_231024_pgaa3_day15m60_v1.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160914_231024_pgaa3_day12m60_v1.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa3_day06m60_v1.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/spk_orx_160908_231024_pgaa2_day06m60_v3.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/orx_160908_231024_pgaa2_day06m60.bsp") @@ -48,6 +49,19 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/de421.bsp") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/background/spk/sb-101955-76.bsp") + -- Nominal_Profile_LowRes + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_600s_20180816T230000_20181119T010000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_NominalProfile_600s_20180816T230000_20181119T010000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_600s_20190108T000000_20190317T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_600s_20181203T230000_20190109T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_600s_20190316T000000_20190521T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_600s_20181119T230000_20181204T010000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_600s_20190519T000000_20190830T000000.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_NominalProfile_600s_20190519T000000_20190830T000000.bc") -- Nominal_Observations_Science openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/03_Approach/DustSearch_v1/Phase03_AP_DustSearch_1.bc") @@ -78,15 +92,19 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_4.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_5.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/04_PrelimSurvey/PolyCam_v1/Phase04_PS_PolyCam_6.bc") + --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_info.TXT") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_v2.bc") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/README.txt") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19013_18_BBD1_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19014_16_BBD2_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19020_18_BBD3_v2.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/BaseballDiamond_v2/atl_19021_19_BBD4_v2.bc") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_1.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_2.bc") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/06_DetailedSurvey/EquatorialStations_v1/Phase06_DS_Equatorial_Stations_3.bc") @@ -102,41 +120,38 @@ function preInitialization() openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_1.a") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_2.a") openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/07_OrbitalB/CandidateSampleSite_v2/CSS_Mapping_3.a") + --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case02_0Latitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case05_20negLatitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case08_40negLatitude.wmv") --openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Case11_60negLatitude.wmv") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case02.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case05.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case08.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case11.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case02_0Latitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case05_20negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case08_40negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case11_60negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case02.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case05.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_0Latitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_atl_19145_04.atf") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_20negLatitude.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_atl_19145_04.atf") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_NominalProfile.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case08_NominalProfile.bc") - -- Nominal_Profile_LowRes - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_600s_20180816T230000_20181119T010000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Approach_NominalProfile_600s_20180816T230000_20181119T010000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_600s_20190108T000000_20190317T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/DetailedSurvey_NominalProfile_600s_20190108T000000_20190317T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_600s_20181203T230000_20190109T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalA_NominalProfile_600s_20181203T230000_20190109T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_600s_20190316T000000_20190521T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/OrbitalB_NominalProfile600s_20190316T000000_20190521T000000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_600s_20181119T230000_20181204T010000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/PrelimSurvey_NominalProfile_600s_20181119T230000_20181204T010000.bc") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_600s_20190519T000000_20190830T000000.bsp") - openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Profile_LowRes/Recon_NominalProfile_600s_20190519T000000_20190830T000000.bc") - + local case = 2 -- Right now we only have the image times for case 2 + + if case == 2 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case02.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_0Latitude.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case02_atl_19145_04.atf") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case02.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case02_0Latitude.bc") + elseif case == 5 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/ORX_Recon_525mSortie_Case05.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_20negLatitude.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_atl_19145_04.atf") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case05_NominalProfile.bc") + + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case05.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case05_20negLatitude.bc") + elseif case == 8 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/525m_Sortie_v2/Recon_525mSortie_Case08_NominalProfile.bc") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case08.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case08_40negLatitude.bc") + elseif case == 11 then + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/ORX_Recon_225mSortie_Case11.bsp") + openspace.spice.loadKernel("${SPICE}/OsirisRexKernels/Nominal_Observations_Science/08_Recon/225m_Sortie_v2/Recon_225mSortie_Case11_60negLatitude.bc") + end + -- Load planetary constants openspace.spice.loadKernel("${SPICE}/pck00010.tpc") @@ -145,8 +160,8 @@ function preInitialization() -- openspace.time.setTime("2018-12-20T22:47:00.00") --openspace.time.setTime("2019-05-25T03:57:55.00") - --openspace.time.setTime("2016 SEP 8 23:05:00.50") - openspace.time.setTime("2019 APR 16 12:03:00.00") + openspace.time.setTime("2016 SEP 8 23:05:00.50") + --openspace.time.setTime("2019 APR 16 12:03:00.00") openspace.time.setDeltaTime(0) end diff --git a/data/scene/osirisrex/bennu/bennu.mod b/data/scene/osirisrex/bennu/bennu.mod index e30d24cd02..d940c9415a 100644 --- a/data/scene/osirisrex/bennu/bennu.mod +++ b/data/scene/osirisrex/bennu/bennu.mod @@ -37,7 +37,7 @@ return { }, Textures = { Type = "simple", - Color = "textures/osirisTex.png", + Color = "textures/white.png", Project = "textures/defaultProj.png", Default = "textures/defaultProj.png" }, @@ -62,7 +62,7 @@ return { "OrbitalB_Site08_PolyCamImages.txt", "Recon_225m_Equatorial_PolyCam.txt", }, - },--[[ + }, ORX_REXIS = { DetectorType = "Camera", Spice = {"ORX_REXIS"}, @@ -71,7 +71,7 @@ return { "Recon_225m_Equatorial_spectrometers.txt", "Recon_525m_Equatorial_spectrometers.txt", }, - },]] + }, }, Target = { Body = BENNU_BODY, -- Do we need this? diff --git a/data/scene/osirisrex/osirisrex/osirisrex.mod b/data/scene/osirisrex/osirisrex/osirisrex.mod index 0cfa8f34e2..4770d5186f 100644 --- a/data/scene/osirisrex/osirisrex/osirisrex.mod +++ b/data/scene/osirisrex/osirisrex/osirisrex.mod @@ -74,7 +74,6 @@ return { }, GuiName = "/Solar/ORX_OCAMS_POLYCAM" }, - --[[ { Name = "ORX_REXIS", Parent = "OsirisRex", @@ -108,8 +107,7 @@ return { }, }, GuiName = "/Solar/ORX_REXIS" - },]] - + }, { Name = "POLYCAM FOV", Parent = "ORX_OCAMS_POLYCAM", @@ -134,7 +132,6 @@ return { }, GuiName = "/Solar/POLYCAM FOV" }, - --[[ { Name = "REXIS FOV", Parent = "ORX_REXIS", @@ -159,12 +156,11 @@ return { }, GuiName = "/Solar/REXIS FOV" }, - ]] --[[ -- Latest image taken by POLYCAM { Name = "ImagePlaneOsirisRex", - Parent = "OsirisRex", + Parent = "Bennu2", Renderable = { Type = "RenderablePlaneProjection", Frame = "IAU_BENNU", @@ -182,7 +178,7 @@ return { -- POLYCAM FoV square { Name = "FovImagePlane", - Parent = "OsirisRex", + Parent = "Bennu2", Renderable = { Type = "RenderablePlaneProjection", Frame = "IAU_BENNU", @@ -190,7 +186,7 @@ return { Spacecraft = "OSIRIS-REX", Instrument = "ORX_OCAMS_POLYCAM", Moving = true, - Texture = "textures/squarefov.png", + Texture = "textures/defaultProj.png", }, Ephemeris = { Type = "Static", From 6b1369f58ce9a2e90a204f9acc356b1d6c51f9c3 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 13:16:10 -0400 Subject: [PATCH 032/205] Log at info level when scheduled scripts are executed --- src/engine/openspaceengine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index e0751a3066..90a3692291 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -755,7 +755,9 @@ void OpenSpaceEngine::preSynchronization() { auto scheduledScripts = _scriptScheduler->scheduledScripts(Time::ref().currentTime()); while(scheduledScripts.size()){ - _scriptEngine->queueScript(scheduledScripts.front()); + auto scheduledScript = scheduledScripts.front(); + LINFO(scheduledScript); + _scriptEngine->queueScript(scheduledScript); scheduledScripts.pop(); } From e7d8308537bc1dfdee4fe2c265fd6c069ac63e14 Mon Sep 17 00:00:00 2001 From: Kalle Bladin Date: Tue, 30 Aug 2016 13:23:21 -0400 Subject: [PATCH 033/205] Add objects to the osiris rex scene --- data/scene/osirisrex.scene | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data/scene/osirisrex.scene b/data/scene/osirisrex.scene index 663dba97fd..62f8cf4a4b 100644 --- a/data/scene/osirisrex.scene +++ b/data/scene/osirisrex.scene @@ -210,16 +210,16 @@ return { }, Modules = { "sun", - --"mercury", - --"venus", + "mercury", + "venus", "lodearth", - --"mars", - --"saturn", - --"uranus", - --"neptune", - --"stars", + "mars", + "saturn", + "uranus", + "neptune", + "stars", -- "stars-denver", - --"milkyway", + "milkyway", -- "milkyway-eso", --"imageplane", "osirisrex", From 8c137a78b23a7f49453e0223eac1f539d772aa67 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 13:34:56 -0400 Subject: [PATCH 034/205] Add scheduled scripts for enabling different Bennu trails --- data/scene/osirisrex/scheduled_scripts.lua | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/data/scene/osirisrex/scheduled_scripts.lua b/data/scene/osirisrex/scheduled_scripts.lua index 5f58a00218..933b74c21b 100644 --- a/data/scene/osirisrex/scheduled_scripts.lua +++ b/data/scene/osirisrex/scheduled_scripts.lua @@ -1,17 +1,25 @@ +function enable(name, enabled) + return "openspace.setPropertyValue('" .. name .. ".renderable.enabled', " .. (enabled and "true" or "false") .. ");"; +end + +function scheduleEnabled(time, name, enabled) + return + { + Time = time, + ReversibleLuaScript = { + Forward = enable(name, enabled), + Backward = enable(name, not enabled) + } + } +end + return { - { - Time = "2016 SEP 08 23:10:13", - ReversibleLuaScript = { - Forward = "openspace.printInfo('forward test 1');", - Backward = "openspace.printInfo('backward test 1');", - } - }, - { - Time = "2016 SEP 09 00:08:13", - ReversibleLuaScript = { - Forward = "openspace.printInfo('forward test 2');", - Backward = "openspace.printInfo('backward test 2');", - } - }, + scheduleEnabled("2016 SEP 08 23:05:01", "OsirisRexTrailEarth", true), + scheduleEnabled("2016 SEP 09 00:00:00", "OsirisRexTrailSolarSystem", true), + scheduleEnabled("2016 SEP 09 02:00:00", "OsirisRexTrailEarth", false), + scheduleEnabled("2018 OCT 11 00:00:00", "OsirisRexTrailBennu", true), + scheduleEnabled("2018 OCT 15 00:00:00", "OsirisRexTrailSolarSystem", false), + scheduleEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailSolarSystem", true), + scheduleEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailBennu", false), } \ No newline at end of file From 5e31638b92c1d3d8c4f85eafaf3cddc9db2f57ea Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 14:01:42 -0400 Subject: [PATCH 035/205] Enable the global Lua state when loading scheduled scripts from file --- include/openspace/scripting/scriptscheduler.h | 2 +- src/scripting/scriptscheduler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/openspace/scripting/scriptscheduler.h b/include/openspace/scripting/scriptscheduler.h index e0783d7c27..320bbac0a7 100644 --- a/include/openspace/scripting/scriptscheduler.h +++ b/include/openspace/scripting/scriptscheduler.h @@ -58,7 +58,7 @@ struct ScheduledScript { class ScriptScheduler { public: - void loadScripts(const std::string& filename); + void loadScripts(const std::string& filename, lua_State* L = nullptr); void loadScripts(const ghoul::Dictionary& dict); void skipTo(double time); diff --git a/src/scripting/scriptscheduler.cpp b/src/scripting/scriptscheduler.cpp index fa2bd0d03b..50ab2c1fd9 100644 --- a/src/scripting/scriptscheduler.cpp +++ b/src/scripting/scriptscheduler.cpp @@ -63,10 +63,10 @@ ScheduledScript::ScheduledScript(const ghoul::Dictionary& dict) } } -void ScriptScheduler::loadScripts(const std::string& filepath) { +void ScriptScheduler::loadScripts(const std::string& filepath, lua_State* L) { ghoul::Dictionary timedScriptsDict; try { - ghoul::lua::loadDictionaryFromFile(absPath(filepath), timedScriptsDict); + ghoul::lua::loadDictionaryFromFile(absPath(filepath), timedScriptsDict, L); } catch (const ghoul::RuntimeError& e) { LERROR(e.what()); @@ -145,7 +145,7 @@ namespace luascriptfunctions { return luaL_error(L, "filepath string is empty"); } - OsEng.scriptScheduler().loadScripts(missionFileName); + OsEng.scriptScheduler().loadScripts(missionFileName, L); } int skipTo(lua_State* L) { From 69681ea36e7251e4120759514998cee5ec7f2786 Mon Sep 17 00:00:00 2001 From: Erik Broberg Date: Tue, 30 Aug 2016 14:03:19 -0400 Subject: [PATCH 036/205] Move helper lua functions for script scheduling to scripts/common.lua --- data/scene/osirisrex/scheduled_scripts.lua | 32 +++++++--------------- scripts/common.lua | 22 +++++++++++++++ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/data/scene/osirisrex/scheduled_scripts.lua b/data/scene/osirisrex/scheduled_scripts.lua index 933b74c21b..3b73b485f9 100644 --- a/data/scene/osirisrex/scheduled_scripts.lua +++ b/data/scene/osirisrex/scheduled_scripts.lua @@ -1,25 +1,13 @@ -function enable(name, enabled) - return "openspace.setPropertyValue('" .. name .. ".renderable.enabled', " .. (enabled and "true" or "false") .. ");"; -end +-- Load the common helper functions +dofile(openspace.absPath('${SCRIPTS}/common.lua')) -function scheduleEnabled(time, name, enabled) - return - { - Time = time, - ReversibleLuaScript = { - Forward = enable(name, enabled), - Backward = enable(name, not enabled) - } - } -end - -return +return { - scheduleEnabled("2016 SEP 08 23:05:01", "OsirisRexTrailEarth", true), - scheduleEnabled("2016 SEP 09 00:00:00", "OsirisRexTrailSolarSystem", true), - scheduleEnabled("2016 SEP 09 02:00:00", "OsirisRexTrailEarth", false), - scheduleEnabled("2018 OCT 11 00:00:00", "OsirisRexTrailBennu", true), - scheduleEnabled("2018 OCT 15 00:00:00", "OsirisRexTrailSolarSystem", false), - scheduleEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailSolarSystem", true), - scheduleEnabled("2019 AUG 01 00:00:00", "OsirisRexTrailBennu", false), + helper.scheduledScript.enable("2016 SEP 08 23:05:01", "OsirisRexTrailEarth", true), + helper.scheduledScript.enable("2016 SEP 09 00:00:00", "OsirisRexTrailSolarSystem", true), + helper.scheduledScript.enable("2016 SEP 09 02:00:00", "OsirisRexTrailEarth", false), + helper.scheduledScript.enable("2018 OCT 11 00:00:00", "OsirisRexTrailBennu", true), + helper.scheduledScript.enable("2018 OCT 15 00:00:00", "OsirisRexTrailSolarSystem", false), + helper.scheduledScript.enable("2019 AUG 01 00:00:00", "OsirisRexTrailSolarSystem", true), + helper.scheduledScript.enable("2019 AUG 01 00:00:00", "OsirisRexTrailBennu", false), } \ No newline at end of file diff --git a/scripts/common.lua b/scripts/common.lua index f346422dbc..1597072c4d 100644 --- a/scripts/common.lua +++ b/scripts/common.lua @@ -4,6 +4,10 @@ helper = {} helper.renderable = {} helper.property = {} +-- These helpers are for scheduling lua scripts +-- See class ScriptScheduler and ScheduledScript for reference +helper.scheduledScript = {} + -- Function that sets the most common key bindings that are common to most (all?) -- scenes helper.setCommonKeys = function() @@ -70,3 +74,21 @@ helper.renderable.toggle = function(renderable) return helper.property.invert(renderable .. ".renderable.enabled") end +-- Function that returns the string that sets the enabled property of to +helper.renderable.enable = function(renderable, enabled) + return "openspace.setPropertyValue('" .. renderable .. ".renderable.enabled', " .. (enabled and "true" or "false") .. ");"; +end + +-- Function that returns a lua table specifying a reversible ScheduledScript for +-- setting the enabled property of to at time